@nylas/web-elements 0.0.0-test-20250320180623 → 0.0.0-test-20250320185733
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/dist/cdn/nylas-scheduler-editor/nylas-scheduler-editor.es.js +25 -25
- package/dist/cdn/nylas-scheduling/nylas-scheduling.es.js +247 -247
- package/dist/cjs/button-component_2.cjs.entry.js +1 -1
- package/dist/cjs/button-component_2.cjs.entry.js.map +1 -1
- package/dist/cjs/calendar-agenda-fill-icon_36.cjs.entry.js +17 -18
- package/dist/cjs/calendar-agenda-fill-icon_36.cjs.entry.js.map +1 -1
- package/dist/cjs/chevron-icon_3.cjs.entry.js +1 -1
- package/dist/cjs/chevron-icon_3.cjs.entry.js.map +1 -1
- package/dist/cjs/google-logo-icon_6.cjs.entry.js +5 -5
- package/dist/cjs/google-logo-icon_6.cjs.entry.js.map +1 -1
- package/dist/cjs/input-dropdown_2.cjs.entry.js +1 -1
- package/dist/cjs/input-dropdown_2.cjs.entry.js.map +1 -1
- package/dist/cjs/multi-select-dropdown_2.cjs.entry.js +2 -2
- package/dist/cjs/multi-select-dropdown_2.cjs.entry.js.map +1 -1
- package/dist/cjs/nylas-provider.cjs.entry.js.map +1 -1
- package/dist/cjs/nylas-scheduling.cjs.entry.js.map +1 -1
- package/dist/cjs/scheduler-store-df3a9a3a.js.map +1 -1
- package/dist/collection/components/design-system/button-component/button-component.js +4 -3
- package/dist/collection/components/design-system/button-component/button-component.js.map +1 -1
- package/dist/collection/components/design-system/input-dropdown/input-dropdown.js +10 -7
- package/dist/collection/components/design-system/input-dropdown/input-dropdown.js.map +1 -1
- package/dist/collection/components/design-system/multi-select-dropdown/multi-select-dropdown.js +5 -4
- package/dist/collection/components/design-system/multi-select-dropdown/multi-select-dropdown.js.map +1 -1
- package/dist/collection/components/design-system/select-dropdown/select-dropdown.js +13 -9
- package/dist/collection/components/design-system/select-dropdown/select-dropdown.js.map +1 -1
- package/dist/collection/components/nylas-provider/nylas-provider.js +1 -1
- package/dist/collection/components/scheduler-editor/nylas-buffer-time/nylas-buffer-time.js +2 -2
- package/dist/collection/components/scheduler-editor/nylas-buffer-time/nylas-buffer-time.js.map +1 -1
- package/dist/collection/components/scheduler-editor/nylas-editor-tabs-group/nylas-editor-tabs-group.js +30 -15
- package/dist/collection/components/scheduler-editor/nylas-editor-tabs-group/nylas-editor-tabs-group.js.map +1 -1
- package/dist/collection/components/scheduler-editor/nylas-event-duration/nylas-event-duration.js +15 -16
- package/dist/collection/components/scheduler-editor/nylas-event-duration/nylas-event-duration.js.map +1 -1
- package/dist/collection/connector/nylas-scheduler-connector/index.js.map +1 -1
- package/dist/collection/connector/shared/api/auth.js.map +1 -1
- package/dist/collection/connector/shared/api/scheduler.js.map +1 -1
- package/dist/components/button-component2.js +1 -1
- package/dist/components/button-component2.js.map +1 -1
- package/dist/components/input-dropdown2.js +1 -1
- package/dist/components/input-dropdown2.js.map +1 -1
- package/dist/components/multi-select-dropdown2.js +2 -2
- package/dist/components/multi-select-dropdown2.js.map +1 -1
- package/dist/components/nylas-buffer-time2.js +2 -2
- package/dist/components/nylas-buffer-time2.js.map +1 -1
- package/dist/components/nylas-editor-tabs-group2.js +5 -5
- package/dist/components/nylas-editor-tabs-group2.js.map +1 -1
- package/dist/components/nylas-event-duration2.js +15 -16
- package/dist/components/nylas-event-duration2.js.map +1 -1
- package/dist/components/nylas-provider.js.map +1 -1
- package/dist/components/nylas-scheduling.js.map +1 -1
- package/dist/components/scheduler-store.js.map +1 -1
- package/dist/components/select-dropdown2.js +1 -1
- package/dist/components/select-dropdown2.js.map +1 -1
- package/dist/esm/button-component_2.entry.js +1 -1
- package/dist/esm/button-component_2.entry.js.map +1 -1
- package/dist/esm/calendar-agenda-fill-icon_36.entry.js +17 -18
- package/dist/esm/calendar-agenda-fill-icon_36.entry.js.map +1 -1
- package/dist/esm/chevron-icon_3.entry.js +1 -1
- package/dist/esm/chevron-icon_3.entry.js.map +1 -1
- package/dist/esm/google-logo-icon_6.entry.js +5 -5
- package/dist/esm/google-logo-icon_6.entry.js.map +1 -1
- package/dist/esm/input-dropdown_2.entry.js +1 -1
- package/dist/esm/input-dropdown_2.entry.js.map +1 -1
- package/dist/esm/multi-select-dropdown_2.entry.js +2 -2
- package/dist/esm/multi-select-dropdown_2.entry.js.map +1 -1
- package/dist/esm/nylas-provider.entry.js.map +1 -1
- package/dist/esm/nylas-scheduling.entry.js.map +1 -1
- package/dist/esm/scheduler-store-ef022be9.js.map +1 -1
- package/dist/nylas-web-elements/nylas-web-elements.esm.js +1 -1
- package/dist/nylas-web-elements/{p-a6a52e17.entry.js → p-09bbd467.entry.js} +2 -2
- package/dist/nylas-web-elements/p-09bbd467.entry.js.map +1 -0
- package/dist/nylas-web-elements/{p-6371e0a3.entry.js → p-0d80f50b.entry.js} +2 -2
- package/dist/nylas-web-elements/p-0d80f50b.entry.js.map +1 -0
- package/dist/nylas-web-elements/p-1fb32e0e.entry.js.map +1 -1
- package/dist/nylas-web-elements/{p-19f6fcf8.entry.js → p-3ca36162.entry.js} +2 -2
- package/dist/nylas-web-elements/p-3ca36162.entry.js.map +1 -0
- package/dist/nylas-web-elements/{p-78bd1f85.entry.js → p-51434e4a.entry.js} +2 -2
- package/dist/nylas-web-elements/p-51434e4a.entry.js.map +1 -0
- package/dist/nylas-web-elements/p-731a856b.js.map +1 -1
- package/dist/nylas-web-elements/p-7b787c73.entry.js +8 -0
- package/dist/nylas-web-elements/p-7b787c73.entry.js.map +1 -0
- package/dist/nylas-web-elements/p-a906d005.entry.js.map +1 -1
- package/dist/nylas-web-elements/{p-55886492.entry.js → p-b1c57792.entry.js} +2 -2
- package/dist/nylas-web-elements/p-b1c57792.entry.js.map +1 -0
- package/dist/types/components/design-system/button-component/button-component.d.ts +1 -2
- package/dist/types/components/design-system/input-dropdown/input-dropdown.d.ts +1 -6
- package/dist/types/components/design-system/multi-select-dropdown/multi-select-dropdown.d.ts +1 -7
- package/dist/types/components/design-system/select-dropdown/select-dropdown.d.ts +1 -6
- package/dist/types/components/scheduler-editor/nylas-editor-tabs-group/nylas-editor-tabs-group.d.ts +12 -11
- package/dist/types/components/scheduler-editor/nylas-event-duration/nylas-event-duration.d.ts +2 -2
- package/dist/types/components.d.ts +7 -7
- package/dist/types/connector/nylas-connector/index.d.ts +1 -1
- package/dist/types/connector/nylas-scheduler-connector/index.d.ts +2 -2
- package/dist/types/connector/shared/api/auth.d.ts +1 -1
- package/dist/types/connector/shared/api/scheduler.d.ts +1 -1
- package/package.json +3 -3
- package/dist/nylas-web-elements/p-19f6fcf8.entry.js.map +0 -1
- package/dist/nylas-web-elements/p-463d9c42.entry.js +0 -8
- package/dist/nylas-web-elements/p-463d9c42.entry.js.map +0 -1
- package/dist/nylas-web-elements/p-55886492.entry.js.map +0 -1
- package/dist/nylas-web-elements/p-6371e0a3.entry.js.map +0 -1
- package/dist/nylas-web-elements/p-78bd1f85.entry.js.map +0 -1
- package/dist/nylas-web-elements/p-a6a52e17.entry.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["iconCss","ChevronIconStyle0","ChevronIcon","render","h","key","xmlns","width","this","height","viewBox","fill","d","SearchIconStyle0","SearchIcon","selectDropdownCss","SelectDropdownStyle0","SelectDropdown","componentType","options","optionsChangedHandler","newValue","oldValue","filteredOptions","defaultSelectedOptionChangedHandler","label","selectedOption","nylasFormDropdownDefaultSelected","emit","value","name","error","componentWillLoad","el","setAttribute","componentDidLoad","defaultSelectedOption","length","handleBookingFormSubmitted","event","validate","preventDefault","handleFormSubmitted","required","errorMessage","toggleDropdown","isOpen","filterOptions","target","searchValue","filter","option","toLowerCase","includes","selectOption","emptyValue","nylasFormDropdownChanged","handleSelectButtonKeyDown","inputRef","focus","handleListboxKeydown","e","items","currentIndex","findIndex","item","ariaActivedescendant","shiftKey","nextIndex","focusOption","prevIndex","index","elementId","element","shadowRoot","getElementById","scrollIntoView","behavior","block","handleComboboxKeyDown","generateButtonText","dropButtonText","pluralizedLabel","handleOutsideClick","path","composedPath","isClickInside","buttonText","dropdownButtonText","class","part","dropbtn","open","onClick","disabled","readOnly","title","onKeyDown","withChevron","closed","chevron","withSearch","type","role","placeholder","ref","onInput","tabindex","map","toString","id","labelHTML"],"sources":["src/common/icons/icon.css?tag=chevron-icon&encapsulation=scoped","src/common/icons/chevron.tsx","src/common/icons/icon.css?tag=search-icon&encapsulation=scoped","src/common/icons/search.tsx","src/components/design-system/select-dropdown/select-dropdown.scss?tag=select-dropdown&encapsulation=shadow","src/components/design-system/select-dropdown/select-dropdown.tsx"],"sourcesContent":[":host {\n display: flex;\n}\n","import { Component, Prop, h } from '@stencil/core';\n\n@Component({\n tag: 'chevron-icon',\n styleUrl: 'icon.css',\n scoped: true,\n})\nexport class ChevronIcon {\n @Prop() width: string = '24';\n @Prop() height: string = '24';\n\n render() {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width={this.width} height={this.height} viewBox=\"0 0 24 24\" fill=\"none\">\n <path fill=\"currentColor\" d=\"M15.53 4.22a.75.75 0 0 1 0 1.06L8.81 12l6.72 6.72a.75.75 0 1 1-1.06 1.06l-7.25-7.25a.75.75 0 0 1 0-1.06l7.25-7.25a.75.75 0 0 1 1.06 0Z\" />\n </svg>\n );\n }\n}\n",":host {\n display: flex;\n}\n","import { Component, Prop, h } from '@stencil/core';\n\n@Component({\n tag: 'search-icon',\n styleUrl: 'icon.css',\n scoped: true,\n})\nexport class SearchIcon {\n @Prop() width: string = '15';\n @Prop() height: string = '15';\n\n render() {\n return (\n <svg width={this.width} height={this.height} fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n fill=\"currentColor\"\n d=\"M5.5 0C8.53757 0 11 2.46243 11 5.5C11 6.83879 10.5217 8.06586 9.72656 9.01962L13.8536 13.1464C14.0488 13.3417 14.0488 13.6583 13.8536 13.8536C13.68 14.0271 13.4106 14.0464 13.2157 13.9114L13.1464 13.8536L9.01962 9.72656C8.06586 10.5217 6.83879 11 5.5 11C2.46243 11 0 8.53757 0 5.5C0 2.46243 2.46243 0 5.5 0ZM5.5 1C3.01472 1 1 3.01472 1 5.5C1 7.98528 3.01472 10 5.5 10C7.98528 10 10 7.98528 10 5.5C10 3.01472 7.98528 1 5.5 1Z\"\n />\n </svg>\n );\n }\n}\n","@import '../../../common/styles/variables.scss';\n@import '../../../common/mixins/inputs.scss';\n\n:host {\n display: block;\n position: relative;\n\n @media #{$mobile} {\n position: unset;\n }\n\n @include default-css-variables;\n width: 100%;\n}\n\nlabel {\n @include input-label;\n flex-direction: column;\n gap: 4px;\n font-family: var(--nylas-font-family);\n font-size: 16px;\n color: var(--nylas-base-800);\n\n p {\n margin: 0;\n }\n\n .error {\n color: var(--nylas-error);\n }\n}\n\n.dropdown {\n display: inline-block;\n width: inherit;\n}\n\n.dropbtn {\n color: var(--nylas-base-800);\n padding: 14px;\n font-size: 16px;\n font-family: var(--nylas-font-family);\n cursor: pointer;\n display: flex;\n justify-content: space-between;\n gap: 0.5rem;\n background: transparent;\n border: 1px solid var(--nylas-base-300);\n border-radius: var(--nylas-border-radius-2x);\n\n &.error {\n border: 1px solid var(--nylas-error);\n }\n\n &.focus {\n background: transparent;\n }\n\n &:hover,\n &:active {\n outline: 1px solid var(--nylas-primary);\n }\n\n &:active {\n outline: 2px solid var(--nylas-primary);\n }\n\n &:disabled {\n cursor: not-allowed;\n background: var(--nylas-base-100);\n }\n\n span {\n &.chevron {\n display: flex;\n align-self: center;\n }\n\n &.open {\n transform: rotate(90deg);\n }\n\n &.closed {\n transform: rotate(270deg);\n }\n\n &.selected-option {\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n max-width: 144px;\n font-size: 14px;\n line-height: 20px;\n\n @media #{$mobile} {\n max-width: 124px;\n font-size: 16px;\n }\n }\n }\n}\n\n.dropdown-content {\n display: block;\n margin-top: 0.5rem;\n background-color: var(--nylas-base-0);\n width: 100%;\n max-height: 336px;\n overflow: auto;\n z-index: 1;\n border-radius: 4px;\n position: absolute;\n\n @media #{$mobile} {\n right: 0;\n width: 325px;\n max-width: unset;\n }\n\n box-shadow: 0px 4px 6px -2px rgba(0, 0, 0, 0.05);\n box-shadow: 0px 10px 15px -3px rgba(0, 0, 0, 0.1);\n}\n\n.search-box {\n border-bottom: 1px solid var(--nylas-base-200);\n padding: 10px;\n position: sticky;\n top: 0;\n background: var(--nylas-base-0);\n\n .icon {\n position: absolute;\n top: 1.25rem;\n left: 1.25rem;\n color: var(--nylas-base-300);\n }\n}\n\n.dropdown-content ul {\n padding: 0;\n list-style-type: none;\n color: var(--nylas-base-900);\n max-height: 336px;\n\n li {\n padding: 16px, 12px, 16px, 12px;\n color: var(--nylas-base-900);\n padding: 12px 16px;\n text-decoration: none;\n display: block;\n font-family: inherit;\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n letter-spacing: 0px;\n text-align: left;\n cursor: pointer;\n\n &:hover,\n &:focus {\n background-color: var(--nylas-base-100);\n }\n }\n}\n\n.dropdown-content .selected {\n background-color: #e7e7e7;\n}\n\ninput[type='text'] {\n width: -webkit-fill-available;\n padding: inherit;\n border: 1px solid #ccc;\n border-radius: 4px;\n position: sticky;\n background: no-repeat scroll 7px 7px;\n padding-left: 30px;\n background-size: 16px 16px;\n color: var(--nylas-base-800);\n}\n","import { Component, Element, Event, EventEmitter, h, Listen, Prop, State, Watch } from '@stencil/core';\n\ninterface DropdownOption {\n labelHTML?: HTMLElement;\n label: string;\n value: string;\n}\n\n/**\n * The `select-dropdown` component is a dropdown that allows users to select an option from a list of options.\n * This component is used in the scheduling form to input dropdown type inputs.\n * @part sd_dropdown - The dropdown container\n * @part sd_dropdown-button - The dropdown button\n * @part sd_dropdown-button-selected-label - The selected option label\n * @part sd_dropdown-content - The dropdown content\n * @part sd_dropdown_label - The dropdown label\n */\n@Component({\n tag: 'select-dropdown',\n styleUrl: 'select-dropdown.scss',\n shadow: true,\n})\nexport class SelectDropdown {\n @Element() el!: HTMLElement;\n private readonly componentType: string = 'select-dropdown';\n\n private inputRef?: HTMLInputElement;\n\n // Props\n /**\n * The name of the dropdown\n */\n @Prop() name!: string;\n /**\n * The options to display in the dropdown\n */\n @Prop() options: DropdownOption[] = [];\n /**\n * The default selected option\n */\n @Prop({ attribute: 'default-selected-option' }) defaultSelectedOption: DropdownOption | null = null;\n /**\n * Should show search input\n */\n @Prop() withSearch: boolean = true;\n\n /**\n * The label for the dropdown, skipped if no label is provided\n */\n @Prop() label?: string;\n\n /**\n * If true, the dropdown is required for form submission\n */\n @Prop() required: boolean = false;\n\n /**\n * The property to make the dropdown read-only. If true, the dropdown cannot be edited.\n */\n @Prop() readOnly: boolean = false;\n\n /**\n * Show pluralized label for the selected option. This is s tring that is appended to the selected option label as a suffix.\n */\n @Prop() pluralizedLabel: string = '';\n /**\n * Overrides the select dropdown to be used as a button with dropdownButtonText representing actions & dropdownText name on the dropdown intead of selected value\n */\n @Prop() dropdownButtonText?: string;\n /**\n * Should show chevron on button\n */\n @Prop() withChevron: boolean = true;\n /**\n * Allows to set the empty value of the dropdown\n */\n @Prop() emptyValue: string = 'Select an option'; // Default empty value\n /**\n * The custom error message to display when the value is empty or null and the dropdown is required\n */\n @Prop() errorMessage: string = '';\n\n // States\n /**\n * The selected option\n */\n @State() selectedOption!: DropdownOption | null;\n /**\n * The open state of the dropdown\n */\n @State() isOpen: boolean = false;\n /**\n * The search value for the dropdown\n */\n @State() searchValue: string = '';\n /**\n * The filtered options based on the search value\n */\n @State() filteredOptions: DropdownOption[] = [...this.options];\n /**\n * The aria-activedescendant attribute for the listbox element to indicate the currently active\n * option in the list box to screen readers. The value of aria-activedescendant is the ID of\n * the active option.\n */\n @State() ariaActivedescendant: string = '';\n\n /**\n * The error message to display when the value is empty or null and the dropdown is required\n */\n @State() error: string = '';\n\n // Events\n /**\n * This event is fired when the selected option is changed\n */\n @Event({ bubbles: true, composed: true }) nylasFormDropdownChanged!: EventEmitter<{\n value: DropdownOption['value'];\n name: string;\n error?: string;\n label?: string;\n }>;\n\n /**\n * This event is fired when the default selected option is set, on component load\n */\n @Event({ bubbles: true, composed: true }) nylasFormDropdownDefaultSelected!: EventEmitter<{\n value: DropdownOption['value'];\n name: string;\n error?: string;\n label?: string;\n }>;\n\n @Watch('options')\n optionsChangedHandler(newValue: DropdownOption[], oldValue: DropdownOption[]) {\n if (newValue === oldValue) {\n return;\n }\n this.filteredOptions = newValue;\n }\n\n @Watch('defaultSelectedOption')\n defaultSelectedOptionChangedHandler(newValue: DropdownOption, oldValue: DropdownOption) {\n if (typeof newValue === 'undefined' || newValue?.label === oldValue?.label) {\n return;\n }\n this.selectedOption = newValue;\n this.nylasFormDropdownDefaultSelected.emit({\n value: newValue?.value || '',\n name: this.name,\n error: this.error,\n label: this.label,\n });\n }\n\n // Lifecycle methods\n componentWillLoad() {\n this.el.setAttribute('component-type', this.componentType);\n }\n\n componentDidLoad() {\n this.filteredOptions = this.options;\n // Set the selected option to the first option if no option is selected\n this.selectedOption = this.defaultSelectedOption;\n\n if (!this.selectedOption && this.options.length > 0) {\n this.selectedOption = this.options[0];\n }\n this.nylasFormDropdownDefaultSelected.emit({\n value: this.selectedOption?.value || '',\n name: this.name,\n error: this.error,\n label: this.label,\n });\n }\n\n // Event listeners\n /**\n * Listen for the bookingFormSubmitted event to validate the input value when the form is submitted.\n */\n @Listen('bookingFormSubmitted', { target: 'document' })\n handleBookingFormSubmitted(event: CustomEvent) {\n this.validate(this.selectedOption?.value || '');\n if (this.error) {\n event.preventDefault();\n }\n }\n\n /**\n * Listen for the formSubmitted event to validate the input value when the form is submitted.\n * @param event\n */\n @Listen('formSubmitted', { target: 'document' })\n handleFormSubmitted(event: CustomEvent) {\n this.validate(this.selectedOption?.value || '');\n if (this.error) {\n event.preventDefault();\n }\n }\n\n // Methods\n validate(value: string) {\n if (this.required && !value) {\n this.error = this.errorMessage || `${this.label} is required.`;\n } else {\n this.error = '';\n }\n }\n toggleDropdown(): void {\n this.isOpen = !this.isOpen;\n }\n\n filterOptions(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n this.searchValue = value;\n this.filteredOptions = this.options.filter(option => option.label.toLowerCase().includes(value.toLowerCase()));\n }\n\n selectOption(option: DropdownOption): void {\n this.error = '';\n this.selectedOption = option;\n this.toggleDropdown();\n if (option.value !== this.emptyValue) {\n this.nylasFormDropdownChanged.emit({\n value: option.value,\n name: this.name,\n error: this.error,\n label: this.label,\n });\n }\n }\n\n handleSelectButtonKeyDown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowDown':\n case 'Enter':\n event.preventDefault();\n if (!this.isOpen) {\n this.toggleDropdown();\n }\n this.inputRef?.focus();\n break;\n case 'Escape':\n this.isOpen = false;\n break;\n }\n }\n\n handleListboxKeydown(e) {\n const items = this.filteredOptions; // Assuming this is the array of your current filtered options\n const currentIndex = items.findIndex(item => item.value === this.ariaActivedescendant);\n if (e.key === 'ArrowDown' || (e.key === 'Tab' && !e.shiftKey)) {\n e.preventDefault();\n if (currentIndex === items.length - 1) {\n this.ariaActivedescendant = '';\n this.inputRef?.focus();\n return;\n }\n const nextIndex = currentIndex + 1 < items.length ? currentIndex + 1 : 0;\n this.ariaActivedescendant = items[nextIndex].value;\n this.focusOption(nextIndex);\n } else if (e.key === 'ArrowUp' || (e.key === 'Tab' && e.shiftKey)) {\n e.preventDefault();\n if (currentIndex === 0) {\n this.ariaActivedescendant = '';\n this.inputRef?.focus();\n return;\n }\n const prevIndex = currentIndex - 1 >= 0 ? currentIndex - 1 : items.length - 1;\n this.ariaActivedescendant = items[prevIndex].value;\n this.focusOption(prevIndex);\n } else if (e.key === 'Enter') {\n e.preventDefault();\n if (this.ariaActivedescendant) {\n this.selectOption(items[currentIndex]);\n }\n } else if (e.key === 'Escape') {\n this.isOpen = false;\n }\n }\n\n focusOption(index) {\n const option = this.filteredOptions[index];\n if (!option) return; // Guard clause in case index is out of bounds\n\n const elementId = option.value;\n const element = this.el.shadowRoot?.getElementById(elementId) as HTMLLIElement;\n\n if (element) {\n element.focus(); // Set focus on the element\n element.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }\n\n handleComboboxKeyDown(event: KeyboardEvent): void {\n if (event.key === 'ArrowDown' || (event.key == 'Tab' && !event.shiftKey)) {\n event.preventDefault();\n this.ariaActivedescendant = this.filteredOptions[0].value;\n this.focusOption(0);\n } else if (event.key === 'ArrowUp' || (event.key === 'Tab' && event.shiftKey)) {\n event.preventDefault();\n this.ariaActivedescendant = this.filteredOptions[this.filteredOptions.length - 1].value;\n this.focusOption(this.filteredOptions.length - 1);\n } else if (event.key === 'Escape') {\n this.isOpen = false;\n }\n }\n\n generateButtonText(option: DropdownOption | null, dropButtonText?: string): string {\n if (dropButtonText) {\n return dropButtonText;\n }\n return option?.label ? `${this.pluralizedLabel ? this.pluralizedLabel : option?.label}` : this.emptyValue;\n }\n\n // Event listeners\n @Listen('click', { target: 'document', capture: true })\n handleOutsideClick(event: MouseEvent) {\n // Get the path of the event\n const path = event.composedPath();\n\n // Check if the path includes the host element\n const isClickInside = path.includes(this.el);\n\n if (!isClickInside && this.isOpen) {\n this.isOpen = false;\n }\n }\n\n render() {\n const buttonText = this.generateButtonText(this.selectedOption, this.dropdownButtonText);\n\n return (\n <div class=\"dropdown\" part=\"sd_dropdown\">\n <label part=\"sd_dropdown_label\" class={{ error: !!this.error }}>\n {this.label && (\n <p>\n <span class=\"label\">{this.label}</span>\n {this.required && <span class=\"required\">*</span>}\n </p>\n )}\n <button\n part=\"sd_dropdown-button\"\n class={{ dropbtn: true, open: this.isOpen, error: !!this.error }}\n onClick={() => this.toggleDropdown()}\n disabled={this.readOnly}\n aria-haspopup=\"listbox\"\n title={this.readOnly ? 'read-only field' : buttonText}\n aria-expanded={this.isOpen ? 'true' : 'false'}\n aria-label={this.name}\n onKeyDown={e => this.handleSelectButtonKeyDown(e)}\n >\n <slot name=\"select-icon\" aria-hidden=\"true\"></slot>\n <span class=\"selected-option\" part=\"sd_dropdown-button-selected-label\">\n {buttonText}\n </span>\n {this.withChevron && (\n <span\n class={{\n open: this.isOpen,\n closed: !this.isOpen,\n chevron: true,\n }}\n aria-hidden=\"true\"\n >\n <chevron-icon width=\"16\" height=\"16\" />\n </span>\n )}\n </button>\n {this.error && <span class=\"error help-text\">{this.error}</span>}\n </label>\n\n {this.isOpen ? (\n <div class=\"dropdown-content\" part=\"sd_dropdown-content\">\n {this.withSearch && (\n <div class={{ 'search-box': true, 'open': this.isOpen }}>\n <search-icon width=\"15\" height=\"15\" class={'icon'} />\n <input\n type=\"text\"\n role=\"combobox\"\n placeholder=\"Search\"\n value={this.searchValue}\n ref={el => (this.inputRef = el)}\n onInput={event => this.filterOptions(event)}\n onKeyDown={e => this.handleComboboxKeyDown(e)}\n />\n </div>\n )}\n <ul tabindex=\"-1\" role=\"listbox\" aria-label={this.name} aria-activedescendant={this.ariaActivedescendant} onKeyDown={e => this.handleListboxKeydown(e)}>\n {this.filteredOptions.map(option =>\n option.value.toString() ? (\n <li tabindex=\"0\" key={option.value} id={option.value} part={`${this.name}-${option.label}`} onClick={() => this.selectOption(option)} role=\"option\">\n {option.labelHTML ? <div part=\"sd_dropdown-labelhtml\">{option.labelHTML}</div> : option.label}\n </li>\n ) : null,\n )}\n </ul>\n </div>\n ) : null}\n </div>\n );\n }\n}\n"],"mappings":"yDAAA,MAAMA,EAAU,mCAChB,MAAAC,EAAeD,E,MCMFE,EAAW,M,oCACE,K,YACC,I,CAEzB,MAAAC,GACE,OACEC,EAAA,OAAAC,IAAA,2CAAKC,MAAM,6BAA6BC,MAAOC,KAAKD,MAAOE,OAAQD,KAAKC,OAAQC,QAAQ,YAAYC,KAAK,QACvGP,EAAA,QAAAC,IAAA,2CAAMM,KAAK,eAAeC,EAAE,2I,aCdpC,MAAMZ,EAAU,kCAChB,MAAAa,EAAeb,E,MCMFc,EAAU,M,oCACG,K,YACC,I,CAEzB,MAAAX,GACE,OACEC,EAAA,OAAAC,IAAA,2CAAKE,MAAOC,KAAKD,MAAOE,OAAQD,KAAKC,OAAQE,KAAK,OAAOL,MAAM,8BAC7DF,EAAA,QAAAC,IAAA,2CACEM,KAAK,eACLC,EAAE,6a,aChBZ,MAAMG,EAAoB,gzJAC1B,MAAAC,EAAeD,E,MCqBFE,EAAc,M,+KAERT,KAAAU,cAAwB,kB,iCAYL,G,2BAI2D,K,gBAIjE,K,mCAUF,M,cAKA,M,qBAKM,G,mDAQH,K,gBAIF,mB,kBAIE,G,0CAUJ,M,iBAII,G,qBAIc,IAAIV,KAAKW,S,0BAMd,G,WAKf,E,CAwBzB,qBAAAC,CAAsBC,EAA4BC,GAChD,GAAID,IAAaC,EAAU,CACzB,M,CAEFd,KAAKe,gBAAkBF,C,CAIzB,mCAAAG,CAAoCH,EAA0BC,GAC5D,UAAWD,IAAa,aAAeA,GAAUI,QAAUH,GAAUG,MAAO,CAC1E,M,CAEFjB,KAAKkB,eAAiBL,EACtBb,KAAKmB,iCAAiCC,KAAK,CACzCC,MAAOR,GAAUQ,OAAS,GAC1BC,KAAMtB,KAAKsB,KACXC,MAAOvB,KAAKuB,MACZN,MAAOjB,KAAKiB,O,CAKhB,iBAAAO,GACExB,KAAKyB,GAAGC,aAAa,iBAAkB1B,KAAKU,c,CAG9C,gBAAAiB,GACE3B,KAAKe,gBAAkBf,KAAKW,QAE5BX,KAAKkB,eAAiBlB,KAAK4B,sBAE3B,IAAK5B,KAAKkB,gBAAkBlB,KAAKW,QAAQkB,OAAS,EAAG,CACnD7B,KAAKkB,eAAiBlB,KAAKW,QAAQ,E,CAErCX,KAAKmB,iCAAiCC,KAAK,CACzCC,MAAOrB,KAAKkB,gBAAgBG,OAAS,GACrCC,KAAMtB,KAAKsB,KACXC,MAAOvB,KAAKuB,MACZN,MAAOjB,KAAKiB,O,CAShB,0BAAAa,CAA2BC,GACzB/B,KAAKgC,SAAShC,KAAKkB,gBAAgBG,OAAS,IAC5C,GAAIrB,KAAKuB,MAAO,CACdQ,EAAME,gB,EASV,mBAAAC,CAAoBH,GAClB/B,KAAKgC,SAAShC,KAAKkB,gBAAgBG,OAAS,IAC5C,GAAIrB,KAAKuB,MAAO,CACdQ,EAAME,gB,EAKV,QAAAD,CAASX,GACP,GAAIrB,KAAKmC,WAAad,EAAO,CAC3BrB,KAAKuB,MAAQvB,KAAKoC,cAAgB,GAAGpC,KAAKiB,oB,KACrC,CACLjB,KAAKuB,MAAQ,E,EAGjB,cAAAc,GACErC,KAAKsC,QAAUtC,KAAKsC,M,CAGtB,aAAAC,CAAcR,GACZ,MAAMV,EAASU,EAAMS,OAA4BnB,MACjDrB,KAAKyC,YAAcpB,EACnBrB,KAAKe,gBAAkBf,KAAKW,QAAQ+B,QAAOC,GAAUA,EAAO1B,MAAM2B,cAAcC,SAASxB,EAAMuB,gB,CAGjG,YAAAE,CAAaH,GACX3C,KAAKuB,MAAQ,GACbvB,KAAKkB,eAAiByB,EACtB3C,KAAKqC,iBACL,GAAIM,EAAOtB,QAAUrB,KAAK+C,WAAY,CACpC/C,KAAKgD,yBAAyB5B,KAAK,CACjCC,MAAOsB,EAAOtB,MACdC,KAAMtB,KAAKsB,KACXC,MAAOvB,KAAKuB,MACZN,MAAOjB,KAAKiB,O,EAKlB,yBAAAgC,CAA0BlB,GACxB,OAAQA,EAAMlC,KACZ,IAAK,YACL,IAAK,QACHkC,EAAME,iBACN,IAAKjC,KAAKsC,OAAQ,CAChBtC,KAAKqC,gB,CAEPrC,KAAKkD,UAAUC,QACf,MACF,IAAK,SACHnD,KAAKsC,OAAS,MACd,M,CAIN,oBAAAc,CAAqBC,GACnB,MAAMC,EAAQtD,KAAKe,gBACnB,MAAMwC,EAAeD,EAAME,WAAUC,GAAQA,EAAKpC,QAAUrB,KAAK0D,uBACjE,GAAIL,EAAExD,MAAQ,aAAgBwD,EAAExD,MAAQ,QAAUwD,EAAEM,SAAW,CAC7DN,EAAEpB,iBACF,GAAIsB,IAAiBD,EAAMzB,OAAS,EAAG,CACrC7B,KAAK0D,qBAAuB,GAC5B1D,KAAKkD,UAAUC,QACf,M,CAEF,MAAMS,EAAYL,EAAe,EAAID,EAAMzB,OAAS0B,EAAe,EAAI,EACvEvD,KAAK0D,qBAAuBJ,EAAMM,GAAWvC,MAC7CrB,KAAK6D,YAAYD,E,MACZ,GAAIP,EAAExD,MAAQ,WAAcwD,EAAExD,MAAQ,OAASwD,EAAEM,SAAW,CACjEN,EAAEpB,iBACF,GAAIsB,IAAiB,EAAG,CACtBvD,KAAK0D,qBAAuB,GAC5B1D,KAAKkD,UAAUC,QACf,M,CAEF,MAAMW,EAAYP,EAAe,GAAK,EAAIA,EAAe,EAAID,EAAMzB,OAAS,EAC5E7B,KAAK0D,qBAAuBJ,EAAMQ,GAAWzC,MAC7CrB,KAAK6D,YAAYC,E,MACZ,GAAIT,EAAExD,MAAQ,QAAS,CAC5BwD,EAAEpB,iBACF,GAAIjC,KAAK0D,qBAAsB,CAC7B1D,KAAK8C,aAAaQ,EAAMC,G,OAErB,GAAIF,EAAExD,MAAQ,SAAU,CAC7BG,KAAKsC,OAAS,K,EAIlB,WAAAuB,CAAYE,GACV,MAAMpB,EAAS3C,KAAKe,gBAAgBgD,GACpC,IAAKpB,EAAQ,OAEb,MAAMqB,EAAYrB,EAAOtB,MACzB,MAAM4C,EAAUjE,KAAKyB,GAAGyC,YAAYC,eAAeH,GAEnD,GAAIC,EAAS,CACXA,EAAQd,QACRc,EAAQG,eAAe,CAAEC,SAAU,SAAUC,MAAO,W,EAIxD,qBAAAC,CAAsBxC,GACpB,GAAIA,EAAMlC,MAAQ,aAAgBkC,EAAMlC,KAAO,QAAUkC,EAAM4B,SAAW,CACxE5B,EAAME,iBACNjC,KAAK0D,qBAAuB1D,KAAKe,gBAAgB,GAAGM,MACpDrB,KAAK6D,YAAY,E,MACZ,GAAI9B,EAAMlC,MAAQ,WAAckC,EAAMlC,MAAQ,OAASkC,EAAM4B,SAAW,CAC7E5B,EAAME,iBACNjC,KAAK0D,qBAAuB1D,KAAKe,gBAAgBf,KAAKe,gBAAgBc,OAAS,GAAGR,MAClFrB,KAAK6D,YAAY7D,KAAKe,gBAAgBc,OAAS,E,MAC1C,GAAIE,EAAMlC,MAAQ,SAAU,CACjCG,KAAKsC,OAAS,K,EAIlB,kBAAAkC,CAAmB7B,EAA+B8B,GAChD,GAAIA,EAAgB,CAClB,OAAOA,C,CAET,OAAO9B,GAAQ1B,MAAQ,GAAGjB,KAAK0E,gBAAkB1E,KAAK0E,gBAAkB/B,GAAQ1B,QAAUjB,KAAK+C,U,CAKjG,kBAAA4B,CAAmB5C,GAEjB,MAAM6C,EAAO7C,EAAM8C,eAGnB,MAAMC,EAAgBF,EAAK/B,SAAS7C,KAAKyB,IAEzC,IAAKqD,GAAiB9E,KAAKsC,OAAQ,CACjCtC,KAAKsC,OAAS,K,EAIlB,MAAA3C,GACE,MAAMoF,EAAa/E,KAAKwE,mBAAmBxE,KAAKkB,eAAgBlB,KAAKgF,oBAErE,OACEpF,EAAA,OAAAC,IAAA,2CAAKoF,MAAM,WAAWC,KAAK,eACzBtF,EAAA,SAAAC,IAAA,2CAAOqF,KAAK,oBAAoBD,MAAO,CAAE1D,QAASvB,KAAKuB,QACpDvB,KAAKiB,OACJrB,EAAA,SACEA,EAAA,QAAMqF,MAAM,SAASjF,KAAKiB,OACzBjB,KAAKmC,UAAYvC,EAAA,QAAMqF,MAAM,YAAU,MAG5CrF,EAAA,UAAAC,IAAA,2CACEqF,KAAK,qBACLD,MAAO,CAAEE,QAAS,KAAMC,KAAMpF,KAAKsC,OAAQf,QAASvB,KAAKuB,OACzD8D,QAAS,IAAMrF,KAAKqC,iBACpBiD,SAAUtF,KAAKuF,SAAQ,gBACT,UACdC,MAAOxF,KAAKuF,SAAW,kBAAoBR,EAAU,gBACtC/E,KAAKsC,OAAS,OAAS,QAAO,aACjCtC,KAAKsB,KACjBmE,UAAWpC,GAAKrD,KAAKiD,0BAA0BI,IAE/CzD,EAAA,QAAAC,IAAA,2CAAMyB,KAAK,cAAa,cAAa,SACrC1B,EAAA,QAAAC,IAAA,2CAAMoF,MAAM,kBAAkBC,KAAK,qCAChCH,GAEF/E,KAAK0F,aACJ9F,EAAA,QACEqF,MAAO,CACLG,KAAMpF,KAAKsC,OACXqD,QAAS3F,KAAKsC,OACdsD,QAAS,MACV,cACW,QAEZhG,EAAA,gBAAcG,MAAM,KAAKE,OAAO,SAIrCD,KAAKuB,OAAS3B,EAAA,QAAMqF,MAAM,mBAAmBjF,KAAKuB,QAGpDvB,KAAKsC,OACJ1C,EAAA,OAAKqF,MAAM,mBAAmBC,KAAK,uBAChClF,KAAK6F,YACJjG,EAAA,OAAKqF,MAAO,CAAE,aAAc,KAAMG,KAAQpF,KAAKsC,SAC7C1C,EAAA,eAAaG,MAAM,KAAKE,OAAO,KAAKgF,MAAO,SAC3CrF,EAAA,SACEkG,KAAK,OACLC,KAAK,WACLC,YAAY,SACZ3E,MAAOrB,KAAKyC,YACZwD,IAAKxE,GAAOzB,KAAKkD,SAAWzB,EAC5ByE,QAASnE,GAAS/B,KAAKuC,cAAcR,GACrC0D,UAAWpC,GAAKrD,KAAKuE,sBAAsBlB,MAIjDzD,EAAA,MAAIuG,SAAS,KAAKJ,KAAK,UAAS,aAAa/F,KAAKsB,KAAI,wBAAyBtB,KAAK0D,qBAAsB+B,UAAWpC,GAAKrD,KAAKoD,qBAAqBC,IACjJrD,KAAKe,gBAAgBqF,KAAIzD,GACxBA,EAAOtB,MAAMgF,WACXzG,EAAA,MAAIuG,SAAS,IAAItG,IAAK8C,EAAOtB,MAAOiF,GAAI3D,EAAOtB,MAAO6D,KAAM,GAAGlF,KAAKsB,QAAQqB,EAAO1B,QAASoE,QAAS,IAAMrF,KAAK8C,aAAaH,GAASoD,KAAK,UACxIpD,EAAO4D,UAAY3G,EAAA,OAAKsF,KAAK,yBAAyBvC,EAAO4D,WAAmB5D,EAAO1B,OAExF,SAIR,K"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["multiSelectDropdownCss","MultiSelectDropdownStyle0","MultiSelectDropdown","this","options","areOptionsEqual","arr1","arr2","length","sorted1","sort","a","b","label","localeCompare","value","sorted2","every","opt1","index","opt2","optionsChangedHandler","newValue","availableOptions","componentDidLoad","debug","componentDidRender","isOpen","shouldFocusFirstOption","ariaActivedescendant","focusOption","handleOutsideClick","event","path","composedPath","isClickInside","includes","el","handleBookingFormSubmitted","selectedOptions","filter","o","selected","map","required","error","preventDefault","selectOption","option","selectedOptionsChanged","emit","name","toggleDropdown","handleSelectButtonKeyDown","key","handleListboxKeydown","e","items","currentIndex","findIndex","item","shiftKey","nextIndex","prevIndex","elementId","element","shadowRoot","getElementById","focus","scrollIntoView","behavior","block","getSelectedOptions","renderOption","h","id","role","tabindex","onClick","stopImmediatePropagation","disabled","class","htmlFor","type","checked","render","Host","part","dropbtn","open","readOnly","title","undefined","onKeyDown","multipleOptionsSelectedLabel","width","height","nylasDateComponentCss","NylasDateComponentStyle0","DefaultPlaceholder","date","NylasDateComponent","handleDefaultValueChange","sanitize","validatePattern","defaultValue","handleFormSubmitted","handleInput","target","isDateValid","validity","valid","nylasFormInputChanged","handleBlur","nylasFormInputBlurred","handleFocus","nylasFormInputFocused","requiredError","pattern","test","patternError","autoFocus","maxLength","placeholder","onInput","onFocus","onBlur"],"sources":["src/components/design-system/multi-select-dropdown/multi-select-dropdown.scss?tag=multi-select-dropdown&encapsulation=shadow","src/components/design-system/multi-select-dropdown/multi-select-dropdown.tsx","src/components/design-system/nylas-date-component/nylas-date-component.scss?tag=nylas-date-component&encapsulation=shadow","src/components/design-system/nylas-date-component/nylas-date-component.tsx"],"sourcesContent":["@import '../../../common/styles/variables.scss';\n\n:host {\n display: block;\n width: inherit;\n @include default-css-variables;\n}\n\n.dropdown {\n display: inline-block;\n width: 100%;\n position: relative;\n\n .dropdown-label {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n color: var(--nylas-base-800);\n\n p {\n margin: 0;\n }\n\n span.required {\n color: var(--nylas-error);\n padding: 0 0.25rem;\n }\n }\n\n span.error {\n color: var(--nylas-error);\n font-size: 14px;\n }\n}\n\n.dropbtn {\n width: inherit;\n height: 48px;\n color: var(--nylas-base-900);\n padding: 0.5rem;\n font-size: 16px;\n cursor: pointer;\n display: flex;\n gap: 0.5rem;\n justify-content: space-between;\n align-items: center;\n background: transparent;\n border: 1px solid var(--nylas-base-200);\n border-radius: var(--nylas-border-radius-2x);\n\n &.focus {\n background: transparent;\n }\n\n &.error {\n border: 1px solid var(--nylas-error);\n }\n\n &:hover,\n &:active {\n border: 1px solid var(--nylas-primary);\n }\n\n &:active {\n outline: 2px solid var(--nylas-primary);\n }\n\n &:disabled {\n cursor: not-allowed;\n background: var(--nylas-base-100);\n }\n\n span {\n &.open {\n transform: rotate(90deg);\n }\n\n &.closed {\n transform: rotate(270deg);\n }\n }\n}\n\n.dropdown-content {\n display: block;\n margin-top: 0.5rem;\n background-color: var(--nylas-base-0);\n width: 100%;\n max-height: 336px;\n overflow: auto;\n z-index: 1;\n border-radius: 4px;\n position: absolute;\n top: calc(48px + 24px);\n box-shadow: 0px 4px 6px -2px #0000000d;\n box-shadow: 0px 10px 15px -3px #0000001a;\n}\n\n.dropdown-content ul {\n padding: 0;\n list-style-type: none;\n color: var(--nylas-base-900);\n max-height: 336px;\n\n li {\n padding: 16px, 12px, 16px, 12px;\n color: var(--nylas-base-900);\n padding: 12px 16px;\n text-decoration: none;\n display: block;\n font-family: inherit;\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n letter-spacing: 0px;\n text-align: left;\n cursor: pointer;\n\n &:hover,\n &:focus {\n background-color: var(--nylas-base-100);\n }\n\n label {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n\n input {\n margin: 0;\n }\n }\n\n &.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n\n label {\n cursor: not-allowed;\n\n input {\n cursor: not-allowed;\n }\n }\n }\n }\n}\n\n.selected-options {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n padding: 0.5rem 0;\n margin-top: 0.25rem;\n background: var(--nylas-base-0);\n\n .selected-option {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 4px 8px;\n border-radius: var(--nylas-border-radius-2x);\n background: var(--nylas-base-100);\n color: var(--nylas-base-800);\n font-size: 16px;\n font-weight: 500;\n line-height: 1.5rem;\n letter-spacing: 0.5px;\n\n button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 0;\n\n &:hover {\n color: var(--nylas-primary);\n }\n\n &:disabled {\n cursor: not-allowed;\n background: var(--nylas-base-100);\n }\n }\n }\n}\n","import { debug } from '@/utils/utils';\nimport { Component, Element, Event, EventEmitter, Host, Listen, Prop, State, Watch, h } from '@stencil/core';\n\ninterface DropdownOption {\n label: string;\n value: string;\n selected?: boolean; // Add a selected flag to each option\n disabled?: boolean; // Add a disabled flag to each option\n}\n\n@Component({\n tag: 'multi-select-dropdown',\n styleUrl: 'multi-select-dropdown.scss',\n shadow: true,\n})\nexport class MultiSelectDropdown {\n @Element() el!: HTMLElement;\n\n // Props\n /**\n * The name of the dropdown\n */\n @Prop() name!: string;\n\n /**\n * The label of the dropdown\n */\n @Prop() label?: string;\n\n /**\n * The options to display in the dropdown\n */\n @Prop() options: DropdownOption[] = [];\n\n /**\n * Error message to display\n */\n @Prop({ mutable: true }) error?: string = '';\n\n /**\n * The option to require selection of at leat one option.\n */\n @Prop() required?: boolean = false;\n\n /**\n * The property to make the multi-select dropdown read-only. If true, the dropdown cannot be edited.\n */\n @Prop() readOnly?: boolean = false;\n\n /**\n * Multiple options selected label\n */\n @Prop() multipleOptionsSelectedLabel?: string = 'Multiple options selected';\n\n /**\n * Select at least one option label\n */\n @Prop() selectAtLeastOneOptionLabel?: string = 'Please select at least one option';\n\n // States\n /**\n * The copy of the options to display in the dropdown\n */\n @State() availableOptions: DropdownOption[] = this.options;\n /**\n * The open state of the dropdown\n */\n @State() isOpen: boolean = false;\n /**\n * The aria-activedescendant attribute for the listbox element to indicate the currently active\n */\n @State() ariaActivedescendant: string = '';\n\n /**\n * This flag is used to focus the first option when the dropdown is opened\n * and reset after the first option is focused\n */\n @State() shouldFocusFirstOption: boolean = false;\n\n // Events\n /**\n * This event is fired when the selected options are changed\n */\n @Event({ bubbles: true, composed: true }) selectedOptionsChanged!: EventEmitter<{\n value: string[];\n name: string;\n }>;\n\n areOptionsEqual(arr1: DropdownOption[], arr2: DropdownOption[]): boolean {\n if (arr1.length !== arr2.length) return false;\n\n // Sort both arrays by a consistent key (e.g., label and value)\n const sorted1 = [...arr1].sort((a, b) => a.label.localeCompare(b.label) || a.value.localeCompare(b.value));\n const sorted2 = [...arr2].sort((a, b) => a.label.localeCompare(b.label) || a.value.localeCompare(b.value));\n\n // Compare each object in the sorted arrays\n return sorted1.every((opt1, index) => {\n const opt2 = sorted2[index];\n return opt1.label === opt2.label && opt1.value === opt2.value;\n });\n }\n\n @Watch('options')\n optionsChangedHandler(newValue: DropdownOption[]) {\n if (!this.areOptionsEqual(newValue, this.availableOptions)) {\n this.availableOptions = newValue;\n }\n }\n\n // Lifecycle methods\n componentDidLoad() {\n debug('multi-select-dropdown', 'componentDidLoad');\n if (this.options) {\n this.availableOptions = this.options;\n }\n }\n\n componentDidRender() {\n debug('multi-select-dropdown', 'componentDidRender');\n if (this.isOpen && this.shouldFocusFirstOption) {\n // The dropdown is open and we should focus the first option\n this.ariaActivedescendant = this.availableOptions[0]?.value;\n this.focusOption(0);\n // Reset the flag\n this.shouldFocusFirstOption = false;\n }\n }\n\n // Event listeners\n @Listen('click', { target: 'document', capture: true })\n handleOutsideClick(event: MouseEvent) {\n // Get the path of the event\n const path = event.composedPath();\n\n // Check if the path includes the host element\n const isClickInside = path.includes(this.el);\n\n if (!isClickInside && this.isOpen) {\n this.isOpen = false;\n }\n }\n\n @Listen('bookingFormSubmitted', { target: 'document' })\n handleBookingFormSubmitted(event: CustomEvent) {\n const selectedOptions = this.availableOptions.filter(o => o.selected).map(o => o.value);\n if (this.required && (!selectedOptions || selectedOptions.length <= 0)) {\n this.error = 'Please select at least one option';\n }\n if (this.error) {\n event.preventDefault();\n }\n }\n\n // Methods\n\n selectOption(option: DropdownOption): void {\n this.availableOptions = this.availableOptions.map(o => {\n if (o.value === option.value) {\n o.selected = option.selected ? false : true;\n if (o.selected) {\n this.error = '';\n }\n }\n return o;\n });\n const selectedOptions = this.availableOptions.filter(o => o.selected).map(o => o.value);\n this.selectedOptionsChanged.emit({\n value: selectedOptions,\n name: this.name,\n });\n }\n\n toggleDropdown(): void {\n this.isOpen = !this.isOpen;\n if (this.isOpen) {\n this.shouldFocusFirstOption = true;\n } else {\n this.ariaActivedescendant = '';\n }\n }\n\n handleSelectButtonKeyDown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowDown':\n case 'Enter':\n event.preventDefault();\n if (!this.isOpen) {\n this.toggleDropdown();\n }\n break;\n case 'Escape':\n this.isOpen = false;\n break;\n }\n }\n\n handleListboxKeydown(e: KeyboardEvent) {\n const items = this.availableOptions;\n const currentIndex = items.findIndex(item => item.value === this.ariaActivedescendant);\n\n switch (e.key) {\n case 'ArrowDown':\n case 'Tab': {\n if (!e.shiftKey) {\n e.preventDefault();\n const nextIndex = currentIndex + 1 < items.length ? currentIndex + 1 : 0;\n this.ariaActivedescendant = items[nextIndex].value;\n this.focusOption(nextIndex);\n } else {\n e.preventDefault();\n const prevIndex = currentIndex - 1 >= 0 ? currentIndex - 1 : items.length - 1;\n this.ariaActivedescendant = items[prevIndex].value;\n this.focusOption(prevIndex);\n }\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n const prevIndex = currentIndex - 1 >= 0 ? currentIndex - 1 : items.length - 1;\n this.ariaActivedescendant = items[prevIndex].value;\n this.focusOption(prevIndex);\n break;\n }\n case 'Enter': {\n e.preventDefault();\n if (this.ariaActivedescendant) {\n this.selectOption(items[currentIndex]);\n }\n break;\n }\n case 'Escape': {\n this.isOpen = false;\n break;\n }\n }\n }\n\n focusOption(index: number) {\n const option = this.availableOptions[index];\n if (!option) return; // Guard clause in case index is out of bounds\n\n const elementId = option.value;\n const element = this.el.shadowRoot?.getElementById(elementId) as HTMLLIElement;\n\n if (element) {\n element.focus(); // Set focus on the element\n element.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }\n\n getSelectedOptions() {\n return this.availableOptions.filter(option => option.selected);\n }\n\n renderOption(option: DropdownOption) {\n return (\n <li\n key={option.value}\n id={option.value}\n role=\"option\"\n tabindex=\"0\"\n aria-selected={option.selected ? 'true' : 'false'}\n onClick={e => {\n e.stopImmediatePropagation();\n if (!option?.disabled) {\n this.selectOption(option);\n }\n }}\n class={{ selected: !!option.selected, disabled: !!option.disabled }}\n >\n <label htmlFor={option.value}>\n <input aria-hidden=\"true\" id={option.value} type=\"checkbox\" checked={option.selected} disabled={!!option?.disabled} />\n <span>{option.label}</span>\n </label>\n </li>\n );\n }\n\n render() {\n return (\n <Host>\n <div class=\"dropdown\" part=\"msd_dropdown\">\n <label class=\"dropdown-label\" part=\"msd_dropdown-label\">\n <p>\n <span class=\"label\">{this.label}</span>\n {this.required && <span class=\"required\">*</span>}\n </p>\n <slot name=\"label-icon\" aria-hidden=\"true\"></slot>\n </label>\n <button\n name={this.name}\n part={`msd_dropdown-button ${this.error ? 'msd_dropdown-button--error' : ''}`}\n class={{ dropbtn: true, open: this.isOpen, error: !!this.error }}\n onClick={() => this.toggleDropdown()}\n disabled={this.readOnly}\n title={this.readOnly ? 'read-only field' : undefined}\n aria-haspopup=\"listbox\"\n aria-expanded={this.isOpen ? 'true' : 'false'}\n aria-label={this.name}\n onKeyDown={e => this.handleSelectButtonKeyDown(e)}\n >\n <slot name=\"select-icon\" aria-hidden=\"true\"></slot>\n <span class=\"selected-option\" part=\"msd_dropdown-button-selected-label\">\n {this.getSelectedOptions().length > 1\n ? this.multipleOptionsSelectedLabel\n : this.availableOptions.filter(o => o.selected)[0]?.label ?? this.availableOptions[0]?.label}\n </span>\n <span class={this.isOpen ? 'open' : 'closed'} aria-hidden=\"true\">\n <chevron-icon width=\"16\" height=\"16\" />\n </span>\n </button>\n {this.error ? (\n <span class=\"error\" part=\"msd_dropdown_error\">\n {this.error}\n </span>\n ) : null}\n <div class={'selected-options'}>\n {this.getSelectedOptions().map(option => (\n <span class=\"selected-option\">\n {option.label}\n <button disabled={this.readOnly || !!option?.disabled} key={option.label} onClick={() => this.selectOption(option)}>\n <close-icon />\n </button>\n </span>\n ))}\n </div>\n {this.isOpen ? (\n <div class=\"dropdown-content\" part=\"msd_dropdown-content\">\n <ul\n tabindex=\"-1\"\n role=\"listbox\"\n aria-label={this.name}\n aria-multiselectable={true}\n aria-activedescendant={this.ariaActivedescendant}\n onKeyDown={e => this.handleListboxKeydown(e)}\n >\n {this.availableOptions.map(option => this.renderOption(option))}\n </ul>\n </div>\n ) : null}\n </div>\n </Host>\n );\n }\n}\n","@import '../../../common/styles/variables.scss';\n@import '../../../common/mixins/inputs.scss';\n\n:host {\n display: block;\n height: auto;\n @include default-css-variables;\n width: 100%;\n}\n\nlabel {\n @include input-label;\n flex-direction: column;\n gap: 4px;\n font-family: var(--nylas-font-family);\n font-size: 16px;\n color: var(--nylas-base-800);\n\n p {\n margin: 0;\n }\n\n .error {\n color: var(--nylas-error);\n }\n}\n\n.input_wrapper {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\ninput[type='date'] {\n @include textfield;\n width: 100%;\n width: -moz-available;\n width: -webkit-fill-available;\n font-family: var(--nylas-font-family);\n cursor: pointer;\n}\n\ninput:read-only {\n background-color: var(--nylas-base-100);\n cursor: not-allowed;\n}\n","import { Component, h, Prop, State, Event, EventEmitter, Listen, Watch, Element } from '@stencil/core';\nimport { sanitize } from '@/utils/utils';\n\nconst DefaultPlaceholder = {\n date: 'YYYY-MM-DD',\n};\n\n/**\n * The `nylas-date-component` component is a UI component that allows users to input text, email, or phone number values.\n * This component is used in the scheduling form to input text, email and phone number type inputs.\n */\n\n@Component({\n tag: 'nylas-date-component',\n styleUrl: 'nylas-date-component.scss',\n shadow: true,\n})\nexport class NylasDateComponent {\n /**\n * The host element\n */\n @Element() el!: HTMLElement;\n /**\n * The name of the input. This is used to identify the input when submitting a form.\n */\n @Prop() name: string = 'input';\n /**\n * The default value of the input. This is the value that is displayed when the input is rendered.\n */\n @Prop() defaultValue?: string;\n /**\n * The label of the input. This is displayed above the input.\n */\n @Prop() label: string = '';\n\n /**\n * The placeholder of the input. This is displayed when the input is empty.\n */\n @Prop() placeholder: string = DefaultPlaceholder['date'];\n /**\n * Whether the input is required. If true, the input must have a value when submitting a form.\n * Default is false. If the input is required and the value is empty, an error message is displayed.\n */\n @Prop() required: boolean = false;\n /**\n * Whether the input is read-only. If true, the input cannot be edited.\n * Default is false.\n */\n @Prop() readOnly: boolean = false;\n /**\n * Whether the input should be focused when rendered.\n * Default is false. If true, the input is focused when rendered.\n * Use this to set the focus on the first input in a form.\n */\n @Prop() autoFocus: boolean = false;\n /**\n * The pattern to validate the input value. If the value does not match the pattern, an error message is displayed.\n * Default is null. If the pattern is not set, the pattern is determined by the input type for 'email' and 'phone_number'.\n */\n @Prop() pattern?: RegExp;\n /**\n * The maximum length of the input value. If the value is longer than the maximum length, an error message is displayed.\n * Default is 255.\n */\n @Prop() maxLength: number = 255;\n /**\n * The error message to display when the value does not match the pattern.\n * Default is 'Invalid <field> format.' where <field> is the input label.\n */\n @Prop() patternError: string = '';\n\n /**\n * This error message is displayed when the input value is empty and the input is required.\n */\n @Prop() requiredError: string = '';\n\n /**\n * The input value state.\n */\n @State() value!: string;\n /**\n * The error message state.\n */\n @State() error: string = '';\n\n /**\n * State to track the validity of the date input.\n */\n @State() isDateValid: boolean = true;\n\n /**\n * This event is fired when the input value is changed.\n * The scheduling form listens for this event to validate the input value and submit the form.\n * If using outside of the scheduling form, listen for this event to validate the input value\n * and handle the input value change.\n */\n @Event() nylasFormInputChanged!: EventEmitter<{\n value: string;\n name: string;\n label: string;\n type: string;\n error: string;\n }>;\n\n @Event() nylasFormInputFocused!: EventEmitter<{\n value: string;\n name: string;\n }>;\n\n @Event() nylasFormInputBlurred!: EventEmitter<{\n value: string;\n name: string;\n }>;\n\n // Lifecycle methods\n @Watch('defaultValue')\n handleDefaultValueChange(newValue: string) {\n this.value = sanitize(newValue);\n if (this.value) {\n this.validatePattern(this.value);\n }\n }\n\n componentDidLoad() {\n this.value = sanitize(this.defaultValue || '');\n if (this.value) {\n this.validatePattern(this.value);\n }\n }\n\n // Event listeners\n /**\n * Listen for the bookingFormSubmitted event to validate the input value when the form is submitted.\n */\n @Listen('bookingFormSubmitted', { target: 'document' })\n handleBookingFormSubmitted(event: CustomEvent) {\n this.validatePattern(this.value);\n if (this.error) {\n event.preventDefault();\n }\n }\n\n @Listen('formSubmitted', { target: 'document' })\n async handleFormSubmitted(event: CustomEvent) {\n this.validatePattern(this.value);\n if (this.error) {\n event.preventDefault();\n }\n }\n\n // Methods\n handleInput(e: Event) {\n this.error = '';\n const target = e.target as HTMLInputElement;\n this.value = sanitize(target.value);\n this.isDateValid = target.validity.valid;\n this.nylasFormInputChanged.emit({\n value: this.value,\n name: this.name,\n label: this.label,\n error: this.error,\n type: 'date',\n });\n }\n\n handleBlur() {\n this.nylasFormInputBlurred.emit({\n value: this.value,\n name: this.name,\n });\n }\n\n handleFocus() {\n this.nylasFormInputFocused.emit({\n value: this.value,\n name: this.name,\n });\n }\n\n validatePattern(value: string) {\n // Reset error\n this.error = '';\n if (this.required && !this.isDateValid) {\n this.error = 'Please enter a valid date';\n return;\n }\n // Check if the field is required and value is empty\n if (this.required && !value) {\n this.error = this.requiredError || 'This field is required.';\n return;\n }\n // Check if value matches pattern\n if (!this.pattern || (!value && !this.required)) return;\n\n if (this.pattern.test(value)) {\n this.error = '';\n } else {\n this.error = this.patternError || 'Invalid format.';\n }\n }\n\n render() {\n return (\n <label part=\"ic__label\" class={{ error: !!this.error }}>\n {this.label && (\n <p>\n <span class=\"label\">{this.label}</span>\n {this.required && <span class=\"required\">*</span>}\n </p>\n )}\n <div part=\"ic__input_wrapper\" class=\"input_wrapper\">\n <input\n type=\"date\"\n name={this.name}\n part=\"ic__date\"\n title={this.readOnly ? 'read-only field' : undefined}\n readOnly={this.readOnly}\n autoFocus={this.autoFocus}\n value={this.value}\n maxLength={this.maxLength}\n placeholder={this.placeholder}\n class={{ error: !!this.error }}\n onInput={e => this.handleInput(e)}\n onFocus={() => this.handleFocus()}\n onBlur={() => this.handleBlur()}\n />\n <slot name=\"additional-input\"></slot>\n </div>\n {this.error && <span class=\"error help-text\">{this.error}</span>}\n </label>\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["inputDropdownCss","InputDropdownStyle0","InputDropdown","this","defaultInputOption","options","optionsChangedHandler","newValue","oldValue","filteredOptions","getFilteredOptions","defaultSelectedOptionChangedHandler","label","selectedOption","inputValueChangedHandler","componentWillLoad","length","filterable","filter","option","value","toString","toLowerCase","includes","typedValue","toggleDropdown","isOpen","selectOption","inputOptionChanged","emit","name","handleOnInput","event","target","optionIndex","findIndex","scrollToViewWithinParent","childElement","el","shadowRoot","getElementById","parentElement","optionsRef","ariaActivedescendant","childRect","getBoundingClientRect","parentRect","top","scrollTop","bottom","handleSelectButtonKeyDown","key","preventDefault","inputRef","focus","handleClick","setTimeout","handleListboxKeydown","e","items","currentIndex","item","shiftKey","nextIndex","focusOption","prevIndex","index","elementId","element","scrollIntoView","behavior","block","handleComboboxKeyDown","shouldAutoScroll","handleOutsideClick","path","composedPath","isClickInside","render","h","class","part","type","id","dropbtn","open","inputValue","onClick","onKeyDown","onInput","ref","tabindex","role","map","focused","labelHTML","timePeriodSelectorCss","TimePeriodSelectorStyle0","pluralToSingular","hours","days","weeks","months","years","TimePeriodSelector","TIME_PERIODS","defaultSelectedPeriod","defaultSelectedNumber","calculateOptions","i","timePeriods","defaultSelectedPeriodChanged","selectedPeriod","updateNumberOptionsAndSelectedNumber","defaultSelectedNumberChanged","selectedNumber","timePeriodsChanged","timePeriodOptions","componentDidLoad","period","numberOptions","Array","from","_","inputOptionChangedHandler","debug","detail","parseInt","selected","number","timePeriodChanged","nylasFormDropdownChangedHandler","error","hasError","exportparts","find","pluralizedLabel","i18next","t","defaultSelectedOption","withSearch"],"sources":["src/components/design-system/input-dropdown/input-dropdown.scss?tag=input-dropdown&encapsulation=shadow","src/components/design-system/input-dropdown/input-dropdown.tsx","src/components/design-system/time-period-selector/time-period-selector.scss?tag=time-period-selector&encapsulation=scoped","src/components/design-system/time-period-selector/time-period-selector.tsx"],"sourcesContent":["@import '../../../common/styles/variables.scss';\n\n:host {\n display: block;\n position: relative;\n\n @media #{$mobile} {\n position: unset;\n }\n\n @include default-css-variables;\n}\n\n.dropdown {\n display: inline-block;\n}\n\n.dropbtn {\n color: var(--nylas-base-800);\n padding: 10px;\n font-size: 16px;\n font-family: var(--nylas-font-family);\n cursor: pointer;\n display: flex;\n gap: 0.5rem;\n background: transparent;\n border: none;\n border-radius: var(--nylas-border-radius-2x);\n width: 50px;\n padding: 14px 16px;\n border-radius: var(--nylas-border-radius-2x);\n\n &.focus {\n background: transparent;\n }\n\n &:hover,\n &:active {\n outline: 1px solid var(--nylas-primary);\n }\n\n &:active {\n outline: 2px solid var(--nylas-primary);\n }\n\n span {\n &.chevron {\n display: flex;\n align-self: center;\n }\n\n &.open {\n transform: rotate(90deg);\n }\n\n &.closed {\n transform: rotate(270deg);\n }\n\n &.selected-option {\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n max-width: 144px;\n font-size: 14px;\n line-height: 20px;\n\n @media #{$mobile} {\n max-width: 124px;\n font-size: 16px;\n }\n }\n }\n}\n\n.dropdown-content {\n display: block;\n margin-top: 0.5rem;\n background-color: var(--nylas-base-0);\n max-width: 306px;\n width: max-content;\n max-height: 336px;\n overflow: auto;\n z-index: 1;\n border-radius: 4px;\n position: absolute;\n\n @media #{$mobile} {\n right: 0;\n width: 325px;\n max-width: unset;\n }\n\n box-shadow: 0px 4px 6px -2px rgba(0, 0, 0, 0.05);\n box-shadow: 0px 10px 15px -3px rgba(0, 0, 0, 0.1);\n}\n\n.search-box {\n border-bottom: 1px solid var(--nylas-base-200);\n padding: 10px;\n position: sticky;\n top: 0;\n background: var(--nylas-base-0);\n\n .icon {\n position: absolute;\n top: 1.25rem;\n left: 1.25rem;\n color: var(--nylas-base-300);\n }\n}\n\n.dropdown-content ul {\n padding: 0;\n list-style-type: none;\n color: var(--nylas-base-900);\n max-height: 336px;\n\n li {\n padding: 16px, 12px, 16px, 12px;\n color: var(--nylas-base-900);\n padding: 12px 16px;\n text-decoration: none;\n display: block;\n font-family: inherit;\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n letter-spacing: 0px;\n text-align: left;\n cursor: pointer;\n\n &:hover,\n &:focus {\n background-color: var(--nylas-base-100);\n }\n }\n}\n\n.dropdown-content .selected {\n background-color: #e7e7e7;\n}\n\ninput[type='text'] {\n width: -webkit-fill-available;\n padding: inherit;\n border: 1px solid #ccc;\n border-radius: 4px;\n position: sticky;\n background: no-repeat scroll 7px 7px;\n padding-left: 30px;\n background-size: 16px 16px;\n}\n","import { Component, Element, Event, EventEmitter, h, Listen, Prop, State, Watch } from '@stencil/core';\n\ninterface DropdownOption {\n labelHTML?: HTMLElement;\n label: string;\n value: string;\n}\n\n/**\n * The `input-dropdown` component is a dropdown that allows users to input an option and/or select from a list of options.\n * @part id_dropdown - The dropdown container\n * @part id_dropdown-input - The dropdown button\n * @part id_dropdown-content - The dropdown content\n */\n@Component({\n tag: 'input-dropdown',\n styleUrl: 'input-dropdown.scss',\n shadow: true,\n})\nexport class InputDropdown {\n @Element() el!: HTMLElement;\n\n private inputRef?: HTMLInputElement;\n private optionsRef!: HTMLElement;\n\n // Props\n /**\n * The name of the dropdown\n */\n @Prop() name!: string;\n /**\n * The options to display in the dropdown\n */\n @Prop() options: DropdownOption[] = [];\n /**\n * The default selected option\n */\n @Prop() defaultInputOption?: DropdownOption;\n /**\n * Should show search input\n */\n @Prop() inputValue!: string;\n /**\n * Show pluralized label for the selected option. This is s tring that is appended to the selected option label as a suffix.\n */\n @Prop() pluralizedLabel: string = '';\n\n /**\n * This is used to set if the dropdown should be filtered based on the input value.\n * If set to true, the dropdown will be filtered based on the input value.\n */\n @Prop() filterable: boolean = false;\n\n // States\n /**\n * The selected option\n */\n @State() selectedOption: DropdownOption | null = this.defaultInputOption || null;\n /**\n * The open state of the dropdown\n */\n @State() isOpen: boolean = false;\n\n /**\n * The typed value in the input\n */\n @State() typedValue: string = '';\n\n /**\n * The filtered options based on the search value\n */\n @State() filteredOptions: DropdownOption[] = [...this.options];\n /**\n * The aria-activedescendant attribute for the listbox element to indicate the currently active\n * option in the list box to screen readers. The value of aria-activedescendant is the ID of\n * the active option.\n */\n @State() ariaActivedescendant: string = '';\n\n /**\n * This is used to scroll to the input value.\n */\n @State() shouldAutoScroll: boolean = false;\n\n // Events\n /**\n * This event is fired when the selected option is changed\n */\n @Event({ bubbles: true, composed: true }) inputOptionChanged!: EventEmitter<{\n value: DropdownOption['value'];\n name: string;\n }>;\n\n @Watch('options')\n optionsChangedHandler(newValue: DropdownOption[], oldValue: DropdownOption[]) {\n if (newValue === oldValue) {\n return;\n }\n this.filteredOptions = this.getFilteredOptions(newValue);\n }\n\n @Watch('defaultInputOption')\n defaultSelectedOptionChangedHandler(newValue: DropdownOption, oldValue: DropdownOption) {\n if (newValue?.label === oldValue?.label) {\n return;\n }\n this.selectedOption = newValue;\n }\n\n @Watch('inputValue')\n inputValueChangedHandler(newValue: string, oldValue: string) {\n if (newValue === oldValue) {\n return;\n }\n this.filteredOptions = this.getFilteredOptions(this.options);\n }\n\n // Lifecycle methods\n componentWillLoad() {\n this.filteredOptions = this.getFilteredOptions(this.options);\n // Set the selected option to the first option if no option is selected\n if (!this.selectedOption && !!this.defaultInputOption) {\n this.selectedOption = this.defaultInputOption;\n }\n if (!this.selectedOption && this.options.length > 0) {\n this.selectedOption = this.options[0];\n }\n }\n\n // Methods\n getFilteredOptions(options): DropdownOption[] {\n if (!this.filterable) {\n return options;\n }\n\n return options.filter(\n option => option?.value?.toString().toLowerCase().includes(this.typedValue?.toLowerCase()) || option?.label?.toLowerCase().includes(this.typedValue?.toLowerCase()),\n );\n }\n toggleDropdown(): void {\n this.isOpen = !this.isOpen;\n }\n\n selectOption(option: DropdownOption): void {\n this.selectedOption = option;\n this.toggleDropdown();\n this.inputOptionChanged.emit({\n value: option.value,\n name: this.name,\n });\n }\n\n handleOnInput(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n this.typedValue = value;\n const optionIndex = this.options.findIndex(option => option.label.toLowerCase().includes(value.toLowerCase()));\n if (optionIndex > -1) {\n this.scrollToViewWithinParent(optionIndex);\n }\n this.inputOptionChanged.emit({\n value,\n name: this.name,\n });\n }\n\n scrollToViewWithinParent(optionIndex: number) {\n const option = this.options[optionIndex];\n const childElement = this.el.shadowRoot?.getElementById(option.value.toString()) as HTMLLIElement;\n const parentElement = this.optionsRef;\n\n this.ariaActivedescendant = option.value.toString();\n if (!childElement || !parentElement) return;\n // Scroll child into view within parent\n const childRect = childElement.getBoundingClientRect();\n const parentRect = parentElement.getBoundingClientRect();\n\n if (childRect.top < parentRect.top) {\n // Child is above the visible area of the parent\n parentElement.scrollTop -= parentRect.top - childRect.top;\n } else if (childRect.bottom > parentRect.bottom) {\n // Child is below the visible area of the parent\n parentElement.scrollTop += childRect.bottom - parentRect.bottom;\n }\n }\n\n handleSelectButtonKeyDown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowDown':\n case 'Enter':\n event.preventDefault();\n if (!this.isOpen) {\n this.toggleDropdown();\n }\n this.inputRef?.focus();\n break;\n case 'Escape':\n this.isOpen = false;\n break;\n }\n }\n\n handleClick(event: Event): void {\n if (this.isOpen) {\n const value = (event.target as HTMLInputElement).value;\n const optionIndex = this.options.findIndex(option => option.label.toLowerCase().includes(value.toLowerCase()));\n if (optionIndex > -1) {\n setTimeout(() => {\n this.scrollToViewWithinParent(optionIndex);\n }, 10);\n }\n }\n }\n\n handleListboxKeydown(e) {\n const items = this.filteredOptions;\n const currentIndex = items.findIndex(item => item.value === this.ariaActivedescendant);\n if (e.key === 'ArrowDown' || (e.key === 'Tab' && !e.shiftKey)) {\n e.preventDefault();\n if (currentIndex === items.length - 1) {\n this.ariaActivedescendant = '';\n this.inputRef?.focus();\n return;\n }\n const nextIndex = currentIndex + 1 < items.length ? currentIndex + 1 : 0;\n this.ariaActivedescendant = items[nextIndex].value;\n this.focusOption(nextIndex);\n } else if (e.key === 'ArrowUp' || (e.key === 'Tab' && e.shiftKey)) {\n e.preventDefault();\n if (currentIndex === 0) {\n this.ariaActivedescendant = '';\n this.inputRef?.focus();\n return;\n }\n const prevIndex = currentIndex - 1 >= 0 ? currentIndex - 1 : items.length - 1;\n this.ariaActivedescendant = items[prevIndex].value;\n this.focusOption(prevIndex);\n } else if (e.key === 'Enter') {\n e.preventDefault();\n if (this.ariaActivedescendant) {\n this.selectOption(items[currentIndex]);\n }\n } else if (e.key === 'Escape') {\n this.isOpen = false;\n }\n }\n\n focusOption(index) {\n const option = this.filteredOptions[index];\n if (!option) return; // Guard clause in case index is out of bounds\n\n const elementId = option.value;\n const element = this.el.shadowRoot?.getElementById(elementId) as HTMLLIElement;\n\n if (element) {\n element.focus(); // Set focus on the element\n element.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }\n\n handleComboboxKeyDown(event: KeyboardEvent): void {\n if (event.key === 'ArrowDown' || (event.key == 'Tab' && !event.shiftKey)) {\n event.preventDefault();\n if (!this.isOpen) {\n this.isOpen = true;\n this.shouldAutoScroll = true;\n return;\n }\n this.ariaActivedescendant = this.filteredOptions[0].value;\n this.focusOption(0);\n } else if (event.key === 'ArrowUp' || (event.key === 'Tab' && event.shiftKey)) {\n event.preventDefault();\n this.ariaActivedescendant = this.filteredOptions[this.filteredOptions.length - 1].value;\n this.focusOption(this.filteredOptions.length - 1);\n } else if (event.key === 'Escape') {\n this.isOpen = false;\n }\n }\n\n // Event listeners\n @Listen('click', { target: 'document', capture: true })\n handleOutsideClick(event: MouseEvent) {\n // Get the path of the event\n const path = event.composedPath();\n\n // Check if the path includes the host element\n const isClickInside = path.includes(this.el);\n\n if (!isClickInside && this.isOpen) {\n this.isOpen = false;\n }\n }\n\n render() {\n return (\n <div class=\"dropdown\" part=\"id_dropdown\">\n <input\n type=\"text\"\n name={this.name}\n id={this.name}\n part=\"id_dropdown-input\"\n class={{ dropbtn: true, open: this.isOpen }}\n value={this.inputValue}\n onClick={(e: Event) => {\n this.toggleDropdown();\n this.shouldAutoScroll = true;\n this.handleClick(e);\n }}\n aria-haspopup=\"listbox\"\n aria-label={this.name}\n aria-expanded={this.isOpen ? 'true' : 'false'}\n onKeyDown={e => this.handleComboboxKeyDown(e)}\n onInput={event => this.handleOnInput(event)}\n />\n {this.isOpen ? (\n <div class=\"dropdown-content\" part=\"id_dropdown-content\" ref={el => (this.optionsRef = el as HTMLElement)}>\n <ul tabindex=\"-1\" role=\"listbox\" aria-label={this.name} aria-activedescendant={this.ariaActivedescendant} onKeyDown={e => this.handleListboxKeydown(e)}>\n {this.filteredOptions.map(option => (\n <li\n tabindex=\"0\"\n key={option.value}\n id={option.value}\n onClick={() => this.selectOption(option)}\n role=\"option\"\n class={{\n focused: this.ariaActivedescendant === option.value.toString(),\n }}\n >\n {option.labelHTML ? option.labelHTML : option.label}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n </div>\n );\n }\n}\n",".time-period-selector {\n display: grid;\n gap: 0.5rem;\n grid-template-columns: auto 1fr;\n\n select-dropdown,\n input-dropdown {\n border: 1px solid var(--nylas-base-200);\n border-radius: var(--nylas-border-radius-2x);\n }\n\n select-dropdown {\n width: 116px;\n }\n\n input-dropdown {\n width: 84px;\n display: flex;\n align-items: center;\n }\n\n select-dropdown#time-period::part(sd_dropdown-button) {\n width: 100%;\n }\n\n input-dropdown::part(id_dropdown) {\n width: inherit;\n height: 100%;\n }\n\n input-dropdown#time-number::part(id_dropdown-input) {\n border: none;\n border-radius: var(--nylas-border-radius-2x);\n }\n\n input-dropdown#time-number.error::part(id_dropdown-input) {\n border: 1px solid var(--nylas-error);\n }\n\n input-dropdown {\n &:hover {\n outline: 1px solid var(--nylas-primary);\n border: none;\n }\n &::part(id_dropdown-input) {\n padding: 16px;\n gap: 1rem;\n &:hover {\n border: none;\n outline: none;\n }\n }\n }\n\n input-dropdown::part(id_dropdown-content) {\n width: 100%;\n max-height: 200px;\n }\n\n select-dropdown::part(sd_dropdown) {\n width: inherit;\n height: 100%;\n }\n\n select-dropdown::part(sd_dropdown_label) {\n height: 100%;\n }\n\n select-dropdown::part(sd_dropdown-button) {\n padding: 1rem;\n gap: 1rem;\n justify-content: space-between;\n border: none;\n align-items: center;\n height: 100%;\n }\n\n select-dropdown::part(sd_dropdown-content) {\n width: 100%;\n max-height: 200px;\n }\n}\n","import { TIME_PERIODS } from '@/common/constants';\nimport { debug } from '@/utils/utils';\nimport { TimePeriod } from '@nylas/core';\nimport { Element, Event, EventEmitter, Watch } from '@stencil/core';\nimport { Component, h, Listen, Prop, State } from '@stencil/core';\nimport i18next from 'i18next';\n\nconst pluralToSingular = {\n hours: 'hour',\n days: 'day',\n weeks: 'week',\n months: 'month',\n years: 'year',\n};\n\n/**\n * The time period selector component allows the user to select a time period and a number value for that time period.\n */\n@Component({\n tag: 'time-period-selector',\n styleUrl: 'time-period-selector.scss',\n scoped: true,\n})\nexport class TimePeriodSelector {\n @Element() host!: HTMLElement;\n\n // The possible values for the time periods dropdown\n @Prop() timePeriods: TimePeriod[] = TIME_PERIODS;\n\n /**\n * The default selected time period.\n */\n @Prop() defaultSelectedPeriod!: string;\n\n /**\n * The default selected number.\n */\n @Prop() defaultSelectedNumber!: number;\n\n /**\n * The error state\n */\n @Prop() hasError: boolean = false;\n\n /**\n * The currently selected time period\n */\n @State() selectedPeriod: string = this.defaultSelectedPeriod;\n\n /**\n * The currently selected number of the time period\n */\n @State() selectedNumber: number = this.defaultSelectedNumber;\n\n /*\n * The options for the number dropdown, to be calculated based on the selectedPeriod\n */\n @State() numberOptions: { label: string; value: string }[] = this.calculateOptions(this.defaultSelectedPeriod || 'hour').map(i => {\n return {\n label: i.toString(),\n value: i.toString(),\n };\n });\n\n /**\n * The options for the time period dropdown\n */\n @State() timePeriodOptions = this.timePeriods.map(i => {\n return {\n label: i.label,\n value: i.value,\n };\n });\n\n @Watch('defaultSelectedPeriod')\n defaultSelectedPeriodChanged(newValue: string) {\n this.selectedPeriod = newValue;\n this.updateNumberOptionsAndSelectedNumber(newValue);\n }\n\n @Watch('defaultSelectedNumber')\n defaultSelectedNumberChanged(newValue: number) {\n this.selectedNumber = newValue;\n }\n\n @Watch('timePeriods')\n timePeriodsChanged(newValue: { label: string; value: string }[]) {\n this.timePeriodOptions = [...newValue];\n }\n\n componentDidLoad() {\n this.selectedNumber = this.defaultSelectedNumber;\n this.selectedPeriod = this.defaultSelectedPeriod;\n const period = pluralToSingular[this.selectedPeriod] ?? this.selectedPeriod;\n const numberOptions = this.calculateOptions(period);\n this.numberOptions = numberOptions.map(i => {\n return {\n label: i.toString(),\n value: i.toString(),\n };\n });\n }\n\n @Event() timePeriodChanged!: EventEmitter<{ number: number; period: string }>;\n\n private calculateOptions(period: string): number[] {\n switch (period) {\n case 'hour':\n return Array.from({ length: 23 }, (_, i) => i + 1);\n case 'minute':\n return Array.from({ length: 13 }, (_, i) => i * 5);\n case 'day':\n return Array.from({ length: 30 }, (_, i) => i + 1);\n case 'week':\n return Array.from({ length: 4 }, (_, i) => i + 1);\n case 'month':\n return Array.from({ length: 12 }, (_, i) => i + 1);\n case 'year':\n return Array.from({ length: 10 }, (_, i) => i + 1);\n default:\n return [];\n }\n }\n\n @Listen('inputOptionChanged')\n inputOptionChangedHandler(event: CustomEvent<{ value: string; name: string }>) {\n debug('time-period-selector', 'inputOptionChangedHandler', event.detail);\n const { value, name } = event.detail;\n if (name === 'time-number') {\n this.selectedNumber = value ? parseInt(value) : this.defaultSelectedNumber;\n }\n const selected = {\n number: this.selectedNumber,\n period: this.selectedPeriod,\n };\n this.timePeriodChanged.emit(selected);\n }\n\n @Listen('nylasFormDropdownChanged')\n nylasFormDropdownChangedHandler(event: CustomEvent<{ value: string; name: string }>) {\n debug('time-period-selector', 'nylasFormDropdownChangedHandler', event.detail);\n const { value, name } = event.detail;\n if (name === 'time-period') {\n this.selectedPeriod = value;\n this.updateNumberOptionsAndSelectedNumber(value);\n } else if (name === 'time-number') {\n this.selectedNumber = parseInt(value);\n }\n const selected = {\n number: this.selectedNumber,\n period: this.selectedPeriod,\n };\n this.timePeriodChanged.emit(selected);\n }\n\n updateNumberOptionsAndSelectedNumber(period: string) {\n const numberOptions = this.calculateOptions(period);\n this.numberOptions = numberOptions.map(i => {\n return {\n label: i.toString(),\n value: i.toString(),\n };\n });\n }\n\n render() {\n return (\n <div class=\"time-period-selector\">\n {typeof this.selectedNumber == 'number' && (\n <input-dropdown\n id=\"time-number\"\n name={'time-number'}\n class={{ error: this.hasError }}\n inputValue={this.selectedNumber.toString()}\n exportparts=\"id_dropdown: tps__number-dropdown, id_dropdown-input: tps__number-dropdown-button, id_dropdown-content: tps__number-dropdown-content\"\n options={this.numberOptions}\n defaultInputOption={this.numberOptions.find(i => i.value == this.selectedNumber.toString())}\n />\n )}\n {typeof this.selectedPeriod == 'string' && (\n <select-dropdown\n id=\"time-period\"\n name={'time-period'}\n options={this.timePeriodOptions}\n exportparts=\"sd_dropdown: tps__period-dropdown, sd_dropdown-button: tps__period-dropdown-button, sd_dropdown-content: tps__period-dropdown-content\"\n pluralizedLabel={this.selectedNumber > 1 ? i18next.t(`time.${this.selectedPeriod}s`) : i18next.t(`time.${this.selectedPeriod}`)}\n defaultSelectedOption={this.timePeriodOptions?.find(i => i.value == this.selectedPeriod)}\n withSearch={false}\n />\n )}\n </div>\n );\n }\n}\n"],"mappings":"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"}
|