@clubmed/trident-ui 2.0.0-beta.9 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/assets/trident-ui.css +3 -0
- package/chunks/Backdrop.js +1 -1
- package/chunks/Backdrop.js.map +1 -1
- package/chunks/Birthdate.js +27 -0
- package/chunks/Birthdate.js.map +1 -0
- package/chunks/Carousel.context.js +1548 -0
- package/chunks/Carousel.context.js.map +1 -0
- package/chunks/ChatMessage.js +14395 -0
- package/chunks/ChatMessage.js.map +1 -0
- package/chunks/CriteriaParticipants.js +415 -0
- package/chunks/CriteriaParticipants.js.map +1 -0
- package/chunks/DateField.js +196 -136
- package/chunks/DateField.js.map +1 -1
- package/chunks/Datepicker.js +2039 -0
- package/chunks/Datepicker.js.map +1 -0
- package/chunks/Day.js +88 -0
- package/chunks/Day.js.map +1 -0
- package/chunks/Range.js +2 -2
- package/chunks/Range.js.map +1 -1
- package/chunks/Tooltip.js +4461 -0
- package/chunks/Tooltip.js.map +1 -0
- package/chunks/addLeadingZeros.js +33 -0
- package/chunks/addLeadingZeros.js.map +1 -0
- package/chunks/addYears.js +18 -0
- package/chunks/addYears.js.map +1 -0
- package/chunks/chunk.js +11 -4
- package/chunks/client.js +18953 -0
- package/chunks/client.js.map +1 -0
- package/chunks/endOfMonth.js +17 -0
- package/chunks/endOfMonth.js.map +1 -0
- package/chunks/format.js +1113 -0
- package/chunks/format.js.map +1 -0
- package/chunks/formatISO.js +29 -0
- package/chunks/formatISO.js.map +1 -0
- package/chunks/isAfter.js +9 -0
- package/chunks/isAfter.js.map +1 -0
- package/chunks/isBefore.js +15 -0
- package/chunks/isBefore.js.map +1 -0
- package/chunks/normalizeDates.js +10 -0
- package/chunks/normalizeDates.js.map +1 -0
- package/chunks/subYears.js +9 -0
- package/chunks/subYears.js.map +1 -0
- package/examples/accordion-demo.d.ts +1 -0
- package/examples/accordion-demo.js +79 -0
- package/examples/accordion-demo.js.map +1 -0
- package/examples/accordion-multiple-demo.d.ts +1 -0
- package/examples/accordion-multiple-demo.js +79 -0
- package/examples/accordion-multiple-demo.js.map +1 -0
- package/examples/accordion-trigger-wrapper-demo.d.ts +1 -0
- package/examples/accordion-trigger-wrapper-demo.js +80 -0
- package/examples/accordion-trigger-wrapper-demo.js.map +1 -0
- package/examples/advanced-toast-demo.js +2 -2
- package/examples/advanced-toast-demo.js.map +1 -1
- package/examples/advanced-toast-green-demo.js +1 -1
- package/examples/advanced-toast-green-demo.js.map +1 -1
- package/examples/advanced-toast-no-dismiss-demo.js +1 -1
- package/examples/advanced-toast-no-dismiss-demo.js.map +1 -1
- package/examples/advanced-toast-red-demo.js +1 -1
- package/examples/advanced-toast-red-demo.js.map +1 -1
- package/examples/advanced-toast-with-details-demo.js +2 -2
- package/examples/advanced-toast-with-details-demo.js.map +1 -1
- package/examples/arrow-button-demo.js +2 -1
- package/examples/arrow-button-demo.js.map +1 -1
- package/examples/arrow-button-disabled-demo.js +2 -1
- package/examples/arrow-button-disabled-demo.js.map +1 -1
- package/examples/arrow-button-left-demo.js +2 -1
- package/examples/arrow-button-left-demo.js.map +1 -1
- package/examples/arrow-button-outline-demo.js +2 -1
- package/examples/arrow-button-outline-demo.js.map +1 -1
- package/examples/arrow-button-tail-demo.js +2 -1
- package/examples/arrow-button-tail-demo.js.map +1 -1
- package/examples/avatar-demo.js +7 -7
- package/examples/button-demo.js +2 -2
- package/examples/button-demo.js.map +1 -1
- package/examples/card-list-demo.js +10 -10
- package/examples/card-no-border-demo.js +7 -7
- package/examples/chapters-demo.d.ts +1 -0
- package/examples/chapters-demo.js +46 -0
- package/examples/chapters-demo.js.map +1 -0
- package/examples/chat-button-demo.js +1 -1
- package/examples/chat-button-demo.js.map +1 -1
- package/examples/chat-button-offset-demo.js +4 -1
- package/examples/chat-button-offset-demo.js.map +1 -1
- package/examples/chat-input-demo.d.ts +1 -0
- package/examples/chat-input-demo.js +22 -0
- package/examples/chat-input-demo.js.map +1 -0
- package/examples/chat-message-demo.d.ts +1 -0
- package/examples/chat-message-demo.js +20 -0
- package/examples/chat-message-demo.js.map +1 -0
- package/examples/chat-typing-indicator-demo.d.ts +1 -0
- package/examples/chat-typing-indicator-demo.js +14 -0
- package/examples/chat-typing-indicator-demo.js.map +1 -0
- package/examples/chat-window-csat-demo.d.ts +1 -0
- package/examples/chat-window-csat-demo.js +69 -0
- package/examples/chat-window-csat-demo.js.map +1 -0
- package/examples/chat-window-csat-prompt-demo.d.ts +1 -0
- package/examples/chat-window-csat-prompt-demo.js +40 -0
- package/examples/chat-window-csat-prompt-demo.js.map +1 -0
- package/examples/chat-window-demo.d.ts +1 -0
- package/examples/chat-window-demo.js +70 -0
- package/examples/chat-window-demo.js.map +1 -0
- package/examples/chat-window-quote-demo.d.ts +1 -0
- package/examples/chat-window-quote-demo.js +47 -0
- package/examples/chat-window-quote-demo.js.map +1 -0
- package/examples/chat-window-quotes-demo.d.ts +1 -0
- package/examples/chat-window-quotes-demo.js +68 -0
- package/examples/chat-window-quotes-demo.js.map +1 -0
- package/examples/checkbox-demo.js +2 -2
- package/examples/checkbox-demo.js.map +1 -1
- package/examples/checkbox-select-demo.d.ts +1 -0
- package/examples/checkbox-select-demo.js +101 -0
- package/examples/checkbox-select-demo.js.map +1 -0
- package/examples/checkboxes-demo.js +1 -0
- package/examples/checkboxes-demo.js.map +1 -1
- package/examples/checkboxes-with-form-control-demo.js +4 -4
- package/examples/chip-demo.js +4 -4
- package/examples/choice-expander-demo.js +5 -67
- package/examples/choice-expander-demo.js.map +1 -1
- package/examples/countdown-demo.d.ts +1 -0
- package/examples/countdown-demo.js +39 -0
- package/examples/countdown-demo.js.map +1 -0
- package/examples/criteria-dates-demo.d.ts +1 -0
- package/examples/criteria-dates-demo.js +41 -0
- package/examples/criteria-dates-demo.js.map +1 -0
- package/examples/criteria-participants-demo.d.ts +1 -0
- package/examples/criteria-participants-demo.js +77 -0
- package/examples/criteria-participants-demo.js.map +1 -0
- package/examples/criteria-participants-flow1-demo.d.ts +1 -0
- package/examples/criteria-participants-flow1-demo.js +53 -0
- package/examples/criteria-participants-flow1-demo.js.map +1 -0
- package/examples/criteria-participants-flow2-demo.d.ts +1 -0
- package/examples/criteria-participants-flow2-demo.js +61 -0
- package/examples/criteria-participants-flow2-demo.js.map +1 -0
- package/examples/criteria-participants-flow3-demo.d.ts +1 -0
- package/examples/criteria-participants-flow3-demo.js +72 -0
- package/examples/criteria-participants-flow3-demo.js.map +1 -0
- package/examples/criteria-transports-b2b-demo.d.ts +1 -0
- package/examples/criteria-transports-b2b-demo.js +118 -0
- package/examples/criteria-transports-b2b-demo.js.map +1 -0
- package/examples/criteria-transports-demo.d.ts +1 -0
- package/examples/criteria-transports-demo.js +223 -0
- package/examples/criteria-transports-demo.js.map +1 -0
- package/examples/datepicker-demo.d.ts +1 -0
- package/examples/datepicker-demo.js +51 -0
- package/examples/datepicker-demo.js.map +1 -0
- package/examples/datepicker-disabled-days-demo.d.ts +1 -0
- package/examples/datepicker-disabled-days-demo.js +42 -0
- package/examples/datepicker-disabled-days-demo.js.map +1 -0
- package/examples/datepicker-duration-tooltip-demo.d.ts +1 -0
- package/examples/datepicker-duration-tooltip-demo.js +68 -0
- package/examples/datepicker-duration-tooltip-demo.js.map +1 -0
- package/examples/datepicker-no-prices-demo.d.ts +1 -0
- package/examples/datepicker-no-prices-demo.js +42 -0
- package/examples/datepicker-no-prices-demo.js.map +1 -0
- package/examples/datepicker-preselected-demo.d.ts +1 -0
- package/examples/datepicker-preselected-demo.js +77 -0
- package/examples/datepicker-preselected-demo.js.map +1 -0
- package/examples/dropdown-demo.js +9 -1
- package/examples/dropdown-demo.js.map +1 -1
- package/examples/expandable-text-demo.d.ts +1 -0
- package/examples/expandable-text-demo.js +22 -0
- package/examples/expandable-text-demo.js.map +1 -0
- package/examples/filter-demo.js +5 -5
- package/examples/floating-label-text-field-demo.d.ts +1 -0
- package/examples/floating-label-text-field-demo.js +32 -0
- package/examples/floating-label-text-field-demo.js.map +1 -0
- package/examples/frame-demo.d.ts +1 -0
- package/examples/frame-demo.js +36 -0
- package/examples/frame-demo.js.map +1 -0
- package/examples/frame-horizontal-demo.d.ts +1 -0
- package/examples/frame-horizontal-demo.js +44 -0
- package/examples/frame-horizontal-demo.js.map +1 -0
- package/examples/frame-no-image-demo.d.ts +1 -0
- package/examples/frame-no-image-demo.js +47 -0
- package/examples/frame-no-image-demo.js.map +1 -0
- package/examples/frame-vertical-demo.d.ts +1 -0
- package/examples/frame-vertical-demo.js +44 -0
- package/examples/frame-vertical-demo.js.map +1 -0
- package/examples/frame-with-tag-demo.d.ts +1 -0
- package/examples/frame-with-tag-demo.js +48 -0
- package/examples/frame-with-tag-demo.js.map +1 -0
- package/examples/journey-card-compact-demo.d.ts +1 -0
- package/examples/journey-card-compact-demo.js +71 -0
- package/examples/journey-card-compact-demo.js.map +1 -0
- package/examples/journey-card-demo.d.ts +1 -0
- package/examples/journey-card-demo.js +123 -0
- package/examples/journey-card-demo.js.map +1 -0
- package/examples/page-navigation-demo.d.ts +1 -0
- package/examples/page-navigation-demo.js +53 -0
- package/examples/page-navigation-demo.js.map +1 -0
- package/examples/password-demo.js +1 -0
- package/examples/password-demo.js.map +1 -1
- package/examples/phone-field-demo.js +6 -2
- package/examples/phone-field-demo.js.map +1 -1
- package/examples/promises-demo.d.ts +1 -0
- package/examples/promises-demo.js +50 -0
- package/examples/promises-demo.js.map +1 -0
- package/examples/radio-demo.js +3 -3
- package/examples/radio-demo.js.map +1 -1
- package/examples/radio-select-demo.d.ts +1 -0
- package/examples/radio-select-demo.js +100 -0
- package/examples/radio-select-demo.js.map +1 -0
- package/examples/scrollbar-demo.d.ts +1 -0
- package/examples/scrollbar-demo.js +42 -0
- package/examples/scrollbar-demo.js.map +1 -0
- package/examples/select-demo.js +1 -0
- package/examples/select-demo.js.map +1 -1
- package/examples/slider-frame-demo.d.ts +1 -0
- package/examples/slider-frame-demo.js +39 -0
- package/examples/slider-frame-demo.js.map +1 -0
- package/examples/slider-frame-with-button-demo.d.ts +1 -0
- package/examples/slider-frame-with-button-demo.js +47 -0
- package/examples/slider-frame-with-button-demo.js.map +1 -0
- package/examples/slider-frame-with-tag-demo.d.ts +1 -0
- package/examples/slider-frame-with-tag-demo.js +51 -0
- package/examples/slider-frame-with-tag-demo.js.map +1 -0
- package/examples/sparkle-wrapper-demo.d.ts +1 -0
- package/examples/sparkle-wrapper-demo.js +34 -0
- package/examples/sparkle-wrapper-demo.js.map +1 -0
- package/examples/switch-demo.js +3 -2
- package/examples/switch-demo.js.map +1 -1
- package/examples/tabs-demo.js +2 -5
- package/examples/tabs-demo.js.map +1 -1
- package/examples/tabs-notification-demo.d.ts +1 -0
- package/examples/tabs-notification-demo.js +64 -0
- package/examples/tabs-notification-demo.js.map +1 -0
- package/examples/tabs-with-select-demo.js +1 -0
- package/examples/tabs-with-select-demo.js.map +1 -1
- package/examples/text-field-demo.js +6 -0
- package/examples/text-field-demo.js.map +1 -1
- package/examples/toggle-demo.d.ts +1 -0
- package/examples/toggle-demo.js +44 -0
- package/examples/toggle-demo.js.map +1 -0
- package/examples/toggle-small-demo.d.ts +1 -0
- package/examples/toggle-small-demo.js +33 -0
- package/examples/toggle-small-demo.js.map +1 -0
- package/examples/tooltip-demo.d.ts +1 -0
- package/examples/tooltip-demo.js +103 -0
- package/examples/tooltip-demo.js.map +1 -0
- package/package.json +9 -3
- package/styles/animate.css +19 -0
- package/styles/components.css +97 -4
- package/styles/index.css +0 -1
- package/styles/theme.css +1 -2
- package/styles/ui/button.css +1 -1
- package/styles/ui/chat-button.css +68 -1
- package/styles/ui/controls.css +11 -58
- package/styles/ui/range.css +6 -1
- package/styles/ui/tabs.css +0 -19
- package/ui/Accordion.d.ts +30 -0
- package/ui/Accordion.js +71 -0
- package/ui/Accordion.js.map +1 -0
- package/ui/AdvancedToast.js +22 -19
- package/ui/AdvancedToast.js.map +1 -1
- package/ui/Avatar.js +1 -1
- package/ui/Avatar.js.map +1 -1
- package/ui/BasicToast.js +12 -12
- package/ui/BasicToast.js.map +1 -1
- package/ui/Breadcrumb.js +7 -6
- package/ui/Breadcrumb.js.map +1 -1
- package/ui/Chapters/Chapter.d.ts +7 -0
- package/ui/Chapters/Chapter.js +36 -0
- package/ui/Chapters/Chapter.js.map +1 -0
- package/ui/Chapters/ChapterTitle.d.ts +14 -0
- package/ui/Chapters/ChapterTitle.js +35 -0
- package/ui/Chapters/ChapterTitle.js.map +1 -0
- package/ui/Chapters/Chapters.d.ts +15 -0
- package/ui/Chapters/Chapters.js +42 -0
- package/ui/Chapters/Chapters.js.map +1 -0
- package/ui/Chapters/Chapters.themes.d.ts +9 -0
- package/ui/Chapters/Chapters.themes.js +65 -0
- package/ui/Chapters/Chapters.themes.js.map +1 -0
- package/ui/Chapters/ChaptersSummary.d.ts +17 -0
- package/ui/Chapters/ChaptersSummary.js +29 -0
- package/ui/Chapters/ChaptersSummary.js.map +1 -0
- package/ui/ChatButton.js +9 -9
- package/ui/ChatButton.js.map +1 -1
- package/ui/ChatInput.d.ts +10 -0
- package/ui/ChatInput.js +149 -0
- package/ui/ChatInput.js.map +1 -0
- package/ui/ChatMessage.d.ts +6 -0
- package/ui/ChatMessage.js +2 -0
- package/ui/ChatTypingIndicator.d.ts +2 -0
- package/ui/ChatTypingIndicator.js +30 -0
- package/ui/ChatTypingIndicator.js.map +1 -0
- package/ui/ChatWindow.d.ts +34 -0
- package/ui/ChatWindow.js +142 -0
- package/ui/ChatWindow.js.map +1 -0
- package/ui/ChatWindowCsatPrompt.d.ts +15 -0
- package/ui/ChatWindowCsatPrompt.js +71 -0
- package/ui/ChatWindowCsatPrompt.js.map +1 -0
- package/ui/ChatWindowCsatThankYou.d.ts +9 -0
- package/ui/ChatWindowCsatThankYou.js +29 -0
- package/ui/ChatWindowCsatThankYou.js.map +1 -0
- package/ui/ChatWindowQuote.d.ts +22 -0
- package/ui/ChatWindowQuote.js +141 -0
- package/ui/ChatWindowQuote.js.map +1 -0
- package/ui/Chip.js +4 -4
- package/ui/ChoiceExpander.js +17 -17
- package/ui/ChoiceExpander.js.map +1 -1
- package/ui/Countdown.d.ts +16 -0
- package/ui/Countdown.js +61 -0
- package/ui/Countdown.js.map +1 -0
- package/ui/Datepicker.d.ts +26 -0
- package/ui/Datepicker.js +2 -0
- package/ui/Day.d.ts +25 -0
- package/ui/Day.js +2 -0
- package/ui/Dropdown.d.ts +20 -3
- package/ui/Dropdown.js +61 -27
- package/ui/Dropdown.js.map +1 -1
- package/ui/ElasticHeight.js +1 -0
- package/ui/ElasticHeight.js.map +1 -1
- package/ui/ExpandableText.d.ts +14 -0
- package/ui/ExpandableText.js +40 -0
- package/ui/ExpandableText.js.map +1 -0
- package/ui/FlipCard.d.ts +7 -0
- package/ui/FlipCard.js +59 -0
- package/ui/FlipCard.js.map +1 -0
- package/ui/HamburgerIcon.js +1 -1
- package/ui/HamburgerIcon.js.map +1 -1
- package/ui/Link.js +8 -8
- package/ui/Link.js.map +1 -1
- package/ui/PageNavigation.d.ts +13 -0
- package/ui/PageNavigation.js +71 -0
- package/ui/PageNavigation.js.map +1 -0
- package/ui/Pagination.js +23 -23
- package/ui/Pagination.js.map +1 -1
- package/ui/Promises/Promises.d.ts +26 -0
- package/ui/Promises/Promises.js +42 -0
- package/ui/Promises/Promises.js.map +1 -0
- package/ui/Promises/PromisesMedia.d.ts +12 -0
- package/ui/Promises/PromisesMedia.js +64 -0
- package/ui/Promises/PromisesMedia.js.map +1 -0
- package/ui/Promises/PromisesMenu.d.ts +11 -0
- package/ui/Promises/PromisesMenu.js +154 -0
- package/ui/Promises/PromisesMenu.js.map +1 -0
- package/ui/Scrollbar.d.ts +14 -0
- package/ui/Scrollbar.js +68 -0
- package/ui/Scrollbar.js.map +1 -0
- package/ui/SidebarLayout.d.ts +3 -1
- package/ui/SidebarLayout.js +67 -59
- package/ui/SidebarLayout.js.map +1 -1
- package/ui/SparkleWrapper.d.ts +5 -0
- package/ui/SparkleWrapper.js +56 -0
- package/ui/SparkleWrapper.js.map +1 -0
- package/ui/Tag.js +6 -6
- package/ui/Toggle.d.ts +15 -0
- package/ui/Toggle.js +42 -0
- package/ui/Toggle.js.map +1 -0
- package/ui/Tooltip.d.ts +8 -0
- package/ui/Tooltip.js +2 -0
- package/ui/buttons/Button.type.d.ts +1 -1
- package/ui/buttons/Button.type.js +1 -1
- package/ui/buttons/Button.type.js.map +1 -1
- package/ui/buttons/ButtonContent.js +3 -3
- package/ui/carousel/Carousel.context.d.ts +27 -0
- package/ui/carousel/Carousel.context.js +2 -0
- package/ui/carousel/Carousel.d.ts +3 -0
- package/ui/carousel/Carousel.js +12 -0
- package/ui/carousel/Carousel.js.map +1 -0
- package/ui/carousel/CarouselBody.d.ts +6 -0
- package/ui/carousel/CarouselBody.js +21 -0
- package/ui/carousel/CarouselBody.js.map +1 -0
- package/ui/carousel/CarouselItem.d.ts +6 -0
- package/ui/carousel/CarouselItem.js +21 -0
- package/ui/carousel/CarouselItem.js.map +1 -0
- package/ui/carousel/CarouselNext.d.ts +8 -0
- package/ui/carousel/CarouselNext.js +23 -0
- package/ui/carousel/CarouselNext.js.map +1 -0
- package/ui/carousel/CarouselPrevious.d.ts +8 -0
- package/ui/carousel/CarouselPrevious.js +23 -0
- package/ui/carousel/CarouselPrevious.js.map +1 -0
- package/ui/contexts/TridentUIConfig.js +1 -1
- package/ui/criteria/Birthdate.d.ts +13 -0
- package/ui/criteria/Birthdate.js +2 -0
- package/ui/criteria/CriteriaDates.d.ts +32 -0
- package/ui/criteria/CriteriaDates.js +76 -0
- package/ui/criteria/CriteriaDates.js.map +1 -0
- package/ui/criteria/CriteriaParticipants.d.ts +106 -0
- package/ui/criteria/CriteriaParticipants.js +2 -0
- package/ui/criteria/CriteriaSection.d.ts +6 -0
- package/ui/criteria/CriteriaSection.js +15 -0
- package/ui/criteria/CriteriaSection.js.map +1 -0
- package/ui/criteria/CriteriaTransports.d.ts +53 -0
- package/ui/criteria/CriteriaTransports.js +274 -0
- package/ui/criteria/CriteriaTransports.js.map +1 -0
- package/ui/forms/CheckboxSelect.d.ts +31 -0
- package/ui/forms/CheckboxSelect.js +119 -0
- package/ui/forms/CheckboxSelect.js.map +1 -0
- package/ui/forms/Filter.d.ts +3 -1
- package/ui/forms/Filter.js +17 -13
- package/ui/forms/Filter.js.map +1 -1
- package/ui/forms/FloatingLabelTextField.d.ts +12 -0
- package/ui/forms/FloatingLabelTextField.js +132 -0
- package/ui/forms/FloatingLabelTextField.js.map +1 -0
- package/ui/forms/FormControl.d.ts +1 -1
- package/ui/forms/FormControl.js.map +1 -1
- package/ui/forms/FormControlError.js +4 -4
- package/ui/forms/NumberField.d.ts +3 -2
- package/ui/forms/NumberField.js +24 -25
- package/ui/forms/NumberField.js.map +1 -1
- package/ui/forms/PhoneField.d.ts +5 -10
- package/ui/forms/PhoneField.js +31 -211
- package/ui/forms/PhoneField.js.map +1 -1
- package/ui/forms/PhoneFieldFullInput.d.ts +16 -0
- package/ui/forms/PhoneFieldFullInput.js +110 -0
- package/ui/forms/PhoneFieldFullInput.js.map +1 -0
- package/ui/forms/PhoneFieldSplitInput.d.ts +19 -0
- package/ui/forms/PhoneFieldSplitInput.js +158 -0
- package/ui/forms/PhoneFieldSplitInput.js.map +1 -0
- package/ui/forms/RadioSelect.d.ts +31 -0
- package/ui/forms/RadioSelect.js +117 -0
- package/ui/forms/RadioSelect.js.map +1 -0
- package/ui/forms/Range.d.ts +1 -1
- package/ui/forms/Select.js +16 -17
- package/ui/forms/Select.js.map +1 -1
- package/ui/forms/Switch.d.ts +5 -3
- package/ui/forms/Switch.js +54 -34
- package/ui/forms/Switch.js.map +1 -1
- package/ui/forms/TextField.js +33 -24
- package/ui/forms/TextField.js.map +1 -1
- package/ui/forms/checkboxes/Checkbox.d.ts +3 -1
- package/ui/forms/checkboxes/Checkbox.js +21 -17
- package/ui/forms/checkboxes/Checkbox.js.map +1 -1
- package/ui/forms/checkboxes/Checkboxes.d.ts +5 -0
- package/ui/forms/checkboxes/Checkboxes.js +8 -8
- package/ui/forms/checkboxes/Checkboxes.js.map +1 -1
- package/ui/forms/password/Password.js +19 -20
- package/ui/forms/password/Password.js.map +1 -1
- package/ui/forms/password/ValidationMessage.js +5 -5
- package/ui/forms/radios/Radio.d.ts +2 -1
- package/ui/forms/radios/Radio.js +6 -3
- package/ui/forms/radios/Radio.js.map +1 -1
- package/ui/forms/radios/RadioGroup.js +5 -6
- package/ui/forms/radios/RadioGroup.js.map +1 -1
- package/ui/frame/Frame.d.ts +8 -0
- package/ui/frame/Frame.js +16 -0
- package/ui/frame/Frame.js.map +1 -0
- package/ui/frame/FrameLabelsWrapper.d.ts +5 -0
- package/ui/frame/FrameLabelsWrapper.js +12 -0
- package/ui/frame/FrameLabelsWrapper.js.map +1 -0
- package/ui/frame/FrameTitle.d.ts +7 -0
- package/ui/frame/FrameTitle.js +25 -0
- package/ui/frame/FrameTitle.js.map +1 -0
- package/ui/frame/FrameWrapper.d.ts +6 -0
- package/ui/frame/FrameWrapper.js +14 -0
- package/ui/frame/FrameWrapper.js.map +1 -0
- package/ui/frame/SliderFrame.d.ts +14 -0
- package/ui/frame/SliderFrame.js +50 -0
- package/ui/frame/SliderFrame.js.map +1 -0
- package/ui/helpers/cn.d.ts +2 -0
- package/ui/helpers/cn.js +10 -0
- package/ui/helpers/cn.js.map +1 -0
- package/ui/helpers/phone/defaultPrefixes.d.ts +1 -0
- package/ui/helpers/phone/defaultPrefixes.js +52 -28
- package/ui/helpers/phone/defaultPrefixes.js.map +1 -1
- package/ui/helpers/phone/formatters.d.ts +11 -0
- package/ui/helpers/phone/formatters.js +32 -1
- package/ui/helpers/phone/formatters.js.map +1 -1
- package/ui/helpers/phone/index.d.ts +1 -1
- package/ui/helpers/phone/index.js +3 -3
- package/ui/hooks/useIsClient.d.ts +1 -0
- package/ui/hooks/useIsClient.js +12 -0
- package/ui/hooks/useIsClient.js.map +1 -0
- package/ui/hooks/useValue.d.ts +3 -4
- package/ui/hooks/useValue.js +11 -11
- package/ui/hooks/useValue.js.map +1 -1
- package/ui/journey-card/FlightSegmentCard.d.ts +15 -0
- package/ui/journey-card/FlightSegmentCard.js +73 -0
- package/ui/journey-card/FlightSegmentCard.js.map +1 -0
- package/ui/journey-card/FlightTimeline.d.ts +5 -0
- package/ui/journey-card/FlightTimeline.js +27 -0
- package/ui/journey-card/FlightTimeline.js.map +1 -0
- package/ui/journey-card/ItineraryDetails.d.ts +9 -0
- package/ui/journey-card/ItineraryDetails.js +40 -0
- package/ui/journey-card/ItineraryDetails.js.map +1 -0
- package/ui/journey-card/JourneyCard.d.ts +17 -0
- package/ui/journey-card/JourneyCard.js +34 -0
- package/ui/journey-card/JourneyCard.js.map +1 -0
- package/ui/journey-card/JourneyDetails.d.ts +47 -0
- package/ui/journey-card/JourneyDetails.js +183 -0
- package/ui/journey-card/JourneyDetails.js.map +1 -0
- package/ui/tabs/Tabs.d.ts +5 -1
- package/ui/tabs/Tabs.js +208 -124
- package/ui/tabs/Tabs.js.map +1 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { t as e } from "../../chunks/clsx.js";
|
|
3
|
+
import { Heading as t } from "../heading/Heading.js";
|
|
4
|
+
import { getTheme as n } from "./Chapters.themes.js";
|
|
5
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
6
|
+
import { Icon as a } from "@clubmed/trident-icons";
|
|
7
|
+
//#region lib/ui/Chapters/ChapterTitle.tsx
|
|
8
|
+
var o = ({ children: o, className: s, hasNext: c = !1, hLevel: l = 2, index: u, isActive: d = !1, onClick: f, theme: p = "coreRange" }) => {
|
|
9
|
+
let { thTitle: m, thTitleUnActive: h } = n(p);
|
|
10
|
+
return /* @__PURE__ */ i(t, {
|
|
11
|
+
className: e("text-h5 @md:text-h2 sticky top-0 z-1 flex justify-between gap-x-8 p-20 font-serif transition-colors duration-300 @md:static @md:bg-transparent @md:p-0", m, s),
|
|
12
|
+
id: `chapter${u}`,
|
|
13
|
+
level: l,
|
|
14
|
+
children: [/* @__PURE__ */ i("a", {
|
|
15
|
+
className: e("flex-1", { [h]: !d }),
|
|
16
|
+
href: `#chapter${u}`,
|
|
17
|
+
onClick: f,
|
|
18
|
+
children: [/* @__PURE__ */ i("span", {
|
|
19
|
+
className: "@md:hidden",
|
|
20
|
+
children: [u + 1, " - "]
|
|
21
|
+
}), o]
|
|
22
|
+
}), c && /* @__PURE__ */ r("a", {
|
|
23
|
+
className: "@md:hidden",
|
|
24
|
+
href: `#chapter${u + 1}`,
|
|
25
|
+
children: /* @__PURE__ */ r(a, {
|
|
26
|
+
name: "ArrowTailDown",
|
|
27
|
+
width: "24px"
|
|
28
|
+
})
|
|
29
|
+
})]
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
export { o as ChapterTitle };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=ChapterTitle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChapterTitle.js","names":[],"sources":["../../../lib/ui/Chapters/ChapterTitle.tsx"],"sourcesContent":["'use client';\nimport clsx from 'clsx';\nimport type { ComponentProps, FunctionComponent, PropsWithChildren } from 'react';\n\nimport { Icon } from '@clubmed/trident-icons';\nimport { Heading } from '../heading/Heading';\nimport type { Theme } from '../types/Theme';\n\nimport { getTheme } from './Chapters.themes';\n\ninterface Props {\n className?: string;\n hasNext?: boolean;\n hLevel?: ComponentProps<typeof Heading>['level'];\n index: number;\n isActive?: boolean;\n onClick?: () => void;\n theme?: Theme;\n}\n\nexport const ChapterTitle: FunctionComponent<PropsWithChildren<Props>> = ({\n children,\n className,\n hasNext = false,\n hLevel = 2,\n index,\n isActive = false,\n onClick,\n theme = 'coreRange',\n}) => {\n const { thTitle, thTitleUnActive } = getTheme(theme);\n\n return (\n <Heading\n className={clsx(\n 'text-h5 @md:text-h2 sticky top-0 z-1 flex justify-between gap-x-8 p-20 font-serif transition-colors duration-300 @md:static @md:bg-transparent @md:p-0',\n thTitle,\n className,\n )}\n id={`chapter${index}`}\n level={hLevel}\n >\n <a\n className={clsx('flex-1', {\n [thTitleUnActive]: !isActive,\n })}\n href={`#chapter${index}`}\n onClick={onClick}\n >\n <span className=\"@md:hidden\">{index + 1} - </span>\n {children}\n </a>\n {hasNext && (\n <a className=\"@md:hidden\" href={`#chapter${index + 1}`}>\n <Icon name=\"ArrowTailDown\" width=\"24px\" />\n </a>\n )}\n </Heading>\n );\n};\n"],"mappings":";;;;;;;AAoBA,IAAa,KAA6D,EACxE,aACA,cACA,aAAU,IACV,YAAS,GACT,UACA,cAAW,IACX,YACA,WAAQ,kBACJ;CACJ,IAAM,EAAE,YAAS,uBAAoB,EAAS,EAAM;AAEpD,QACE,kBAAC,GAAD;EACE,WAAW,EACT,0JACA,GACA,EACD;EACD,IAAI,UAAU;EACd,OAAO;YAPT,CASE,kBAAC,KAAD;GACE,WAAW,EAAK,UAAU,GACvB,IAAkB,CAAC,GACrB,CAAC;GACF,MAAM,WAAW;GACR;aALX,CAOE,kBAAC,QAAD;IAAM,WAAU;cAAhB,CAA8B,IAAQ,GAAE,MAAA;OACvC,EAAA;MAEF,KACC,kBAAC,KAAD;GAAG,WAAU;GAAa,MAAM,WAAW,IAAQ;aACjD,kBAAC,GAAD;IAAM,MAAK;IAAgB,OAAM;IAAS,CAAA;GACxC,CAAA,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef, FunctionComponent, ReactNode } from 'react';
|
|
2
|
+
import { IconicNames } from '@clubmed/trident-icons';
|
|
3
|
+
import { Theme } from '../types/Theme';
|
|
4
|
+
export interface ChapterItem {
|
|
5
|
+
content: ReactNode;
|
|
6
|
+
title: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ChaptersProps extends Omit<ComponentPropsWithoutRef<'section'>, 'onClick' | 'children'> {
|
|
9
|
+
chapters: ChapterItem[];
|
|
10
|
+
hLevel?: 2 | 3 | 4;
|
|
11
|
+
icon?: IconicNames;
|
|
12
|
+
onClick?: (chapter: ChapterItem) => void;
|
|
13
|
+
theme?: Theme;
|
|
14
|
+
}
|
|
15
|
+
export declare const Chapters: FunctionComponent<ChaptersProps>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { t as e } from "../../chunks/clsx.js";
|
|
3
|
+
import { Chapter as t } from "./Chapter.js";
|
|
4
|
+
import { ChapterTitle as n } from "./ChapterTitle.js";
|
|
5
|
+
import { ChaptersSummary as r } from "./ChaptersSummary.js";
|
|
6
|
+
import { useState as i } from "react";
|
|
7
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
8
|
+
//#region lib/ui/Chapters/Chapters.tsx
|
|
9
|
+
var s = ({ chapters: s, className: c, hLevel: l = 2, icon: u, onClick: d, theme: f = "coreRange", ...p }) => {
|
|
10
|
+
let [m, h] = i(0);
|
|
11
|
+
return /* @__PURE__ */ o("section", {
|
|
12
|
+
...p,
|
|
13
|
+
className: e(c, "flex @container/chapters"),
|
|
14
|
+
children: [/* @__PURE__ */ a(r, {
|
|
15
|
+
activeChapter: m,
|
|
16
|
+
chapters: s,
|
|
17
|
+
className: "hidden w-3/10 @md:block @xl:w-[calc(50%-380px)]",
|
|
18
|
+
icon: u,
|
|
19
|
+
onClick: d,
|
|
20
|
+
theme: f
|
|
21
|
+
}), /* @__PURE__ */ a("div", {
|
|
22
|
+
className: e("relative isolate w-full flex-1 @md:max-w-7/10 @xl:max-w-[calc(50%+380px)]", "@md:ps-20 @lg:ps-40 @xl:ps-120"),
|
|
23
|
+
children: s.map((e, r) => /* @__PURE__ */ o(t, {
|
|
24
|
+
index: r,
|
|
25
|
+
setActiveChapter: h,
|
|
26
|
+
children: [/* @__PURE__ */ a(n, {
|
|
27
|
+
hasNext: r < s.length - 1,
|
|
28
|
+
hLevel: l,
|
|
29
|
+
index: r,
|
|
30
|
+
isActive: r === m,
|
|
31
|
+
onClick: () => d?.(e),
|
|
32
|
+
theme: f,
|
|
33
|
+
children: e.title
|
|
34
|
+
}), e.content]
|
|
35
|
+
}, e.title))
|
|
36
|
+
})]
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
export { s as Chapters };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=Chapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Chapters.js","names":[],"sources":["../../../lib/ui/Chapters/Chapters.tsx"],"sourcesContent":["'use client';\nimport clsx from 'clsx';\nimport {\n useState,\n type ComponentPropsWithoutRef,\n type FunctionComponent,\n type ReactNode,\n} from 'react';\n\nimport type { IconicNames } from '@clubmed/trident-icons';\nimport type { Theme } from '../types/Theme';\n\nimport { Chapter } from './Chapter';\nimport { ChapterTitle } from './ChapterTitle';\nimport { ChaptersSummary } from './ChaptersSummary';\n\nexport interface ChapterItem {\n content: ReactNode;\n title: string;\n}\n\nexport interface ChaptersProps\n extends Omit<ComponentPropsWithoutRef<'section'>, 'onClick' | 'children'> {\n chapters: ChapterItem[];\n hLevel?: 2 | 3 | 4;\n icon?: IconicNames;\n onClick?: (chapter: ChapterItem) => void;\n theme?: Theme;\n}\n\nexport const Chapters: FunctionComponent<ChaptersProps> = ({\n chapters,\n className,\n hLevel = 2,\n icon,\n onClick,\n theme = 'coreRange',\n ...attrs\n}) => {\n const [activeChapter, setActiveChapter] = useState(0);\n\n return (\n <section {...attrs} className={clsx(className, 'flex @container/chapters')}>\n <ChaptersSummary\n activeChapter={activeChapter}\n chapters={chapters}\n className=\"hidden w-3/10 @md:block @xl:w-[calc(50%-380px)]\"\n icon={icon}\n onClick={onClick}\n theme={theme}\n />\n\n <div\n className={clsx(\n 'relative isolate w-full flex-1 @md:max-w-7/10 @xl:max-w-[calc(50%+380px)]',\n '@md:ps-20 @lg:ps-40 @xl:ps-120',\n )}\n >\n {chapters.map((chapter, index) => (\n <Chapter index={index} key={chapter.title} setActiveChapter={setActiveChapter}>\n <ChapterTitle\n hasNext={index < chapters.length - 1}\n hLevel={hLevel}\n index={index}\n isActive={index === activeChapter}\n onClick={() => onClick?.(chapter)}\n theme={theme}\n >\n {chapter.title}\n </ChapterTitle>\n {chapter.content}\n </Chapter>\n ))}\n </div>\n </section>\n );\n};\n"],"mappings":";;;;;;;;AA8BA,IAAa,KAA8C,EACzD,aACA,cACA,YAAS,GACT,SACA,YACA,WAAQ,aACR,GAAG,QACC;CACJ,IAAM,CAAC,GAAe,KAAoB,EAAS,EAAE;AAErD,QACE,kBAAC,WAAD;EAAS,GAAI;EAAO,WAAW,EAAK,GAAW,2BAA2B;YAA1E,CACE,kBAAC,GAAD;GACiB;GACL;GACV,WAAU;GACJ;GACG;GACF;GACP,CAAA,EAEF,kBAAC,OAAD;GACE,WAAW,EACT,6EACA,iCACD;aAEA,EAAS,KAAK,GAAS,MACtB,kBAAC,GAAD;IAAgB;IAA6C;cAA7D,CACE,kBAAC,GAAD;KACE,SAAS,IAAQ,EAAS,SAAS;KAC3B;KACD;KACP,UAAU,MAAU;KACpB,eAAe,IAAU,EAAQ;KAC1B;eAEN,EAAQ;KACI,CAAA,EACd,EAAQ,QAAA;MAXiB,EAAQ,MAY1B,CAAA;GAER,CAAA,CAAA"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
//#region lib/ui/Chapters/Chapters.themes.ts
|
|
2
|
+
var e = {
|
|
3
|
+
BLACK: {
|
|
4
|
+
thSummary: "bg-black text-white",
|
|
5
|
+
thSummaryIcon: "text-white max-w-140",
|
|
6
|
+
thSummaryIconName: "Trident",
|
|
7
|
+
thSummaryIconWidth: "100%",
|
|
8
|
+
thTitle: "bg-black text-white",
|
|
9
|
+
thTitleUnActive: "max-md:text-white/50"
|
|
10
|
+
},
|
|
11
|
+
CORE_RANGE: {
|
|
12
|
+
thSummary: "bg-lightSand text-black",
|
|
13
|
+
thSummaryIcon: "text-sand max-w-140",
|
|
14
|
+
thSummaryIconName: "Trident",
|
|
15
|
+
thSummaryIconWidth: "100%",
|
|
16
|
+
thTitle: "bg-lightSand text-black",
|
|
17
|
+
thTitleUnActive: "max-md:text-black/50"
|
|
18
|
+
},
|
|
19
|
+
EXCLUSIVE_COLLECTION: {
|
|
20
|
+
thSummary: "bg-ultramarine text-white",
|
|
21
|
+
thSummaryIcon: "text-white max-w-220",
|
|
22
|
+
thSummaryIconName: "ExclusiveCollection",
|
|
23
|
+
thSummaryIconWidth: "100%",
|
|
24
|
+
thTitle: "bg-ultramarine text-white md:text-black",
|
|
25
|
+
thTitleUnActive: "max-md:text-white/50"
|
|
26
|
+
},
|
|
27
|
+
HAPPY_TO_CARE: {
|
|
28
|
+
thSummary: "bg-verdigris text-black",
|
|
29
|
+
thSummaryIcon: "text-black max-w-220",
|
|
30
|
+
thSummaryIconName: "HappyToCare",
|
|
31
|
+
thSummaryIconWidth: "100%",
|
|
32
|
+
thTitle: "bg-verdigris text-black",
|
|
33
|
+
thTitleUnActive: "max-md:text-black/50"
|
|
34
|
+
},
|
|
35
|
+
SIENNA: {
|
|
36
|
+
thSummary: "bg-sienna text-white",
|
|
37
|
+
thSummaryIcon: "text-white max-w-140",
|
|
38
|
+
thSummaryIconName: "Trident",
|
|
39
|
+
thSummaryIconWidth: "100%",
|
|
40
|
+
thTitle: "bg-sienna text-white md:text-black",
|
|
41
|
+
thTitleUnActive: "max-md:text-white/50"
|
|
42
|
+
},
|
|
43
|
+
WHITE: {
|
|
44
|
+
thSummary: "bg-white text-black",
|
|
45
|
+
thSummaryIcon: "text-sand max-w-140",
|
|
46
|
+
thSummaryIconName: "Trident",
|
|
47
|
+
thSummaryIconWidth: "100%",
|
|
48
|
+
thTitle: "bg-white text-black",
|
|
49
|
+
thTitleUnActive: "max-md:text-black/50"
|
|
50
|
+
}
|
|
51
|
+
}, t = (t) => {
|
|
52
|
+
switch (t) {
|
|
53
|
+
case "black": return e.BLACK;
|
|
54
|
+
case "dark":
|
|
55
|
+
case "exclusiveCollection": return e.EXCLUSIVE_COLLECTION;
|
|
56
|
+
case "happyToCare": return e.HAPPY_TO_CARE;
|
|
57
|
+
case "sienna": return e.SIENNA;
|
|
58
|
+
case "white": return e.WHITE;
|
|
59
|
+
default: return e.CORE_RANGE;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
//#endregion
|
|
63
|
+
export { t as getTheme };
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=Chapters.themes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Chapters.themes.js","names":[],"sources":["../../../lib/ui/Chapters/Chapters.themes.ts"],"sourcesContent":["import type { Theme } from '../types/Theme';\n\nconst THEMES = {\n BLACK: {\n thSummary: 'bg-black text-white',\n thSummaryIcon: 'text-white max-w-140',\n thSummaryIconName: 'Trident',\n thSummaryIconWidth: '100%',\n thTitle: 'bg-black text-white',\n thTitleUnActive: 'max-md:text-white/50',\n },\n CORE_RANGE: {\n thSummary: 'bg-lightSand text-black',\n thSummaryIcon: 'text-sand max-w-140',\n thSummaryIconName: 'Trident',\n thSummaryIconWidth: '100%',\n thTitle: 'bg-lightSand text-black',\n thTitleUnActive: 'max-md:text-black/50',\n },\n EXCLUSIVE_COLLECTION: {\n thSummary: 'bg-ultramarine text-white',\n thSummaryIcon: 'text-white max-w-220',\n thSummaryIconName: 'ExclusiveCollection',\n thSummaryIconWidth: '100%',\n thTitle: 'bg-ultramarine text-white md:text-black',\n thTitleUnActive: 'max-md:text-white/50',\n },\n HAPPY_TO_CARE: {\n thSummary: 'bg-verdigris text-black',\n thSummaryIcon: 'text-black max-w-220',\n thSummaryIconName: 'HappyToCare',\n thSummaryIconWidth: '100%',\n thTitle: 'bg-verdigris text-black',\n thTitleUnActive: 'max-md:text-black/50',\n },\n SIENNA: {\n thSummary: 'bg-sienna text-white',\n thSummaryIcon: 'text-white max-w-140',\n thSummaryIconName: 'Trident',\n thSummaryIconWidth: '100%',\n thTitle: 'bg-sienna text-white md:text-black',\n thTitleUnActive: 'max-md:text-white/50',\n },\n WHITE: {\n thSummary: 'bg-white text-black',\n thSummaryIcon: 'text-sand max-w-140',\n thSummaryIconName: 'Trident',\n thSummaryIconWidth: '100%',\n thTitle: 'bg-white text-black',\n thTitleUnActive: 'max-md:text-black/50',\n },\n};\n\nexport const getTheme = (theme: Theme) => {\n switch (theme) {\n case 'black':\n return THEMES.BLACK;\n case 'dark':\n case 'exclusiveCollection':\n return THEMES.EXCLUSIVE_COLLECTION;\n case 'happyToCare':\n return THEMES.HAPPY_TO_CARE;\n case 'sienna':\n return THEMES.SIENNA;\n case 'white':\n return THEMES.WHITE;\n case 'light':\n case 'coreRange':\n default:\n return THEMES.CORE_RANGE;\n }\n};\n"],"mappings":";AAEA,IAAM,IAAS;CACb,OAAO;EACL,WAAW;EACX,eAAe;EACf,mBAAmB;EACnB,oBAAoB;EACpB,SAAS;EACT,iBAAiB;EAClB;CACD,YAAY;EACV,WAAW;EACX,eAAe;EACf,mBAAmB;EACnB,oBAAoB;EACpB,SAAS;EACT,iBAAiB;EAClB;CACD,sBAAsB;EACpB,WAAW;EACX,eAAe;EACf,mBAAmB;EACnB,oBAAoB;EACpB,SAAS;EACT,iBAAiB;EAClB;CACD,eAAe;EACb,WAAW;EACX,eAAe;EACf,mBAAmB;EACnB,oBAAoB;EACpB,SAAS;EACT,iBAAiB;EAClB;CACD,QAAQ;EACN,WAAW;EACX,eAAe;EACf,mBAAmB;EACnB,oBAAoB;EACpB,SAAS;EACT,iBAAiB;EAClB;CACD,OAAO;EACL,WAAW;EACX,eAAe;EACf,mBAAmB;EACnB,oBAAoB;EACpB,SAAS;EACT,iBAAiB;EAClB;CACF,EAEY,KAAY,MAAiB;AACxC,SAAQ,GAAR;EACE,KAAK,QACH,QAAO,EAAO;EAChB,KAAK;EACL,KAAK,sBACH,QAAO,EAAO;EAChB,KAAK,cACH,QAAO,EAAO;EAChB,KAAK,SACH,QAAO,EAAO;EAChB,KAAK,QACH,QAAO,EAAO;EAGhB,QACE,QAAO,EAAO"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FunctionComponent, ReactNode } from 'react';
|
|
2
|
+
import { IconicNames } from '@clubmed/trident-icons';
|
|
3
|
+
import { Theme } from '../types/Theme';
|
|
4
|
+
interface ChapterSummaryItem {
|
|
5
|
+
content: ReactNode;
|
|
6
|
+
title: string;
|
|
7
|
+
}
|
|
8
|
+
interface Props {
|
|
9
|
+
activeChapter: number;
|
|
10
|
+
chapters: ChapterSummaryItem[];
|
|
11
|
+
className?: string;
|
|
12
|
+
icon?: IconicNames;
|
|
13
|
+
onClick?: (chapter: ChapterSummaryItem) => void;
|
|
14
|
+
theme?: Theme;
|
|
15
|
+
}
|
|
16
|
+
export declare const ChaptersSummary: FunctionComponent<Props>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { t as e } from "../../chunks/clsx.js";
|
|
3
|
+
import { getTheme as t } from "./Chapters.themes.js";
|
|
4
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
5
|
+
import { Icon as i } from "@clubmed/trident-icons";
|
|
6
|
+
//#region lib/ui/Chapters/ChaptersSummary.tsx
|
|
7
|
+
var a = { HappyToCareFRCA: "translate-y-[28px]" }, o = ({ activeChapter: o, chapters: s, className: c, icon: l, onClick: u, theme: d = "coreRange" }) => {
|
|
8
|
+
let { thSummary: f, thSummaryIcon: p, thSummaryIconName: m, thSummaryIconWidth: h } = t(d), g = l ?? m, _ = a[g];
|
|
9
|
+
return /* @__PURE__ */ n("div", {
|
|
10
|
+
className: e("rounded-e-16", f, c),
|
|
11
|
+
children: /* @__PURE__ */ r("nav", {
|
|
12
|
+
className: "sticky top-0 ms-auto flex w-full max-w-380 flex-col gap-y-20 p-40",
|
|
13
|
+
children: [s.map((t, r) => /* @__PURE__ */ n("a", {
|
|
14
|
+
className: e("text-h5 block font-serif", { "opacity-50": r !== o }),
|
|
15
|
+
href: `#chapter${r}`,
|
|
16
|
+
onClick: () => u?.(t),
|
|
17
|
+
children: t.title
|
|
18
|
+
}, t.title)), /* @__PURE__ */ n(i, {
|
|
19
|
+
className: e("mt-90 self-center", p, _),
|
|
20
|
+
name: g,
|
|
21
|
+
width: h
|
|
22
|
+
})]
|
|
23
|
+
})
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { o as ChaptersSummary };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=ChaptersSummary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChaptersSummary.js","names":[],"sources":["../../../lib/ui/Chapters/ChaptersSummary.tsx"],"sourcesContent":["'use client';\nimport clsx from 'clsx';\nimport type { FunctionComponent, ReactNode } from 'react';\n\nimport { Icon, type IconicNames } from '@clubmed/trident-icons';\nimport type { Theme } from '../types/Theme';\n\nimport { getTheme } from './Chapters.themes';\n\nconst ICON_VERTICAL_OFFSET_CLASS: Partial<Record<IconicNames, string>> = {\n // FR-CA asset has an intrinsic Y offset; compensate to match EN-CA visual alignment.\n HappyToCareFRCA: 'translate-y-[28px]',\n};\n\ninterface ChapterSummaryItem {\n content: ReactNode;\n title: string;\n}\n\ninterface Props {\n activeChapter: number;\n chapters: ChapterSummaryItem[];\n className?: string;\n icon?: IconicNames;\n onClick?: (chapter: ChapterSummaryItem) => void;\n theme?: Theme;\n}\n\nexport const ChaptersSummary: FunctionComponent<Props> = ({\n activeChapter,\n chapters,\n className,\n icon,\n onClick,\n theme = 'coreRange',\n}) => {\n const { thSummary, thSummaryIcon, thSummaryIconName, thSummaryIconWidth } = getTheme(theme);\n const summaryIconName = (icon ?? thSummaryIconName) as IconicNames;\n const iconVerticalOffsetClass = ICON_VERTICAL_OFFSET_CLASS[summaryIconName];\n\n return (\n <div className={clsx('rounded-e-16', thSummary, className)}>\n <nav className=\"sticky top-0 ms-auto flex w-full max-w-380 flex-col gap-y-20 p-40\">\n {chapters.map((chapter, index) => (\n <a\n className={clsx('text-h5 block font-serif', {\n 'opacity-50': index !== activeChapter,\n })}\n href={`#chapter${index}`}\n key={chapter.title}\n onClick={() => onClick?.(chapter)}\n >\n {chapter.title}\n </a>\n ))}\n <Icon\n className={clsx('mt-90 self-center', thSummaryIcon, iconVerticalOffsetClass)}\n name={summaryIconName}\n width={thSummaryIconWidth}\n />\n </nav>\n </div>\n );\n};\n"],"mappings":";;;;;;AASA,IAAM,IAAmE,EAEvE,iBAAiB,sBAClB,EAgBY,KAA6C,EACxD,kBACA,aACA,cACA,SACA,YACA,WAAQ,kBACJ;CACJ,IAAM,EAAE,cAAW,kBAAe,sBAAmB,0BAAuB,EAAS,EAAM,EACrF,IAAmB,KAAQ,GAC3B,IAA0B,EAA2B;AAE3D,QACE,kBAAC,OAAD;EAAK,WAAW,EAAK,gBAAgB,GAAW,EAAU;YACxD,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAS,KAAK,GAAS,MACtB,kBAAC,KAAD;IACE,WAAW,EAAK,4BAA4B,EAC1C,cAAc,MAAU,GACzB,CAAC;IACF,MAAM,WAAW;IAEjB,eAAe,IAAU,EAAQ;cAEhC,EAAQ;IACP,EAJG,EAAQ,MAIX,CACJ,EACF,kBAAC,GAAD;IACE,WAAW,EAAK,qBAAqB,GAAe,EAAwB;IAC5E,MAAM;IACN,OAAO;IACP,CAAA,CAAA;;EAEA,CAAA"}
|
package/ui/ChatButton.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { twMerge as e } from "./helpers/twMerge.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
3
|
+
import { Icon as r } from "@clubmed/trident-icons";
|
|
4
4
|
//#region lib/ui/ChatButton.tsx
|
|
5
|
-
var i = "
|
|
5
|
+
var i = "AI Agent: Have you got a question?", a = "Chat with your assistant";
|
|
6
6
|
function o({ children: o = i, className: s, type: c = "button", "aria-label": l, tabIndex: u, offset: d, unfoldOn: f = "hover", ...p }) {
|
|
7
7
|
let m = l ?? (typeof o == "string" && o.trim().length > 0 ? o.trim() : a);
|
|
8
|
-
return /* @__PURE__ */
|
|
8
|
+
return /* @__PURE__ */ n("button", {
|
|
9
9
|
type: c,
|
|
10
10
|
"aria-label": m,
|
|
11
11
|
tabIndex: u ?? 0,
|
|
12
12
|
...p,
|
|
13
|
-
className: e("chat-
|
|
14
|
-
children: [/* @__PURE__ */
|
|
13
|
+
className: e("chat-border grid grid-cols-[24px_0fr] transition-[grid-template-columns] justify-center items-center overflow-hidden cursor-pointer transition-all rounded-pill px-8 md:px-16 outline-none group/Chatbutton focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2 pointer-events-auto h-48 min-h-48 md:min-w-80 md:h-80 active:scale-[0.98]", d && "md:translate-x-[40px] focus-visible:translate-x-0", f === "hover" && "group/hoverChatbutton hover:grid-cols-[24px_1fr] hover:translate-x-0", f === "active" && "group/activeChatbutton active:grid-cols-[24px_1fr] active:translate-x-0", "focus-visible:grid-cols-[24px_1fr]", s),
|
|
14
|
+
children: [/* @__PURE__ */ t(r, {
|
|
15
15
|
name: "Sparkles",
|
|
16
16
|
className: e("chat-button-icon w-24 transition-all", d && "relative md:start-[calc(-16px)] group-focus-visible/Chatbutton:start-0 group-hover/hoverChatbutton:start-0 group-active/activeChatbutton:start-0")
|
|
17
|
-
}), /* @__PURE__ */
|
|
17
|
+
}), /* @__PURE__ */ t("div", {
|
|
18
18
|
className: "grid grid-cols-[0fr] overflow-hidden opacity-0 transition-opacity group-hover/hoverChatbutton:opacity-100 group-focus-visible/Chatbutton:opacity-100 group-active/activeChatbutton:opacity-100 duration-500",
|
|
19
|
-
children: /* @__PURE__ */
|
|
19
|
+
children: /* @__PURE__ */ n("span", {
|
|
20
20
|
"aria-hidden": "true",
|
|
21
21
|
className: "chat-button-text items-center ps-20 flex gap-10 whitespace-nowrap font-semibold text-b3 text-black",
|
|
22
|
-
children: [o, /* @__PURE__ */
|
|
22
|
+
children: [o, /* @__PURE__ */ t(r, {
|
|
23
23
|
name: "ArrowTailRight",
|
|
24
24
|
width: "24px"
|
|
25
25
|
})]
|
package/ui/ChatButton.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatButton.js","names":[],"sources":["../../lib/ui/ChatButton.tsx"],"sourcesContent":["import { Icon } from '@clubmed/trident-icons';\nimport type { ButtonHTMLAttributes } from 'react';\nimport { twMerge } from './helpers/twMerge';\n\nconst DEFAULT_TEASER_COPY = '
|
|
1
|
+
{"version":3,"file":"ChatButton.js","names":[],"sources":["../../lib/ui/ChatButton.tsx"],"sourcesContent":["import { Icon } from '@clubmed/trident-icons';\nimport type { ButtonHTMLAttributes } from 'react';\nimport { twMerge } from './helpers/twMerge';\n\nconst DEFAULT_TEASER_COPY = 'AI Agent: Have you got a question?';\nconst FALLBACK_ARIA_LABEL = 'Chat with your assistant';\n\nexport type ChatButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n offset?: boolean;\n unfoldOn?: 'hover' | 'active';\n};\n\nexport function ChatButton({\n children = DEFAULT_TEASER_COPY,\n className,\n type = 'button',\n 'aria-label': ariaLabel,\n tabIndex,\n offset,\n unfoldOn = 'hover',\n ...rest\n}: ChatButtonProps) {\n const label =\n ariaLabel ??\n (typeof children === 'string' && children.trim().length > 0\n ? children.trim()\n : FALLBACK_ARIA_LABEL);\n\n return (\n <button\n type={type}\n aria-label={label}\n tabIndex={tabIndex ?? 0}\n {...rest}\n className={twMerge(\n 'chat-border grid grid-cols-[24px_0fr] transition-[grid-template-columns] justify-center items-center overflow-hidden cursor-pointer transition-all rounded-pill px-8 md:px-16 outline-none group/Chatbutton focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2 pointer-events-auto h-48 min-h-48 md:min-w-80 md:h-80 active:scale-[0.98]',\n offset && 'md:translate-x-[40px] focus-visible:translate-x-0',\n unfoldOn === 'hover' &&\n 'group/hoverChatbutton hover:grid-cols-[24px_1fr] hover:translate-x-0',\n unfoldOn === 'active' &&\n 'group/activeChatbutton active:grid-cols-[24px_1fr] active:translate-x-0',\n 'focus-visible:grid-cols-[24px_1fr]',\n className,\n )}\n >\n <Icon\n name=\"Sparkles\"\n className={twMerge(\n 'chat-button-icon w-24 transition-all',\n offset &&\n 'relative md:start-[calc(-16px)] group-focus-visible/Chatbutton:start-0 group-hover/hoverChatbutton:start-0 group-active/activeChatbutton:start-0',\n )}\n />\n <div className=\"grid grid-cols-[0fr] overflow-hidden opacity-0 transition-opacity group-hover/hoverChatbutton:opacity-100 group-focus-visible/Chatbutton:opacity-100 group-active/activeChatbutton:opacity-100 duration-500\">\n <span\n aria-hidden=\"true\"\n className=\"chat-button-text items-center ps-20 flex gap-10 whitespace-nowrap font-semibold text-b3 text-black\"\n >\n {children}\n <Icon name=\"ArrowTailRight\" width=\"24px\" />\n </span>\n </div>\n </button>\n );\n}\n"],"mappings":";;;;AAIA,IAAM,IAAsB,sCACtB,IAAsB;AAO5B,SAAgB,EAAW,EACzB,cAAW,GACX,cACA,UAAO,UACP,cAAc,GACd,aACA,WACA,cAAW,SACX,GAAG,KACe;CAClB,IAAM,IACJ,MACC,OAAO,KAAa,YAAY,EAAS,MAAM,CAAC,SAAS,IACtD,EAAS,MAAM,GACf;AAEN,QACE,kBAAC,UAAD;EACQ;EACN,cAAY;EACZ,UAAU,KAAY;EACtB,GAAI;EACJ,WAAW,EACT,mWACA,KAAU,qDACV,MAAa,WACX,wEACF,MAAa,YACX,2EACF,sCACA,EACD;YAdH,CAgBE,kBAAC,GAAD;GACE,MAAK;GACL,WAAW,EACT,wCACA,KACE,mJACH;GACD,CAAA,EACF,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,QAAD;IACE,eAAY;IACZ,WAAU;cAFZ,CAIG,GACD,kBAAC,GAAD;KAAM,MAAK;KAAiB,OAAM;KAAS,CAAA,CACtC;;GACH,CAAA,CACC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FormHTMLAttributes } from 'react';
|
|
2
|
+
export interface ChatInputProps extends FormHTMLAttributes<HTMLFormElement> {
|
|
3
|
+
value: string;
|
|
4
|
+
placeholder?: string;
|
|
5
|
+
onValueChange: (value: string) => void;
|
|
6
|
+
onSubmit: () => void;
|
|
7
|
+
/** Fallback for when the browser does not support the Web Speech API */
|
|
8
|
+
onAudioClick?: () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function ChatInput({ value, placeholder, onValueChange, onSubmit, onAudioClick, className, ...props }: ChatInputProps): import("react/jsx-runtime").JSX.Element;
|
package/ui/ChatInput.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Button as e } from "./buttons/Button.js";
|
|
3
|
+
import { twMerge as t } from "./helpers/twMerge.js";
|
|
4
|
+
import { useEffect as n, useRef as r, useState as i } from "react";
|
|
5
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
6
|
+
//#region lib/ui/ChatInput.tsx
|
|
7
|
+
var s = 12, c = 48, l = 8;
|
|
8
|
+
function u(e) {
|
|
9
|
+
let t = r(e);
|
|
10
|
+
return n(() => {
|
|
11
|
+
t.current = e;
|
|
12
|
+
}), t;
|
|
13
|
+
}
|
|
14
|
+
var d = 3e3;
|
|
15
|
+
function f(e) {
|
|
16
|
+
let [t, a] = i(!1), [o, s] = i(!1), c = r(null), l = r(null), f = r(!1), p = u(e);
|
|
17
|
+
function m() {
|
|
18
|
+
l.current && clearTimeout(l.current);
|
|
19
|
+
}
|
|
20
|
+
function h() {
|
|
21
|
+
m(), l.current = setTimeout(() => {
|
|
22
|
+
f.current = !1, s(!1), c.current?.stop();
|
|
23
|
+
}, d);
|
|
24
|
+
}
|
|
25
|
+
n(() => {
|
|
26
|
+
let e = window.webkitSpeechRecognition ?? window.SpeechRecognition;
|
|
27
|
+
if (!e) return;
|
|
28
|
+
a(!0);
|
|
29
|
+
let t = new e();
|
|
30
|
+
return t.continuous = !0, t.interimResults = !0, t.lang = navigator.language, t.onresult = (e) => {
|
|
31
|
+
let t = Array.from(e.results).map((e) => e[0].transcript).join("");
|
|
32
|
+
p.current(t), h();
|
|
33
|
+
}, t.onend = () => {
|
|
34
|
+
if (m(), f.current) try {
|
|
35
|
+
t.start();
|
|
36
|
+
} catch {}
|
|
37
|
+
else s(!1);
|
|
38
|
+
}, t.onerror = (e) => {
|
|
39
|
+
(e.error === "not-allowed" || e.error === "aborted") && (f.current = !1, s(!1), m());
|
|
40
|
+
}, c.current = t, () => {
|
|
41
|
+
t.abort(), m();
|
|
42
|
+
};
|
|
43
|
+
}, []);
|
|
44
|
+
function g() {
|
|
45
|
+
let e = c.current;
|
|
46
|
+
e && (f.current ? (f.current = !1, e.stop()) : (f.current = !0, s(!0), e.start(), h()));
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
isSupported: t,
|
|
50
|
+
isListening: o,
|
|
51
|
+
toggle: g
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function p(e) {
|
|
55
|
+
let t = r(null);
|
|
56
|
+
return n(() => {
|
|
57
|
+
let n = t.current;
|
|
58
|
+
if (!e) {
|
|
59
|
+
n && (n.style.height = "0px");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
let r, i = null, a = null;
|
|
63
|
+
return navigator.mediaDevices.getUserMedia({
|
|
64
|
+
audio: !0,
|
|
65
|
+
video: !1
|
|
66
|
+
}).then((e) => {
|
|
67
|
+
i = e, a = new AudioContext();
|
|
68
|
+
let n = a.createMediaStreamSource(i), o = a.createAnalyser();
|
|
69
|
+
o.fftSize = 256, n.connect(o);
|
|
70
|
+
let s = new Uint8Array(o.frequencyBinCount);
|
|
71
|
+
function c() {
|
|
72
|
+
o.getByteFrequencyData(s);
|
|
73
|
+
let e = s.reduce((e, t) => e + t, 0) / s.length, n = t.current;
|
|
74
|
+
n && (n.style.height = `${Math.sqrt(e / 255) * 10}px`), r = requestAnimationFrame(c);
|
|
75
|
+
}
|
|
76
|
+
r = requestAnimationFrame(c);
|
|
77
|
+
}), () => {
|
|
78
|
+
cancelAnimationFrame(r), i?.getTracks().forEach((e) => e.stop()), a?.close();
|
|
79
|
+
};
|
|
80
|
+
}, [e]), t;
|
|
81
|
+
}
|
|
82
|
+
function m({ value: n, placeholder: r = "Ask a question?", onValueChange: u, onSubmit: d, onAudioClick: m, className: h, ...g }) {
|
|
83
|
+
let [_, v] = i(!1), y = n.trim(), b = _ || y.length > 0, { isSupported: x, isListening: S, toggle: C } = f(u), w = p(S), T = x || !!m, E = T ? c + l + c : c;
|
|
84
|
+
function D() {
|
|
85
|
+
x ? C() : m?.();
|
|
86
|
+
}
|
|
87
|
+
function O(e) {
|
|
88
|
+
e.preventDefault(), y && d();
|
|
89
|
+
}
|
|
90
|
+
return /* @__PURE__ */ o("form", {
|
|
91
|
+
onSubmit: O,
|
|
92
|
+
onMouseDown: (e) => {
|
|
93
|
+
e.target.tagName !== "TEXTAREA" && e.preventDefault();
|
|
94
|
+
},
|
|
95
|
+
...g,
|
|
96
|
+
style: { paddingBottom: b ? s + l + c : s },
|
|
97
|
+
className: t("relative flex items-start overflow-hidden bg-white border border-light-grey p-12 w-full", "transition-[padding-bottom,border-radius] duration-250 ease-out rounded-b-[24]", b ? "rounded-32" : "rounded-[40]", h),
|
|
98
|
+
children: [/* @__PURE__ */ a("textarea", {
|
|
99
|
+
rows: b ? 3 : 1,
|
|
100
|
+
value: n,
|
|
101
|
+
onChange: (e) => u(e.target.value),
|
|
102
|
+
onKeyDown: (e) => {
|
|
103
|
+
e.key === "Enter" && (e.metaKey || e.ctrlKey) && y && (e.preventDefault(), d());
|
|
104
|
+
},
|
|
105
|
+
onFocus: () => v(!0),
|
|
106
|
+
onBlur: () => v(!1),
|
|
107
|
+
placeholder: r,
|
|
108
|
+
"aria-label": r,
|
|
109
|
+
style: { marginInlineEnd: b ? 0 : E + l },
|
|
110
|
+
className: t("scrollbar-hidden bg-transparent text-b3 py-12 outline-none focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2 resize-none w-full px-20 border border-middleGrey", "transition-[margin-inline-end,border-radius] duration-250 ease-out", b ? "text-black rounded-[20]" : "text-darkGrey placeholder:text-darkGrey rounded-[40]")
|
|
111
|
+
}), /* @__PURE__ */ o("div", {
|
|
112
|
+
style: {
|
|
113
|
+
insetInlineStart: b ? `calc(50% - ${E / 2}px)` : `calc(100% - ${s + E}px)`,
|
|
114
|
+
bottom: s
|
|
115
|
+
},
|
|
116
|
+
className: "absolute flex gap-8 items-center transition-[inset-inline-start] duration-250 ease-out",
|
|
117
|
+
children: [/* @__PURE__ */ a(e, {
|
|
118
|
+
type: "submit",
|
|
119
|
+
"aria-label": "Send message",
|
|
120
|
+
disabled: !y,
|
|
121
|
+
variant: "circle",
|
|
122
|
+
color: "saffron",
|
|
123
|
+
icon: "ArrowTailRight",
|
|
124
|
+
iconWidth: "24px"
|
|
125
|
+
}), T && /* @__PURE__ */ a(e, {
|
|
126
|
+
type: "button",
|
|
127
|
+
"aria-label": S ? "Stop recording" : "Use microphone",
|
|
128
|
+
"aria-pressed": S,
|
|
129
|
+
onClick: D,
|
|
130
|
+
variant: "circle",
|
|
131
|
+
theme: S ? "solid" : "outline",
|
|
132
|
+
color: S ? "sienna" : "black",
|
|
133
|
+
icon: "Audio",
|
|
134
|
+
iconWidth: "24px",
|
|
135
|
+
className: t("relative", S && "animate-pulse", !S && "border-lightGrey"),
|
|
136
|
+
children: /* @__PURE__ */ a("span", {
|
|
137
|
+
ref: w,
|
|
138
|
+
"aria-hidden": "true",
|
|
139
|
+
className: "bg-current absolute w-5 bottom-21",
|
|
140
|
+
style: { height: "0px" }
|
|
141
|
+
})
|
|
142
|
+
})]
|
|
143
|
+
})]
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
//#endregion
|
|
147
|
+
export { m as ChatInput };
|
|
148
|
+
|
|
149
|
+
//# sourceMappingURL=ChatInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatInput.js","names":[],"sources":["../../lib/ui/ChatInput.tsx"],"sourcesContent":["/// <reference types=\"@types/dom-speech-recognition\" />\n'use client';\n\nimport type { FormHTMLAttributes } from 'react';\nimport { useEffect, useRef, useState } from 'react';\nimport { Button } from './buttons/Button';\nimport { twMerge } from './helpers/twMerge';\n\nexport interface ChatInputProps extends FormHTMLAttributes<HTMLFormElement> {\n value: string;\n placeholder?: string;\n onValueChange: (value: string) => void;\n onSubmit: () => void;\n /** Fallback for when the browser does not support the Web Speech API */\n onAudioClick?: () => void;\n}\n\nconst FORM_PAD = 12; // matches p-12\nconst BTN_SIZE = 48; // matches size-48\nconst BTN_GAP = 8; // matches gap-8\n\n// Keep onValueChange stable inside the recognition handler without re-creating the SR instance\nfunction useCallbackRef<T extends (...args: never[]) => unknown>(fn: T) {\n const ref = useRef(fn);\n useEffect(() => {\n ref.current = fn;\n });\n return ref;\n}\n\nconst SILENCE_TIMEOUT_MS = 3_000;\n\nfunction useSpeechRecognition(onValueChange: (v: string) => void) {\n const [isSupported, setIsSupported] = useState(false);\n const [isListening, setIsListening] = useState(false);\n const recognitionRef = useRef<SpeechRecognition | null>(null);\n const silenceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isListeningRef = useRef(false);\n const onValueChangeRef = useCallbackRef(onValueChange);\n\n function clearSilenceTimer() {\n if (silenceTimerRef.current) clearTimeout(silenceTimerRef.current);\n }\n\n function resetSilenceTimer() {\n clearSilenceTimer();\n silenceTimerRef.current = setTimeout(() => {\n isListeningRef.current = false;\n setIsListening(false);\n recognitionRef.current?.stop();\n }, SILENCE_TIMEOUT_MS);\n }\n\n useEffect(() => {\n const SR: typeof SpeechRecognition | undefined =\n (window as Window & { webkitSpeechRecognition?: typeof SpeechRecognition })\n .webkitSpeechRecognition ?? window.SpeechRecognition;\n if (!SR) return;\n\n setIsSupported(true);\n\n const recognition = new SR();\n recognition.continuous = true;\n recognition.interimResults = true;\n recognition.lang = navigator.language;\n\n recognition.onresult = (event: SpeechRecognitionEvent) => {\n const transcript = Array.from(event.results)\n .map((r: SpeechRecognitionResult) => r[0].transcript)\n .join('');\n onValueChangeRef.current(transcript);\n resetSilenceTimer();\n };\n\n recognition.onend = () => {\n clearSilenceTimer();\n // Restart automatically if the user hasn't manually stopped (browser cut us off)\n if (isListeningRef.current) {\n try {\n recognition.start();\n } catch {\n /* already starting */\n }\n } else {\n setIsListening(false);\n }\n };\n\n recognition.onerror = (e: SpeechRecognitionErrorEvent) => {\n if (e.error === 'not-allowed' || e.error === 'aborted') {\n isListeningRef.current = false;\n setIsListening(false);\n clearSilenceTimer();\n }\n };\n\n recognitionRef.current = recognition;\n return () => {\n recognition.abort();\n clearSilenceTimer();\n };\n // SR detection and instance creation only needs to run once on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n function toggle() {\n const recognition = recognitionRef.current;\n if (!recognition) return;\n if (isListeningRef.current) {\n isListeningRef.current = false;\n recognition.stop();\n } else {\n isListeningRef.current = true;\n setIsListening(true);\n recognition.start();\n resetSilenceTimer();\n }\n }\n\n return { isSupported, isListening, toggle };\n}\n\n/**\n * Drives the audio-level indicator by writing directly to the DOM element's\n * style — avoids triggering a React re-render on every animation frame\n * (rule: rerender-use-ref-transient-values).\n *\n * Returns a ref to attach to the indicator <span>.\n */\nfunction useAudioLevel(isListening: boolean) {\n const indicatorRef = useRef<HTMLSpanElement>(null);\n\n useEffect(() => {\n const el = indicatorRef.current;\n\n if (!isListening) {\n if (el) el.style.height = '0px';\n return;\n }\n\n let animId: number;\n let stream: MediaStream | null = null;\n let ctx: AudioContext | null = null;\n\n navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then((s) => {\n stream = s;\n ctx = new AudioContext();\n const source = ctx.createMediaStreamSource(stream);\n const analyser = ctx.createAnalyser();\n analyser.fftSize = 256;\n source.connect(analyser);\n const data = new Uint8Array(analyser.frequencyBinCount);\n\n function tick() {\n analyser.getByteFrequencyData(data);\n const avg = data.reduce((sum, v) => sum + v, 0) / data.length;\n // Square-root curve so quiet sounds register more visibly\n const node = indicatorRef.current;\n if (node) node.style.height = `${Math.sqrt(avg / 255) * 10}px`;\n animId = requestAnimationFrame(tick);\n }\n animId = requestAnimationFrame(tick);\n });\n\n return () => {\n cancelAnimationFrame(animId);\n stream?.getTracks().forEach((t) => t.stop());\n ctx?.close();\n };\n }, [isListening]);\n\n return indicatorRef;\n}\n\nexport function ChatInput({\n value,\n placeholder = 'Ask a question?',\n onValueChange,\n onSubmit,\n onAudioClick,\n className,\n ...props\n}: ChatInputProps) {\n const [isFocused, setIsFocused] = useState(false);\n const trimmed = value.trim();\n const isOpen = isFocused || trimmed.length > 0;\n const { isSupported, isListening, toggle } = useSpeechRecognition(onValueChange);\n const audioIndicatorRef = useAudioLevel(isListening);\n\n const showAudio = isSupported || !!onAudioClick;\n const btnW = showAudio ? BTN_SIZE + BTN_GAP + BTN_SIZE : BTN_SIZE;\n\n function handleAudioClick() {\n if (isSupported) {\n toggle();\n } else {\n onAudioClick?.();\n }\n }\n\n function handleSubmit(e: React.FormEvent) {\n e.preventDefault();\n if (trimmed) onSubmit();\n }\n\n return (\n <form\n onSubmit={handleSubmit}\n onMouseDown={(e) => {\n if ((e.target as HTMLElement).tagName !== 'TEXTAREA') e.preventDefault();\n }}\n {...props}\n style={{\n paddingBottom: isOpen ? FORM_PAD + BTN_GAP + BTN_SIZE : FORM_PAD,\n }}\n className={twMerge(\n 'relative flex items-start overflow-hidden bg-white border border-light-grey p-12 w-full',\n 'transition-[padding-bottom,border-radius] duration-250 ease-out rounded-b-[24]',\n isOpen ? 'rounded-32' : 'rounded-[40]',\n className,\n )}\n >\n <textarea\n rows={isOpen ? 3 : 1}\n value={value}\n onChange={(e) => onValueChange(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey) && trimmed) {\n e.preventDefault();\n onSubmit();\n }\n }}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n placeholder={placeholder}\n aria-label={placeholder}\n style={{\n marginInlineEnd: isOpen ? 0 : btnW + BTN_GAP,\n }}\n className={twMerge(\n 'scrollbar-hidden bg-transparent text-b3 py-12 outline-none focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2 resize-none w-full px-20 border border-middleGrey',\n 'transition-[margin-inline-end,border-radius] duration-250 ease-out',\n isOpen\n ? 'text-black rounded-[20]'\n : 'text-darkGrey placeholder:text-darkGrey rounded-[40]',\n )}\n />\n\n <div\n style={{\n insetInlineStart: isOpen\n ? `calc(50% - ${btnW / 2}px)`\n : `calc(100% - ${FORM_PAD + btnW}px)`,\n bottom: FORM_PAD,\n }}\n className=\"absolute flex gap-8 items-center transition-[inset-inline-start] duration-250 ease-out\"\n >\n <Button\n type=\"submit\"\n aria-label=\"Send message\"\n disabled={!trimmed}\n variant=\"circle\"\n color=\"saffron\"\n icon=\"ArrowTailRight\"\n iconWidth=\"24px\"\n />\n {showAudio && (\n <Button\n type=\"button\"\n aria-label={isListening ? 'Stop recording' : 'Use microphone'}\n aria-pressed={isListening}\n onClick={handleAudioClick}\n variant=\"circle\"\n theme={isListening ? 'solid' : 'outline'}\n color={isListening ? 'sienna' : 'black'}\n icon=\"Audio\"\n iconWidth=\"24px\"\n className={twMerge(\n 'relative',\n isListening && 'animate-pulse',\n !isListening && 'border-lightGrey',\n )}\n >\n <span\n ref={audioIndicatorRef}\n aria-hidden=\"true\"\n className=\"bg-current absolute w-5 bottom-21\"\n style={{ height: '0px' }}\n />\n </Button>\n )}\n </div>\n </form>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { HTMLAttributes, PropsWithChildren } from 'react';
|
|
2
|
+
export type ChatMessageSender = 'assistant' | 'user';
|
|
3
|
+
export interface ChatMessageProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
sender: ChatMessageSender;
|
|
5
|
+
}
|
|
6
|
+
export declare const ChatMessage: import('react').NamedExoticComponent<PropsWithChildren<ChatMessageProps>>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { twMerge as e } from "./helpers/twMerge.js";
|
|
2
|
+
import { memo as t } from "react";
|
|
3
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
4
|
+
//#region lib/ui/ChatTypingIndicator.tsx
|
|
5
|
+
var i = t(function({ className: t, ...i }) {
|
|
6
|
+
return /* @__PURE__ */ r("div", {
|
|
7
|
+
role: "status",
|
|
8
|
+
"aria-label": "Typing",
|
|
9
|
+
...i,
|
|
10
|
+
className: e("flex items-center gap-4 h-34 w-66 overflow-hidden rounded-pill bg-pearl px-20", t),
|
|
11
|
+
children: [
|
|
12
|
+
/* @__PURE__ */ n("span", {
|
|
13
|
+
"aria-hidden": "true",
|
|
14
|
+
className: "size-6 rounded-full bg-black animate-bounce [animation-delay:-300ms]"
|
|
15
|
+
}),
|
|
16
|
+
/* @__PURE__ */ n("span", {
|
|
17
|
+
"aria-hidden": "true",
|
|
18
|
+
className: "size-6 rounded-full bg-black animate-bounce [animation-delay:-150ms]"
|
|
19
|
+
}),
|
|
20
|
+
/* @__PURE__ */ n("span", {
|
|
21
|
+
"aria-hidden": "true",
|
|
22
|
+
className: "size-6 rounded-full bg-black animate-bounce"
|
|
23
|
+
})
|
|
24
|
+
]
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
//#endregion
|
|
28
|
+
export { i as ChatTypingIndicator };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=ChatTypingIndicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatTypingIndicator.js","names":[],"sources":["../../lib/ui/ChatTypingIndicator.tsx"],"sourcesContent":["import { memo, type HTMLAttributes } from 'react';\nimport { twMerge } from './helpers/twMerge';\n\nexport const ChatTypingIndicator = memo(function ChatTypingIndicator({\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n role=\"status\"\n aria-label=\"Typing\"\n {...props}\n className={twMerge(\n 'flex items-center gap-4 h-34 w-66 overflow-hidden rounded-pill bg-pearl px-20',\n className,\n )}\n >\n <span\n aria-hidden=\"true\"\n className=\"size-6 rounded-full bg-black animate-bounce [animation-delay:-300ms]\"\n />\n <span\n aria-hidden=\"true\"\n className=\"size-6 rounded-full bg-black animate-bounce [animation-delay:-150ms]\"\n />\n <span aria-hidden=\"true\" className=\"size-6 rounded-full bg-black animate-bounce\" />\n </div>\n );\n});\n"],"mappings":";;;;AAGA,IAAa,IAAsB,EAAK,SAA6B,EACnE,cACA,GAAG,KAC8B;AACjC,QACE,kBAAC,OAAD;EACE,MAAK;EACL,cAAW;EACX,GAAI;EACJ,WAAW,EACT,iFACA,EACD;YAPH;GASE,kBAAC,QAAD;IACE,eAAY;IACZ,WAAU;IACV,CAAA;GACF,kBAAC,QAAD;IACE,eAAY;IACZ,WAAU;IACV,CAAA;GACF,kBAAC,QAAD;IAAM,eAAY;IAAO,WAAU;IAAgD,CAAA;GAC/E;;EAER"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { ChatMessageSender } from './ChatMessage';
|
|
3
|
+
import { ChatWindowCsatPromptLabels } from './ChatWindowCsatPrompt';
|
|
4
|
+
import { ChatWindowCsatThankYouLabels } from './ChatWindowCsatThankYou';
|
|
5
|
+
import { ChatWindowQuoteItem } from './ChatWindowQuote';
|
|
6
|
+
export type { ChatWindowCsatPromptLabels, ChatWindowCsatThankYouLabels, ChatWindowQuoteItem };
|
|
7
|
+
export interface ChatWindowMessage {
|
|
8
|
+
id: string;
|
|
9
|
+
sender: ChatMessageSender;
|
|
10
|
+
content: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ChatWindowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
13
|
+
title?: string;
|
|
14
|
+
greeting?: string;
|
|
15
|
+
messages: ChatWindowMessage[];
|
|
16
|
+
inputValue: string;
|
|
17
|
+
inputPlaceholder?: string;
|
|
18
|
+
isTyping?: boolean;
|
|
19
|
+
onInputChange: (value: string) => void;
|
|
20
|
+
onSubmit: () => void;
|
|
21
|
+
onClose?: () => void;
|
|
22
|
+
onAudioClick?: () => void;
|
|
23
|
+
logo?: ReactNode;
|
|
24
|
+
onFeedbackRate?: (rating: number) => void;
|
|
25
|
+
csatLabels?: ChatWindowCsatPromptLabels;
|
|
26
|
+
csatRenderRatingLabel?: (rating: number) => ReactNode;
|
|
27
|
+
csatThankYouLabels?: ChatWindowCsatThankYouLabels;
|
|
28
|
+
onQuoteCtaClick?: (quote: ChatWindowQuoteItem) => void;
|
|
29
|
+
}
|
|
30
|
+
export interface ChatWindowHandle {
|
|
31
|
+
askForFeedback: () => void;
|
|
32
|
+
showQuotes: (quotes: ChatWindowQuoteItem[]) => void;
|
|
33
|
+
}
|
|
34
|
+
export declare const ChatWindow: import('react').ForwardRefExoticComponent<ChatWindowProps & import('react').RefAttributes<ChatWindowHandle>>;
|