q2-tecton-elements 1.54.0 → 1.54.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle-report.json +12 -12
- package/dist/cjs/q2-badge_7.cjs.entry.js +3 -3
- package/dist/cjs/q2-badge_7.cjs.entry.js.map +1 -1
- package/dist/cjs/q2-file-picker.cjs.entry.js +1 -1
- package/dist/cjs/q2-file-picker.cjs.entry.js.map +1 -1
- package/dist/cjs/q2-select.cjs.entry.js +5 -5
- package/dist/cjs/q2-select.cjs.entry.js.map +1 -1
- package/dist/collection/components/q2-btn/q2-btn.css +29 -3
- package/dist/collection/components/q2-btn/q2-btn.js +2 -2
- package/dist/collection/components/q2-btn/q2-btn.js.map +1 -1
- package/dist/collection/components/q2-btn/test/q2-btn-test.e2e.js +72 -4
- package/dist/collection/components/q2-btn/test/q2-btn-test.e2e.js.map +1 -1
- package/dist/collection/components/q2-file-picker/q2-file-picker.js +2 -2
- package/dist/collection/components/q2-file-picker/q2-file-picker.js.map +1 -1
- package/dist/collection/components/q2-file-picker/test/q2-file-picker-test.spec.js +34 -0
- package/dist/collection/components/q2-file-picker/test/q2-file-picker-test.spec.js.map +1 -1
- package/dist/collection/components/q2-select/q2-select.js +5 -5
- package/dist/collection/components/q2-select/q2-select.js.map +1 -1
- package/dist/components/q2-btn2.js +3 -3
- package/dist/components/q2-btn2.js.map +1 -1
- package/dist/components/q2-file-picker.js +1 -1
- package/dist/components/q2-file-picker.js.map +1 -1
- package/dist/components/q2-select2.js +5 -5
- package/dist/components/q2-select2.js.map +1 -1
- package/dist/esm/q2-badge_7.entry.js +3 -3
- package/dist/esm/q2-badge_7.entry.js.map +1 -1
- package/dist/esm/q2-file-picker.entry.js +1 -1
- package/dist/esm/q2-file-picker.entry.js.map +1 -1
- package/dist/esm/q2-select.entry.js +5 -5
- package/dist/esm/q2-select.entry.js.map +1 -1
- package/dist/q2-tecton-elements/q2-badge_7.entry.js +40 -38
- package/dist/q2-tecton-elements/q2-badge_7.entry.js.map +1 -1
- package/dist/q2-tecton-elements/q2-file-picker.entry.js +1 -1
- package/dist/q2-tecton-elements/q2-file-picker.entry.js.map +1 -1
- package/dist/q2-tecton-elements/q2-select.entry.js +8 -7
- package/dist/q2-tecton-elements/q2-select.entry.js.map +1 -1
- package/dist/types/components/q2-file-picker/q2-file-picker.d.ts +4 -2
- package/dist/types/components.d.ts +2 -2
- package/package.json +3 -3
|
@@ -170,7 +170,7 @@ const c = class {
|
|
|
170
170
|
return t.join(" ");
|
|
171
171
|
}
|
|
172
172
|
get fileTypesArray() {
|
|
173
|
-
return Array.isArray(this.fileTypes) ? this.fileTypes : this.fileTypes.split(",");
|
|
173
|
+
return Array.isArray(this.fileTypes) ? this.fileTypes : this.fileTypes.split(",").map((t => t.trim()));
|
|
174
174
|
}
|
|
175
175
|
get hasDescription() {
|
|
176
176
|
return !!this.description || this.hasDescriptionSlotContent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["q2FilePickerCss","Q2FilePickerStyle0","Q2FilePicker","this","queuedFiles","dimDropZone","e","disableEvent","isDropZoneHighlighted","grabDroppedFiles","droppedFiles","Array","from","dataTransfer","files","filesObject","buildFilesObject","emitChange","value","grabSelectedFiles","selectedFiles","target","highlightDropZone","render","h","class","hasLabel","hasDescription","htmlFor","label","loc","hasLabelSlotContent","name","id","description","hasDescriptionSlotContent","variant","dropZoneClasses","onDragEnter","onDragLeave","onDragOver","onDrop","ref","el","dropZone","areFilesUploading","Fragment","type","onTctClick","launchFileBrowser","maxFiles","disabled","intent","loading","onClick","size","undefined","onChange","browseButtonInput","multiple","displayedFiles","map","file","getFileItemClasses","key","onAnimationEnd","getAnimationendHandlerToRemoveFileItem","slot","status","getFileItemStatusMessage","getClickHandlerToRemoveFileItem","Infinity","invalidFiles","validFiles","updateFileList","newValue","forEach","statusItem","matchingQueuedFileIndex","findIndex","matchingFile","splice","matchingDisplayedFileIndex","disableLoaderIfAllFilesUploaded","classes","push","join","fileTypesArray","isArray","fileTypes","split","hasSlotContent","filesToUpload","extractFilesOfInvalidTypes","extractFilesOverSizeLimit","extractFilesOverMaxFilesLimit","length","event","preventDefault","stopPropagation","some","tctChange","emit","fileExtension","pop","toLowerCase","includes","invalidFile","index","indexOf","filesOverMaxFilesLimit","excessFiles","filesOverSizeLimit","maxFileSize","overSizeFile","forceRerender","refreshCounter","fileName","animationName","filter","fileToDelete","find","toBeRemoved","toFixed","dispatchEvent","MouseEvent"],"sources":["src/components/q2-file-picker/q2-file-picker.scss?tag=q2-file-picker&encapsulation=shadow","src/components/q2-file-picker/q2-file-picker.tsx"],"sourcesContent":["@import '../../styles/host.scss';\n@import '../../styles/functions';\n@import '../q2-btn/q2-btn-mixins';\n\n@keyframes growFromCenterFadeIn {\n from {\n transform: scaleX(.75) scaleY(.75);\n opacity: 0;\n }\n to {\n transform: scaleX(1) scaleY(1);\n opacity: 1;\n }\n}\n\n@keyframes shrinkToCenterFadeOut {\n from {\n transform: scaleX(1) scaleY(1);\n opacity: 1;\n }\n to {\n transform: scaleX(.75) scaleY(.75);\n opacity: 0;\n }\n}\n\n:host {\n display: block;\n}\n\n.browse {\n text-align: left;\n}\n\n.drop-zone-text {\n color: var-list(--tct-file-picker-drop-zone-text-color, --t-gray-6, #4D4D4D);\n font-size: var-list(--tct-file-picker-drop-zone-font-size, --app-font-size-small, 12px);\n font-weight: var(--tct-file-picker-browse-link-font-weight, 700);\n margin-bottom: 0;\n margin-top: var-list(--tct-file-picker-drop-zone-text-margin-top, --app-scale-2x, 10px);\n}\n\n.description {\n color: var-list(--tct-file-picker-description-text-color, --t-gray-1, #0D0D0D);\n font-size: var-list(--tct-file-picker-description-font-size, --app-font-size-small, 12px);\n font-weight: var(--tct-file-picker-description-font-weight, 400);\n text-align: var(--tct-file-picker-description-text-align, left);\n}\n\n.drop-zone {\n align-items: center;\n background-color: var-list(--tct-file-picker-drop-zone-background, --t-tertiary, #E8F5FC);\n border-radius: var-list(--tct-file-picker-drop-zone-border-radius, --app-border-radius-2, 6px);\n border-width: var(--tct-file-picker-drop-zone-border-width, 2px);\n border-style: var(--tct-file-picker-drop-zone-border-style, dashed);\n border-color: var-list(--tct-file-picker-drop-zone-border-color, --t-gray-8, #808080);\n color: var(--tct-file-picker-drop-zone-color, #747474);\n display: flex;\n flex-direction: column;\n font-size: var(--tct-file-picker-drop-zone-font-size, --app-font-size, 14px);\n font-weight: var(--tct-file-picker-drop-zone-font-weight, 400);\n height: var(--tct-file-picker-drop-zone-height, 150px);\n justify-content: center;\n padding: var(--tct-file-picker-drop-zone-padding, 20px);\n text-align: center;\n width: var(--tct-file-picker-drop-zone-width, 100%);\n}\n\n.drop-zone-highlighted {\n background-color: var-list(--tct-file-picker-drop-zone-highlighted-background, --tertiary-d-1, #BEE1F6);\n border-color: var-list(--tct-file-picker-drop-zone-highlighted-border, --t-gray-8, #808080);\n}\n\n.fade-in {\n animation-fill-mode: both;\n animation-play-state: running;\n animation: growFromCenterFadeIn 0.2s ease-in;\n}\n\n.fade-out {\n animation: shrinkToCenterFadeOut 0.1s ease-out;\n animation-play-state: running;\n animation-fill-mode: both;\n}\n\n.file-item {\n --tct-btn-icon-border-radius: 4px;\n --tct-btn-neutral-text-active-font-color: #{var-list(--tct-file-picker-item-close-btn-active-color, --t-gray-1, #0D0D0D)};\n --tct-btn-neutral-text-focus-visible-outer-ring-color: #{var-list(--tct-file-picker-item-close-btn-color, --t-gray-1, #0D0D0D)};\n --tct-btn-neutral-text-font-color: #{var-list(--tct-file-picker-item-close-btn-color, --t-gray-1, #0D0D0D)};\n --tct-btn-neutral-text-hover-outer-ring-color: #{var-list(--tct-file-picker-item-close-btn-hover-focus-ring-color, --t-gray-1, #0D0D0D)};\n --tct-btn-padding: 0;\n --tct-icon-stroke-primary: #{var-list(--tct-file-picker-item-close-btn-color, --t-gray-1, #0D0D0D)};\n --tct-item-body-font-size: #{var-list(--tct-file-picker-item-font-size, --app-font-size-small, 12px)};\n --tct-item-body-font-weight: var(--tct-file-picker-item-font-weight, 400);\n --tct-item-border-radius: #{var-list(--tct-file-picker-item-border-radius, --app-border-radius-3, 12px)};\n --tct-item-border: var(--tct-file-picker-item-border-width, 1px) solid #{var-list(--tct-file-picker-item-border-color, --t-gray-8, #808080)};\n --tct-item-header-color: #{var-list(--tct-file-picker-item-name-color, --t-gray-1, #0D0D0D)};\n --tct-item-header-font-size: #{var-list(--tct-file-picker-item-name-font-size, --app-font-size-small, 12px)};\n --tct-item-header-font-weight: var(--tct-file-picker-item-name-font-weight, 400);\n --tct-item-padding: var(--tct-file-picker-item-padding, var(--app-scale-1x, 5px) var(--app-scale-2x, 10px));\n text-align: left;\n}\n\n.file-item-loading {\n font-size: var-list(--tct-file-picker-file-item-loading-size, --app-scale-6x, 30px);\n // FIXME: This is a temporary fix to match the height of the closing icon which has 3.5px of padding I can't account for\n margin-bottom: calc(var-list(--tct-file-picker-file-item-loading-margin-bottom, --app-scale-6x, 30px) / 8.57);\n margin-left: calc(var-list(--tct-file-picker-file-item-loading-margin-bottom, --app-scale-1x, 5px) / 2);\n}\n\n.file-list {\n --tct-list-item-gap: #{var-list(--tct-file-picker-section-gap, --app-scale-3x, 15px)};\n}\n\n.file-list-container {\n max-height: var(--tct-file-picker-list-max-height, 190px);\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: #{var-list(--tct-file-picker-scrollbar-color, --t-a11y-gray-color, #949494)} transparent;\n}\n\n.file-picker {\n display: flex;\n flex-direction: column;\n gap: #{var-list(--tct-file-picker-file-item-gap, --app-scale-3x, 15px)};\n}\n\n.heading {\n display: flex;\n flex-direction: column;\n gap: #{var-list(--tct-file-picker-heading-gap, --app-scale-1x, 5px)};\n justify-content: space-between;\n}\n\n.icon-success,\n.icon-error {\n --tct-icon-size: #{var-list(--tct-file-picker-file-item-icon-size, --app-scale-6x, 30px)};\n --tct-icon-stroke-width: 2px;\n}\n\n.label {\n color: var-list(--tct-file-picker-label-color, --t-gray-1, #0D0D0D);\n // cursor: pointer;\n display: inline-block;\n font-size: var-list(--tct-file-picker-label-font-size, --app-font-size, 14px);\n font-weight: var(--tct-file-picker-label-font-weight, 600);\n text-align: var(--tct-file-picker-label-text-align, left);\n}\n\n.loading {\n font-size: var-list(--tct-file-picker-loading-size, --app-scale-6x, 25px);\n}\n\n.loading-file {\n color: var-list(--tct-file-picker-loading-file-color, --t-gray-1, #0D0D0D);\n font-size: var-list(--tct-file-picker-loading-file-font-size, --app-font-size-small, 12px);\n font-weight: var(--tct-file-picker-loading-file-font-weight, 400);\n margin: 0;\n}\n\n.loading-message {\n color: var-list(--tct-file-picker-loading-message-color, --t-gray-1, #0D0D0D);\n font-size: var-list(--tct-file-picker-loading-message-font-size, --app-font-size-small, 12px);\n font-weight: var(--tct-file-picker-loading-message-font-weight, 700);\n margin-bottom: var-list(--tct-file-picker-loading-message-margin-bottom, --app-scale-2x, 10px);\n margin-top: var-list(--tct-file-picker-loading-message-margin-top, --app-scale-2x, 10px);\n}\n\n.dismiss-button {\n height: 30px;\n width: 30px;\n &:hover {\n --tct-icon-stroke-primary: #{var-list(--tct-file-picker-item-close-btn-hover-color, --t-gray-1, #0D0D0D)};\n }\n}\n\n[slot=\"action\"] {\n display: flex;\n align-items: center;\n}\n","import {\n Component,\n ComponentInterface,\n Element,\n Event,\n EventEmitter,\n Fragment,\n h,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\nimport { hasSlotContent, loc } from 'src/utils';\n\ntype FileStatus = 'invalid-type' | 'over-size-limit' | 'over-max-files-limit' | 'in-progress' | 'failed' | 'uploaded';\nexport type FilesObject = {\n invalidFiles: {\n file: File;\n status: 'invalid-type' | 'over-size-limit' | 'over-max-files-limit' | 'in-progress' | 'failed' | 'uploaded';\n }[];\n validFiles: File[];\n};\n\n@Component({\n tag: 'q2-file-picker',\n styleUrl: 'q2-file-picker.scss',\n shadow: true,\n})\nexport class Q2FilePicker implements ComponentInterface {\n // #region Own Properties\n\n browseButtonInput: HTMLElement;\n dropZone: HTMLElement;\n fileItemsToBeDeleted;\n queuedFiles: File[] = [];\n\n // #endregion\n // #region Host HTML Element\n\n @Element()\n el: HTMLElement;\n\n // #endregion\n // #region State Properties\n\n @State()\n areFilesUploading: boolean = false;\n\n @State()\n displayedFiles: {\n file: File;\n status: FileStatus;\n toBeRemoved?: boolean;\n }[] = [];\n\n @State()\n isDropZoneHighlighted: boolean = false;\n\n @State()\n refreshCounter = 0;\n\n // #endregion\n // #region Public Property API\n\n /**\n * A description of the field. This is announced by screen readers when the field is focused.\n * @localizable\n */\n @Prop({ reflect: true })\n description: string;\n\n /**\n * An array of strings representing the allowed file types based on file extension.\n * Example: ['jpg', 'png', 'pdf']\n */\n @Prop({ reflect: true })\n fileTypes: string[] | string = [];\n\n /**\n * The label for the field. This is announced by screen readers when the field is focused.\n * @localizable\n */\n @Prop({ reflect: true })\n label: string;\n\n /**\n * The maximum number of files that can be selected.\n */\n @Prop({ reflect: true })\n // maxFiles: number | string = Infinity;\n maxFiles: number = Infinity;\n\n /**\n * The maximum size (in bytes) of any file that can be selected.\n */\n @Prop({ reflect: true })\n maxFileSize: number = Infinity;\n\n /**\n * An array of objects representing the status of the files being uploaded.\n * Each object should have a `name` property (the file name) and a `status`\n * property (the status of the file) that equals either 'in-progress',\n * 'failed' or 'uploaded'.\n */\n @Prop({ reflect: true })\n status: { name: string; status: 'in-progress' | 'failed' | 'uploaded' }[] = [];\n\n /**\n * Returns an array of File objects representing the files selected by the\n * user. If no files are selected, the value is an empty array.\n * @readonly\n */\n @Prop({ mutable: true })\n value: FilesObject = { invalidFiles: [], validFiles: [] }; // Ensure FilesObject is exported or imported correctly\n\n /**\n * Determines if the file picker is a browse button or a drop zone with a\n * browse link.\n */\n @Prop({ reflect: true })\n variant: 'browse' | 'browse-drop' = 'browse';\n\n // #endregion\n // #region Events\n\n @Event()\n tctChange: EventEmitter<FilesObject>;\n\n // #endregion\n // #region Watchers\n\n @Watch('status')\n updateFileList(newValue: { name: string; status: FileStatus }[]) {\n newValue.forEach(statusItem => {\n const matchingQueuedFileIndex = this.queuedFiles.findIndex(file => file.name === statusItem.name);\n if (matchingQueuedFileIndex > -1) {\n const matchingFile = this.queuedFiles.splice(matchingQueuedFileIndex, 1)[0];\n this.displayedFiles = [{ file: matchingFile, status: statusItem.status }, ...this.displayedFiles];\n } else {\n const matchingDisplayedFileIndex = this.displayedFiles.findIndex(\n file => file.file.name === statusItem.name\n );\n if (matchingDisplayedFileIndex > -1) {\n this.displayedFiles[matchingDisplayedFileIndex].status = statusItem.status;\n this.disableLoaderIfAllFilesUploaded();\n }\n }\n });\n }\n\n // #endregion\n // #region Local Methods\n\n get dropZoneClasses() {\n const classes = ['drop-zone'];\n if (this.isDropZoneHighlighted) {\n classes.push('drop-zone-highlighted');\n }\n\n return classes.join(' ');\n }\n\n get fileTypesArray() {\n return Array.isArray(this.fileTypes) ? this.fileTypes : this.fileTypes.split(',');\n }\n\n get hasDescription() {\n return !!this.description || this.hasDescriptionSlotContent;\n }\n\n get hasDescriptionSlotContent() {\n return hasSlotContent(this.el, 'description');\n }\n\n get hasLabel() {\n return !!this.label || this.hasLabelSlotContent;\n }\n\n get hasLabelSlotContent() {\n return hasSlotContent(this.el, 'label');\n }\n\n buildFilesObject(filesToUpload: File[]): FilesObject {\n const invalidFiles = [];\n invalidFiles.push(...this.extractFilesOfInvalidTypes(filesToUpload));\n invalidFiles.push(...this.extractFilesOverSizeLimit(filesToUpload));\n invalidFiles.push(...this.extractFilesOverMaxFilesLimit(filesToUpload));\n this.displayedFiles = [...invalidFiles];\n\n if (filesToUpload.length === 0) {\n this.areFilesUploading = false;\n } else {\n this.queuedFiles = filesToUpload;\n }\n\n return { invalidFiles, validFiles: filesToUpload };\n }\n\n dimDropZone = (e: DragEvent) => {\n this.disableEvent(e);\n this.isDropZoneHighlighted = false;\n };\n\n disableEvent(event: Event) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n disableLoaderIfAllFilesUploaded() {\n if (this.queuedFiles.length === 0 && !this.displayedFiles.some(file => file.status === 'in-progress')) {\n this.areFilesUploading = false;\n }\n }\n\n emitChange(filesObject: FilesObject) {\n this.areFilesUploading = filesObject.validFiles.length > 0;\n this.tctChange.emit(filesObject);\n }\n\n extractFilesOfInvalidTypes(files: File[]) {\n const invalidFiles = [];\n\n if (this.fileTypesArray.length === 0) return invalidFiles;\n\n files.forEach(file => {\n const fileExtension = file.name.split('.').pop().toLowerCase();\n if (!this.fileTypesArray.includes(fileExtension)) {\n invalidFiles.push({ file, status: 'invalid-type' });\n }\n });\n\n // Remove invalid files from the files array\n invalidFiles.forEach(invalidFile => {\n const index = files.indexOf(invalidFile.file);\n if (index > -1) {\n files.splice(index, 1);\n }\n });\n\n return invalidFiles;\n }\n\n extractFilesOverMaxFilesLimit(files: File[]) {\n const filesOverMaxFilesLimit = [];\n\n if (this.maxFiles === Infinity) return filesOverMaxFilesLimit;\n\n if (files.length > this.maxFiles) {\n const excessFiles = files.splice(this.maxFiles);\n excessFiles.forEach(file => {\n filesOverMaxFilesLimit.push({ file, status: 'over-max-files-limit' });\n });\n }\n\n return filesOverMaxFilesLimit;\n }\n\n extractFilesOverSizeLimit(files: File[]) {\n const filesOverSizeLimit = [];\n\n if (this.maxFileSize === Infinity) return filesOverSizeLimit;\n\n files.forEach(file => {\n if (file.size > this.maxFileSize) {\n filesOverSizeLimit.push({ file, status: 'over-size-limit' });\n }\n });\n\n // Remove files over size limit from the files array\n filesOverSizeLimit.forEach(overSizeFile => {\n const index = files.indexOf(overSizeFile.file);\n if (index > -1) {\n files.splice(index, 1);\n }\n });\n\n return filesOverSizeLimit;\n }\n\n forceRerender() {\n this.refreshCounter += 1; // Triggers re-render\n }\n\n getAnimationendHandlerToRemoveFileItem(fileName: string) {\n return (e: AnimationEvent) => {\n if (e.animationName === 'shrinkToCenterFadeOut') {\n this.displayedFiles = this.displayedFiles.filter(file => file.file.name !== fileName);\n }\n };\n }\n\n getClickHandlerToRemoveFileItem(fileName: string) {\n return () => {\n const fileToDelete = this.displayedFiles.find(file => file.file.name === fileName);\n if (fileToDelete) {\n fileToDelete.toBeRemoved = true;\n this.forceRerender();\n }\n };\n }\n\n getFileItemClasses(fileName: string) {\n const classes = ['file-item'];\n const matchingFile = this.displayedFiles.find(file => file.file.name === fileName);\n if (matchingFile?.toBeRemoved) {\n classes.push('fade-out');\n } else {\n classes.push('fade-in');\n }\n return classes.join(' ');\n }\n\n getFileItemStatusMessage(status: FileStatus, size: number) {\n switch (status) {\n case 'invalid-type':\n return loc('tecton.element.filePicker.unsupportedFileType');\n case 'over-size-limit':\n return loc('tecton.element.filePicker.sizeExceedsLimit');\n case 'over-max-files-limit':\n return loc('tecton.element.filePicker.overMaxFilesLimit');\n case 'in-progress':\n return loc('tecton.element.filePicker.uploadingEllipsis');\n case 'failed':\n return loc('tecton.element.filePicker.uploadFailed');\n case 'uploaded':\n default:\n return loc('tecton.element.filePicker.fileSize', [(size / (1000 * 1000)).toFixed(2)]);\n }\n }\n\n grabDroppedFiles = (e: DragEvent) => {\n this.disableEvent(e);\n this.isDropZoneHighlighted = false;\n const droppedFiles = Array.from(e.dataTransfer.files);\n const filesObject = this.buildFilesObject(droppedFiles);\n\n this.emitChange(filesObject);\n this.value = filesObject;\n };\n\n grabSelectedFiles = (e: Event) => {\n const selectedFiles = Array.from((e.target as HTMLInputElement).files);\n const filesObject = this.buildFilesObject(selectedFiles);\n\n this.emitChange(filesObject);\n this.value = filesObject;\n };\n\n highlightDropZone = (e: DragEvent) => {\n this.disableEvent(e);\n this.isDropZoneHighlighted = true;\n };\n\n launchFileBrowser() {\n this.browseButtonInput.dispatchEvent(new MouseEvent('click'));\n }\n\n // #endregion\n // #region Render Methods\n\n render = () => {\n return (\n <div class=\"file-picker\">\n {(this.hasLabel || this.hasDescription) && (\n <div class=\"heading\">\n {this.hasLabel && (\n <label\n class=\"label\"\n htmlFor=\"file-field\"\n test-id=\"label\"\n >\n {!!this.label ? loc(this.label) : this.hasLabelSlotContent ? <slot name=\"label\" /> : ''}\n </label>\n )}\n {this.hasDescription && (\n <div\n class=\"description\"\n id=\"description\"\n test-id=\"description\"\n >\n {!!this.description ? (\n loc(this.description)\n ) : this.hasDescriptionSlotContent ? (\n <slot name=\"description\" />\n ) : (\n ''\n )}\n </div>\n )}\n </div>\n )}\n\n {(this.variant === 'browse-drop' && (\n <div\n class={this.dropZoneClasses}\n onDragEnter={this.disableEvent}\n onDragLeave={this.dimDropZone}\n onDragOver={this.highlightDropZone}\n onDrop={this.grabDroppedFiles}\n ref={el => (this.dropZone = el ?? this.dropZone)}\n test-id=\"drop-zone\"\n >\n {(this.areFilesUploading && (\n <Fragment>\n <q2-loading class=\"loading\"></q2-loading>\n <p class=\"drop-zone-text\">{loc('tecton.element.filePicker.uploadingEllipsis')}</p>\n </Fragment>\n )) || (\n <Fragment>\n <q2-icon type=\"upload\"></q2-icon>\n <p class=\"drop-zone-text\">\n <q2-link\n label={loc('tecton.element.filePicker.browse')}\n onTctClick={() => this.launchFileBrowser()}\n variant=\"inline\"\n test-id=\"browse-link\"\n />\n {loc('tecton.element.filePicker.orDragFilesHere', [this.maxFiles])}\n </p>\n </Fragment>\n )}\n </div>\n )) || (\n <div\n class=\"browse\"\n test-id=\"browse\"\n >\n <q2-btn\n disabled={this.areFilesUploading}\n intent=\"workflow-primary\"\n loading={this.areFilesUploading}\n onClick={() => this.launchFileBrowser()}\n size=\"medium\"\n test-id=\"browse-button\"\n >\n <q2-icon type=\"paperclip\"></q2-icon>\n <span>{loc('tecton.element.filePicker.attachFiles', [this.maxFiles])}</span>\n </q2-btn>\n </div>\n )}\n <input\n aria-describedby={(!!this.description && 'description') || undefined}\n class=\"sr\"\n id=\"file-field\"\n onChange={this.grabSelectedFiles}\n ref={el => (this.browseButtonInput = el ?? this.browseButtonInput)}\n type=\"file\"\n test-id=\"file-input\"\n multiple\n />\n <div class=\"file-list-container\">\n <q2-list class=\"file-list\">\n {this.displayedFiles.map(file => (\n <q2-item\n class={this.getFileItemClasses(file.file.name)}\n key={file.file.name}\n onAnimationEnd={this.getAnimationendHandlerToRemoveFileItem(file.file.name)}\n >\n <div slot=\"bullet\">\n {file.status === 'invalid-type' ||\n file.status === 'over-size-limit' ||\n file.status === 'failed' ||\n file.status === 'over-max-files-limit' ? (\n <q2-icon\n class=\"icon-error\"\n type=\"error\"\n ></q2-icon>\n ) : file.status === 'in-progress' ? (\n <q2-loading class=\"file-item-loading\"></q2-loading>\n ) : (\n <q2-icon\n class=\"icon-success\"\n type=\"success\"\n ></q2-icon>\n )}\n </div>\n <div slot=\"header\">{file.file.name}</div>\n <div slot=\"body\">{this.getFileItemStatusMessage(file.status, file.file.size)}</div>\n <div slot=\"action\">\n <q2-btn\n class=\"dismiss-button\"\n intent=\"neutral-text\"\n onClick={this.getClickHandlerToRemoveFileItem(file.file.name)}\n >\n <q2-icon type=\"close\"></q2-icon>\n </q2-btn>\n </div>\n </q2-item>\n ))}\n </q2-list>\n </div>\n </div>\n );\n };\n\n // #endregion\n}\n"],"mappings":";;;;AAAA,MAAMA,IAAkB;;AACxB,MAAAC,IAAeD;;MC2BFE,IAAY;;;;IAMrBC,KAAAC,cAAsB;IAoKtBD,KAAAE,cAAeC;MACXH,KAAKI,aAAaD;MAClBH,KAAKK,wBAAwB;AAAK;IAkItCL,KAAAM,mBAAoBH;MAChBH,KAAKI,aAAaD;MAClBH,KAAKK,wBAAwB;MAC7B,MAAME,IAAeC,MAAMC,KAAKN,EAAEO,aAAaC;MAC/C,MAAMC,IAAcZ,KAAKa,iBAAiBN;MAE1CP,KAAKc,WAAWF;MAChBZ,KAAKe,QAAQH;AAAW;IAG5BZ,KAAAgB,oBAAqBb;MACjB,MAAMc,IAAgBT,MAAMC,KAAMN,EAAEe,OAA4BP;MAChE,MAAMC,IAAcZ,KAAKa,iBAAiBI;MAE1CjB,KAAKc,WAAWF;MAChBZ,KAAKe,QAAQH;AAAW;IAG5BZ,KAAAmB,oBAAqBhB;MACjBH,KAAKI,aAAaD;MAClBH,KAAKK,wBAAwB;AAAI;;;QAUrCL,KAAAoB,SAAS,MAEDC,EAAA;MAAKC,OAAM;QACLtB,KAAKuB,YAAYvB,KAAKwB,mBACpBH,EAAA;MAAKC,OAAM;OACNtB,KAAKuB,YACFF,EAAA;MACIC,OAAM;MACNG,SAAQ;MAAY,WACZ;SAELzB,KAAK0B,QAAQC,EAAI3B,KAAK0B,SAAS1B,KAAK4B,sBAAsBP,EAAA;MAAMQ,MAAK;SAAa,KAG5F7B,KAAKwB,kBACFH,EAAA;MACIC,OAAM;MACNQ,IAAG;MAAa,WACR;SAEL9B,KAAK+B,cACJJ,EAAI3B,KAAK+B,eACT/B,KAAKgC,4BACLX,EAAA;MAAMQ,MAAK;SAAgB,MAS7C7B,KAAKiC,YAAY,iBACfZ,EAAA;MACIC,OAAOtB,KAAKkC;MACZC,aAAanC,KAAKI;MAClBgC,aAAapC,KAAKE;MAClBmC,YAAYrC,KAAKmB;MACjBmB,QAAQtC,KAAKM;MACbiC,KAAKC,KAAOxC,KAAKyC,WAAWD,MAAE,QAAFA,WAAE,IAAFA,IAAMxC,KAAKyC;MAAS,WACxC;OAENzC,KAAK0C,qBACHrB,EAACsB,GAAQ,MACLtB,EAAA;MAAYC,OAAM;QAClBD,EAAA;MAAGC,OAAM;OAAkBK,EAAI,oDAGnCN,EAACsB,GAAQ,MACLtB,EAAA;MAASuB,MAAK;QACdvB,EAAA;MAAGC,OAAM;OACLD,EAAA;MACIK,OAAOC,EAAI;MACXkB,YAAY,MAAM7C,KAAK8C;MACvBb,SAAQ;MAAQ,WACR;QAEXN,EAAI,6CAA6C,EAAC3B,KAAK+C,kBAMxE1B,EAAA;MACIC,OAAM;MAAQ,WACN;OAERD,EAAA;MACI2B,UAAUhD,KAAK0C;MACfO,QAAO;MACPC,SAASlD,KAAK0C;MACdS,SAAS,MAAMnD,KAAK8C;MACpBM,MAAK;MAAQ,WACL;OAER/B,EAAA;MAASuB,MAAK;QACdvB,EAAA,cAAOM,EAAI,yCAAyC,EAAC3B,KAAK+C,gBAItE1B,EAAA;MAAA,sBACyBrB,KAAK+B,eAAe,iBAAkBsB;MAC3D/B,OAAM;MACNQ,IAAG;MACHwB,UAAUtD,KAAKgB;MACfuB,KAAKC,KAAOxC,KAAKuD,oBAAoBf,MAAE,QAAFA,WAAE,IAAFA,IAAMxC,KAAKuD;MAChDX,MAAK;MAAM,WACH;MACRY,UAAQ;QAEZnC,EAAA;MAAKC,OAAM;OACPD,EAAA;MAASC,OAAM;OACVtB,KAAKyD,eAAeC,KAAIC,KACrBtC,EAAA;MACIC,OAAOtB,KAAK4D,mBAAmBD,EAAKA,KAAK9B;MACzCgC,KAAKF,EAAKA,KAAK9B;MACfiC,gBAAgB9D,KAAK+D,uCAAuCJ,EAAKA,KAAK9B;OAEtER,EAAA;MAAK2C,MAAK;OACLL,EAAKM,WAAW,kBACjBN,EAAKM,WAAW,qBAChBN,EAAKM,WAAW,YAChBN,EAAKM,WAAW,yBACZ5C,EAAA;MACIC,OAAM;MACNsB,MAAK;SAETe,EAAKM,WAAW,gBAChB5C,EAAA;MAAYC,OAAM;SAElBD,EAAA;MACIC,OAAM;MACNsB,MAAK;SAIjBvB,EAAA;MAAK2C,MAAK;OAAUL,EAAKA,KAAK9B,OAC9BR,EAAA;MAAK2C,MAAK;OAAQhE,KAAKkE,yBAAyBP,EAAKM,QAAQN,EAAKA,KAAKP,QACvE/B,EAAA;MAAK2C,MAAK;OACN3C,EAAA;MACIC,OAAM;MACN2B,QAAO;MACPE,SAASnD,KAAKmE,gCAAgCR,EAAKA,KAAK9B;OAExDR,EAAA;MAASuB,MAAK;;6BAtbrB;0BAOvB;iCAG2B;0BAGhB;;qBAiBc;;oBAcZwB;uBAMGA;kBASsD;iBAQvD;MAAEC,cAAc;MAAIC,YAAY;;mBAOjB;;;;EAYpC,cAAAC,CAAeC;IACXA,EAASC,SAAQC;MACb,MAAMC,IAA0B3E,KAAKC,YAAY2E,WAAUjB,KAAQA,EAAK9B,SAAS6C,EAAW7C;MAC5F,IAAI8C,KAA2B,GAAG;QAC9B,MAAME,IAAe7E,KAAKC,YAAY6E,OAAOH,GAAyB,GAAG;QACzE3E,KAAKyD,iBAAiB,EAAC;UAAEE,MAAMkB;UAAcZ,QAAQS,EAAWT;cAAajE,KAAKyD;aAC/E;QACH,MAAMsB,IAA6B/E,KAAKyD,eAAemB,WACnDjB,KAAQA,EAAKA,KAAK9B,SAAS6C,EAAW7C;QAE1C,IAAIkD,KAA8B,GAAG;UACjC/E,KAAKyD,eAAesB,GAA4Bd,SAASS,EAAWT;UACpEjE,KAAKgF;;;;;;;EASrB,mBAAI9C;IACA,MAAM+C,IAAU,EAAC;IACjB,IAAIjF,KAAKK,uBAAuB;MAC5B4E,EAAQC,KAAK;;IAGjB,OAAOD,EAAQE,KAAK;;EAGxB,kBAAIC;IACA,OAAO5E,MAAM6E,QAAQrF,KAAKsF,aAAatF,KAAKsF,YAAYtF,KAAKsF,UAAUC,MAAM;;EAGjF,kBAAI/D;IACA,SAASxB,KAAK+B,eAAe/B,KAAKgC;;EAGtC,6BAAIA;IACA,OAAOwD,EAAexF,KAAKwC,IAAI;;EAGnC,YAAIjB;IACA,SAASvB,KAAK0B,SAAS1B,KAAK4B;;EAGhC,uBAAIA;IACA,OAAO4D,EAAexF,KAAKwC,IAAI;;EAGnC,gBAAA3B,CAAiB4E;IACb,MAAMpB,IAAe;IACrBA,EAAaa,QAAQlF,KAAK0F,2BAA2BD;IACrDpB,EAAaa,QAAQlF,KAAK2F,0BAA0BF;IACpDpB,EAAaa,QAAQlF,KAAK4F,8BAA8BH;IACxDzF,KAAKyD,iBAAiB,KAAIY;IAE1B,IAAIoB,EAAcI,WAAW,GAAG;MAC5B7F,KAAK0C,oBAAoB;WACtB;MACH1C,KAAKC,cAAcwF;;IAGvB,OAAO;MAAEpB;MAAcC,YAAYmB;;;EAQvC,YAAArF,CAAa0F;IACTA,EAAMC;IACND,EAAME;;EAGV,+BAAAhB;IACI,IAAIhF,KAAKC,YAAY4F,WAAW,MAAM7F,KAAKyD,eAAewC,MAAKtC,KAAQA,EAAKM,WAAW,iBAAgB;MACnGjE,KAAK0C,oBAAoB;;;EAIjC,UAAA5B,CAAWF;IACPZ,KAAK0C,oBAAoB9B,EAAY0D,WAAWuB,SAAS;IACzD7F,KAAKkG,UAAUC,KAAKvF;;EAGxB,0BAAA8E,CAA2B/E;IACvB,MAAM0D,IAAe;IAErB,IAAIrE,KAAKoF,eAAeS,WAAW,GAAG,OAAOxB;IAE7C1D,EAAM8D,SAAQd;MACV,MAAMyC,IAAgBzC,EAAK9B,KAAK0D,MAAM,KAAKc,MAAMC;MACjD,KAAKtG,KAAKoF,eAAemB,SAASH,IAAgB;QAC9C/B,EAAaa,KAAK;UAAEvB;UAAMM,QAAQ;;;;;QAK1CI,EAAaI,SAAQ+B;MACjB,MAAMC,IAAQ9F,EAAM+F,QAAQF,EAAY7C;MACxC,IAAI8C,KAAS,GAAG;QACZ9F,EAAMmE,OAAO2B,GAAO;;;IAI5B,OAAOpC;;EAGX,6BAAAuB,CAA8BjF;IAC1B,MAAMgG,IAAyB;IAE/B,IAAI3G,KAAK+C,aAAaqB,UAAU,OAAOuC;IAEvC,IAAIhG,EAAMkF,SAAS7F,KAAK+C,UAAU;MAC9B,MAAM6D,IAAcjG,EAAMmE,OAAO9E,KAAK+C;MACtC6D,EAAYnC,SAAQd;QAChBgD,EAAuBzB,KAAK;UAAEvB;UAAMM,QAAQ;;AAAyB;;IAI7E,OAAO0C;;EAGX,yBAAAhB,CAA0BhF;IACtB,MAAMkG,IAAqB;IAE3B,IAAI7G,KAAK8G,gBAAgB1C,UAAU,OAAOyC;IAE1ClG,EAAM8D,SAAQd;MACV,IAAIA,EAAKP,OAAOpD,KAAK8G,aAAa;QAC9BD,EAAmB3B,KAAK;UAAEvB;UAAMM,QAAQ;;;;;QAKhD4C,EAAmBpC,SAAQsC;MACvB,MAAMN,IAAQ9F,EAAM+F,QAAQK,EAAapD;MACzC,IAAI8C,KAAS,GAAG;QACZ9F,EAAMmE,OAAO2B,GAAO;;;IAI5B,OAAOI;;EAGX,aAAAG;IACIhH,KAAKiH,kBAAkB;;;EAG3B,sCAAAlD,CAAuCmD;IACnC,OAAQ/G;MACJ,IAAIA,EAAEgH,kBAAkB,yBAAyB;QAC7CnH,KAAKyD,iBAAiBzD,KAAKyD,eAAe2D,QAAOzD,KAAQA,EAAKA,KAAK9B,SAASqF;;;;EAKxF,+BAAA/C,CAAgC+C;IAC5B,OAAO;MACH,MAAMG,IAAerH,KAAKyD,eAAe6D,MAAK3D,KAAQA,EAAKA,KAAK9B,SAASqF;MACzE,IAAIG,GAAc;QACdA,EAAaE,cAAc;QAC3BvH,KAAKgH;;;;EAKjB,kBAAApD,CAAmBsD;IACf,MAAMjC,IAAU,EAAC;IACjB,MAAMJ,IAAe7E,KAAKyD,eAAe6D,MAAK3D,KAAQA,EAAKA,KAAK9B,SAASqF;IACzE,IAAIrC,MAAY,QAAZA,WAAY,aAAZA,EAAc0C,aAAa;MAC3BtC,EAAQC,KAAK;WACV;MACHD,EAAQC,KAAK;;IAEjB,OAAOD,EAAQE,KAAK;;EAGxB,wBAAAjB,CAAyBD,GAAoBb;IACzC,QAAQa;KACJ,KAAK;MACD,OAAOtC,EAAI;;KACf,KAAK;MACD,OAAOA,EAAI;;KACf,KAAK;MACD,OAAOA,EAAI;;KACf,KAAK;MACD,OAAOA,EAAI;;KACf,KAAK;MACD,OAAOA,EAAI;;KACf,KAAK;KACL;MACI,OAAOA,EAAI,sCAAsC,GAAEyB,KAAQ,MAAO,MAAOoE,QAAQ;;;EA2B7F,iBAAA1E;IACI9C,KAAKuD,kBAAkBkE,cAAc,IAAIC,WAAW"}
|
|
1
|
+
{"version":3,"names":["q2FilePickerCss","Q2FilePickerStyle0","Q2FilePicker","this","queuedFiles","dimDropZone","e","disableEvent","isDropZoneHighlighted","grabDroppedFiles","droppedFiles","Array","from","dataTransfer","files","filesObject","buildFilesObject","emitChange","value","grabSelectedFiles","selectedFiles","target","highlightDropZone","render","h","class","hasLabel","hasDescription","htmlFor","label","loc","hasLabelSlotContent","name","id","description","hasDescriptionSlotContent","variant","dropZoneClasses","onDragEnter","onDragLeave","onDragOver","onDrop","ref","el","dropZone","areFilesUploading","Fragment","type","onTctClick","launchFileBrowser","maxFiles","disabled","intent","loading","onClick","size","undefined","onChange","browseButtonInput","multiple","displayedFiles","map","file","getFileItemClasses","key","onAnimationEnd","getAnimationendHandlerToRemoveFileItem","slot","status","getFileItemStatusMessage","getClickHandlerToRemoveFileItem","Infinity","invalidFiles","validFiles","updateFileList","newValue","forEach","statusItem","matchingQueuedFileIndex","findIndex","matchingFile","splice","matchingDisplayedFileIndex","disableLoaderIfAllFilesUploaded","classes","push","join","fileTypesArray","isArray","fileTypes","split","trim","hasSlotContent","filesToUpload","extractFilesOfInvalidTypes","extractFilesOverSizeLimit","extractFilesOverMaxFilesLimit","length","event","preventDefault","stopPropagation","some","tctChange","emit","fileExtension","pop","toLowerCase","includes","invalidFile","index","indexOf","filesOverMaxFilesLimit","excessFiles","filesOverSizeLimit","maxFileSize","overSizeFile","forceRerender","refreshCounter","fileName","animationName","filter","fileToDelete","find","toBeRemoved","toFixed","dispatchEvent","MouseEvent"],"sources":["src/components/q2-file-picker/q2-file-picker.scss?tag=q2-file-picker&encapsulation=shadow","src/components/q2-file-picker/q2-file-picker.tsx"],"sourcesContent":["@import '../../styles/host.scss';\n@import '../../styles/functions';\n@import '../q2-btn/q2-btn-mixins';\n\n@keyframes growFromCenterFadeIn {\n from {\n transform: scaleX(.75) scaleY(.75);\n opacity: 0;\n }\n to {\n transform: scaleX(1) scaleY(1);\n opacity: 1;\n }\n}\n\n@keyframes shrinkToCenterFadeOut {\n from {\n transform: scaleX(1) scaleY(1);\n opacity: 1;\n }\n to {\n transform: scaleX(.75) scaleY(.75);\n opacity: 0;\n }\n}\n\n:host {\n display: block;\n}\n\n.browse {\n text-align: left;\n}\n\n.drop-zone-text {\n color: var-list(--tct-file-picker-drop-zone-text-color, --t-gray-6, #4D4D4D);\n font-size: var-list(--tct-file-picker-drop-zone-font-size, --app-font-size-small, 12px);\n font-weight: var(--tct-file-picker-browse-link-font-weight, 700);\n margin-bottom: 0;\n margin-top: var-list(--tct-file-picker-drop-zone-text-margin-top, --app-scale-2x, 10px);\n}\n\n.description {\n color: var-list(--tct-file-picker-description-text-color, --t-gray-1, #0D0D0D);\n font-size: var-list(--tct-file-picker-description-font-size, --app-font-size-small, 12px);\n font-weight: var(--tct-file-picker-description-font-weight, 400);\n text-align: var(--tct-file-picker-description-text-align, left);\n}\n\n.drop-zone {\n align-items: center;\n background-color: var-list(--tct-file-picker-drop-zone-background, --t-tertiary, #E8F5FC);\n border-radius: var-list(--tct-file-picker-drop-zone-border-radius, --app-border-radius-2, 6px);\n border-width: var(--tct-file-picker-drop-zone-border-width, 2px);\n border-style: var(--tct-file-picker-drop-zone-border-style, dashed);\n border-color: var-list(--tct-file-picker-drop-zone-border-color, --t-gray-8, #808080);\n color: var(--tct-file-picker-drop-zone-color, #747474);\n display: flex;\n flex-direction: column;\n font-size: var(--tct-file-picker-drop-zone-font-size, --app-font-size, 14px);\n font-weight: var(--tct-file-picker-drop-zone-font-weight, 400);\n height: var(--tct-file-picker-drop-zone-height, 150px);\n justify-content: center;\n padding: var(--tct-file-picker-drop-zone-padding, 20px);\n text-align: center;\n width: var(--tct-file-picker-drop-zone-width, 100%);\n}\n\n.drop-zone-highlighted {\n background-color: var-list(--tct-file-picker-drop-zone-highlighted-background, --tertiary-d-1, #BEE1F6);\n border-color: var-list(--tct-file-picker-drop-zone-highlighted-border, --t-gray-8, #808080);\n}\n\n.fade-in {\n animation-fill-mode: both;\n animation-play-state: running;\n animation: growFromCenterFadeIn 0.2s ease-in;\n}\n\n.fade-out {\n animation: shrinkToCenterFadeOut 0.1s ease-out;\n animation-play-state: running;\n animation-fill-mode: both;\n}\n\n.file-item {\n --tct-btn-icon-border-radius: 4px;\n --tct-btn-neutral-text-active-font-color: #{var-list(--tct-file-picker-item-close-btn-active-color, --t-gray-1, #0D0D0D)};\n --tct-btn-neutral-text-focus-visible-outer-ring-color: #{var-list(--tct-file-picker-item-close-btn-color, --t-gray-1, #0D0D0D)};\n --tct-btn-neutral-text-font-color: #{var-list(--tct-file-picker-item-close-btn-color, --t-gray-1, #0D0D0D)};\n --tct-btn-neutral-text-hover-outer-ring-color: #{var-list(--tct-file-picker-item-close-btn-hover-focus-ring-color, --t-gray-1, #0D0D0D)};\n --tct-btn-padding: 0;\n --tct-icon-stroke-primary: #{var-list(--tct-file-picker-item-close-btn-color, --t-gray-1, #0D0D0D)};\n --tct-item-body-font-size: #{var-list(--tct-file-picker-item-font-size, --app-font-size-small, 12px)};\n --tct-item-body-font-weight: var(--tct-file-picker-item-font-weight, 400);\n --tct-item-border-radius: #{var-list(--tct-file-picker-item-border-radius, --app-border-radius-3, 12px)};\n --tct-item-border: var(--tct-file-picker-item-border-width, 1px) solid #{var-list(--tct-file-picker-item-border-color, --t-gray-8, #808080)};\n --tct-item-header-color: #{var-list(--tct-file-picker-item-name-color, --t-gray-1, #0D0D0D)};\n --tct-item-header-font-size: #{var-list(--tct-file-picker-item-name-font-size, --app-font-size-small, 12px)};\n --tct-item-header-font-weight: var(--tct-file-picker-item-name-font-weight, 400);\n --tct-item-padding: var(--tct-file-picker-item-padding, var(--app-scale-1x, 5px) var(--app-scale-2x, 10px));\n text-align: left;\n}\n\n.file-item-loading {\n font-size: var-list(--tct-file-picker-file-item-loading-size, --app-scale-6x, 30px);\n // FIXME: This is a temporary fix to match the height of the closing icon which has 3.5px of padding I can't account for\n margin-bottom: calc(var-list(--tct-file-picker-file-item-loading-margin-bottom, --app-scale-6x, 30px) / 8.57);\n margin-left: calc(var-list(--tct-file-picker-file-item-loading-margin-bottom, --app-scale-1x, 5px) / 2);\n}\n\n.file-list {\n --tct-list-item-gap: #{var-list(--tct-file-picker-section-gap, --app-scale-3x, 15px)};\n}\n\n.file-list-container {\n max-height: var(--tct-file-picker-list-max-height, 190px);\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: #{var-list(--tct-file-picker-scrollbar-color, --t-a11y-gray-color, #949494)} transparent;\n}\n\n.file-picker {\n display: flex;\n flex-direction: column;\n gap: #{var-list(--tct-file-picker-file-item-gap, --app-scale-3x, 15px)};\n}\n\n.heading {\n display: flex;\n flex-direction: column;\n gap: #{var-list(--tct-file-picker-heading-gap, --app-scale-1x, 5px)};\n justify-content: space-between;\n}\n\n.icon-success,\n.icon-error {\n --tct-icon-size: #{var-list(--tct-file-picker-file-item-icon-size, --app-scale-6x, 30px)};\n --tct-icon-stroke-width: 2px;\n}\n\n.label {\n color: var-list(--tct-file-picker-label-color, --t-gray-1, #0D0D0D);\n // cursor: pointer;\n display: inline-block;\n font-size: var-list(--tct-file-picker-label-font-size, --app-font-size, 14px);\n font-weight: var(--tct-file-picker-label-font-weight, 600);\n text-align: var(--tct-file-picker-label-text-align, left);\n}\n\n.loading {\n font-size: var-list(--tct-file-picker-loading-size, --app-scale-6x, 25px);\n}\n\n.loading-file {\n color: var-list(--tct-file-picker-loading-file-color, --t-gray-1, #0D0D0D);\n font-size: var-list(--tct-file-picker-loading-file-font-size, --app-font-size-small, 12px);\n font-weight: var(--tct-file-picker-loading-file-font-weight, 400);\n margin: 0;\n}\n\n.loading-message {\n color: var-list(--tct-file-picker-loading-message-color, --t-gray-1, #0D0D0D);\n font-size: var-list(--tct-file-picker-loading-message-font-size, --app-font-size-small, 12px);\n font-weight: var(--tct-file-picker-loading-message-font-weight, 700);\n margin-bottom: var-list(--tct-file-picker-loading-message-margin-bottom, --app-scale-2x, 10px);\n margin-top: var-list(--tct-file-picker-loading-message-margin-top, --app-scale-2x, 10px);\n}\n\n.dismiss-button {\n height: 30px;\n width: 30px;\n &:hover {\n --tct-icon-stroke-primary: #{var-list(--tct-file-picker-item-close-btn-hover-color, --t-gray-1, #0D0D0D)};\n }\n}\n\n[slot=\"action\"] {\n display: flex;\n align-items: center;\n}\n","import {\n Component,\n ComponentInterface,\n Element,\n Event,\n EventEmitter,\n Fragment,\n h,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\nimport { hasSlotContent, loc } from 'src/utils';\n\ntype FileStatus = 'invalid-type' | 'over-size-limit' | 'over-max-files-limit' | 'in-progress' | 'failed' | 'uploaded';\nexport type FilesObject = {\n invalidFiles: {\n file: File;\n status: 'invalid-type' | 'over-size-limit' | 'over-max-files-limit' | 'in-progress' | 'failed' | 'uploaded';\n }[];\n validFiles: File[];\n};\n\n@Component({\n tag: 'q2-file-picker',\n styleUrl: 'q2-file-picker.scss',\n shadow: true,\n})\nexport class Q2FilePicker implements ComponentInterface {\n // #region Own Properties\n\n browseButtonInput: HTMLElement;\n dropZone: HTMLElement;\n fileItemsToBeDeleted;\n queuedFiles: File[] = [];\n\n // #endregion\n // #region Host HTML Element\n\n @Element()\n el: HTMLElement;\n\n // #endregion\n // #region State Properties\n\n @State()\n areFilesUploading: boolean = false;\n\n @State()\n displayedFiles: {\n file: File;\n status: FileStatus;\n toBeRemoved?: boolean;\n }[] = [];\n\n @State()\n isDropZoneHighlighted: boolean = false;\n\n @State()\n refreshCounter = 0;\n\n // #endregion\n // #region Public Property API\n\n /**\n * A description of the field. This is announced by screen readers when the field is focused.\n * @localizable\n */\n @Prop({ reflect: true })\n description: string;\n\n /**\n * Allowed file types based on extensions (e.g., ['jpg', 'png', 'pdf'] or\n * 'jpg, png, pdf'). When using the attribute, provide a comma-separated\n * string (e.g., 'jpg, png, pdf'). Arrays can only be set programmatically\n * via JavaScript.\n */\n @Prop({ reflect: true })\n fileTypes: string[] | string = [];\n\n /**\n * The label for the field. This is announced by screen readers when the field is focused.\n * @localizable\n */\n @Prop({ reflect: true })\n label: string;\n\n /**\n * The maximum number of files that can be selected.\n */\n @Prop({ reflect: true })\n // maxFiles: number | string = Infinity;\n maxFiles: number = Infinity;\n\n /**\n * The maximum size (in bytes) of any file that can be selected.\n */\n @Prop({ reflect: true })\n maxFileSize: number = Infinity;\n\n /**\n * An array of objects representing the status of the files being uploaded.\n * Each object should have a `name` property (the file name) and a `status`\n * property (the status of the file) that equals either 'in-progress',\n * 'failed' or 'uploaded'.\n */\n @Prop({ reflect: true })\n status: { name: string; status: 'in-progress' | 'failed' | 'uploaded' }[] = [];\n\n /**\n * Returns an array of File objects representing the files selected by the\n * user. If no files are selected, the value is an empty array.\n * @readonly\n */\n @Prop({ mutable: true })\n value: FilesObject = { invalidFiles: [], validFiles: [] }; // Ensure FilesObject is exported or imported correctly\n\n /**\n * Determines if the file picker is a browse button or a drop zone with a\n * browse link.\n */\n @Prop({ reflect: true })\n variant: 'browse' | 'browse-drop' = 'browse';\n\n // #endregion\n // #region Events\n\n @Event()\n tctChange: EventEmitter<FilesObject>;\n\n // #endregion\n // #region Watchers\n\n @Watch('status')\n updateFileList(newValue: { name: string; status: FileStatus }[]) {\n newValue.forEach(statusItem => {\n const matchingQueuedFileIndex = this.queuedFiles.findIndex(file => file.name === statusItem.name);\n if (matchingQueuedFileIndex > -1) {\n const matchingFile = this.queuedFiles.splice(matchingQueuedFileIndex, 1)[0];\n this.displayedFiles = [{ file: matchingFile, status: statusItem.status }, ...this.displayedFiles];\n } else {\n const matchingDisplayedFileIndex = this.displayedFiles.findIndex(\n file => file.file.name === statusItem.name\n );\n if (matchingDisplayedFileIndex > -1) {\n this.displayedFiles[matchingDisplayedFileIndex].status = statusItem.status;\n this.disableLoaderIfAllFilesUploaded();\n }\n }\n });\n }\n\n // #endregion\n // #region Local Methods\n\n get dropZoneClasses() {\n const classes = ['drop-zone'];\n if (this.isDropZoneHighlighted) {\n classes.push('drop-zone-highlighted');\n }\n\n return classes.join(' ');\n }\n\n get fileTypesArray() {\n return Array.isArray(this.fileTypes) ? this.fileTypes : this.fileTypes.split(',').map(type => type.trim());\n }\n\n get hasDescription() {\n return !!this.description || this.hasDescriptionSlotContent;\n }\n\n get hasDescriptionSlotContent() {\n return hasSlotContent(this.el, 'description');\n }\n\n get hasLabel() {\n return !!this.label || this.hasLabelSlotContent;\n }\n\n get hasLabelSlotContent() {\n return hasSlotContent(this.el, 'label');\n }\n\n buildFilesObject(filesToUpload: File[]): FilesObject {\n const invalidFiles = [];\n invalidFiles.push(...this.extractFilesOfInvalidTypes(filesToUpload));\n invalidFiles.push(...this.extractFilesOverSizeLimit(filesToUpload));\n invalidFiles.push(...this.extractFilesOverMaxFilesLimit(filesToUpload));\n this.displayedFiles = [...invalidFiles];\n\n if (filesToUpload.length === 0) {\n this.areFilesUploading = false;\n } else {\n this.queuedFiles = filesToUpload;\n }\n\n return { invalidFiles, validFiles: filesToUpload };\n }\n\n dimDropZone = (e: DragEvent) => {\n this.disableEvent(e);\n this.isDropZoneHighlighted = false;\n };\n\n disableEvent(event: Event) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n disableLoaderIfAllFilesUploaded() {\n if (this.queuedFiles.length === 0 && !this.displayedFiles.some(file => file.status === 'in-progress')) {\n this.areFilesUploading = false;\n }\n }\n\n emitChange(filesObject: FilesObject) {\n this.areFilesUploading = filesObject.validFiles.length > 0;\n this.tctChange.emit(filesObject);\n }\n\n extractFilesOfInvalidTypes(files: File[]) {\n const invalidFiles = [];\n\n if (this.fileTypesArray.length === 0) return invalidFiles;\n\n files.forEach(file => {\n const fileExtension = file.name.split('.').pop().toLowerCase();\n if (!this.fileTypesArray.includes(fileExtension)) {\n invalidFiles.push({ file, status: 'invalid-type' });\n }\n });\n\n // Remove invalid files from the files array\n invalidFiles.forEach(invalidFile => {\n const index = files.indexOf(invalidFile.file);\n if (index > -1) {\n files.splice(index, 1);\n }\n });\n\n return invalidFiles;\n }\n\n extractFilesOverMaxFilesLimit(files: File[]) {\n const filesOverMaxFilesLimit = [];\n\n if (this.maxFiles === Infinity) return filesOverMaxFilesLimit;\n\n if (files.length > this.maxFiles) {\n const excessFiles = files.splice(this.maxFiles);\n excessFiles.forEach(file => {\n filesOverMaxFilesLimit.push({ file, status: 'over-max-files-limit' });\n });\n }\n\n return filesOverMaxFilesLimit;\n }\n\n extractFilesOverSizeLimit(files: File[]) {\n const filesOverSizeLimit = [];\n\n if (this.maxFileSize === Infinity) return filesOverSizeLimit;\n\n files.forEach(file => {\n if (file.size > this.maxFileSize) {\n filesOverSizeLimit.push({ file, status: 'over-size-limit' });\n }\n });\n\n // Remove files over size limit from the files array\n filesOverSizeLimit.forEach(overSizeFile => {\n const index = files.indexOf(overSizeFile.file);\n if (index > -1) {\n files.splice(index, 1);\n }\n });\n\n return filesOverSizeLimit;\n }\n\n forceRerender() {\n this.refreshCounter += 1; // Triggers re-render\n }\n\n getAnimationendHandlerToRemoveFileItem(fileName: string) {\n return (e: AnimationEvent) => {\n if (e.animationName === 'shrinkToCenterFadeOut') {\n this.displayedFiles = this.displayedFiles.filter(file => file.file.name !== fileName);\n }\n };\n }\n\n getClickHandlerToRemoveFileItem(fileName: string) {\n return () => {\n const fileToDelete = this.displayedFiles.find(file => file.file.name === fileName);\n if (fileToDelete) {\n fileToDelete.toBeRemoved = true;\n this.forceRerender();\n }\n };\n }\n\n getFileItemClasses(fileName: string) {\n const classes = ['file-item'];\n const matchingFile = this.displayedFiles.find(file => file.file.name === fileName);\n if (matchingFile?.toBeRemoved) {\n classes.push('fade-out');\n } else {\n classes.push('fade-in');\n }\n return classes.join(' ');\n }\n\n getFileItemStatusMessage(status: FileStatus, size: number) {\n switch (status) {\n case 'invalid-type':\n return loc('tecton.element.filePicker.unsupportedFileType');\n case 'over-size-limit':\n return loc('tecton.element.filePicker.sizeExceedsLimit');\n case 'over-max-files-limit':\n return loc('tecton.element.filePicker.overMaxFilesLimit');\n case 'in-progress':\n return loc('tecton.element.filePicker.uploadingEllipsis');\n case 'failed':\n return loc('tecton.element.filePicker.uploadFailed');\n case 'uploaded':\n default:\n return loc('tecton.element.filePicker.fileSize', [(size / (1000 * 1000)).toFixed(2)]);\n }\n }\n\n grabDroppedFiles = (e: DragEvent) => {\n this.disableEvent(e);\n this.isDropZoneHighlighted = false;\n const droppedFiles = Array.from(e.dataTransfer.files);\n const filesObject = this.buildFilesObject(droppedFiles);\n\n this.emitChange(filesObject);\n this.value = filesObject;\n };\n\n grabSelectedFiles = (e: Event) => {\n const selectedFiles = Array.from((e.target as HTMLInputElement).files);\n const filesObject = this.buildFilesObject(selectedFiles);\n\n this.emitChange(filesObject);\n this.value = filesObject;\n };\n\n highlightDropZone = (e: DragEvent) => {\n this.disableEvent(e);\n this.isDropZoneHighlighted = true;\n };\n\n launchFileBrowser() {\n this.browseButtonInput.dispatchEvent(new MouseEvent('click'));\n }\n\n // #endregion\n // #region Render Methods\n\n render = () => {\n return (\n <div class=\"file-picker\">\n {(this.hasLabel || this.hasDescription) && (\n <div class=\"heading\">\n {this.hasLabel && (\n <label\n class=\"label\"\n htmlFor=\"file-field\"\n test-id=\"label\"\n >\n {!!this.label ? loc(this.label) : this.hasLabelSlotContent ? <slot name=\"label\" /> : ''}\n </label>\n )}\n {this.hasDescription && (\n <div\n class=\"description\"\n id=\"description\"\n test-id=\"description\"\n >\n {!!this.description ? (\n loc(this.description)\n ) : this.hasDescriptionSlotContent ? (\n <slot name=\"description\" />\n ) : (\n ''\n )}\n </div>\n )}\n </div>\n )}\n\n {(this.variant === 'browse-drop' && (\n <div\n class={this.dropZoneClasses}\n onDragEnter={this.disableEvent}\n onDragLeave={this.dimDropZone}\n onDragOver={this.highlightDropZone}\n onDrop={this.grabDroppedFiles}\n ref={el => (this.dropZone = el ?? this.dropZone)}\n test-id=\"drop-zone\"\n >\n {(this.areFilesUploading && (\n <Fragment>\n <q2-loading class=\"loading\"></q2-loading>\n <p class=\"drop-zone-text\">{loc('tecton.element.filePicker.uploadingEllipsis')}</p>\n </Fragment>\n )) || (\n <Fragment>\n <q2-icon type=\"upload\"></q2-icon>\n <p class=\"drop-zone-text\">\n <q2-link\n label={loc('tecton.element.filePicker.browse')}\n onTctClick={() => this.launchFileBrowser()}\n variant=\"inline\"\n test-id=\"browse-link\"\n />\n {loc('tecton.element.filePicker.orDragFilesHere', [this.maxFiles])}\n </p>\n </Fragment>\n )}\n </div>\n )) || (\n <div\n class=\"browse\"\n test-id=\"browse\"\n >\n <q2-btn\n disabled={this.areFilesUploading}\n intent=\"workflow-primary\"\n loading={this.areFilesUploading}\n onClick={() => this.launchFileBrowser()}\n size=\"medium\"\n test-id=\"browse-button\"\n >\n <q2-icon type=\"paperclip\"></q2-icon>\n <span>{loc('tecton.element.filePicker.attachFiles', [this.maxFiles])}</span>\n </q2-btn>\n </div>\n )}\n <input\n aria-describedby={(!!this.description && 'description') || undefined}\n class=\"sr\"\n id=\"file-field\"\n onChange={this.grabSelectedFiles}\n ref={el => (this.browseButtonInput = el ?? this.browseButtonInput)}\n type=\"file\"\n test-id=\"file-input\"\n multiple\n />\n <div class=\"file-list-container\">\n <q2-list class=\"file-list\">\n {this.displayedFiles.map(file => (\n <q2-item\n class={this.getFileItemClasses(file.file.name)}\n key={file.file.name}\n onAnimationEnd={this.getAnimationendHandlerToRemoveFileItem(file.file.name)}\n >\n <div slot=\"bullet\">\n {file.status === 'invalid-type' ||\n file.status === 'over-size-limit' ||\n file.status === 'failed' ||\n file.status === 'over-max-files-limit' ? (\n <q2-icon\n class=\"icon-error\"\n type=\"error\"\n ></q2-icon>\n ) : file.status === 'in-progress' ? (\n <q2-loading class=\"file-item-loading\"></q2-loading>\n ) : (\n <q2-icon\n class=\"icon-success\"\n type=\"success\"\n ></q2-icon>\n )}\n </div>\n <div slot=\"header\">{file.file.name}</div>\n <div slot=\"body\">{this.getFileItemStatusMessage(file.status, file.file.size)}</div>\n <div slot=\"action\">\n <q2-btn\n class=\"dismiss-button\"\n intent=\"neutral-text\"\n onClick={this.getClickHandlerToRemoveFileItem(file.file.name)}\n >\n <q2-icon type=\"close\"></q2-icon>\n </q2-btn>\n </div>\n </q2-item>\n ))}\n </q2-list>\n </div>\n </div>\n );\n };\n\n // #endregion\n}\n"],"mappings":"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"}
|
|
@@ -207,8 +207,9 @@ const v = class {
|
|
|
207
207
|
this.clearValue();
|
|
208
208
|
}
|
|
209
209
|
handleSelectedDisplay(t) {
|
|
210
|
-
if (this.multiple)
|
|
211
|
-
|
|
210
|
+
if (!this.multiple && !!this.value && this.value === t.detail.value) {
|
|
211
|
+
this.inputField.value = t.detail.display;
|
|
212
|
+
}
|
|
212
213
|
}
|
|
213
214
|
delegateFocus(t) {
|
|
214
215
|
const e = r(t, this.hostElement);
|
|
@@ -618,17 +619,17 @@ const v = class {
|
|
|
618
619
|
render() {
|
|
619
620
|
var t;
|
|
620
621
|
return i("click-elsewhere", {
|
|
621
|
-
key: "
|
|
622
|
+
key: "cc3d7571025183c900c7dbeda597835e88d9224b",
|
|
622
623
|
class: this.wrapperClasses,
|
|
623
624
|
onChange: this.clickedElsewhere
|
|
624
625
|
}, i("div", {
|
|
625
|
-
key: "
|
|
626
|
+
key: "5ab3dec7a6e57ccaeef904ea07e52c29b88a0a91",
|
|
626
627
|
"aria-live": "polite",
|
|
627
628
|
"aria-atomic": "true",
|
|
628
629
|
role: "status",
|
|
629
630
|
class: "sr"
|
|
630
631
|
}, this.statusMessage), i("q2-input", {
|
|
631
|
-
key: "
|
|
632
|
+
key: "3d7c3ded01c34866fdebc4503bc2bac46ba67018",
|
|
632
633
|
ref: t => this.inputField = t,
|
|
633
634
|
class: "q2-select-input",
|
|
634
635
|
label: this.label && o(this.label) || "",
|
|
@@ -657,12 +658,12 @@ const v = class {
|
|
|
657
658
|
_role: "combobox",
|
|
658
659
|
_preventEntry: !this.searchable
|
|
659
660
|
}, this.renderCustomDisplay()), i("div", {
|
|
660
|
-
key: "
|
|
661
|
+
key: "37662b940b1a51d9abfb681d248607ff049a8655",
|
|
661
662
|
class: "custom-display-content",
|
|
662
663
|
hidden: !this.hasCustomDisplay || !!this.searchText,
|
|
663
664
|
onClick: this.onCustomDisplayClick
|
|
664
665
|
}, i("slot", {
|
|
665
|
-
key: "
|
|
666
|
+
key: "74441951077fd4476ccf3c820392e346ba6dd313",
|
|
666
667
|
name: "q2-select-display"
|
|
667
668
|
})), this.renderOptionsDropdown());
|
|
668
669
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["q2SelectCss","Q2SelectStyle0","Q2Select","this","scheduledAfterRender","clickedElsewhere","event","target","localName","stopPropagation","inputBlurHandler","inputFocused","inputChangeHandler","inputClickHandler","async","shouldShowActionSheet","executeActionSheet","toggleDropdown","focusInput","inputFocusHandler","inputInputHandler","eventValue","detail","value","shouldClearValue","clearValue","open","openDropdownWithoutActiveElement","prioritizeSearch","searchText","input","emit","query","inputKeydownHandler","readonly","disabled","key","shiftKey","isShiftTab","hasSlot","hasPopoverTop","hasPopoverBottom","keysForOptionListToHandle","searchable","inputField","preventDefault","includes","shouldClearSearchText","clearSearchText","optionList","handleExternalKeydown","onCustomDisplayClick","onMutationObserved","hostElement","slotContainer","querySelector","displaySlot","shadowRoot","hasCustomDisplay","assignedNodes","length","children","popTopSlot","topSlotHasNode","popBottomSlot","bottomSlotHasNode","checkSelectedOptions","onOptionListChange","values","showAllOptions","handleSelectionChanges","onPopoverState","action","setActiveElement","focus","showSelected","showSelectedOptions","visibilityToggleKeyDown","isRadioControlKey","setDefaultActiveElement","_a","window","Tecton","useActionSheets","loc","disconnectedCallback","mutationObserver","disconnect","componentWillLoad","handleAriaLabel","buildStructuredSelectedOptions","handleMultilineOptionsUpdate","multilineOptions","componentDidLoad","observer","MutationObserver","observe","childList","subtree","overrideFocus","setTimeout","checkSelectedDisplay","componentDidRender","forEach","fn","onHostElementChange","onchange","multiple","selectedOptions","onClearHandler","handleSelectedDisplay","display","delegateFocus","fromHost","isRelatedTargetWithinHost","clearSelectedDisplay","isEventFromElement","handleFocusout","relatedTarget","isLeavingHost","popoverElement","contains","closeDropdown","onHostElementInput","oninput","options","optionElements","trim","toLocaleLowerCase","matchedCount","option","hidden","title","firstElementChild","tagName","innerText","searchParams","matched","some","text","statusMessageLocString","count","setStatusMessage","keydownHandler","closePopover","_togglePopover","openPopover","searchOptions","innerInputField","dispatchEvent","FocusEvent","InputEvent","setValue","valuesSet","Set","Array","isArray","waitForNextPaint","find","click","ariaLabelObserver","newValue","oldValue","element","multiline","openChanged","isOpen","push","popoverTopContainer","height","offsetHeight","style","setProperty","removeProperty","structuredSelectedOptions","map","valueUpdated","badgeValue","optionsLength","_b","firstSelectedOptionElement","firstSelectedValue","innerInputContainer","from","querySelectorAll","popoverMinHeight","minRows","firstOption","minHeight","getComputedStyle","parseInt","selectedDisplay","calculateMultiSelectSelectedDisplay","calculateSingleSelectSelectedDisplay","selectedDisplaySlot","wrapperClasses","errors","classes","join","_c","textContent","namedSlot","hasNoValue","selectionClone","cloneNode","remove","clientHeight","outerHTML","replaceChild","document","createElement","slot","appendChild","checkSelectedDisplayHeight","selected","change","undefined","result","showActionSheetList","changeDetails","selectedOptionValues","message","clearTimeout","statusMessageTimer","statusMessage","renderCustomDisplay","hasSelectedDisplay","h","name","renderOptionsDropdown","ref","el","controlElement","popoverMaxHeight","direction","popDirection","mode","popoverMode","block","class","type","id","label","listLabel","onChange","tabindex","renderVisibilityToggle","selectedOptionsCount","checked","onClick","onKeyDown","htmlFor","render","role","clearable","error","invalid","optional","placeholder","hideLabel","ariaExpanded","ariaControls","ariaHaspopup","iconRight","onInput","onFocus","onBlur","badgeTheme","_role","_preventEntry"],"sources":["src/components/q2-select/q2-select.scss?tag=q2-select&encapsulation=shadow","src/components/q2-select/q2-select.tsx"],"sourcesContent":["@import '../../styles/host.scss';\n@import '../../styles/functions';\n@import '../../styles/dropdowns';\n\n:host {\n --comp-select-margin: #{var-list(\n --tct-select-margin,\n unquote(\n '#{var-list(var-prefixer(select-margin-top), --app-scale-4, 30px)} 0 #{var-list(var-prefixer(select-margin-bottom), --app-scale-4, 30px)}'\n )\n )};\n display: block;\n margin: var(--comp-select-margin);\n}\n\n.q2-select-container {\n position: relative;\n display: block;\n}\n\n.q2-select-input {\n margin: 0;\n\n --tct-input-min-height: #{var-list(var-prefixer(select-input-min-height))};\n --tct-input-max-height: #{var-list(var-prefixer(select-input-max-height), none)};\n}\n\n::slotted([slot='_selected-display']) {\n width: 100%;\n min-height: var(--comp-selected-display-height, 44px);\n}\n\n.custom-display-content {\n position: absolute;\n bottom: 0;\n left: calc(var-list(--tct-scale-2, --app-scale-2x, 10px) + 1px);\n height: 44px;\n width: calc(100% - 34px - var-list(--tct-scale-3, --app-scale-3x, 15px));\n overflow: hidden;\n cursor: pointer;\n transition: left var-list(--tct-tween-2, --app-tween-1, unquote('0.2s ease'));\n}\n\n.custom-display-content:not([hidden]) {\n display: flex;\n align-items: center;\n}\n\n.is-searchable.is-focused .custom-display-content,\n.is-searchable .custom-display-content:active {\n left: calc(var-list(--tct-scale-3, --app-scale-3x, 15px) + 1px);\n}\n\n.has-error .custom-display-content {\n width: calc(100% - 68px - var-list(--tct-scale-3, --app-scale-3x, 15px));\n}\n\n.popover-content {\n display: flex;\n flex-direction: column-reverse;\n}\n\n.popover-bottom-container {\n position: sticky;\n bottom: 0;\n z-index: 5;\n}\n\n.popover-top-container {\n position: sticky;\n top: 0;\n z-index: 5;\n .multi-select-header {\n padding: var(--tct-scale-2, var(--app-scale-2x, 10px)) var(--tct-scale-2, var(--app-scale-2x, 10px));\n background: var(--app-white);\n display: flex;\n gap: var-list(--app-scale-2x, 10px);\n align-items: center;\n\n fieldset {\n margin: 0;\n padding: 0;\n border: 0;\n display: flex;\n gap: var-list(--app-scale-2x, 10px);\n }\n\n legend {\n padding: 0;\n float: left;\n }\n\n label {\n cursor: pointer;\n padding: var-list(\n var-prefixer(select-multi-select-option-padding),\n var-prefixer(btn-badge-padding),\n unquote('2px 5px')\n );\n font-size: var-list(\n var-prefixer(select-multi-select-option-font-size),\n var-prefixer(btn-badge-font-size),\n inherit\n );\n border-radius: var-list(\n var-prefixer(select-multi-select-option-radius),\n var-prefixer(btn-badge-border-radius),\n --app-border-radius-1,\n 4px\n );\n background: var-list(\n --tct-select-multi-select-option-background,\n var-prefixer(select-multi-select-option-bg),\n --tct-badge-background,\n var-prefixer(btn-badge-bg),\n transparent\n );\n color: var-list(\n var-prefixer(select-multi-select-option-color),\n var-prefixer(btn-badge-font-color),\n inherit\n );\n\n &:hover {\n background: var-list(\n --tct-select-multi-select-option-hover-background,\n var-prefixer(select-multi-select-option-hover-background-color),\n var-prefixer(btn-badge-hover-bg),\n var-prefixer(gray-14),\n --app-gray-l3,\n #f2f2f2\n );\n color: var-list(\n --tct-select-multi-select-option-hover-color,\n var-prefixer(select-multi-select-option-color),\n var-prefixer(btn-badge-hover-font-color),\n var-prefixer(gray-5),\n --app-gray-d2,\n #404040\n );\n }\n }\n\n input {\n &:checked + label {\n &,\n &:enabled:hover {\n background: var-list(\n --tct-select-multi-select-option-active-background,\n var-prefixer(select-multi-select-option-active-background-color),\n var-prefixer(btn-primary-bg),\n #2e2e2e\n );\n color: var-list(\n var-prefixer(select-multi-select-option-active-color),\n var-prefixer(btn-primary-font-color),\n --app-white,\n #ffffff\n );\n }\n }\n\n &:disabled + label {\n opacity: var-list(\n var-prefixer(select-multi-select-option-disabled-opacity),\n var-prefixer(btn-disabled-opacity),\n --app-disabled-opacity,\n 0.4\n );\n cursor: not-allowed;\n }\n\n &:focus + label {\n box-shadow: var(--const-double-focus-ring);\n }\n }\n }\n}\n","import {\n Component,\n Prop,\n Element,\n h,\n Listen,\n State,\n EventEmitter,\n Event,\n ComponentInterface,\n Watch,\n Method,\n} from '@stencil/core';\nimport { IEventDetail, Q2InputCustomEvent, Q2OptionListCustomEvent } from 'src/components';\nimport {\n handleAriaLabel,\n isEventFromElement,\n isRelatedTargetWithinHost,\n loc,\n overrideFocus,\n waitForNextPaint,\n} from '../../utils';\nimport { IOptionValue } from '../q2-option-list/q2-option-list';\nimport { shouldShowActionSheet, showActionSheetList } from 'src/utils/action-sheet';\n\n@Component({ tag: 'q2-select', shadow: true, styleUrl: 'q2-select.scss' })\nexport class Q2Select implements ComponentInterface {\n // #region Own Properties\n\n inputField?: HTMLQ2InputElement;\n mutationObserver: MutationObserver;\n optionList: HTMLQ2OptionListElement;\n popoverElement?: HTMLQ2PopoverElement;\n popoverTopContainer?: HTMLDivElement;\n scheduledAfterRender: (() => void)[] = [];\n statusMessageTimer: NodeJS.Timeout;\n\n // #endregion\n // #region Host HTML Element\n\n @Element()\n hostElement: HTMLElement;\n\n // #endregion\n // #region State Properties\n\n @State()\n hasCustomDisplay: boolean = false;\n\n @State()\n hasPopoverBottom: boolean = false;\n\n @State()\n hasPopoverTop: boolean = false;\n\n @State()\n inputFocused: boolean = false;\n\n @State()\n open: boolean = false;\n\n @State()\n prioritizeSearch: boolean = false;\n\n @State()\n searchText: string = '';\n\n @State()\n showSelected: boolean = false;\n\n @State()\n statusMessage: string;\n\n @State()\n structuredSelectedOptions: IOptionValue[] = [];\n\n // #endregion\n // #region Public Property API\n\n /** @deprecated */\n @Prop({ reflect: true, mutable: true })\n ariaLabel: string;\n\n /** Renders an icon button when the field is non-empty. Pressing the button clears all input from the field. */\n @Prop({ reflect: true })\n clearable: boolean;\n\n /** Disables all interaction with the field and leverages the disabled visual style of `q2-input`. */\n @Prop({ reflect: true })\n disabled: boolean = false;\n\n /**\n * The presence of `errors` will mark the field as invalid, putting it into an error state.\n * @localizable\n */\n @Prop()\n errors: string[];\n\n /**\n * Hide's the field's `<label>` element from view.\n * @warning\n * Only use when a visible label is impractical.\n */\n @Prop({ reflect: true, mutable: true })\n hideLabel: boolean;\n\n /**\n * Instructs the component to use the action sheet workflow for displaying its options.\n *\n * For more information, see [Action Sheets](https://tecton.q2developer.com/guides/action-sheets/).\n * @warning\n * If your `q2-select` renders inside of an iframe, and you are using multiline/robust content options,\n * any custom CSS you apply to your options will not get passed up to the platform which displays the action sheet.\n * For this reason, we strongly suggest using the [q2-card](https://tecton.q2developer.com/design-system/q2-card/) component since its styling is managed by Tecton.\n */\n @Prop()\n hoist: boolean = !!window.Tecton?.useActionSheets;\n\n /** Determines whether to show an error state. Its primary use-case is for an unfilled field. */\n @Prop({ reflect: true })\n invalid: boolean;\n\n /**\n * The text that will be used as the label for the field.\n * @localizable\n */\n @Prop({ reflect: true, mutable: true })\n label: string;\n\n /**\n * Determines the label that is applied to the option list for accessibility purposes.\n * @localizable\n */\n @Prop()\n listLabel: string = loc('tecton.element.select.listLabel');\n\n /** The minimum number of rows the component will try to display below or above the component when opened. */\n @Prop()\n minRows: number = 3;\n\n /** Enables text wrapping for `q2-option` elements. When `false`, the text truncates and does not wrap. */\n @Prop({ reflect: true })\n multilineOptions: boolean = false;\n\n /** Enables multi-select functionality. */\n @Prop({ reflect: true })\n multiple: boolean = false;\n\n /** Appends \"(optional)\" to the field label, and sets `aria-required` on the nested input tag to `false`. */\n @Prop({ reflect: true })\n optional: boolean = false;\n\n /**\n * Text that appears within the field when it is blurred and empty.\n * Placeholder text disappears when the user selects an option.\n * @localizable\n */\n @Prop({ reflect: true })\n placeholder: string;\n\n /** @deprecated */\n @Prop({ reflect: true })\n popDirection: 'up' | 'down';\n\n /**\n * Force the maximum height of the popover. This value will be interpreted as pixels.\n * If no value is passed, or the value exceeds available space, the component will auto-detect the maximum height based on available space.\n */\n @Prop()\n popoverMaxHeight: number;\n\n /**\n * Determines the display mode of the popover.\n *\n * Providing a value of `legacy` instructs the popover to use absolute positioning instead of fixed positioning.\n *\n * @info\n * This is a temporary solution to work around styling issues related to using fixed positioning for the popover\n * when nested inside of elements with transform properties. This will be removed once the popover API is available\n * for use.\n */\n @Prop({ mutable: true })\n popoverMode: 'legacy' = null;\n\n /**\n * Appends \"(read only)\" to the field label, and field becomes unusable, but remains focusable.\n * Takes priority over `optional` if both are `true`.\n */\n @Prop({ reflect: true })\n readonly: boolean = false;\n\n /** Enables search functionality. */\n @Prop({ reflect: true })\n searchable: boolean = false;\n\n /**\n * Each item in this array should correspond to the value of a `q2-option` element.\n * This property is only relevant for `multiple` (i.e., multi-select) implementations.\n */\n @Prop({ mutable: true })\n selectedOptions: string[] = [];\n\n /**\n * The current value for the select. This should correspond to the value of a nested q2-option element.\n * This property is only relevant for single-select implementations.\n */\n @Prop({ mutable: true })\n value: string;\n\n // #endregion\n // #region Events\n\n /**\n * Emitted when an option is selected or deselected.\n *\n * When the multi-select is enabled, the `value` property will be `undefined` and the `selectedOptions` property\n * will contain the selected option values.\n *\n * @legacyEvent\n */\n @Event()\n change: EventEmitter<{ value: string; selectedOptions: string[] }>;\n\n /**\n * Emitted when the input value changes.\n *\n * Requires the `searchable` prop to be set to `true`.\n */\n @Event()\n input: EventEmitter<{ query: string }>;\n\n // #endregion\n // #region Component Lifecycle Events\n\n disconnectedCallback() {\n this.mutationObserver?.disconnect();\n this.mutationObserver = null;\n }\n\n componentWillLoad() {\n handleAriaLabel(this);\n this.buildStructuredSelectedOptions();\n this.handleMultilineOptionsUpdate(this.multilineOptions, false);\n }\n\n componentDidLoad() {\n const observer = new MutationObserver(this.onMutationObserved);\n observer.observe(this.hostElement, { childList: true, subtree: true });\n this.mutationObserver = observer;\n this.onMutationObserved();\n overrideFocus(this.hostElement);\n setTimeout(() => this.checkSelectedDisplay(), 0);\n }\n\n componentDidRender() {\n setTimeout(() => {\n this.scheduledAfterRender.forEach(fn => fn());\n this.scheduledAfterRender = [];\n }, 25);\n }\n\n // #endregion\n // #region Listeners\n\n @Listen('change')\n onHostElementChange(event: CustomEvent<{ value: string; selectedOptions: string[] }>) {\n if (this.readonly || this.disabled) return;\n if (event.target !== this.hostElement || this.hostElement.onchange) return;\n if (this.multiple) {\n this.value = null;\n this.selectedOptions = event.detail.selectedOptions;\n } else {\n this.value = event.detail.value;\n this.selectedOptions = [];\n }\n }\n\n @Listen('clear')\n onClearHandler() {\n this.clearValue();\n }\n\n @Listen('displayChanged')\n handleSelectedDisplay(event: CustomEvent) {\n if (this.multiple) return;\n this.inputField.value = event.detail.display;\n }\n\n @Listen('focus')\n delegateFocus(event: FocusEvent) {\n const fromHost = isRelatedTargetWithinHost(event, this.hostElement);\n const prioritizeSearch = (this.prioritizeSearch = fromHost && this.searchable);\n if (prioritizeSearch) {\n this.clearSelectedDisplay();\n } else if (isEventFromElement(event, this.hostElement)) {\n this.inputField.shadowRoot.querySelector<HTMLElement>('.input-field').focus();\n }\n }\n\n @Listen('focusout')\n handleFocusout(event: FocusEvent) {\n const relatedTarget = event.relatedTarget as HTMLElement;\n const isLeavingHost =\n !this.popoverElement?.contains(relatedTarget) && !this.hostElement.contains(relatedTarget);\n if (isLeavingHost) this.closeDropdown();\n this.prioritizeSearch = !isLeavingHost && this.searchable;\n }\n\n @Listen('input')\n onHostElementInput(event: CustomEvent) {\n if (!this.searchable || event.target !== this.hostElement || this.hostElement.oninput) return;\n const options = this.optionElements;\n const query = this.searchText.trim().toLocaleLowerCase();\n let matchedCount = 0;\n options.forEach(option => {\n if (query === '') {\n option.hidden = false;\n return;\n }\n\n const title =\n option.firstElementChild?.tagName === 'Q2-CARD'\n ? (option.firstElementChild as HTMLQ2CardElement).title\n : null;\n const { display = '', innerText = '' } = option;\n const searchParams = [display, title, innerText];\n const matched = searchParams.some(text => text?.toLocaleLowerCase().includes(query) ?? false);\n\n option.hidden = !matched;\n if (matched) matchedCount++;\n });\n\n const statusMessageLocString = query\n ? 'tecton.element.select.searchable.results'\n : 'tecton.element.select.allOptions';\n const count = query ? matchedCount : options.length;\n this.setStatusMessage(loc(statusMessageLocString, [count]));\n }\n\n @Listen('keydown')\n keydownHandler(event: KeyboardEvent) {\n this.inputKeydownHandler(event);\n }\n\n // #endregion\n // #region Public Methods API\n\n /**\n * Emulates clicking the `<input>` to hide the popover if it is visible.\n *\n * @testOnly\n */\n @Method()\n async closePopover() {\n if (!this.open || this.disabled) return;\n this._togglePopover();\n }\n\n /**\n * Emulates clicking the `<input>` to display the popover if it is hidden.\n *\n * @testOnly\n */\n @Method()\n async openPopover() {\n if (this.open || this.disabled) return;\n this._togglePopover();\n }\n\n /**\n * Emulates focusing the `<input>`, entering the provided value, and emitting an `input` event.\n *\n * @warning\n * Only applicable when the input is searchable.\n *\n * @testOnly\n */\n @Method()\n searchOptions(query: string) {\n if (!this.searchable) return;\n\n const { innerInputField } = this;\n innerInputField.focus();\n innerInputField.dispatchEvent(new FocusEvent('focus'));\n innerInputField.value = query;\n innerInputField.dispatchEvent(new InputEvent('input'));\n }\n\n /**\n * Emulates clicking the `<input>` to display the popover and selecting the option(s) with the specified value(s).\n *\n * If the multi-select is enabled and the `closePopover` argument is `true` (default), the popover will be closed\n * after the option(s) are selected.\n *\n * @testOnly\n */\n @Method()\n async setValue(values: string | string[], options: { closePopover?: boolean } = { closePopover: true }) {\n const valuesSet = new Set(Array.isArray(values) ? values : [values]);\n if (!this.open) {\n await this.openPopover();\n await waitForNextPaint();\n }\n\n valuesSet.forEach(value => {\n this.optionElements.find(option => option.value === value)?.click();\n });\n\n if (options.closePopover) {\n await this.closePopover();\n await waitForNextPaint();\n }\n }\n\n // #endregion\n // #region Watchers\n\n @Watch('ariaLabel')\n ariaLabelObserver() {\n handleAriaLabel(this);\n }\n\n @Watch('multilineOptions')\n handleMultilineOptionsUpdate(newValue, oldValue) {\n if (newValue === oldValue) return;\n this.optionElements.forEach(element => (element.multiline = newValue));\n }\n\n @Watch('open')\n openChanged(isOpen: boolean) {\n this.scheduledAfterRender.push(async () => {\n await waitForNextPaint();\n const { popoverTopContainer, popoverElement } = this;\n const height = (isOpen && popoverTopContainer?.offsetHeight) || 0;\n if (height) {\n popoverElement.style.setProperty('--comp-popover-top-container-height', `${height}px`);\n } else {\n popoverElement.style.removeProperty('--comp-popover-top-container-height');\n }\n });\n }\n\n @Watch('value')\n @Watch('selectedOptions')\n buildStructuredSelectedOptions() {\n const { multiple, selectedOptions, value } = this;\n if (multiple) {\n this.structuredSelectedOptions = !!selectedOptions?.length\n ? selectedOptions.map(option => (typeof option === 'string' ? { value: option } : option))\n : [];\n } else {\n this.structuredSelectedOptions = value ? [{ value }] : [];\n }\n }\n\n @Watch('value')\n valueUpdated() {\n if (this.multiple) return;\n this.clearSearchText();\n }\n\n // #endregion\n // #region Local Methods\n\n get badgeValue(): string {\n if (!this.multiple) return null;\n const optionsLength = this.selectedOptions?.length ?? 0;\n if (this.open && this.searchable) return optionsLength ? `${optionsLength}` : null;\n else return optionsLength > 1 ? `+${optionsLength - 1}` : null;\n }\n\n get firstSelectedOptionElement() {\n const { firstSelectedValue } = this;\n return firstSelectedValue ? this.optionElements.find(({ value }) => value === firstSelectedValue) : null;\n }\n\n get firstSelectedValue() {\n return this.multiple ? this.selectedOptions?.[0] : this.value;\n }\n\n get innerInputContainer(): HTMLElement {\n return this.inputField?.shadowRoot?.querySelector('.input-container');\n }\n\n get innerInputField(): HTMLInputElement | HTMLButtonElement {\n return this.inputField?.shadowRoot?.querySelector('.input-field');\n }\n\n get optionElements() {\n return Array.from(this.hostElement.querySelectorAll<HTMLQ2OptionElement>('q2-option'));\n }\n\n get popoverMinHeight() {\n const { minRows } = this;\n const firstOption = this.hostElement.querySelector<HTMLQ2OptionElement>('q2-option:not([hidden])');\n let minHeight = firstOption && window.getComputedStyle(firstOption).minHeight;\n\n // Safari doesn't return a min-height for non-visible items\n if (!minHeight || minHeight === '0px') minHeight = '44px';\n\n return minRows * parseInt(minHeight);\n }\n\n get selectedDisplay() {\n if (this.prioritizeSearch || this.searchText) return this.searchText;\n if (this.hasCustomDisplay) return '';\n return this.multiple ? this.calculateMultiSelectSelectedDisplay() : this.calculateSingleSelectSelectedDisplay();\n }\n\n get selectedDisplaySlot() {\n return this.hostElement.querySelector<HTMLElement>('[slot=\"_selected-display\"]');\n }\n\n get wrapperClasses() {\n const { errors } = this;\n const classes = ['q2-select-container'];\n if (Array.isArray(errors) && errors.length > 0) classes.push('has-error');\n if (this.inputFocused) classes.push('is-focused');\n if (this.searchable) classes.push('is-searchable');\n return classes.join(' ');\n }\n\n _togglePopover() {\n const { innerInputField } = this;\n innerInputField?.click();\n innerInputField?.focus();\n innerInputField.dispatchEvent(new FocusEvent('focus'));\n }\n\n calculateMultiSelectSelectedDisplay() {\n const { firstSelectedOptionElement, firstSelectedValue, multilineOptions } = this;\n if (!firstSelectedValue) return '';\n if (firstSelectedOptionElement?.display) return loc(firstSelectedOptionElement.display);\n if (multilineOptions && this.searchable) return this.searchText;\n if (multilineOptions) return '';\n return (\n firstSelectedOptionElement?.textContent?.trim() ?? firstSelectedOptionElement?.value ?? firstSelectedValue\n );\n }\n\n calculateSingleSelectSelectedDisplay() {\n const { firstSelectedOptionElement, multilineOptions } = this;\n if (multilineOptions) {\n return (firstSelectedOptionElement?.display && loc(firstSelectedOptionElement.display)) || this.value || '';\n } else {\n return (\n (firstSelectedOptionElement?.display && loc(firstSelectedOptionElement.display)) ||\n firstSelectedOptionElement?.textContent?.trim() ||\n this.value ||\n ''\n );\n }\n }\n\n checkSelectedDisplay() {\n let namedSlot = this.selectedDisplaySlot;\n const { value, multiple, selectedOptions, multilineOptions, firstSelectedOptionElement, prioritizeSearch } =\n this;\n const hasNoValue = !value && multiple && !selectedOptions?.length;\n if (prioritizeSearch || !multilineOptions || hasNoValue) return this.clearSelectedDisplay();\n\n if (!firstSelectedOptionElement || firstSelectedOptionElement.display) return this.clearSelectedDisplay();\n\n // Clone selected option and remove elements with hide-on-select attribute\n const selectionClone = firstSelectedOptionElement.firstElementChild.cloneNode(true) as HTMLElement;\n selectionClone.querySelectorAll('[hide-on-select]').forEach(element => element.remove());\n\n if (namedSlot) {\n const height = namedSlot.clientHeight === 0 ? 'auto' : `${namedSlot.clientHeight}px`;\n namedSlot.style.setProperty('--comp-selected-display-height', height);\n if (namedSlot.firstElementChild.outerHTML !== selectionClone.outerHTML) {\n namedSlot.replaceChild(selectionClone, namedSlot.firstElementChild);\n }\n } else {\n namedSlot = document.createElement('div');\n namedSlot.slot = '_selected-display';\n namedSlot.appendChild(selectionClone);\n this.hostElement.appendChild(namedSlot);\n }\n return namedSlot;\n }\n\n checkSelectedDisplayHeight() {\n const { selectedDisplaySlot } = this;\n if (!selectedDisplaySlot) return;\n selectedDisplaySlot.style.setProperty('--comp-selected-display-height', '44px');\n }\n\n checkSelectedOptions() {\n const { multiple, selectedOptions, value } = this;\n this.optionElements.forEach(option => {\n if (multiple) {\n option.selected = selectedOptions.includes(option.value);\n } else {\n option.selected = option.value === value;\n }\n });\n }\n\n clearSearchText() {\n if (!this.searchText) return;\n this.searchText = '';\n this.input.emit({ query: '' });\n }\n\n clearSelectedDisplay() {\n this.selectedDisplaySlot?.remove();\n }\n\n clearValue() {\n const { multiple } = this;\n this.value = '';\n this.selectedOptions = [];\n this.change.emit({ value: multiple ? undefined : '', selectedOptions: multiple ? [] : undefined });\n }\n\n clickedElsewhere = (event: CustomEvent) => {\n const target = event.target as HTMLClickElsewhereElement;\n if (target.localName !== 'click-elsewhere') return;\n event.stopPropagation();\n };\n\n closeDropdown() {\n this.open = false;\n this.clearSearchText();\n }\n\n async executeActionSheet(event: MouseEvent | KeyboardEvent) {\n const result = await showActionSheetList(this, event);\n this.focusInput();\n this.handleSelectionChanges(result);\n }\n\n focusInput() {\n this.inputField?.dispatchEvent(new FocusEvent('focus'));\n }\n\n handleSelectionChanges(changeDetails: { value?: string; values?: IOptionValue[] }) {\n const { value = '', values = [] } = changeDetails;\n const selectedOptionValues = values.map(value => value.value);\n const { multiple } = this;\n if (!this.hostElement.onchange) {\n this.selectedOptions = selectedOptionValues;\n }\n\n this.change.emit({\n value: multiple ? undefined : value,\n selectedOptions: multiple ? selectedOptionValues : undefined,\n });\n }\n\n inputBlurHandler = () => {\n this.inputFocused = false;\n };\n\n inputChangeHandler = (event: Event) => {\n event.stopPropagation();\n };\n\n inputClickHandler = async (event: MouseEvent) => {\n event.stopPropagation();\n if (shouldShowActionSheet(this)) {\n return this.executeActionSheet(event);\n }\n this.toggleDropdown();\n this.focusInput();\n };\n\n inputFocusHandler = () => {\n this.inputFocused = true;\n };\n\n inputInputHandler = (event: Q2InputCustomEvent<IEventDetail> & InputEvent) => {\n event.stopPropagation();\n const eventValue = event.detail.value;\n const shouldClearValue = !!this.value;\n\n if (shouldClearValue) this.clearValue();\n if (!this.open) this.openDropdownWithoutActiveElement();\n\n this.prioritizeSearch = true;\n this.searchText = eventValue;\n this.input.emit({ query: eventValue });\n };\n\n inputKeydownHandler = (event: KeyboardEvent) => {\n if (this.readonly || this.disabled) return;\n const { key, shiftKey } = event;\n const isShiftTab = key === 'Tab' && shiftKey;\n const hasSlot = this.hasPopoverTop || this.hasPopoverBottom;\n if (hasSlot && (key === 'Tab' || isShiftTab)) return;\n\n // slots are incompatible with action sheet\n if (shouldShowActionSheet(this, event) && !hasSlot) {\n return this.executeActionSheet(event);\n }\n\n const keysForOptionListToHandle = [\n 'ArrowDown',\n 'ArrowUp',\n 'PageDown',\n 'PageUp',\n 'Home',\n 'End',\n 'Escape',\n 'Tab',\n ];\n\n if (this.searchable && (key === ' ' || key === 'Enter') && this.inputField.value == '') {\n event.preventDefault();\n if (!this.open) this.openDropdownWithoutActiveElement();\n }\n\n if (this.searchable && !keysForOptionListToHandle.includes(key)) return;\n if (this.shouldClearSearchText(event)) this.clearSearchText();\n\n // Prevent click event from firing when spacebar is pressed\n if (key === ' ') event.preventDefault();\n\n this.optionList.handleExternalKeydown(event);\n };\n\n onCustomDisplayClick = (event: MouseEvent) => {\n event.stopPropagation();\n this.focusInput();\n this.toggleDropdown();\n };\n\n onMutationObserved = () => {\n const { hostElement, hasPopoverTop, hasPopoverBottom } = this;\n const slotContainer = hostElement.querySelector('.custom-display-content');\n const displaySlot = hostElement.shadowRoot.querySelector<HTMLSlotElement>('slot[name=\"q2-select-display\"]');\n const hasCustomDisplay = !!displaySlot\n ? displaySlot.assignedNodes().length > 0\n : slotContainer.children.length > 0;\n\n if (this.hasCustomDisplay !== hasCustomDisplay) {\n this.hasCustomDisplay = hasCustomDisplay;\n }\n\n const popTopSlot = hostElement.shadowRoot.querySelector<HTMLSlotElement>('slot[name=\"popover-top\"]');\n const topSlotHasNode = popTopSlot?.assignedNodes().length > 0;\n if (hasPopoverTop !== topSlotHasNode) {\n this.hasPopoverTop = topSlotHasNode;\n }\n\n const popBottomSlot = hostElement.shadowRoot.querySelector<HTMLSlotElement>('slot[name=\"popover-bottom\"]');\n const bottomSlotHasNode = popBottomSlot?.assignedNodes().length > 0;\n if (hasPopoverBottom !== bottomSlotHasNode) {\n this.hasPopoverBottom = bottomSlotHasNode;\n }\n\n this.checkSelectedOptions();\n };\n\n onOptionListChange = (event: Q2OptionListCustomEvent<{ value: string; values: IOptionValue[] }>) => {\n event.stopPropagation();\n const { values } = event.detail;\n\n if (values.length === 0) this.showAllOptions();\n this.handleSelectionChanges(event.detail);\n };\n\n onPopoverState = ({\n detail: { open, action },\n }: CustomEvent<{ open: boolean; action: 'close' | 'select' | 'open' }>) => {\n if (!open || this.searchText) {\n if (action !== 'select') {\n this.optionList.setActiveElement(null);\n }\n this.inputField.focus();\n }\n\n if (this.open === open) return;\n this.open = open;\n };\n\n openDropdownWithoutActiveElement() {\n if (this.readonly || this.disabled) return;\n this.optionList.setActiveElement(null);\n this.open = true;\n }\n\n setStatusMessage(message) {\n clearTimeout(this.statusMessageTimer);\n this.statusMessage = '';\n this.statusMessageTimer = setTimeout(() => {\n this.statusMessage = message;\n }, 1000);\n }\n\n shouldClearSearchText(event: KeyboardEvent) {\n return this.searchable && !!this.searchText && event.key === 'Escape';\n }\n\n showAllOptions = () => {\n this.showSelected = false;\n };\n\n showSelectedOptions = () => {\n this.showSelected = true;\n };\n\n toggleDropdown() {\n if (this.readonly || this.disabled) return;\n\n if (this.open && !this.searchText) {\n this.closeDropdown();\n } else {\n this.openDropdownWithoutActiveElement();\n }\n }\n\n visibilityToggleKeyDown = (event: KeyboardEvent) => {\n const key = event.key;\n const isShiftTab = key === 'Tab' && event.shiftKey;\n const isRadioControlKey = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(key);\n if (isRadioControlKey) event.stopPropagation();\n if (isShiftTab) {\n event.stopPropagation();\n // allows shift+tab keys to select the top slot when present\n if (this.hasPopoverTop) return;\n\n this.optionList.setDefaultActiveElement();\n }\n };\n\n // #endregion\n // #region Render Methods\n\n renderCustomDisplay() {\n const hasSelectedDisplay = this.checkSelectedDisplay();\n if (!hasSelectedDisplay) return;\n this.checkSelectedDisplayHeight();\n\n return (\n <slot\n name=\"_selected-display\"\n slot=\"custom-display\"\n />\n );\n }\n\n renderOptionsDropdown() {\n return (\n <q2-popover\n ref={el => (this.popoverElement = el)}\n controlElement={this.innerInputContainer}\n open={this.open}\n max-height={this.popoverMaxHeight}\n minHeight={this.popoverMinHeight}\n direction={this.popDirection}\n mode={this.popoverMode || undefined}\n block\n >\n <div class=\"popover-content\">\n <q2-option-list\n onPopoverState={this.onPopoverState}\n ref={el => (this.optionList = el)}\n type=\"listbox\"\n id=\"option-list\"\n show-selected={this.showSelected}\n label={this.listLabel}\n multiple={this.multiple}\n selectedOptions={this.structuredSelectedOptions}\n onChange={this.onOptionListChange}\n >\n <slot />\n </q2-option-list>\n <div\n class=\"popover-top-container\"\n ref={el => (this.popoverTopContainer = el)}\n hidden={!this.multiple && !this.hasPopoverTop}\n tabindex=\"-1\"\n >\n <slot name=\"popover-top\"></slot>\n {this.multiple && this.renderVisibilityToggle()}\n </div>\n </div>\n <div\n class=\"popover-bottom-container\"\n hidden={!this.hasPopoverBottom}\n tabindex=\"-1\"\n >\n <slot name=\"popover-bottom\" />\n </div>\n </q2-popover>\n );\n }\n\n renderVisibilityToggle() {\n const selectedOptionsCount = this.selectedOptions?.length ?? 0;\n const { showSelected } = this;\n return (\n <div class=\"multi-select-header\">\n <fieldset>\n <legend aria-label={loc('tecton.element.select.multiHeader.showing')}>\n {loc('tecton.element.select.multiHeader.showing')}\n </legend>\n <div>\n <input\n class=\"sr\"\n type=\"radio\"\n id=\"all\"\n name=\"viewDisplay\"\n value=\"all\"\n checked={!showSelected}\n aria-label={loc('tecton.element.select.multiHeader.allAriaLabel')}\n test-id=\"allOptionsButton\"\n onClick={this.showAllOptions}\n onKeyDown={this.visibilityToggleKeyDown}\n />\n <label htmlFor=\"all\">{loc('tecton.element.select.multiHeader.all')}</label>\n </div>\n\n <div>\n <input\n class=\"sr\"\n type=\"radio\"\n id=\"selected\"\n disabled={selectedOptionsCount === 0}\n name=\"viewDisplay\"\n value=\"selected\"\n aria-label={loc('tecton.element.select.multiHeader.selectedAriaLabel', [\n selectedOptionsCount,\n ])}\n checked={showSelected}\n test-id=\"selectedOptionsButton\"\n onClick={this.showSelectedOptions}\n onKeyDown={this.visibilityToggleKeyDown}\n />\n <label htmlFor=\"selected\">\n {loc('tecton.element.select.multiHeader.selected', [selectedOptionsCount])}\n </label>\n </div>\n </fieldset>\n </div>\n );\n }\n\n render() {\n return (\n <click-elsewhere\n class={this.wrapperClasses}\n onChange={this.clickedElsewhere}\n >\n <div\n aria-live=\"polite\"\n aria-atomic=\"true\"\n role=\"status\"\n class=\"sr\"\n >\n {this.statusMessage}\n </div>\n <q2-input\n ref={el => (this.inputField = el)}\n class=\"q2-select-input\"\n label={(this.label && loc(this.label)) || ''}\n value={this.selectedDisplay}\n clearable={(this.clearable && (!!this.value || !!this.selectedOptions?.length)) || undefined}\n errors={\n (Array.isArray(this.errors) &&\n this.errors.length > 0 &&\n this.errors.map(error => loc(error))) ||\n (this.invalid && ['tecton.element.select.invalid']) ||\n []\n }\n disabled={this.disabled}\n optional={this.optional}\n readonly={!!this.readonly}\n placeholder={this.placeholder || undefined}\n hideLabel={this.hideLabel}\n ariaExpanded={`${this.open}`}\n ariaControls=\"option-list\"\n ariaHaspopup=\"listbox\"\n test-id=\"toggleDropdown\"\n hide-messages\n iconRight=\"chevron-down\"\n onClick={this.inputClickHandler}\n onInput={this.inputInputHandler}\n onKeyDown={this.inputKeydownHandler}\n onFocus={this.inputFocusHandler}\n onBlur={this.inputBlurHandler}\n onChange={this.inputChangeHandler}\n badgeValue={this.badgeValue}\n badgeTheme={this.inputFocused ? 'primary' : undefined}\n _role=\"combobox\"\n _preventEntry={!this.searchable}\n >\n {this.renderCustomDisplay()}\n </q2-input>\n <div\n class=\"custom-display-content\"\n hidden={!this.hasCustomDisplay || !!this.searchText}\n onClick={this.onCustomDisplayClick}\n >\n <slot name=\"q2-select-display\" />\n </div>\n {this.renderOptionsDropdown()}\n </click-elsewhere>\n );\n }\n\n // #endregion\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["q2SelectCss","Q2SelectStyle0","Q2Select","this","scheduledAfterRender","clickedElsewhere","event","target","localName","stopPropagation","inputBlurHandler","inputFocused","inputChangeHandler","inputClickHandler","async","shouldShowActionSheet","executeActionSheet","toggleDropdown","focusInput","inputFocusHandler","inputInputHandler","eventValue","detail","value","shouldClearValue","clearValue","open","openDropdownWithoutActiveElement","prioritizeSearch","searchText","input","emit","query","inputKeydownHandler","readonly","disabled","key","shiftKey","isShiftTab","hasSlot","hasPopoverTop","hasPopoverBottom","keysForOptionListToHandle","searchable","inputField","preventDefault","includes","shouldClearSearchText","clearSearchText","optionList","handleExternalKeydown","onCustomDisplayClick","onMutationObserved","hostElement","slotContainer","querySelector","displaySlot","shadowRoot","hasCustomDisplay","assignedNodes","length","children","popTopSlot","topSlotHasNode","popBottomSlot","bottomSlotHasNode","checkSelectedOptions","onOptionListChange","values","showAllOptions","handleSelectionChanges","onPopoverState","action","setActiveElement","focus","showSelected","showSelectedOptions","visibilityToggleKeyDown","isRadioControlKey","setDefaultActiveElement","_a","window","Tecton","useActionSheets","loc","disconnectedCallback","mutationObserver","disconnect","componentWillLoad","handleAriaLabel","buildStructuredSelectedOptions","handleMultilineOptionsUpdate","multilineOptions","componentDidLoad","observer","MutationObserver","observe","childList","subtree","overrideFocus","setTimeout","checkSelectedDisplay","componentDidRender","forEach","fn","onHostElementChange","onchange","multiple","selectedOptions","onClearHandler","handleSelectedDisplay","display","delegateFocus","fromHost","isRelatedTargetWithinHost","clearSelectedDisplay","isEventFromElement","handleFocusout","relatedTarget","isLeavingHost","popoverElement","contains","closeDropdown","onHostElementInput","oninput","options","optionElements","trim","toLocaleLowerCase","matchedCount","option","hidden","title","firstElementChild","tagName","innerText","searchParams","matched","some","text","statusMessageLocString","count","setStatusMessage","keydownHandler","closePopover","_togglePopover","openPopover","searchOptions","innerInputField","dispatchEvent","FocusEvent","InputEvent","setValue","valuesSet","Set","Array","isArray","waitForNextPaint","find","click","ariaLabelObserver","newValue","oldValue","element","multiline","openChanged","isOpen","push","popoverTopContainer","height","offsetHeight","style","setProperty","removeProperty","structuredSelectedOptions","map","valueUpdated","badgeValue","optionsLength","_b","firstSelectedOptionElement","firstSelectedValue","innerInputContainer","from","querySelectorAll","popoverMinHeight","minRows","firstOption","minHeight","getComputedStyle","parseInt","selectedDisplay","calculateMultiSelectSelectedDisplay","calculateSingleSelectSelectedDisplay","selectedDisplaySlot","wrapperClasses","errors","classes","join","_c","textContent","namedSlot","hasNoValue","selectionClone","cloneNode","remove","clientHeight","outerHTML","replaceChild","document","createElement","slot","appendChild","checkSelectedDisplayHeight","selected","change","undefined","result","showActionSheetList","changeDetails","selectedOptionValues","message","clearTimeout","statusMessageTimer","statusMessage","renderCustomDisplay","hasSelectedDisplay","h","name","renderOptionsDropdown","ref","el","controlElement","popoverMaxHeight","direction","popDirection","mode","popoverMode","block","class","type","id","label","listLabel","onChange","tabindex","renderVisibilityToggle","selectedOptionsCount","checked","onClick","onKeyDown","htmlFor","render","role","clearable","error","invalid","optional","placeholder","hideLabel","ariaExpanded","ariaControls","ariaHaspopup","iconRight","onInput","onFocus","onBlur","badgeTheme","_role","_preventEntry"],"sources":["src/components/q2-select/q2-select.scss?tag=q2-select&encapsulation=shadow","src/components/q2-select/q2-select.tsx"],"sourcesContent":["@import '../../styles/host.scss';\n@import '../../styles/functions';\n@import '../../styles/dropdowns';\n\n:host {\n --comp-select-margin: #{var-list(\n --tct-select-margin,\n unquote(\n '#{var-list(var-prefixer(select-margin-top), --app-scale-4, 30px)} 0 #{var-list(var-prefixer(select-margin-bottom), --app-scale-4, 30px)}'\n )\n )};\n display: block;\n margin: var(--comp-select-margin);\n}\n\n.q2-select-container {\n position: relative;\n display: block;\n}\n\n.q2-select-input {\n margin: 0;\n\n --tct-input-min-height: #{var-list(var-prefixer(select-input-min-height))};\n --tct-input-max-height: #{var-list(var-prefixer(select-input-max-height), none)};\n}\n\n::slotted([slot='_selected-display']) {\n width: 100%;\n min-height: var(--comp-selected-display-height, 44px);\n}\n\n.custom-display-content {\n position: absolute;\n bottom: 0;\n left: calc(var-list(--tct-scale-2, --app-scale-2x, 10px) + 1px);\n height: 44px;\n width: calc(100% - 34px - var-list(--tct-scale-3, --app-scale-3x, 15px));\n overflow: hidden;\n cursor: pointer;\n transition: left var-list(--tct-tween-2, --app-tween-1, unquote('0.2s ease'));\n}\n\n.custom-display-content:not([hidden]) {\n display: flex;\n align-items: center;\n}\n\n.is-searchable.is-focused .custom-display-content,\n.is-searchable .custom-display-content:active {\n left: calc(var-list(--tct-scale-3, --app-scale-3x, 15px) + 1px);\n}\n\n.has-error .custom-display-content {\n width: calc(100% - 68px - var-list(--tct-scale-3, --app-scale-3x, 15px));\n}\n\n.popover-content {\n display: flex;\n flex-direction: column-reverse;\n}\n\n.popover-bottom-container {\n position: sticky;\n bottom: 0;\n z-index: 5;\n}\n\n.popover-top-container {\n position: sticky;\n top: 0;\n z-index: 5;\n .multi-select-header {\n padding: var(--tct-scale-2, var(--app-scale-2x, 10px)) var(--tct-scale-2, var(--app-scale-2x, 10px));\n background: var(--app-white);\n display: flex;\n gap: var-list(--app-scale-2x, 10px);\n align-items: center;\n\n fieldset {\n margin: 0;\n padding: 0;\n border: 0;\n display: flex;\n gap: var-list(--app-scale-2x, 10px);\n }\n\n legend {\n padding: 0;\n float: left;\n }\n\n label {\n cursor: pointer;\n padding: var-list(\n var-prefixer(select-multi-select-option-padding),\n var-prefixer(btn-badge-padding),\n unquote('2px 5px')\n );\n font-size: var-list(\n var-prefixer(select-multi-select-option-font-size),\n var-prefixer(btn-badge-font-size),\n inherit\n );\n border-radius: var-list(\n var-prefixer(select-multi-select-option-radius),\n var-prefixer(btn-badge-border-radius),\n --app-border-radius-1,\n 4px\n );\n background: var-list(\n --tct-select-multi-select-option-background,\n var-prefixer(select-multi-select-option-bg),\n --tct-badge-background,\n var-prefixer(btn-badge-bg),\n transparent\n );\n color: var-list(\n var-prefixer(select-multi-select-option-color),\n var-prefixer(btn-badge-font-color),\n inherit\n );\n\n &:hover {\n background: var-list(\n --tct-select-multi-select-option-hover-background,\n var-prefixer(select-multi-select-option-hover-background-color),\n var-prefixer(btn-badge-hover-bg),\n var-prefixer(gray-14),\n --app-gray-l3,\n #f2f2f2\n );\n color: var-list(\n --tct-select-multi-select-option-hover-color,\n var-prefixer(select-multi-select-option-color),\n var-prefixer(btn-badge-hover-font-color),\n var-prefixer(gray-5),\n --app-gray-d2,\n #404040\n );\n }\n }\n\n input {\n &:checked + label {\n &,\n &:enabled:hover {\n background: var-list(\n --tct-select-multi-select-option-active-background,\n var-prefixer(select-multi-select-option-active-background-color),\n var-prefixer(btn-primary-bg),\n #2e2e2e\n );\n color: var-list(\n var-prefixer(select-multi-select-option-active-color),\n var-prefixer(btn-primary-font-color),\n --app-white,\n #ffffff\n );\n }\n }\n\n &:disabled + label {\n opacity: var-list(\n var-prefixer(select-multi-select-option-disabled-opacity),\n var-prefixer(btn-disabled-opacity),\n --app-disabled-opacity,\n 0.4\n );\n cursor: not-allowed;\n }\n\n &:focus + label {\n box-shadow: var(--const-double-focus-ring);\n }\n }\n }\n}\n","import {\n Component,\n Prop,\n Element,\n h,\n Listen,\n State,\n EventEmitter,\n Event,\n ComponentInterface,\n Watch,\n Method,\n} from '@stencil/core';\nimport { IEventDetail, Q2InputCustomEvent, Q2OptionListCustomEvent } from 'src/components';\nimport {\n handleAriaLabel,\n isEventFromElement,\n isRelatedTargetWithinHost,\n loc,\n overrideFocus,\n waitForNextPaint,\n} from '../../utils';\nimport { IOptionValue } from '../q2-option-list/q2-option-list';\nimport { shouldShowActionSheet, showActionSheetList } from 'src/utils/action-sheet';\n\n@Component({ tag: 'q2-select', shadow: true, styleUrl: 'q2-select.scss' })\nexport class Q2Select implements ComponentInterface {\n // #region Own Properties\n\n inputField?: HTMLQ2InputElement;\n mutationObserver: MutationObserver;\n optionList: HTMLQ2OptionListElement;\n popoverElement?: HTMLQ2PopoverElement;\n popoverTopContainer?: HTMLDivElement;\n scheduledAfterRender: (() => void)[] = [];\n statusMessageTimer: NodeJS.Timeout;\n\n // #endregion\n // #region Host HTML Element\n\n @Element()\n hostElement: HTMLElement;\n\n // #endregion\n // #region State Properties\n\n @State()\n hasCustomDisplay: boolean = false;\n\n @State()\n hasPopoverBottom: boolean = false;\n\n @State()\n hasPopoverTop: boolean = false;\n\n @State()\n inputFocused: boolean = false;\n\n @State()\n open: boolean = false;\n\n @State()\n prioritizeSearch: boolean = false;\n\n @State()\n searchText: string = '';\n\n @State()\n showSelected: boolean = false;\n\n @State()\n statusMessage: string;\n\n @State()\n structuredSelectedOptions: IOptionValue[] = [];\n\n // #endregion\n // #region Public Property API\n\n /** @deprecated */\n @Prop({ reflect: true, mutable: true })\n ariaLabel: string;\n\n /** Renders an icon button when the field is non-empty. Pressing the button clears all input from the field. */\n @Prop({ reflect: true })\n clearable: boolean;\n\n /** Disables all interaction with the field and leverages the disabled visual style of `q2-input`. */\n @Prop({ reflect: true })\n disabled: boolean = false;\n\n /**\n * The presence of `errors` will mark the field as invalid, putting it into an error state.\n * @localizable\n */\n @Prop()\n errors: string[];\n\n /**\n * Hide's the field's `<label>` element from view.\n * @warning\n * Only use when a visible label is impractical.\n */\n @Prop({ reflect: true, mutable: true })\n hideLabel: boolean;\n\n /**\n * Instructs the component to use the action sheet workflow for displaying its options.\n *\n * For more information, see [Action Sheets](https://tecton.q2developer.com/guides/action-sheets/).\n * @warning\n * If your `q2-select` renders inside of an iframe, and you are using multiline/robust content options,\n * any custom CSS you apply to your options will not get passed up to the platform which displays the action sheet.\n * For this reason, we strongly suggest using the [q2-card](https://tecton.q2developer.com/design-system/q2-card/) component since its styling is managed by Tecton.\n */\n @Prop()\n hoist: boolean = !!window.Tecton?.useActionSheets;\n\n /** Determines whether to show an error state. Its primary use-case is for an unfilled field. */\n @Prop({ reflect: true })\n invalid: boolean;\n\n /**\n * The text that will be used as the label for the field.\n * @localizable\n */\n @Prop({ reflect: true, mutable: true })\n label: string;\n\n /**\n * Determines the label that is applied to the option list for accessibility purposes.\n * @localizable\n */\n @Prop()\n listLabel: string = loc('tecton.element.select.listLabel');\n\n /** The minimum number of rows the component will try to display below or above the component when opened. */\n @Prop()\n minRows: number = 3;\n\n /** Enables text wrapping for `q2-option` elements. When `false`, the text truncates and does not wrap. */\n @Prop({ reflect: true })\n multilineOptions: boolean = false;\n\n /** Enables multi-select functionality. */\n @Prop({ reflect: true })\n multiple: boolean = false;\n\n /** Appends \"(optional)\" to the field label, and sets `aria-required` on the nested input tag to `false`. */\n @Prop({ reflect: true })\n optional: boolean = false;\n\n /**\n * Text that appears within the field when it is blurred and empty.\n * Placeholder text disappears when the user selects an option.\n * @localizable\n */\n @Prop({ reflect: true })\n placeholder: string;\n\n /** @deprecated */\n @Prop({ reflect: true })\n popDirection: 'up' | 'down';\n\n /**\n * Force the maximum height of the popover. This value will be interpreted as pixels.\n * If no value is passed, or the value exceeds available space, the component will auto-detect the maximum height based on available space.\n */\n @Prop()\n popoverMaxHeight: number;\n\n /**\n * Determines the display mode of the popover.\n *\n * Providing a value of `legacy` instructs the popover to use absolute positioning instead of fixed positioning.\n *\n * @info\n * This is a temporary solution to work around styling issues related to using fixed positioning for the popover\n * when nested inside of elements with transform properties. This will be removed once the popover API is available\n * for use.\n */\n @Prop({ mutable: true })\n popoverMode: 'legacy' = null;\n\n /**\n * Appends \"(read only)\" to the field label, and field becomes unusable, but remains focusable.\n * Takes priority over `optional` if both are `true`.\n */\n @Prop({ reflect: true })\n readonly: boolean = false;\n\n /** Enables search functionality. */\n @Prop({ reflect: true })\n searchable: boolean = false;\n\n /**\n * Each item in this array should correspond to the value of a `q2-option` element.\n * This property is only relevant for `multiple` (i.e., multi-select) implementations.\n */\n @Prop({ mutable: true })\n selectedOptions: string[] = [];\n\n /**\n * The current value for the select. This should correspond to the value of a nested q2-option element.\n * This property is only relevant for single-select implementations.\n */\n @Prop({ mutable: true })\n value: string;\n\n // #endregion\n // #region Events\n\n /**\n * Emitted when an option is selected or deselected.\n *\n * When the multi-select is enabled, the `value` property will be `undefined` and the `selectedOptions` property\n * will contain the selected option values.\n *\n * @legacyEvent\n */\n @Event()\n change: EventEmitter<{ value: string; selectedOptions: string[] }>;\n\n /**\n * Emitted when the input value changes.\n *\n * Requires the `searchable` prop to be set to `true`.\n */\n @Event()\n input: EventEmitter<{ query: string }>;\n\n // #endregion\n // #region Component Lifecycle Events\n\n disconnectedCallback() {\n this.mutationObserver?.disconnect();\n this.mutationObserver = null;\n }\n\n componentWillLoad() {\n handleAriaLabel(this);\n this.buildStructuredSelectedOptions();\n this.handleMultilineOptionsUpdate(this.multilineOptions, false);\n }\n\n componentDidLoad() {\n const observer = new MutationObserver(this.onMutationObserved);\n observer.observe(this.hostElement, { childList: true, subtree: true });\n this.mutationObserver = observer;\n this.onMutationObserved();\n overrideFocus(this.hostElement);\n setTimeout(() => this.checkSelectedDisplay(), 0);\n }\n\n componentDidRender() {\n setTimeout(() => {\n this.scheduledAfterRender.forEach(fn => fn());\n this.scheduledAfterRender = [];\n }, 25);\n }\n\n // #endregion\n // #region Listeners\n\n @Listen('change')\n onHostElementChange(event: CustomEvent<{ value: string; selectedOptions: string[] }>) {\n if (this.readonly || this.disabled) return;\n if (event.target !== this.hostElement || this.hostElement.onchange) return;\n if (this.multiple) {\n this.value = null;\n this.selectedOptions = event.detail.selectedOptions;\n } else {\n this.value = event.detail.value;\n this.selectedOptions = [];\n }\n }\n\n @Listen('clear')\n onClearHandler() {\n this.clearValue();\n }\n\n @Listen('displayChanged')\n handleSelectedDisplay(event: CustomEvent) {\n if (!this.multiple && !!this.value && this.value === event.detail.value) {\n this.inputField.value = event.detail.display;\n }\n }\n\n @Listen('focus')\n delegateFocus(event: FocusEvent) {\n const fromHost = isRelatedTargetWithinHost(event, this.hostElement);\n const prioritizeSearch = (this.prioritizeSearch = fromHost && this.searchable);\n if (prioritizeSearch) {\n this.clearSelectedDisplay();\n } else if (isEventFromElement(event, this.hostElement)) {\n this.inputField.shadowRoot.querySelector<HTMLElement>('.input-field').focus();\n }\n }\n\n @Listen('focusout')\n handleFocusout(event: FocusEvent) {\n const relatedTarget = event.relatedTarget as HTMLElement;\n const isLeavingHost =\n !this.popoverElement?.contains(relatedTarget) && !this.hostElement.contains(relatedTarget);\n if (isLeavingHost) this.closeDropdown();\n this.prioritizeSearch = !isLeavingHost && this.searchable;\n }\n\n @Listen('input')\n onHostElementInput(event: CustomEvent) {\n if (!this.searchable || event.target !== this.hostElement || this.hostElement.oninput) return;\n const options = this.optionElements;\n const query = this.searchText.trim().toLocaleLowerCase();\n let matchedCount = 0;\n options.forEach(option => {\n if (query === '') {\n option.hidden = false;\n return;\n }\n\n const title =\n option.firstElementChild?.tagName === 'Q2-CARD'\n ? (option.firstElementChild as HTMLQ2CardElement).title\n : null;\n const { display = '', innerText = '' } = option;\n const searchParams = [display, title, innerText];\n const matched = searchParams.some(text => text?.toLocaleLowerCase().includes(query) ?? false);\n\n option.hidden = !matched;\n if (matched) matchedCount++;\n });\n\n const statusMessageLocString = query\n ? 'tecton.element.select.searchable.results'\n : 'tecton.element.select.allOptions';\n const count = query ? matchedCount : options.length;\n this.setStatusMessage(loc(statusMessageLocString, [count]));\n }\n\n @Listen('keydown')\n keydownHandler(event: KeyboardEvent) {\n this.inputKeydownHandler(event);\n }\n\n // #endregion\n // #region Public Methods API\n\n /**\n * Emulates clicking the `<input>` to hide the popover if it is visible.\n *\n * @testOnly\n */\n @Method()\n async closePopover() {\n if (!this.open || this.disabled) return;\n this._togglePopover();\n }\n\n /**\n * Emulates clicking the `<input>` to display the popover if it is hidden.\n *\n * @testOnly\n */\n @Method()\n async openPopover() {\n if (this.open || this.disabled) return;\n this._togglePopover();\n }\n\n /**\n * Emulates focusing the `<input>`, entering the provided value, and emitting an `input` event.\n *\n * @warning\n * Only applicable when the input is searchable.\n *\n * @testOnly\n */\n @Method()\n searchOptions(query: string) {\n if (!this.searchable) return;\n\n const { innerInputField } = this;\n innerInputField.focus();\n innerInputField.dispatchEvent(new FocusEvent('focus'));\n innerInputField.value = query;\n innerInputField.dispatchEvent(new InputEvent('input'));\n }\n\n /**\n * Emulates clicking the `<input>` to display the popover and selecting the option(s) with the specified value(s).\n *\n * If the multi-select is enabled and the `closePopover` argument is `true` (default), the popover will be closed\n * after the option(s) are selected.\n *\n * @testOnly\n */\n @Method()\n async setValue(values: string | string[], options: { closePopover?: boolean } = { closePopover: true }) {\n const valuesSet = new Set(Array.isArray(values) ? values : [values]);\n if (!this.open) {\n await this.openPopover();\n await waitForNextPaint();\n }\n\n valuesSet.forEach(value => {\n this.optionElements.find(option => option.value === value)?.click();\n });\n\n if (options.closePopover) {\n await this.closePopover();\n await waitForNextPaint();\n }\n }\n\n // #endregion\n // #region Watchers\n\n @Watch('ariaLabel')\n ariaLabelObserver() {\n handleAriaLabel(this);\n }\n\n @Watch('multilineOptions')\n handleMultilineOptionsUpdate(newValue, oldValue) {\n if (newValue === oldValue) return;\n this.optionElements.forEach(element => (element.multiline = newValue));\n }\n\n @Watch('open')\n openChanged(isOpen: boolean) {\n this.scheduledAfterRender.push(async () => {\n await waitForNextPaint();\n const { popoverTopContainer, popoverElement } = this;\n const height = (isOpen && popoverTopContainer?.offsetHeight) || 0;\n if (height) {\n popoverElement.style.setProperty('--comp-popover-top-container-height', `${height}px`);\n } else {\n popoverElement.style.removeProperty('--comp-popover-top-container-height');\n }\n });\n }\n\n @Watch('value')\n @Watch('selectedOptions')\n buildStructuredSelectedOptions() {\n const { multiple, selectedOptions, value } = this;\n if (multiple) {\n this.structuredSelectedOptions = !!selectedOptions?.length\n ? selectedOptions.map(option => (typeof option === 'string' ? { value: option } : option))\n : [];\n } else {\n this.structuredSelectedOptions = value ? [{ value }] : [];\n }\n }\n\n @Watch('value')\n valueUpdated() {\n if (this.multiple) return;\n this.clearSearchText();\n }\n\n // #endregion\n // #region Local Methods\n\n get badgeValue(): string {\n if (!this.multiple) return null;\n const optionsLength = this.selectedOptions?.length ?? 0;\n if (this.open && this.searchable) return optionsLength ? `${optionsLength}` : null;\n else return optionsLength > 1 ? `+${optionsLength - 1}` : null;\n }\n\n get firstSelectedOptionElement() {\n const { firstSelectedValue } = this;\n return firstSelectedValue ? this.optionElements.find(({ value }) => value === firstSelectedValue) : null;\n }\n\n get firstSelectedValue() {\n return this.multiple ? this.selectedOptions?.[0] : this.value;\n }\n\n get innerInputContainer(): HTMLElement {\n return this.inputField?.shadowRoot?.querySelector('.input-container');\n }\n\n get innerInputField(): HTMLInputElement | HTMLButtonElement {\n return this.inputField?.shadowRoot?.querySelector('.input-field');\n }\n\n get optionElements() {\n return Array.from(this.hostElement.querySelectorAll<HTMLQ2OptionElement>('q2-option'));\n }\n\n get popoverMinHeight() {\n const { minRows } = this;\n const firstOption = this.hostElement.querySelector<HTMLQ2OptionElement>('q2-option:not([hidden])');\n let minHeight = firstOption && window.getComputedStyle(firstOption).minHeight;\n\n // Safari doesn't return a min-height for non-visible items\n if (!minHeight || minHeight === '0px') minHeight = '44px';\n\n return minRows * parseInt(minHeight);\n }\n\n get selectedDisplay() {\n if (this.prioritizeSearch || this.searchText) return this.searchText;\n if (this.hasCustomDisplay) return '';\n return this.multiple ? this.calculateMultiSelectSelectedDisplay() : this.calculateSingleSelectSelectedDisplay();\n }\n\n get selectedDisplaySlot() {\n return this.hostElement.querySelector<HTMLElement>('[slot=\"_selected-display\"]');\n }\n\n get wrapperClasses() {\n const { errors } = this;\n const classes = ['q2-select-container'];\n if (Array.isArray(errors) && errors.length > 0) classes.push('has-error');\n if (this.inputFocused) classes.push('is-focused');\n if (this.searchable) classes.push('is-searchable');\n return classes.join(' ');\n }\n\n _togglePopover() {\n const { innerInputField } = this;\n innerInputField?.click();\n innerInputField?.focus();\n innerInputField.dispatchEvent(new FocusEvent('focus'));\n }\n\n calculateMultiSelectSelectedDisplay() {\n const { firstSelectedOptionElement, firstSelectedValue, multilineOptions } = this;\n if (!firstSelectedValue) return '';\n if (firstSelectedOptionElement?.display) return loc(firstSelectedOptionElement.display);\n if (multilineOptions && this.searchable) return this.searchText;\n if (multilineOptions) return '';\n return (\n firstSelectedOptionElement?.textContent?.trim() ?? firstSelectedOptionElement?.value ?? firstSelectedValue\n );\n }\n\n calculateSingleSelectSelectedDisplay() {\n const { firstSelectedOptionElement, multilineOptions } = this;\n if (multilineOptions) {\n return (firstSelectedOptionElement?.display && loc(firstSelectedOptionElement.display)) || this.value || '';\n } else {\n return (\n (firstSelectedOptionElement?.display && loc(firstSelectedOptionElement.display)) ||\n firstSelectedOptionElement?.textContent?.trim() ||\n this.value ||\n ''\n );\n }\n }\n\n checkSelectedDisplay() {\n let namedSlot = this.selectedDisplaySlot;\n const { value, multiple, selectedOptions, multilineOptions, firstSelectedOptionElement, prioritizeSearch } =\n this;\n const hasNoValue = !value && multiple && !selectedOptions?.length;\n if (prioritizeSearch || !multilineOptions || hasNoValue) return this.clearSelectedDisplay();\n\n if (!firstSelectedOptionElement || firstSelectedOptionElement.display) return this.clearSelectedDisplay();\n\n // Clone selected option and remove elements with hide-on-select attribute\n const selectionClone = firstSelectedOptionElement.firstElementChild.cloneNode(true) as HTMLElement;\n selectionClone.querySelectorAll('[hide-on-select]').forEach(element => element.remove());\n\n if (namedSlot) {\n const height = namedSlot.clientHeight === 0 ? 'auto' : `${namedSlot.clientHeight}px`;\n namedSlot.style.setProperty('--comp-selected-display-height', height);\n if (namedSlot.firstElementChild.outerHTML !== selectionClone.outerHTML) {\n namedSlot.replaceChild(selectionClone, namedSlot.firstElementChild);\n }\n } else {\n namedSlot = document.createElement('div');\n namedSlot.slot = '_selected-display';\n namedSlot.appendChild(selectionClone);\n this.hostElement.appendChild(namedSlot);\n }\n return namedSlot;\n }\n\n checkSelectedDisplayHeight() {\n const { selectedDisplaySlot } = this;\n if (!selectedDisplaySlot) return;\n selectedDisplaySlot.style.setProperty('--comp-selected-display-height', '44px');\n }\n\n checkSelectedOptions() {\n const { multiple, selectedOptions, value } = this;\n this.optionElements.forEach(option => {\n if (multiple) {\n option.selected = selectedOptions.includes(option.value);\n } else {\n option.selected = option.value === value;\n }\n });\n }\n\n clearSearchText() {\n if (!this.searchText) return;\n this.searchText = '';\n this.input.emit({ query: '' });\n }\n\n clearSelectedDisplay() {\n this.selectedDisplaySlot?.remove();\n }\n\n clearValue() {\n const { multiple } = this;\n this.value = '';\n this.selectedOptions = [];\n this.change.emit({ value: multiple ? undefined : '', selectedOptions: multiple ? [] : undefined });\n }\n\n clickedElsewhere = (event: CustomEvent) => {\n const target = event.target as HTMLClickElsewhereElement;\n if (target.localName !== 'click-elsewhere') return;\n event.stopPropagation();\n };\n\n closeDropdown() {\n this.open = false;\n this.clearSearchText();\n }\n\n async executeActionSheet(event: MouseEvent | KeyboardEvent) {\n const result = await showActionSheetList(this, event);\n this.focusInput();\n this.handleSelectionChanges(result);\n }\n\n focusInput() {\n this.inputField?.dispatchEvent(new FocusEvent('focus'));\n }\n\n handleSelectionChanges(changeDetails: { value?: string; values?: IOptionValue[] }) {\n const { value = '', values = [] } = changeDetails;\n const selectedOptionValues = values.map(value => value.value);\n const { multiple } = this;\n if (!this.hostElement.onchange) {\n this.selectedOptions = selectedOptionValues;\n }\n\n this.change.emit({\n value: multiple ? undefined : value,\n selectedOptions: multiple ? selectedOptionValues : undefined,\n });\n }\n\n inputBlurHandler = () => {\n this.inputFocused = false;\n };\n\n inputChangeHandler = (event: Event) => {\n event.stopPropagation();\n };\n\n inputClickHandler = async (event: MouseEvent) => {\n event.stopPropagation();\n if (shouldShowActionSheet(this)) {\n return this.executeActionSheet(event);\n }\n this.toggleDropdown();\n this.focusInput();\n };\n\n inputFocusHandler = () => {\n this.inputFocused = true;\n };\n\n inputInputHandler = (event: Q2InputCustomEvent<IEventDetail> & InputEvent) => {\n event.stopPropagation();\n const eventValue = event.detail.value;\n const shouldClearValue = !!this.value;\n\n if (shouldClearValue) this.clearValue();\n if (!this.open) this.openDropdownWithoutActiveElement();\n\n this.prioritizeSearch = true;\n this.searchText = eventValue;\n this.input.emit({ query: eventValue });\n };\n\n inputKeydownHandler = (event: KeyboardEvent) => {\n if (this.readonly || this.disabled) return;\n const { key, shiftKey } = event;\n const isShiftTab = key === 'Tab' && shiftKey;\n const hasSlot = this.hasPopoverTop || this.hasPopoverBottom;\n if (hasSlot && (key === 'Tab' || isShiftTab)) return;\n\n // slots are incompatible with action sheet\n if (shouldShowActionSheet(this, event) && !hasSlot) {\n return this.executeActionSheet(event);\n }\n\n const keysForOptionListToHandle = [\n 'ArrowDown',\n 'ArrowUp',\n 'PageDown',\n 'PageUp',\n 'Home',\n 'End',\n 'Escape',\n 'Tab',\n ];\n\n if (this.searchable && (key === ' ' || key === 'Enter') && this.inputField.value == '') {\n event.preventDefault();\n if (!this.open) this.openDropdownWithoutActiveElement();\n }\n\n if (this.searchable && !keysForOptionListToHandle.includes(key)) return;\n if (this.shouldClearSearchText(event)) this.clearSearchText();\n\n // Prevent click event from firing when spacebar is pressed\n if (key === ' ') event.preventDefault();\n\n this.optionList.handleExternalKeydown(event);\n };\n\n onCustomDisplayClick = (event: MouseEvent) => {\n event.stopPropagation();\n this.focusInput();\n this.toggleDropdown();\n };\n\n onMutationObserved = () => {\n const { hostElement, hasPopoverTop, hasPopoverBottom } = this;\n const slotContainer = hostElement.querySelector('.custom-display-content');\n const displaySlot = hostElement.shadowRoot.querySelector<HTMLSlotElement>('slot[name=\"q2-select-display\"]');\n const hasCustomDisplay = !!displaySlot\n ? displaySlot.assignedNodes().length > 0\n : slotContainer.children.length > 0;\n\n if (this.hasCustomDisplay !== hasCustomDisplay) {\n this.hasCustomDisplay = hasCustomDisplay;\n }\n\n const popTopSlot = hostElement.shadowRoot.querySelector<HTMLSlotElement>('slot[name=\"popover-top\"]');\n const topSlotHasNode = popTopSlot?.assignedNodes().length > 0;\n if (hasPopoverTop !== topSlotHasNode) {\n this.hasPopoverTop = topSlotHasNode;\n }\n\n const popBottomSlot = hostElement.shadowRoot.querySelector<HTMLSlotElement>('slot[name=\"popover-bottom\"]');\n const bottomSlotHasNode = popBottomSlot?.assignedNodes().length > 0;\n if (hasPopoverBottom !== bottomSlotHasNode) {\n this.hasPopoverBottom = bottomSlotHasNode;\n }\n\n this.checkSelectedOptions();\n };\n\n onOptionListChange = (event: Q2OptionListCustomEvent<{ value: string; values: IOptionValue[] }>) => {\n event.stopPropagation();\n const { values } = event.detail;\n\n if (values.length === 0) this.showAllOptions();\n this.handleSelectionChanges(event.detail);\n };\n\n onPopoverState = ({\n detail: { open, action },\n }: CustomEvent<{ open: boolean; action: 'close' | 'select' | 'open' }>) => {\n if (!open || this.searchText) {\n if (action !== 'select') {\n this.optionList.setActiveElement(null);\n }\n this.inputField.focus();\n }\n\n if (this.open === open) return;\n this.open = open;\n };\n\n openDropdownWithoutActiveElement() {\n if (this.readonly || this.disabled) return;\n this.optionList.setActiveElement(null);\n this.open = true;\n }\n\n setStatusMessage(message) {\n clearTimeout(this.statusMessageTimer);\n this.statusMessage = '';\n this.statusMessageTimer = setTimeout(() => {\n this.statusMessage = message;\n }, 1000);\n }\n\n shouldClearSearchText(event: KeyboardEvent) {\n return this.searchable && !!this.searchText && event.key === 'Escape';\n }\n\n showAllOptions = () => {\n this.showSelected = false;\n };\n\n showSelectedOptions = () => {\n this.showSelected = true;\n };\n\n toggleDropdown() {\n if (this.readonly || this.disabled) return;\n\n if (this.open && !this.searchText) {\n this.closeDropdown();\n } else {\n this.openDropdownWithoutActiveElement();\n }\n }\n\n visibilityToggleKeyDown = (event: KeyboardEvent) => {\n const key = event.key;\n const isShiftTab = key === 'Tab' && event.shiftKey;\n const isRadioControlKey = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(key);\n if (isRadioControlKey) event.stopPropagation();\n if (isShiftTab) {\n event.stopPropagation();\n // allows shift+tab keys to select the top slot when present\n if (this.hasPopoverTop) return;\n\n this.optionList.setDefaultActiveElement();\n }\n };\n\n // #endregion\n // #region Render Methods\n\n renderCustomDisplay() {\n const hasSelectedDisplay = this.checkSelectedDisplay();\n if (!hasSelectedDisplay) return;\n this.checkSelectedDisplayHeight();\n\n return (\n <slot\n name=\"_selected-display\"\n slot=\"custom-display\"\n />\n );\n }\n\n renderOptionsDropdown() {\n return (\n <q2-popover\n ref={el => (this.popoverElement = el)}\n controlElement={this.innerInputContainer}\n open={this.open}\n max-height={this.popoverMaxHeight}\n minHeight={this.popoverMinHeight}\n direction={this.popDirection}\n mode={this.popoverMode || undefined}\n block\n >\n <div class=\"popover-content\">\n <q2-option-list\n onPopoverState={this.onPopoverState}\n ref={el => (this.optionList = el)}\n type=\"listbox\"\n id=\"option-list\"\n show-selected={this.showSelected}\n label={this.listLabel}\n multiple={this.multiple}\n selectedOptions={this.structuredSelectedOptions}\n onChange={this.onOptionListChange}\n >\n <slot />\n </q2-option-list>\n <div\n class=\"popover-top-container\"\n ref={el => (this.popoverTopContainer = el)}\n hidden={!this.multiple && !this.hasPopoverTop}\n tabindex=\"-1\"\n >\n <slot name=\"popover-top\"></slot>\n {this.multiple && this.renderVisibilityToggle()}\n </div>\n </div>\n <div\n class=\"popover-bottom-container\"\n hidden={!this.hasPopoverBottom}\n tabindex=\"-1\"\n >\n <slot name=\"popover-bottom\" />\n </div>\n </q2-popover>\n );\n }\n\n renderVisibilityToggle() {\n const selectedOptionsCount = this.selectedOptions?.length ?? 0;\n const { showSelected } = this;\n return (\n <div class=\"multi-select-header\">\n <fieldset>\n <legend aria-label={loc('tecton.element.select.multiHeader.showing')}>\n {loc('tecton.element.select.multiHeader.showing')}\n </legend>\n <div>\n <input\n class=\"sr\"\n type=\"radio\"\n id=\"all\"\n name=\"viewDisplay\"\n value=\"all\"\n checked={!showSelected}\n aria-label={loc('tecton.element.select.multiHeader.allAriaLabel')}\n test-id=\"allOptionsButton\"\n onClick={this.showAllOptions}\n onKeyDown={this.visibilityToggleKeyDown}\n />\n <label htmlFor=\"all\">{loc('tecton.element.select.multiHeader.all')}</label>\n </div>\n\n <div>\n <input\n class=\"sr\"\n type=\"radio\"\n id=\"selected\"\n disabled={selectedOptionsCount === 0}\n name=\"viewDisplay\"\n value=\"selected\"\n aria-label={loc('tecton.element.select.multiHeader.selectedAriaLabel', [\n selectedOptionsCount,\n ])}\n checked={showSelected}\n test-id=\"selectedOptionsButton\"\n onClick={this.showSelectedOptions}\n onKeyDown={this.visibilityToggleKeyDown}\n />\n <label htmlFor=\"selected\">\n {loc('tecton.element.select.multiHeader.selected', [selectedOptionsCount])}\n </label>\n </div>\n </fieldset>\n </div>\n );\n }\n\n render() {\n return (\n <click-elsewhere\n class={this.wrapperClasses}\n onChange={this.clickedElsewhere}\n >\n <div\n aria-live=\"polite\"\n aria-atomic=\"true\"\n role=\"status\"\n class=\"sr\"\n >\n {this.statusMessage}\n </div>\n <q2-input\n ref={el => (this.inputField = el)}\n class=\"q2-select-input\"\n label={(this.label && loc(this.label)) || ''}\n value={this.selectedDisplay}\n clearable={(this.clearable && (!!this.value || !!this.selectedOptions?.length)) || undefined}\n errors={\n (Array.isArray(this.errors) &&\n this.errors.length > 0 &&\n this.errors.map(error => loc(error))) ||\n (this.invalid && ['tecton.element.select.invalid']) ||\n []\n }\n disabled={this.disabled}\n optional={this.optional}\n readonly={!!this.readonly}\n placeholder={this.placeholder || undefined}\n hideLabel={this.hideLabel}\n ariaExpanded={`${this.open}`}\n ariaControls=\"option-list\"\n ariaHaspopup=\"listbox\"\n test-id=\"toggleDropdown\"\n hide-messages\n iconRight=\"chevron-down\"\n onClick={this.inputClickHandler}\n onInput={this.inputInputHandler}\n onKeyDown={this.inputKeydownHandler}\n onFocus={this.inputFocusHandler}\n onBlur={this.inputBlurHandler}\n onChange={this.inputChangeHandler}\n badgeValue={this.badgeValue}\n badgeTheme={this.inputFocused ? 'primary' : undefined}\n _role=\"combobox\"\n _preventEntry={!this.searchable}\n >\n {this.renderCustomDisplay()}\n </q2-input>\n <div\n class=\"custom-display-content\"\n hidden={!this.hasCustomDisplay || !!this.searchText}\n onClick={this.onCustomDisplayClick}\n >\n <slot name=\"q2-select-display\" />\n </div>\n {this.renderOptionsDropdown()}\n </click-elsewhere>\n );\n }\n\n // #endregion\n}\n"],"mappings":"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"}
|
|
@@ -27,8 +27,10 @@ export declare class Q2FilePicker implements ComponentInterface {
|
|
|
27
27
|
*/
|
|
28
28
|
description: string;
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
30
|
+
* Allowed file types based on extensions (e.g., ['jpg', 'png', 'pdf'] or
|
|
31
|
+
* 'jpg, png, pdf'). When using the attribute, provide a comma-separated
|
|
32
|
+
* string (e.g., 'jpg, png, pdf'). Arrays can only be set programmatically
|
|
33
|
+
* via JavaScript.
|
|
32
34
|
*/
|
|
33
35
|
fileTypes: string[] | string;
|
|
34
36
|
/**
|
|
@@ -1231,7 +1231,7 @@ export namespace Components {
|
|
|
1231
1231
|
*/
|
|
1232
1232
|
"description": string;
|
|
1233
1233
|
/**
|
|
1234
|
-
*
|
|
1234
|
+
* Allowed file types based on extensions (e.g., ['jpg', 'png', 'pdf'] or 'jpg, png, pdf'). When using the attribute, provide a comma-separated string (e.g., 'jpg, png, pdf'). Arrays can only be set programmatically via JavaScript.
|
|
1235
1235
|
*/
|
|
1236
1236
|
"fileTypes": string[] | string;
|
|
1237
1237
|
/**
|
|
@@ -4707,7 +4707,7 @@ declare namespace LocalJSX {
|
|
|
4707
4707
|
*/
|
|
4708
4708
|
"description"?: string;
|
|
4709
4709
|
/**
|
|
4710
|
-
*
|
|
4710
|
+
* Allowed file types based on extensions (e.g., ['jpg', 'png', 'pdf'] or 'jpg, png, pdf'). When using the attribute, provide a comma-separated string (e.g., 'jpg, png, pdf'). Arrays can only be set programmatically via JavaScript.
|
|
4711
4711
|
*/
|
|
4712
4712
|
"fileTypes"?: string[] | string;
|
|
4713
4713
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "q2-tecton-elements",
|
|
3
|
-
"version": "1.54.
|
|
3
|
+
"version": "1.54.1",
|
|
4
4
|
"description": "Q2 Tecton Custom Elements",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Q2 Tecton Team",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@stencil/core": "4.18.0",
|
|
39
|
-
"q2-tecton-common": "1.54.
|
|
39
|
+
"q2-tecton-common": "1.54.1",
|
|
40
40
|
"swiper": "8.4.4"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"typescript": "5.4.5",
|
|
62
62
|
"typescript-eslint": "^7.11.0"
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "d855734a979ef757c8d2a7dd8f7e69224c9fa517"
|
|
65
65
|
}
|