@internetarchive/elements 0.3.0 → 0.4.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/src/elements/ia-audio-element/ia-audio-element.d.ts.map +1 -1
- package/dist/src/elements/ia-audio-element/ia-audio-element.js +2 -1
- package/dist/src/elements/ia-audio-element/ia-audio-element.js.map +1 -1
- package/dist/src/elements/ia-button/ia-button.d.ts.map +1 -1
- package/dist/src/elements/ia-button/ia-button.js +2 -1
- package/dist/src/elements/ia-button/ia-button.js.map +1 -1
- package/dist/src/elements/ia-combo-box/ia-combo-box.d.ts.map +1 -1
- package/dist/src/elements/ia-combo-box/ia-combo-box.js +2 -1
- package/dist/src/elements/ia-combo-box/ia-combo-box.js.map +1 -1
- package/dist/src/elements/ia-dropdown-search-bar/ia-dropdown-search-bar.d.ts.map +1 -1
- package/dist/src/elements/ia-dropdown-search-bar/ia-dropdown-search-bar.js +2 -1
- package/dist/src/elements/ia-dropdown-search-bar/ia-dropdown-search-bar.js.map +1 -1
- package/dist/src/elements/ia-expandable-search-bar/ia-expandable-search-bar.d.ts.map +1 -1
- package/dist/src/elements/ia-expandable-search-bar/ia-expandable-search-bar.js +2 -1
- package/dist/src/elements/ia-expandable-search-bar/ia-expandable-search-bar.js.map +1 -1
- package/dist/src/elements/ia-expandable-search-bar/ia-quick-search.d.ts.map +1 -1
- package/dist/src/elements/ia-expandable-search-bar/ia-quick-search.js +2 -1
- package/dist/src/elements/ia-expandable-search-bar/ia-quick-search.js.map +1 -1
- package/dist/src/elements/ia-image-viewer/ia-image-viewer.d.ts +147 -0
- package/dist/src/elements/ia-image-viewer/ia-image-viewer.d.ts.map +1 -0
- package/dist/src/elements/ia-image-viewer/ia-image-viewer.js +534 -0
- package/dist/src/elements/ia-image-viewer/ia-image-viewer.js.map +1 -0
- package/dist/src/elements/ia-image-viewer/ia-imgview-controls.d.ts +22 -0
- package/dist/src/elements/ia-image-viewer/ia-imgview-controls.d.ts.map +1 -0
- package/dist/src/elements/ia-image-viewer/ia-imgview-controls.js +146 -0
- package/dist/src/elements/ia-image-viewer/ia-imgview-controls.js.map +1 -0
- package/dist/src/elements/ia-image-viewer/ia-imgview-slide.d.ts +44 -0
- package/dist/src/elements/ia-image-viewer/ia-imgview-slide.d.ts.map +1 -0
- package/dist/src/elements/ia-image-viewer/ia-imgview-slide.js +214 -0
- package/dist/src/elements/ia-image-viewer/ia-imgview-slide.js.map +1 -0
- package/dist/src/elements/ia-image-viewer/image-viewer-gestures.d.ts +79 -0
- package/dist/src/elements/ia-image-viewer/image-viewer-gestures.d.ts.map +1 -0
- package/dist/src/elements/ia-image-viewer/image-viewer-gestures.js +254 -0
- package/dist/src/elements/ia-image-viewer/image-viewer-gestures.js.map +1 -0
- package/dist/src/elements/ia-image-viewer/models.d.ts +20 -0
- package/dist/src/elements/ia-image-viewer/models.d.ts.map +1 -0
- package/dist/src/elements/ia-image-viewer/models.js +2 -0
- package/dist/src/elements/ia-image-viewer/models.js.map +1 -0
- package/dist/src/elements/ia-item-navigator/ia-item-navigator.d.ts.map +1 -1
- package/dist/src/elements/ia-item-navigator/ia-item-navigator.js +2 -1
- package/dist/src/elements/ia-item-navigator/ia-item-navigator.js.map +1 -1
- package/dist/src/elements/ia-item-navigator/ia-itemnav-menu-button.d.ts.map +1 -1
- package/dist/src/elements/ia-item-navigator/ia-itemnav-menu-button.js +2 -1
- package/dist/src/elements/ia-item-navigator/ia-itemnav-menu-button.js.map +1 -1
- package/dist/src/elements/ia-item-navigator/ia-itemnav-menu-slider.d.ts.map +1 -1
- package/dist/src/elements/ia-item-navigator/ia-itemnav-menu-slider.js +2 -1
- package/dist/src/elements/ia-item-navigator/ia-itemnav-menu-slider.js.map +1 -1
- package/dist/src/elements/ia-item-navigator/ia-itemnav-no-theater-available.d.ts.map +1 -1
- package/dist/src/elements/ia-item-navigator/ia-itemnav-no-theater-available.js +2 -1
- package/dist/src/elements/ia-item-navigator/ia-itemnav-no-theater-available.js.map +1 -1
- package/dist/src/elements/ia-item-navigator/menus/ia-itemnav-share-panel.d.ts.map +1 -1
- package/dist/src/elements/ia-item-navigator/menus/ia-itemnav-share-panel.js +2 -1
- package/dist/src/elements/ia-item-navigator/menus/ia-itemnav-share-panel.js.map +1 -1
- package/dist/src/elements/ia-item-navigator/menus/ia-itemnav-sort-files-button.d.ts.map +1 -1
- package/dist/src/elements/ia-item-navigator/menus/ia-itemnav-sort-files-button.js +2 -1
- package/dist/src/elements/ia-item-navigator/menus/ia-itemnav-sort-files-button.js.map +1 -1
- package/dist/src/elements/ia-item-navigator/menus/ia-itemnav-viewable-files-panel.d.ts.map +1 -1
- package/dist/src/elements/ia-item-navigator/menus/ia-itemnav-viewable-files-panel.js +2 -1
- package/dist/src/elements/ia-item-navigator/menus/ia-itemnav-viewable-files-panel.js.map +1 -1
- package/dist/src/elements/ia-otp-form/ia-otp-form.d.ts.map +1 -1
- package/dist/src/elements/ia-otp-form/ia-otp-form.js +2 -1
- package/dist/src/elements/ia-otp-form/ia-otp-form.js.map +1 -1
- package/dist/src/elements/ia-otp-input/ia-otp-input.d.ts.map +1 -1
- package/dist/src/elements/ia-otp-input/ia-otp-input.js +2 -1
- package/dist/src/elements/ia-otp-input/ia-otp-input.js.map +1 -1
- package/dist/src/elements/ia-playback-controls/ia-playback-controls.d.ts.map +1 -1
- package/dist/src/elements/ia-playback-controls/ia-playback-controls.js +2 -1
- package/dist/src/elements/ia-playback-controls/ia-playback-controls.js.map +1 -1
- package/dist/src/elements/ia-radio-player/ia-radio-player.d.ts.map +1 -1
- package/dist/src/elements/ia-radio-player/ia-radio-player.js +2 -1
- package/dist/src/elements/ia-radio-player/ia-radio-player.js.map +1 -1
- package/dist/src/elements/ia-radio-player/ia-search-results-switcher.d.ts.map +1 -1
- package/dist/src/elements/ia-radio-player/ia-search-results-switcher.js +2 -1
- package/dist/src/elements/ia-radio-player/ia-search-results-switcher.js.map +1 -1
- package/dist/src/elements/ia-scrubber-bar/ia-scrubber-bar.d.ts.map +1 -1
- package/dist/src/elements/ia-scrubber-bar/ia-scrubber-bar.js +2 -1
- package/dist/src/elements/ia-scrubber-bar/ia-scrubber-bar.js.map +1 -1
- package/dist/src/elements/ia-scrubber-bar/ia-section-marker.d.ts.map +1 -1
- package/dist/src/elements/ia-scrubber-bar/ia-section-marker.js +2 -1
- package/dist/src/elements/ia-scrubber-bar/ia-section-marker.js.map +1 -1
- package/dist/src/elements/ia-sr-only-text/ia-sr-only-text.js +1 -1
- package/dist/src/elements/ia-sr-only-text/ia-sr-only-text.js.map +1 -1
- package/dist/src/elements/ia-status-indicator/ia-status-indicator.d.ts.map +1 -1
- package/dist/src/elements/ia-status-indicator/ia-status-indicator.js +2 -1
- package/dist/src/elements/ia-status-indicator/ia-status-indicator.js.map +1 -1
- package/dist/src/elements/ia-transcript-view/ia-transcript-entry.d.ts.map +1 -1
- package/dist/src/elements/ia-transcript-view/ia-transcript-entry.js +2 -1
- package/dist/src/elements/ia-transcript-view/ia-transcript-entry.js.map +1 -1
- package/dist/src/elements/ia-transcript-view/ia-transcript-view.d.ts.map +1 -1
- package/dist/src/elements/ia-transcript-view/ia-transcript-view.js +2 -1
- package/dist/src/elements/ia-transcript-view/ia-transcript-view.js.map +1 -1
- package/dist/src/elements/ia-waveform-progress/ia-waveform-progress.d.ts.map +1 -1
- package/dist/src/elements/ia-waveform-progress/ia-waveform-progress.js +2 -1
- package/dist/src/elements/ia-waveform-progress/ia-waveform-progress.js.map +1 -1
- package/dist/src/elements/index.d.ts +1 -0
- package/dist/src/elements/index.d.ts.map +1 -1
- package/dist/src/elements/index.js +1 -0
- package/dist/src/elements/index.js.map +1 -1
- package/dist/src/labs/ia-snow/ia-snow.js +1 -1
- package/dist/src/labs/ia-snow/ia-snow.js.map +1 -1
- package/dist/src/util/custom-element.d.ts +39 -0
- package/dist/src/util/custom-element.d.ts.map +1 -0
- package/dist/src/util/custom-element.js +50 -0
- package/dist/src/util/custom-element.js.map +1 -0
- package/dist/src/util/prefers-reduced-motion.d.ts +10 -0
- package/dist/src/util/prefers-reduced-motion.d.ts.map +1 -0
- package/dist/src/util/prefers-reduced-motion.js +12 -0
- package/dist/src/util/prefers-reduced-motion.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ia-status-indicator.js","sourceRoot":"","sources":["../../../../src/elements/ia-status-indicator/ia-status-indicator.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n css,\n CSSResultGroup,\n html,\n LitElement,\n nothing,\n svg,\n SVGTemplateResult,\n TemplateResult,\n} from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { msg } from '@lit/localize';\nimport { choose } from 'lit/directives/choose.js';\n\nimport themeStyles from '@src/themes/theme-styles';\nimport { maskedIcon } from '@src/util/masked-icon';\n\nimport audioIcon from './icons/audio.svg';\nimport collectionIcon from './icons/collection.svg';\nimport etreeIcon from './icons/etree.svg';\nimport imagesIcon from './icons/images.svg';\nimport searchIcon from './icons/search.svg';\nimport softwareIcon from './icons/software.svg';\nimport textsIcon from './icons/texts.svg';\nimport tvIcon from './icons/tv.svg';\nimport videoIcon from './icons/video.svg';\nimport webIcon from './icons/web.svg';\n\nexport type LoadingStatus = 'ready' | 'loading' | 'success' | 'error';\n\n/**\n * The mediatype glyphs this element ships. These are *icon* names, which do not\n * map one-to-one onto archive.org mediatype values — a consumer holding a\n * `MediaType` translates at its own call site (e.g. `movies` -> `video`).\n */\nexport type MediaTypeIcon =\n | 'audio'\n | 'collection'\n | 'etree'\n | 'images'\n | 'search'\n | 'software'\n | 'texts'\n | 'tv'\n | 'video'\n | 'web';\n\nconst MEDIATYPE_ICONS: Record<MediaTypeIcon, string> = {\n audio: audioIcon,\n collection: collectionIcon,\n etree: etreeIcon,\n images: imagesIcon,\n search: searchIcon,\n software: softwareIcon,\n texts: textsIcon,\n tv: tvIcon,\n video: videoIcon,\n web: webIcon,\n};\n\n/**\n * Renders an SVG indicator, which defaults to an animated circular indicator.\n *\n * In `loading` mode the middle of the ring resolves in this order:\n * 1. slotted `icon` content\n * 2. the `mediatype` glyph\n * 3. nothing, when `hideDots` is set\n * 4. three animated dots (the default)\n */\n@customElement('ia-status-indicator')\nexport class IAStatusIndicator extends LitElement {\n /* An optional title to use for the loading state of the indicator. Will be used for screen readers. */\n @property({ type: String }) loadingTitle = msg('Loading...');\n\n /* An optional title to use for the success state of the indicator. Will be used for screen readers. */\n @property({ type: String }) successTitle = msg('Success');\n\n /* An optional title to use for the error state of the indicator. Will be used for screen readers. */\n @property({ type: String }) errorTitle = msg('Error');\n\n /* The state of the indicator that should be shown */\n @property({ type: String }) mode: LoadingStatus = 'loading';\n\n /* An optional mediatype glyph to render in the middle of the loading ring */\n @property({ type: String }) mediatype?: MediaTypeIcon;\n\n /* Renders a bare ring, with no dots in the middle. Ignored when a center icon is present. */\n @property({ type: Boolean }) hideDots = false;\n\n /* Whether a consumer has slotted their own center icon */\n @state() private hasSlottedIcon = false;\n\n render(): TemplateResult {\n return html`${choose(this.mode, [\n ['ready', () => this.placeholderTemplate],\n ['loading', () => this.loadingIndicatorTemplate],\n ['success', () => this.successIndicatorTemplate],\n ['error', () => this.errorIndicatorTemplate],\n ])}`;\n }\n\n /**\n * The `ready` state: reserves the indicator's space without drawing, so a\n * consumer's layout doesn't shift once the indicator appears.\n */\n private get placeholderTemplate(): TemplateResult {\n return html`<div class=\"placeholder\"></div>`;\n }\n\n /**\n * The asset URL for the current mediatype, if it maps to a glyph we ship.\n *\n * Unmapped values (e.g. archive.org's `account` or `data`) resolve to\n * undefined and degrade to the default dots rather than a broken mask.\n */\n private get mediatypeIconUrl(): string | undefined {\n if (!this.mediatype) return undefined;\n return MEDIATYPE_ICONS[this.mediatype];\n }\n\n /** Whether the middle of the ring is occupied by a glyph rather than dots */\n private get hasCenterIcon(): boolean {\n return this.hasSlottedIcon || !!this.mediatypeIconUrl;\n }\n\n /**\n * A circular loading indicator to render when processing.\n *\n * Two ring geometries are kept deliberately: the original 120x120 ring is\n * tuned for the dots, and the roomier 100x100 ring leaves space for a center\n * glyph. Keeping both means existing consumers see no visual change.\n */\n private get loadingIndicatorTemplate(): TemplateResult {\n const hasCenterIcon = this.hasCenterIcon;\n return html`\n <div class=\"indicator\">\n ${hasCenterIcon ? this.iconRingSvg : this.dottedRingSvg}\n <span class=\"center\" ?hidden=${!hasCenterIcon}>\n <slot name=\"icon\" @slotchange=${this.handleIconSlotChange}>\n ${this.mediatypeIconTemplate}\n </slot>\n </span>\n </div>\n `;\n }\n\n /** The original ring, with the three animated dots in the middle */\n private get dottedRingSvg(): SVGTemplateResult {\n return svg`\n <svg\n class=\"loading-indicator\"\n viewBox=\"0 0 120 120\"\n preserveAspectRatio=\"none\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n role=\"status\"\n >\n <title>${this.loadingTitle}</title>\n <g stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n class=\"loading-ring\"\n d=\"M60,10 C69.8019971,10 78.9452178,12.8205573 86.6623125,17.6943223 L76.4086287,27.9484118 C71.4880919,25.4243078 65.9103784,24 60,24 C40.117749,24 24,40.117749 24,60 C24,79.882251 40.117749,96 60,96 C79.882251,96 96,79.882251 96,60 C96,53.3014663 94.1704984,47.0302355 90.9839104,41.6587228 L101.110332,31.5326452 C106.715332,39.6116982 110,49.4222615 110,60 C110,87.6142375 87.6142375,110 60,110 C32.3857625,110 10,87.6142375 10,60 C10,32.3857625 32.3857625,10 60,10 Z\"\n ></path>\n <g\n class=\"loading-dots ${this.hideDots ? 'hidden' : ''}\"\n transform=\"translate(40.000000, 55.000000)\"\n >\n <circle id=\"left-dot\" cx=\"5\" cy=\"5\" r=\"5\"></circle>\n <circle id=\"middle-dot\" cx=\"20\" cy=\"5\" r=\"5\"></circle>\n <circle id=\"right-dot\" cx=\"35\" cy=\"5\" r=\"5\"></circle>\n </g>\n </g>\n </svg>\n `;\n }\n\n /** The roomier ring, used when a glyph occupies the middle */\n private get iconRingSvg(): SVGTemplateResult {\n return svg`\n <svg\n class=\"loading-indicator icon-ring\"\n viewBox=\"0 0 100 100\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n role=\"status\"\n >\n <title>${this.loadingTitle}</title>\n <g fill-rule=\"evenodd\">\n <path\n class=\"loading-ring\"\n fill-rule=\"nonzero\"\n d=\"m17.8618849 11.6970233c18.5864635-15.59603144 45.6875867-15.59603102 64.2740497.000001 1.9271446 1.6170806 2.1785128 4.4902567.5614466 6.4174186-1.6170661 1.9271618-4.4902166 2.1785323-6.4173612.5614517-15.1996922-12.75416882-37.3625282-12.75416916-52.5622206-.000001-15.19969387 12.7541707-19.04823077 34.5805019-9.1273354 51.7641499 9.9208955 17.183646 30.7471499 24.7638499 49.3923323 17.9774983 18.6451823-6.7863521 29.7266014-25.9801026 26.2811129-45.5206248-.436848-2.4775114 1.2174186-4.8400696 3.6949079-5.2769215 2.4774893-.4368518 4.8400264 1.2174296 5.2768744 3.694941 4.2132065 23.8945096-9.3373563 47.3649806-32.137028 55.6634567-22.799672 8.2984758-48.2663986-.9707372-60.39785211-21.9832155-12.1314534-21.012481-7.42539173-47.7021198 11.16107351-63.2981544z\"\n ></path>\n </g>\n </svg>\n `;\n }\n\n /**\n * The bundled mediatype glyph. `maskedIcon` supplies the mask geometry and\n * the decorative `aria-hidden`; this component supplies the size and paint.\n */\n private get mediatypeIconTemplate(): TemplateResult | typeof nothing {\n const url = this.mediatypeIconUrl;\n if (!url) return nothing;\n\n return maskedIcon(url);\n }\n\n private handleIconSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this.hasSlottedIcon = slot.assignedNodes({ flatten: false }).length > 0;\n }\n\n /** A check mark to render on success */\n private get successIndicatorTemplate(): TemplateResult {\n return html`\n <svg\n class=\"success-indicator\"\n viewBox=\"0 0 120 120\"\n preserveAspectRatio=\"none\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n role=\"status\"\n >\n <title>${this.successTitle}</title>\n <g stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n class=\"success-icon\"\n d=\"M60,10 C70.5816709,10 80.3955961,13.2871104 88.4763646,18.8959201 L78.3502633,29.0214223 C72.9767592,25.8315427 66.7022695,24 60,24 C40.117749,24 24,40.117749 24,60 C24,79.882251 40.117749,96 60,96 C79.882251,96 96,79.882251 96,60 L95.995,59.46 L108.327675,47.128668 C109.350926,50.9806166 109.925886,55.015198 109.993301,59.1731586 L110,60 C110,87.6142375 87.6142375,110 60,110 C32.3857625,110 10,87.6142375 10,60 C10,32.3857625 32.3857625,10 60,10 Z\"\n ></path>\n <polygon\n class=\"success-icon\"\n transform=\"translate(75.000000, 41.500000) rotate(44.000000) translate(-75.000000, -41.500000) \"\n points=\"96 85 54 85 54 65 76 64.999 76 -2 96 -2\"\n ></polygon>\n </g>\n </svg>\n `;\n }\n\n /** An \"!\" to render on error */\n private get errorIndicatorTemplate(): TemplateResult {\n return html`\n <svg\n class=\"error-indicator\"\n viewBox=\"0 0 120 120\"\n preserveAspectRatio=\"none\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n role=\"status\"\n >\n <title>${this.errorTitle}</title>\n <path\n class=\"error-icon\"\n d=\"m56.4612493 8.80450354 41.8901185 75.94632926c1.7706782 2.8433173 2.1150372 5.2623412 1.0330766 7.2570716-1.0819604 1.9947304-3.26978 2.9920956-6.5634587 2.9920956h-85.69973905c-3.29367873 0-5.46954894-.9973652-6.52761065-2.9920956-1.0580617-1.9947304-.70175345-4.4137543 1.06892476-7.2570716l41.89011844-75.12308969c1.8184757-2.84331737 3.9693609-4.37738627 6.4526556-4.60220671s4.6341799 1.03483527 6.4526556 3.77896714zm28.5387507 75.19549646-35.037482-62-34.962518 62zm-31-34.7484359v-10.2515641h-8v10.2515641l2.089172 14.7484359h3.8184713zm-8 19.7484359v8h8v-8z\"\n />\n </svg>\n `;\n }\n\n static get styles(): CSSResultGroup {\n return [\n themeStyles,\n css`\n :host {\n --indicator-width--: var(--icon-width);\n\n /* Loading */\n --loading-ring-color--: var(--primary-text-color);\n --loading-dot-color--: var(--primary-text-color);\n --loading-icon-color--: var(--primary-text-color);\n\n /* Success */\n --success-icon-color--: var(--color-success);\n\n /* Error */\n --error-icon-color--: var(--color-danger);\n\n display: inline-block;\n width: var(--indicator-width--);\n }\n\n .placeholder {\n height: var(--indicator-width--);\n }\n\n /* Stacks the center glyph over the ring */\n .indicator {\n position: relative;\n display: block;\n }\n\n .indicator svg {\n display: block;\n width: 100%;\n height: auto;\n }\n\n .center {\n position: absolute;\n inset: 0;\n display: grid;\n place-items: center;\n }\n\n .center[hidden] {\n display: none;\n }\n\n /*\n * Sized to fit within the icon ring's inner diameter. maskedIcon sets\n * the mask itself; background-color is what paints the glyph, so it\n * recolors with the ring.\n */\n .ia-icon {\n width: 50%;\n height: 50%;\n background-color: var(--loading-icon-color--);\n }\n\n .success-icon {\n fill: var(--success-icon-color--);\n }\n\n .error-icon {\n fill: var(--error-icon-color--);\n }\n\n .loading-ring {\n fill: var(--loading-ring-color--);\n animation: rotate 1.3s infinite linear;\n transform-origin: 50px 50px;\n transform-box: fill-box;\n }\n\n .loading-dots {\n fill: var(--loading-dot-color--);\n transition: opacity 0.25s ease-out;\n }\n\n .loading-dots.hidden {\n display: none;\n }\n\n .loading-dots > * {\n opacity: 0;\n animation: dot 1.3s infinite;\n }\n\n .loading-dots #left-dot {\n animation-delay: 0.2s;\n }\n\n .loading-dots #middle-dot {\n animation-delay: 0.4s;\n }\n\n .loading-dots #right-dot {\n animation-delay: 0.6s;\n }\n\n @keyframes rotate {\n 0% {\n transform: rotate(-360deg);\n }\n 100% {\n /* This frame is supposed to be inferred, but Safari doesn't rotate it unless we're explicit */\n transform: rotate(0deg);\n }\n }\n\n @keyframes dot {\n 0% {\n opacity: 0;\n }\n 25% {\n opacity: 1;\n }\n 100% {\n opacity: 0;\n }\n }\n `,\n ];\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ia-status-indicator': IAStatusIndicator;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ia-status-indicator.js","sourceRoot":"","sources":["../../../../src/elements/ia-status-indicator/ia-status-indicator.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n css,\n CSSResultGroup,\n html,\n LitElement,\n nothing,\n svg,\n SVGTemplateResult,\n TemplateResult,\n} from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { customElement } from '@src/util/custom-element';\nimport { msg } from '@lit/localize';\nimport { choose } from 'lit/directives/choose.js';\n\nimport themeStyles from '@src/themes/theme-styles';\nimport { maskedIcon } from '@src/util/masked-icon';\n\nimport audioIcon from './icons/audio.svg';\nimport collectionIcon from './icons/collection.svg';\nimport etreeIcon from './icons/etree.svg';\nimport imagesIcon from './icons/images.svg';\nimport searchIcon from './icons/search.svg';\nimport softwareIcon from './icons/software.svg';\nimport textsIcon from './icons/texts.svg';\nimport tvIcon from './icons/tv.svg';\nimport videoIcon from './icons/video.svg';\nimport webIcon from './icons/web.svg';\n\nexport type LoadingStatus = 'ready' | 'loading' | 'success' | 'error';\n\n/**\n * The mediatype glyphs this element ships. These are *icon* names, which do not\n * map one-to-one onto archive.org mediatype values — a consumer holding a\n * `MediaType` translates at its own call site (e.g. `movies` -> `video`).\n */\nexport type MediaTypeIcon =\n | 'audio'\n | 'collection'\n | 'etree'\n | 'images'\n | 'search'\n | 'software'\n | 'texts'\n | 'tv'\n | 'video'\n | 'web';\n\nconst MEDIATYPE_ICONS: Record<MediaTypeIcon, string> = {\n audio: audioIcon,\n collection: collectionIcon,\n etree: etreeIcon,\n images: imagesIcon,\n search: searchIcon,\n software: softwareIcon,\n texts: textsIcon,\n tv: tvIcon,\n video: videoIcon,\n web: webIcon,\n};\n\n/**\n * Renders an SVG indicator, which defaults to an animated circular indicator.\n *\n * In `loading` mode the middle of the ring resolves in this order:\n * 1. slotted `icon` content\n * 2. the `mediatype` glyph\n * 3. nothing, when `hideDots` is set\n * 4. three animated dots (the default)\n */\n@customElement('ia-status-indicator')\nexport class IAStatusIndicator extends LitElement {\n /* An optional title to use for the loading state of the indicator. Will be used for screen readers. */\n @property({ type: String }) loadingTitle = msg('Loading...');\n\n /* An optional title to use for the success state of the indicator. Will be used for screen readers. */\n @property({ type: String }) successTitle = msg('Success');\n\n /* An optional title to use for the error state of the indicator. Will be used for screen readers. */\n @property({ type: String }) errorTitle = msg('Error');\n\n /* The state of the indicator that should be shown */\n @property({ type: String }) mode: LoadingStatus = 'loading';\n\n /* An optional mediatype glyph to render in the middle of the loading ring */\n @property({ type: String }) mediatype?: MediaTypeIcon;\n\n /* Renders a bare ring, with no dots in the middle. Ignored when a center icon is present. */\n @property({ type: Boolean }) hideDots = false;\n\n /* Whether a consumer has slotted their own center icon */\n @state() private hasSlottedIcon = false;\n\n render(): TemplateResult {\n return html`${choose(this.mode, [\n ['ready', () => this.placeholderTemplate],\n ['loading', () => this.loadingIndicatorTemplate],\n ['success', () => this.successIndicatorTemplate],\n ['error', () => this.errorIndicatorTemplate],\n ])}`;\n }\n\n /**\n * The `ready` state: reserves the indicator's space without drawing, so a\n * consumer's layout doesn't shift once the indicator appears.\n */\n private get placeholderTemplate(): TemplateResult {\n return html`<div class=\"placeholder\"></div>`;\n }\n\n /**\n * The asset URL for the current mediatype, if it maps to a glyph we ship.\n *\n * Unmapped values (e.g. archive.org's `account` or `data`) resolve to\n * undefined and degrade to the default dots rather than a broken mask.\n */\n private get mediatypeIconUrl(): string | undefined {\n if (!this.mediatype) return undefined;\n return MEDIATYPE_ICONS[this.mediatype];\n }\n\n /** Whether the middle of the ring is occupied by a glyph rather than dots */\n private get hasCenterIcon(): boolean {\n return this.hasSlottedIcon || !!this.mediatypeIconUrl;\n }\n\n /**\n * A circular loading indicator to render when processing.\n *\n * Two ring geometries are kept deliberately: the original 120x120 ring is\n * tuned for the dots, and the roomier 100x100 ring leaves space for a center\n * glyph. Keeping both means existing consumers see no visual change.\n */\n private get loadingIndicatorTemplate(): TemplateResult {\n const hasCenterIcon = this.hasCenterIcon;\n return html`\n <div class=\"indicator\">\n ${hasCenterIcon ? this.iconRingSvg : this.dottedRingSvg}\n <span class=\"center\" ?hidden=${!hasCenterIcon}>\n <slot name=\"icon\" @slotchange=${this.handleIconSlotChange}>\n ${this.mediatypeIconTemplate}\n </slot>\n </span>\n </div>\n `;\n }\n\n /** The original ring, with the three animated dots in the middle */\n private get dottedRingSvg(): SVGTemplateResult {\n return svg`\n <svg\n class=\"loading-indicator\"\n viewBox=\"0 0 120 120\"\n preserveAspectRatio=\"none\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n role=\"status\"\n >\n <title>${this.loadingTitle}</title>\n <g stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n class=\"loading-ring\"\n d=\"M60,10 C69.8019971,10 78.9452178,12.8205573 86.6623125,17.6943223 L76.4086287,27.9484118 C71.4880919,25.4243078 65.9103784,24 60,24 C40.117749,24 24,40.117749 24,60 C24,79.882251 40.117749,96 60,96 C79.882251,96 96,79.882251 96,60 C96,53.3014663 94.1704984,47.0302355 90.9839104,41.6587228 L101.110332,31.5326452 C106.715332,39.6116982 110,49.4222615 110,60 C110,87.6142375 87.6142375,110 60,110 C32.3857625,110 10,87.6142375 10,60 C10,32.3857625 32.3857625,10 60,10 Z\"\n ></path>\n <g\n class=\"loading-dots ${this.hideDots ? 'hidden' : ''}\"\n transform=\"translate(40.000000, 55.000000)\"\n >\n <circle id=\"left-dot\" cx=\"5\" cy=\"5\" r=\"5\"></circle>\n <circle id=\"middle-dot\" cx=\"20\" cy=\"5\" r=\"5\"></circle>\n <circle id=\"right-dot\" cx=\"35\" cy=\"5\" r=\"5\"></circle>\n </g>\n </g>\n </svg>\n `;\n }\n\n /** The roomier ring, used when a glyph occupies the middle */\n private get iconRingSvg(): SVGTemplateResult {\n return svg`\n <svg\n class=\"loading-indicator icon-ring\"\n viewBox=\"0 0 100 100\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n role=\"status\"\n >\n <title>${this.loadingTitle}</title>\n <g fill-rule=\"evenodd\">\n <path\n class=\"loading-ring\"\n fill-rule=\"nonzero\"\n d=\"m17.8618849 11.6970233c18.5864635-15.59603144 45.6875867-15.59603102 64.2740497.000001 1.9271446 1.6170806 2.1785128 4.4902567.5614466 6.4174186-1.6170661 1.9271618-4.4902166 2.1785323-6.4173612.5614517-15.1996922-12.75416882-37.3625282-12.75416916-52.5622206-.000001-15.19969387 12.7541707-19.04823077 34.5805019-9.1273354 51.7641499 9.9208955 17.183646 30.7471499 24.7638499 49.3923323 17.9774983 18.6451823-6.7863521 29.7266014-25.9801026 26.2811129-45.5206248-.436848-2.4775114 1.2174186-4.8400696 3.6949079-5.2769215 2.4774893-.4368518 4.8400264 1.2174296 5.2768744 3.694941 4.2132065 23.8945096-9.3373563 47.3649806-32.137028 55.6634567-22.799672 8.2984758-48.2663986-.9707372-60.39785211-21.9832155-12.1314534-21.012481-7.42539173-47.7021198 11.16107351-63.2981544z\"\n ></path>\n </g>\n </svg>\n `;\n }\n\n /**\n * The bundled mediatype glyph. `maskedIcon` supplies the mask geometry and\n * the decorative `aria-hidden`; this component supplies the size and paint.\n */\n private get mediatypeIconTemplate(): TemplateResult | typeof nothing {\n const url = this.mediatypeIconUrl;\n if (!url) return nothing;\n\n return maskedIcon(url);\n }\n\n private handleIconSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this.hasSlottedIcon = slot.assignedNodes({ flatten: false }).length > 0;\n }\n\n /** A check mark to render on success */\n private get successIndicatorTemplate(): TemplateResult {\n return html`\n <svg\n class=\"success-indicator\"\n viewBox=\"0 0 120 120\"\n preserveAspectRatio=\"none\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n role=\"status\"\n >\n <title>${this.successTitle}</title>\n <g stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n class=\"success-icon\"\n d=\"M60,10 C70.5816709,10 80.3955961,13.2871104 88.4763646,18.8959201 L78.3502633,29.0214223 C72.9767592,25.8315427 66.7022695,24 60,24 C40.117749,24 24,40.117749 24,60 C24,79.882251 40.117749,96 60,96 C79.882251,96 96,79.882251 96,60 L95.995,59.46 L108.327675,47.128668 C109.350926,50.9806166 109.925886,55.015198 109.993301,59.1731586 L110,60 C110,87.6142375 87.6142375,110 60,110 C32.3857625,110 10,87.6142375 10,60 C10,32.3857625 32.3857625,10 60,10 Z\"\n ></path>\n <polygon\n class=\"success-icon\"\n transform=\"translate(75.000000, 41.500000) rotate(44.000000) translate(-75.000000, -41.500000) \"\n points=\"96 85 54 85 54 65 76 64.999 76 -2 96 -2\"\n ></polygon>\n </g>\n </svg>\n `;\n }\n\n /** An \"!\" to render on error */\n private get errorIndicatorTemplate(): TemplateResult {\n return html`\n <svg\n class=\"error-indicator\"\n viewBox=\"0 0 120 120\"\n preserveAspectRatio=\"none\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n role=\"status\"\n >\n <title>${this.errorTitle}</title>\n <path\n class=\"error-icon\"\n d=\"m56.4612493 8.80450354 41.8901185 75.94632926c1.7706782 2.8433173 2.1150372 5.2623412 1.0330766 7.2570716-1.0819604 1.9947304-3.26978 2.9920956-6.5634587 2.9920956h-85.69973905c-3.29367873 0-5.46954894-.9973652-6.52761065-2.9920956-1.0580617-1.9947304-.70175345-4.4137543 1.06892476-7.2570716l41.89011844-75.12308969c1.8184757-2.84331737 3.9693609-4.37738627 6.4526556-4.60220671s4.6341799 1.03483527 6.4526556 3.77896714zm28.5387507 75.19549646-35.037482-62-34.962518 62zm-31-34.7484359v-10.2515641h-8v10.2515641l2.089172 14.7484359h3.8184713zm-8 19.7484359v8h8v-8z\"\n />\n </svg>\n `;\n }\n\n static get styles(): CSSResultGroup {\n return [\n themeStyles,\n css`\n :host {\n --indicator-width--: var(--icon-width);\n\n /* Loading */\n --loading-ring-color--: var(--primary-text-color);\n --loading-dot-color--: var(--primary-text-color);\n --loading-icon-color--: var(--primary-text-color);\n\n /* Success */\n --success-icon-color--: var(--color-success);\n\n /* Error */\n --error-icon-color--: var(--color-danger);\n\n display: inline-block;\n width: var(--indicator-width--);\n }\n\n .placeholder {\n height: var(--indicator-width--);\n }\n\n /* Stacks the center glyph over the ring */\n .indicator {\n position: relative;\n display: block;\n }\n\n .indicator svg {\n display: block;\n width: 100%;\n height: auto;\n }\n\n .center {\n position: absolute;\n inset: 0;\n display: grid;\n place-items: center;\n }\n\n .center[hidden] {\n display: none;\n }\n\n /*\n * Sized to fit within the icon ring's inner diameter. maskedIcon sets\n * the mask itself; background-color is what paints the glyph, so it\n * recolors with the ring.\n */\n .ia-icon {\n width: 50%;\n height: 50%;\n background-color: var(--loading-icon-color--);\n }\n\n .success-icon {\n fill: var(--success-icon-color--);\n }\n\n .error-icon {\n fill: var(--error-icon-color--);\n }\n\n .loading-ring {\n fill: var(--loading-ring-color--);\n animation: rotate 1.3s infinite linear;\n transform-origin: 50px 50px;\n transform-box: fill-box;\n }\n\n .loading-dots {\n fill: var(--loading-dot-color--);\n transition: opacity 0.25s ease-out;\n }\n\n .loading-dots.hidden {\n display: none;\n }\n\n .loading-dots > * {\n opacity: 0;\n animation: dot 1.3s infinite;\n }\n\n .loading-dots #left-dot {\n animation-delay: 0.2s;\n }\n\n .loading-dots #middle-dot {\n animation-delay: 0.4s;\n }\n\n .loading-dots #right-dot {\n animation-delay: 0.6s;\n }\n\n @keyframes rotate {\n 0% {\n transform: rotate(-360deg);\n }\n 100% {\n /* This frame is supposed to be inferred, but Safari doesn't rotate it unless we're explicit */\n transform: rotate(0deg);\n }\n }\n\n @keyframes dot {\n 0% {\n opacity: 0;\n }\n 25% {\n opacity: 1;\n }\n 100% {\n opacity: 0;\n }\n }\n `,\n ];\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ia-status-indicator': IAStatusIndicator;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ia-transcript-entry.d.ts","sourceRoot":"","sources":["../../../../src/elements/ia-transcript-view/ia-transcript-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"ia-transcript-entry.d.ts","sourceRoot":"","sources":["../../../../src/elements/ia-transcript-view/ia-transcript-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAI5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEtD;;;;;;GAMG;AACH,qBACa,iBAAkB,SAAQ,UAAU;IAC/C,0BAA0B;IACE,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAE1D,sDAAsD;IACV,QAAQ,UAAS;IAE7D,kEAAkE;IACtB,UAAU,UAAS;IAE/D,gDAAgD;IACJ,WAAW,UAAS;IAEhE,oDAAoD;IACR,cAAc,UAAS;IAEnE,kEAAkE;IACtB,YAAY,UAAS;IAEjE,MAAM,IAAI,cAAc;CAGzB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { html, LitElement } from 'lit';
|
|
3
|
-
import {
|
|
3
|
+
import { property } from 'lit/decorators.js';
|
|
4
|
+
import { customElement } from '../../util/custom-element.js';
|
|
4
5
|
/**
|
|
5
6
|
* One line of the transcript.
|
|
6
7
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ia-transcript-entry.js","sourceRoot":"","sources":["../../../../src/elements/ia-transcript-view/ia-transcript-entry.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAuB,MAAM,KAAK,CAAC;AAC5D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ia-transcript-entry.js","sourceRoot":"","sources":["../../../../src/elements/ia-transcript-view/ia-transcript-entry.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAuB,MAAM,KAAK,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAIzD;;;;;;GAMG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,UAAU;IAA1C;;QAIL,sDAAsD;QACV,aAAQ,GAAG,KAAK,CAAC;QAE7D,kEAAkE;QACtB,eAAU,GAAG,KAAK,CAAC;QAE/D,gDAAgD;QACJ,gBAAW,GAAG,KAAK,CAAC;QAEhE,oDAAoD;QACR,mBAAc,GAAG,KAAK,CAAC;QAEnE,kEAAkE;QACtB,iBAAY,GAAG,KAAK,CAAC;IAKnE,CAAC;IAHC,MAAM;QACJ,OAAO,IAAI,CAAA,GAAG,IAAI,CAAC,KAAK,EAAE,WAAW,IAAI,EAAE,EAAE,CAAC;IAChD,CAAC;CACF,CAAA;AApB6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gDAA+B;AAGd;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;mDAAkB;AAGjB;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;qDAAoB;AAGnB;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;sDAAqB;AAGpB;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;yDAAwB;AAGvB;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;uDAAsB;AAjBtD,iBAAiB;IAD7B,aAAa,CAAC,qBAAqB,CAAC;GACxB,iBAAiB,CAsB7B","sourcesContent":["import { html, LitElement, type TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { customElement } from '@src/util/custom-element';\n\nimport type { TranscriptEntryConfig } from './models';\n\n/**\n * One line of the transcript.\n *\n * Carries no styles of its own. Every flag reflects to an attribute so the\n * transcript view around it can style entries from a single stylesheet rather\n * than pushing styles down into each one.\n */\n@customElement('ia-transcript-entry')\nexport class IATranscriptEntry extends LitElement {\n /** The entry to render */\n @property({ type: Object }) entry?: TranscriptEntryConfig;\n\n /** Whether playback is currently inside this entry */\n @property({ type: Boolean, reflect: true }) isActive = false;\n\n /** Whether this is the search result currently being looked at */\n @property({ type: Boolean, reflect: true }) isSelected = false;\n\n /** Whether clicking this entry does anything */\n @property({ type: Boolean, reflect: true }) isClickable = false;\n\n /** Whether this entry matched the current search */\n @property({ type: Boolean, reflect: true }) isSearchResult = false;\n\n /** Whether this entry is a stretch of music rather than speech */\n @property({ type: Boolean, reflect: true }) isMusicEntry = false;\n\n render(): TemplateResult {\n return html`${this.entry?.displayText ?? ''}`;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ia-transcript-view.d.ts","sourceRoot":"","sources":["../../../../src/elements/ia-transcript-view/ia-transcript-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,UAAU,EAEV,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"ia-transcript-view.d.ts","sourceRoot":"","sources":["../../../../src/elements/ia-transcript-view/ia-transcript-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,UAAU,EAEV,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,KAAK,CAAC;AAOb,OAAO,KAAK,EAAE,gBAAgB,EAAyB,MAAM,UAAU,CAAC;AAGxE,OAAO,uBAAuB,CAAC;AAc/B;;;;;GAKG;AACH,qBACa,gBAAiB,SAAQ,UAAU;IAC9C,+BAA+B;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAEtD,mDAAmD;IACvB,WAAW,SAAK;IAE5C,qEAAqE;IACzC,gBAAgB,SAAM;IAElD,qEAAqE;IACzC,mBAAmB,SAAM;IAErD,8CAA8C;IACjB,UAAU,UAAQ;IAE/C,uDAAuD;IAC3B,yBAAyB,SAAK;IAE1D,yEAAyE;IAC5C,gBAAgB,UAAS;IAEtD,6EAA6E;IACjD,gBAAgB,SAAS;IAE5C,OAAO,CAAC,aAAa,CAAK;IAE1B,OAAO,CAAC,cAAc,CAA+B;IAElC,OAAO,CAAC,UAAU,CAAC,CAAqB;IAEpE,OAAO,CAAC,mBAAmB,CAAC,CAAgC;IAE5D,OAAO,CAAC,iBAAiB,CAAC,CAAS;IAEnC,oBAAoB,IAAI,IAAI;IAM5B,MAAM,IAAI,cAAc;IAwBxB,oDAAoD;IACpD,4BAA4B,IAAI,IAAI;IAQpC,6EAA6E;IAC7E,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAkBzD,OAAO,KAAK,wBAAwB,GAUnC;IAED,OAAO,KAAK,mBAAmB,GAM9B;IAED,OAAO,CAAC,uBAAuB;IAsB/B,OAAO,KAAK,oBAAoB,GAW/B;IAED,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,CAAC,iBAAiB,EAAE,cAAc,GAAG,IAAI;IAsBhD,OAAO,CAAC,uBAAuB;IAiB/B;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAY/B,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,oBAAoB;IAQ5B;;;;;;;OAOG;IACH,OAAO,CAAC,SAAS;IAWjB,8EAA8E;IAC9E,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,KAAK,qBAAqB,GAIhC;IAED,OAAO,KAAK,oBAAoB,GAM/B;IAED,OAAO,KAAK,yBAAyB,GAIpC;IAED,OAAO,CAAC,oBAAoB;IAO5B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,kBAAkB;IAY1B;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IA+BtB,OAAO,CAAC,qBAAqB;IAO7B,MAAM,KAAK,MAAM,IAAI,cAAc,CAyMlC;CACF"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
var IATranscriptView_1;
|
|
2
2
|
import { __decorate } from "tslib";
|
|
3
3
|
import { css, html, LitElement, nothing, } from 'lit';
|
|
4
|
-
import {
|
|
4
|
+
import { property, query, state } from 'lit/decorators.js';
|
|
5
|
+
import { customElement } from '../../util/custom-element.js';
|
|
5
6
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
6
7
|
import { msg } from '@lit/localize';
|
|
7
8
|
import { formatDuration } from './duration-formatter.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ia-transcript-view.js","sourceRoot":"","sources":["../../../../src/elements/ia-transcript-view/ia-transcript-view.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n css,\n html,\n LitElement,\n nothing,\n type CSSResultGroup,\n type PropertyValues,\n type TemplateResult,\n} from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { msg } from '@lit/localize';\n\nimport { formatDuration } from './duration-formatter';\nimport type { TranscriptConfig, TranscriptEntryConfig } from './models';\nimport type { IATranscriptEntry } from './ia-transcript-entry';\n\nimport './ia-transcript-entry';\n\n/**\n * Event names emitted by this component\n */\nconst Events = {\n TranscriptEntrySelected: 'transcriptEntrySelected',\n CurrentEntriesUpdated: 'currentEntriesUpdated',\n AutoScrollChanged: 'autoScrollChanged',\n};\n\n/** How long a scroll animation runs, in seconds */\nconst SCROLL_DURATION_SECONDS = 1;\n\n/**\n * A scrolling transcript that follows playback.\n *\n * It keeps itself scrolled to whatever is being spoken, steps aside when the\n * listener scrolls by hand, and picks the job back up once they've stopped.\n */\n@customElement('ia-transcript-view')\nexport class IATranscriptView extends LitElement {\n /** The transcript to render */\n @property({ type: Object }) config?: TranscriptConfig;\n\n /** Playback position, in seconds into the track */\n @property({ type: Number }) currentTime = 0;\n\n /** How much room to leave above the entry being spoken, in pixels */\n @property({ type: Number }) topContextHeight = 50;\n\n /** How much room to leave below the entry being spoken, in pixels */\n @property({ type: Number }) bottomContextHeight = 50;\n\n /** Whether the transcript follows playback */\n @property({ type: Boolean }) autoScroll = true;\n\n /** Which search result is currently being looked at */\n @property({ type: Number }) selectedSearchResultIndex = 0;\n\n /** Whether to outline the context zones, for working on the scrolling */\n @property({ type: Boolean }) showContextZones = false;\n\n /** How long to wait after a manual scroll before following playback again */\n @property({ type: Number }) scrollTimerDelay = 15000;\n\n @state() private timeScrollTop = 0;\n\n @state() private currentEntries: TranscriptEntryConfig[] = [];\n\n @query('#scroll-container') private scrollView?: HTMLElement | null;\n\n private scrollResumeTimerId?: ReturnType<typeof setTimeout>;\n\n private scrollAnimationId?: number;\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n clearTimeout(this.scrollResumeTimerId);\n this.cancelScrollAnimation();\n }\n\n render(): TemplateResult {\n return html`\n <div class=\"container\">\n ${this.showContextZones ? this.contextZoneTemplates : nothing}\n\n <div\n class=\"scroll-container\"\n id=\"scroll-container\"\n @wheel=${this.didScroll}\n @touchmove=${this.didScroll}\n >\n <div class=\"col time\">${this.timeDisplayTemplate}</div>\n\n <div class=\"col\">\n ${this.autoScrollButtonTemplate}\n ${this.transcriptEntries.map((entry) =>\n this.transcriptEntryTemplate(entry),\n )}\n </div>\n </div>\n </div>\n `;\n }\n\n /** Scrolls the selected search result into view. */\n scrollToSelectedSearchResult(): void {\n const { selectedSearchResult } = this;\n if (!selectedSearchResult) return;\n\n this.autoScroll = false;\n this.scrollToElement(selectedSearchResult);\n }\n\n /** The id of the entry starting closest to a given time, if there is one. */\n entryIdentifierClosestToTime(time: number): number | null {\n const entries = this.transcriptEntries;\n if (entries.length === 0) return null;\n\n let closest = entries[0];\n let smallestDelta = Math.abs(time - closest.start);\n\n for (const entry of entries) {\n const delta = Math.abs(time - entry.start);\n if (delta < smallestDelta) {\n smallestDelta = delta;\n closest = entry;\n }\n }\n\n return closest.id;\n }\n\n private get autoScrollButtonTemplate(): TemplateResult {\n return html`\n <button\n type=\"button\"\n class=\"auto-scroll-button ${this.autoScroll ? 'hidden' : ''}\"\n @click=${this.enableAutoScroll}\n >\n ${msg('Scroll text with audio')}\n </button>\n `;\n }\n\n private get timeDisplayTemplate(): TemplateResult {\n return html`\n <div class=\"time-display\" style=\"top: ${this.timeScrollTop}px\">\n ${formatDuration(this.currentTime)}\n </div>\n `;\n }\n\n private transcriptEntryTemplate(\n entry: TranscriptEntryConfig,\n ): TemplateResult {\n const isActive = this.currentEntries.some(\n (currentEntry) => currentEntry.id === entry.id,\n );\n\n return html`\n <ia-transcript-entry\n .entry=${entry}\n ?isActive=${isActive}\n ?isSelected=${entry.searchMatchIndex === this.selectedSearchResultIndex}\n ?isSearchResult=${entry.searchMatchIndex !== undefined}\n ?isMusicEntry=${entry.isMusic}\n isClickable\n data-search-result-index=${ifDefined(entry.searchMatchIndex)}\n data-identifier=${entry.id}\n @click=${this.transcriptEntrySelected}\n ></ia-transcript-entry>\n `;\n }\n\n private get contextZoneTemplates(): TemplateResult {\n return html`\n <div\n class=\"top context-overlay\"\n style=\"height: ${this.topContextHeight}px\"\n ></div>\n <div\n class=\"bottom context-overlay\"\n style=\"height: ${this.bottomContextHeight}px\"\n ></div>\n `;\n }\n\n private get transcriptEntries(): TranscriptEntryConfig[] {\n return this.config?.entries ?? [];\n }\n\n updated(changedProperties: PropertyValues): void {\n if (changedProperties.has('currentTime')) this.handleCurrentTimeChange();\n if (changedProperties.has('selectedSearchResultIndex')) {\n this.scrollToSelectedSearchResult();\n }\n if (changedProperties.has('currentEntries')) {\n this.scrollToClosestEntry();\n this.updateTimePosition();\n }\n if (changedProperties.has('autoScroll')) {\n this.dispatchEvent(\n new CustomEvent<{ autoScroll: boolean }>(Events.AutoScrollChanged, {\n detail: { autoScroll: this.autoScroll },\n }),\n );\n }\n if (changedProperties.has('config')) {\n this.selectedSearchResultIndex = 0;\n this.scrollToSelectedSearchResult();\n }\n }\n\n private transcriptEntrySelected(e: Event): void {\n const { entry } = e.currentTarget as IATranscriptEntry;\n if (!entry) return;\n\n this.dispatchEvent(\n new CustomEvent<{ entry: TranscriptEntryConfig }>(\n Events.TranscriptEntrySelected,\n { detail: { entry } },\n ),\n );\n\n if (entry.searchMatchIndex !== undefined) {\n this.selectedSearchResultIndex = entry.searchMatchIndex;\n }\n this.autoScroll = false;\n }\n\n /**\n * Works out which entries are being spoken now.\n *\n * Runs on every time update, several times a second, so it only touches the\n * rendered state when the set of entries has actually changed.\n */\n private handleCurrentTimeChange(): void {\n const entries = this.transcriptEntries;\n if (entries.length === 0) return;\n\n const activeEntries = entries.filter(\n (entry) =>\n this.currentTime >= entry.start && this.currentTime <= entry.end,\n );\n\n if (IATranscriptView.entryArraysMatch(activeEntries, this.currentEntries)) {\n return;\n }\n\n this.dispatchEvent(new Event(Events.CurrentEntriesUpdated));\n this.currentEntries = activeEntries;\n }\n\n private static entryArraysMatch(\n a: TranscriptEntryConfig[],\n b: TranscriptEntryConfig[],\n ): boolean {\n if (a.length !== b.length) return false;\n\n const aIds = a.map((entry) => entry.id).sort((x, y) => x - y);\n const bIds = b.map((entry) => entry.id).sort((x, y) => x - y);\n\n return aIds.every((id, index) => bIds[index] === id);\n }\n\n private elementClosestToTime(time: number): HTMLElement | null {\n const closestIdentifier = this.entryIdentifierClosestToTime(time);\n // Compared against null rather than tested for truthiness, so an entry\n // whose id is 0 is still found.\n if (closestIdentifier === null) return null;\n\n return this.elementForIdentifier(closestIdentifier);\n }\n\n private elementForIdentifier(identifier: number): HTMLElement | null {\n return (\n this.shadowRoot?.querySelector(\n `ia-transcript-entry[data-identifier=\"${identifier}\"]`,\n ) ?? null\n );\n }\n\n /**\n * Steps auto-scroll aside when the listener scrolls by hand, and arranges to\n * pick it back up once they've left it alone for a while.\n *\n * A wheel that the transcript cannot act on, such as a wheel-up when it is\n * already at the top, is ignored: the listener sees nothing move, so taking\n * auto-scroll away from them reads as the page misbehaving.\n */\n private didScroll(event: Event): void {\n if (event instanceof WheelEvent && !this.canScrollBy(event.deltaY)) return;\n\n this.autoScroll = false;\n\n clearTimeout(this.scrollResumeTimerId);\n this.scrollResumeTimerId = setTimeout(() => {\n this.autoScroll = true;\n }, this.scrollTimerDelay);\n }\n\n /** Whether the transcript has anywhere left to go in `deltaY`'s direction. */\n private canScrollBy(deltaY: number): boolean {\n const { scrollView } = this;\n if (!scrollView) return false;\n\n const { scrollTop, scrollHeight, clientHeight } = scrollView;\n if (deltaY < 0) return scrollTop > 0;\n if (deltaY > 0) return Math.ceil(scrollTop + clientHeight) < scrollHeight;\n return false;\n }\n\n private enableAutoScroll(): void {\n this.autoScroll = true;\n this.scrollToClosestEntry();\n }\n\n private get activeTranscriptEntry(): HTMLElement | null {\n return (\n this.shadowRoot?.querySelector('ia-transcript-entry[isActive]') ?? null\n );\n }\n\n private get selectedSearchResult(): HTMLElement | null {\n return (\n this.shadowRoot?.querySelector(\n `ia-transcript-entry[data-search-result-index=\"${this.selectedSearchResultIndex}\"]`,\n ) ?? null\n );\n }\n\n private get closestEntryToCurrentTime(): HTMLElement | null {\n return (\n this.activeTranscriptEntry ?? this.elementClosestToTime(this.currentTime)\n );\n }\n\n private scrollToClosestEntry(): void {\n if (!this.autoScroll) return;\n\n const closestEntry = this.closestEntryToCurrentTime;\n if (closestEntry) this.scrollToElement(closestEntry);\n }\n\n /**\n * Scrolls an entry to the top of the focus area, if it isn't in there\n * already.\n */\n private scrollToElement(element: HTMLElement): void {\n const { scrollView } = this;\n if (!scrollView) return;\n\n const containerRect = scrollView.getBoundingClientRect();\n const entryRect = element.getBoundingClientRect();\n const focusBottom = containerRect.height - this.bottomContextHeight;\n\n const isBelowFocusArea = entryRect.bottom > containerRect.top + focusBottom;\n const isAboveFocusArea = entryRect.top < containerRect.top;\n if (!isBelowFocusArea && !isAboveFocusArea) return;\n\n this.scrollToOffset(\n entryRect.top -\n containerRect.top +\n scrollView.scrollTop -\n this.topContextHeight,\n );\n }\n\n private updateTimePosition(): void {\n const scrollToEntry = this.closestEntryToCurrentTime;\n if (!scrollToEntry) return;\n\n const parent = scrollToEntry.parentNode as HTMLElement | null;\n if (!parent) return;\n\n this.timeScrollTop =\n scrollToEntry.getBoundingClientRect().top -\n parent.getBoundingClientRect().top;\n }\n\n /**\n * Eases the scroll container to an offset.\n *\n * Only one animation runs at a time: playback ticks arrive faster than an\n * animation finishes, and two loops writing `scrollTop` fight each other.\n */\n private scrollToOffset(offset: number): void {\n const { scrollView } = this;\n if (!scrollView) return;\n\n this.cancelScrollAnimation();\n\n const start = scrollView.scrollTop;\n const change = offset - start;\n const startTime = performance.now();\n\n const easeInOutQuad = (time: number): number =>\n time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time;\n\n const animate = (): void => {\n const elapsed = (performance.now() - startTime) / 1000;\n // Clamped so the last frame lands exactly on the target rather than\n // overshooting past it.\n const progress = Math.min(elapsed / SCROLL_DURATION_SECONDS, 1);\n\n scrollView.scrollTop = start + change * easeInOutQuad(progress);\n\n if (progress < 1) {\n this.scrollAnimationId = requestAnimationFrame(animate);\n } else {\n this.scrollAnimationId = undefined;\n }\n };\n\n animate();\n }\n\n private cancelScrollAnimation(): void {\n if (this.scrollAnimationId === undefined) return;\n\n cancelAnimationFrame(this.scrollAnimationId);\n this.scrollAnimationId = undefined;\n }\n\n static get styles(): CSSResultGroup {\n return css`\n :host {\n --transcript-height--: var(--ia-theme-transcript-height, 200px);\n\n --transcript-normal-text-color--: var(\n --ia-theme-transcript-normal-text-color,\n gray\n );\n --transcript-active-text-color--: var(\n --ia-theme-transcript-active-text-color,\n white\n );\n --transcript-hover-text-color--: var(\n --ia-theme-transcript-hover-text-color,\n silver\n );\n\n --transcript-music-normal-text-color--: var(\n --ia-theme-transcript-music-normal-text-color,\n gray\n );\n --transcript-music-active-text-color--: var(\n --ia-theme-transcript-music-active-text-color,\n white\n );\n --transcript-music-hover-text-color--: var(\n --ia-theme-transcript-music-hover-text-color,\n silver\n );\n\n --transcript-search-result-inactive-border-color--: var(\n --ia-theme-transcript-search-result-inactive-border-color,\n gray\n );\n --transcript-search-result-active-border-color--: var(\n --ia-theme-transcript-search-result-active-border-color,\n green\n );\n\n --transcript-time-color--: var(--ia-theme-transcript-time-color, white);\n --transcript-time-column-width--: var(\n --ia-theme-transcript-time-column-width,\n 3rem\n );\n --transcript-time-font-size--: var(\n --ia-theme-transcript-time-font-size,\n 1em\n );\n --transcript-time-line-height--: var(\n --ia-theme-transcript-time-line-height,\n 1em\n );\n --transcript-time-display--: var(\n --ia-theme-transcript-time-display,\n block\n );\n\n --transcript-auto-scroll-button-color--: var(\n --ia-theme-transcript-auto-scroll-button-color,\n black\n );\n --transcript-auto-scroll-button-background--: var(\n --ia-theme-transcript-auto-scroll-button-background,\n white\n );\n --transcript-auto-scroll-button-width--: var(\n --ia-theme-transcript-auto-scroll-button-width,\n 12rem\n );\n --transcript-auto-scroll-button-font-size--: var(\n --ia-theme-transcript-auto-scroll-button-font-size,\n 1em\n );\n\n color: var(--transcript-normal-text-color--);\n }\n\n .container {\n position: relative;\n }\n\n .auto-scroll-button {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 1rem;\n margin: auto;\n width: var(--transcript-auto-scroll-button-width--);\n border-radius: 1em;\n border: 0;\n display: inline-block;\n color: var(--transcript-auto-scroll-button-color--);\n background-color: var(--transcript-auto-scroll-button-background--);\n font-size: var(--transcript-auto-scroll-button-font-size--);\n cursor: pointer;\n z-index: 10;\n }\n\n .auto-scroll-button.hidden {\n display: none;\n }\n\n .context-overlay {\n position: absolute;\n left: 0;\n width: 100%;\n height: 0;\n /* Purely a guide. It sits over the top and bottom of the scroll area,\n so without this it would swallow the wheel and the entry clicks\n there, breaking the scrolling it exists to help you look at. */\n pointer-events: none;\n }\n\n .context-overlay.top {\n top: 0;\n border-bottom: 1px solid green;\n }\n\n .context-overlay.bottom {\n bottom: 0;\n border-top: 1px solid green;\n }\n\n .time {\n display: var(--transcript-time-display--);\n flex: 0 0 var(--transcript-time-column-width--);\n color: var(--transcript-time-color--);\n position: relative;\n }\n\n .time-display {\n position: absolute;\n top: 0;\n font-size: var(--transcript-time-font-size--);\n line-height: var(--transcript-time-line-height--);\n transition: top 1s;\n }\n\n .scroll-container {\n display: flex;\n overflow-y: auto;\n -ms-overflow-style: none;\n scrollbar-width: none;\n height: var(--transcript-height--);\n }\n\n .scroll-container::-webkit-scrollbar {\n display: none;\n }\n\n ia-transcript-entry {\n cursor: pointer;\n }\n\n ia-transcript-entry:hover {\n color: var(--transcript-hover-text-color--);\n }\n\n ia-transcript-entry[ismusicentry] {\n color: var(--transcript-music-normal-text-color--);\n display: block;\n font-style: italic;\n }\n\n ia-transcript-entry[ismusicentry]:hover {\n color: var(--transcript-music-hover-text-color--);\n }\n\n ia-transcript-entry[ismusicentry][isactive] {\n color: var(--transcript-music-active-text-color--);\n }\n\n ia-transcript-entry[isactive] {\n color: var(--transcript-active-text-color--);\n }\n\n ia-transcript-entry[issearchresult] {\n /* Inline-block, or the outline adds a space to the right of the text */\n display: inline-block;\n padding: 0 5px;\n position: relative;\n }\n\n ia-transcript-entry[issearchresult]:after {\n content: '';\n display: block;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n border: 2px solid\n var(--transcript-search-result-inactive-border-color--);\n border-radius: 5px;\n }\n\n ia-transcript-entry[issearchresult][isselected]:after {\n border: 2px solid var(--transcript-search-result-active-border-color--);\n }\n `;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ia-transcript-view.js","sourceRoot":"","sources":["../../../../src/elements/ia-transcript-view/ia-transcript-view.ts"],"names":[],"mappings":";;AAAA,OAAO,EACL,GAAG,EACH,IAAI,EACJ,UAAU,EACV,OAAO,GAIR,MAAM,KAAK,CAAC;AACb,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAItD,OAAO,uBAAuB,CAAC;AAE/B;;GAEG;AACH,MAAM,MAAM,GAAG;IACb,uBAAuB,EAAE,yBAAyB;IAClD,qBAAqB,EAAE,uBAAuB;IAC9C,iBAAiB,EAAE,mBAAmB;CACvC,CAAC;AAEF,mDAAmD;AACnD,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAElC;;;;;GAKG;AAEI,IAAM,gBAAgB,wBAAtB,MAAM,gBAAiB,SAAQ,UAAU;IAAzC;;QAIL,mDAAmD;QACvB,gBAAW,GAAG,CAAC,CAAC;QAE5C,qEAAqE;QACzC,qBAAgB,GAAG,EAAE,CAAC;QAElD,qEAAqE;QACzC,wBAAmB,GAAG,EAAE,CAAC;QAErD,8CAA8C;QACjB,eAAU,GAAG,IAAI,CAAC;QAE/C,uDAAuD;QAC3B,8BAAyB,GAAG,CAAC,CAAC;QAE1D,yEAAyE;QAC5C,qBAAgB,GAAG,KAAK,CAAC;QAEtD,6EAA6E;QACjD,qBAAgB,GAAG,KAAK,CAAC;QAEpC,kBAAa,GAAG,CAAC,CAAC;QAElB,mBAAc,GAA4B,EAAE,CAAC;IAgjBhE,CAAC;IAxiBC,oBAAoB;QAClB,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAC7B,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACvC,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC/B,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,OAAO;;;;;mBAKlD,IAAI,CAAC,SAAS;uBACV,IAAI,CAAC,SAAS;;kCAEH,IAAI,CAAC,mBAAmB;;;cAG5C,IAAI,CAAC,wBAAwB;cAC7B,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACrC,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,CACpC;;;;KAIR,CAAC;IACJ,CAAC;IAED,oDAAoD;IACpD,4BAA4B;QAC1B,MAAM,EAAE,oBAAoB,EAAE,GAAG,IAAI,CAAC;QACtC,IAAI,CAAC,oBAAoB;YAAE,OAAO;QAElC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,eAAe,CAAC,oBAAoB,CAAC,CAAC;IAC7C,CAAC;IAED,6EAA6E;IAC7E,4BAA4B,CAAC,IAAY;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACvC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEtC,IAAI,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAEnD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAI,KAAK,GAAG,aAAa,EAAE,CAAC;gBAC1B,aAAa,GAAG,KAAK,CAAC;gBACtB,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC,EAAE,CAAC;IACpB,CAAC;IAED,IAAY,wBAAwB;QAClC,OAAO,IAAI,CAAA;;;oCAGqB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;iBAClD,IAAI,CAAC,gBAAgB;;UAE5B,GAAG,CAAC,wBAAwB,CAAC;;KAElC,CAAC;IACJ,CAAC;IAED,IAAY,mBAAmB;QAC7B,OAAO,IAAI,CAAA;8CAC+B,IAAI,CAAC,aAAa;UACtD,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC;;KAErC,CAAC;IACJ,CAAC;IAEO,uBAAuB,CAC7B,KAA4B;QAE5B,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CACvC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAC/C,CAAC;QAEF,OAAO,IAAI,CAAA;;iBAEE,KAAK;oBACF,QAAQ;sBACN,KAAK,CAAC,gBAAgB,KAAK,IAAI,CAAC,yBAAyB;0BACrD,KAAK,CAAC,gBAAgB,KAAK,SAAS;wBACtC,KAAK,CAAC,OAAO;;mCAEF,SAAS,CAAC,KAAK,CAAC,gBAAgB,CAAC;0BAC1C,KAAK,CAAC,EAAE;iBACjB,IAAI,CAAC,uBAAuB;;KAExC,CAAC;IACJ,CAAC;IAED,IAAY,oBAAoB;QAC9B,OAAO,IAAI,CAAA;;;yBAGU,IAAI,CAAC,gBAAgB;;;;yBAIrB,IAAI,CAAC,mBAAmB;;KAE5C,CAAC;IACJ,CAAC;IAED,IAAY,iBAAiB;QAC3B,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC;IACpC,CAAC;IAED,OAAO,CAAC,iBAAiC;QACvC,IAAI,iBAAiB,CAAC,GAAG,CAAC,aAAa,CAAC;YAAE,IAAI,CAAC,uBAAuB,EAAE,CAAC;QACzE,IAAI,iBAAiB,CAAC,GAAG,CAAC,2BAA2B,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,4BAA4B,EAAE,CAAC;QACtC,CAAC;QACD,IAAI,iBAAiB,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC5B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC;QACD,IAAI,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAA0B,MAAM,CAAC,iBAAiB,EAAE;gBACjE,MAAM,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE;aACxC,CAAC,CACH,CAAC;QACJ,CAAC;QACD,IAAI,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,yBAAyB,GAAG,CAAC,CAAC;YACnC,IAAI,CAAC,4BAA4B,EAAE,CAAC;QACtC,CAAC;IACH,CAAC;IAEO,uBAAuB,CAAC,CAAQ;QACtC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,aAAkC,CAAC;QACvD,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CACb,MAAM,CAAC,uBAAuB,EAC9B,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,CACtB,CACF,CAAC;QAEF,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,yBAAyB,GAAG,KAAK,CAAC,gBAAgB,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC1B,CAAC;IAED;;;;;OAKG;IACK,uBAAuB;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACvC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEjC,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAClC,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,GAAG,CACnE,CAAC;QAEF,IAAI,kBAAgB,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;YAC1E,OAAO;QACT,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;IACtC,CAAC;IAEO,MAAM,CAAC,gBAAgB,CAC7B,CAA0B,EAC1B,CAA0B;QAE1B,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAExC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAE9D,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;IACvD,CAAC;IAEO,oBAAoB,CAAC,IAAY;QACvC,MAAM,iBAAiB,GAAG,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC;QAClE,uEAAuE;QACvE,gCAAgC;QAChC,IAAI,iBAAiB,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAE5C,OAAO,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IACtD,CAAC;IAEO,oBAAoB,CAAC,UAAkB;QAC7C,OAAO,CACL,IAAI,CAAC,UAAU,EAAE,aAAa,CAC5B,wCAAwC,UAAU,IAAI,CACvD,IAAI,IAAI,CACV,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACK,SAAS,CAAC,KAAY;QAC5B,IAAI,KAAK,YAAY,UAAU,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;YAAE,OAAO;QAE3E,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAExB,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACvC,IAAI,CAAC,mBAAmB,GAAG,UAAU,CAAC,GAAG,EAAE;YACzC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC5B,CAAC;IAED,8EAA8E;IACtE,WAAW,CAAC,MAAc;QAChC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QAE9B,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,UAAU,CAAC;QAC7D,IAAI,MAAM,GAAG,CAAC;YAAE,OAAO,SAAS,GAAG,CAAC,CAAC;QACrC,IAAI,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,YAAY,CAAC,GAAG,YAAY,CAAC;QAC1E,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,gBAAgB;QACtB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAED,IAAY,qBAAqB;QAC/B,OAAO,CACL,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,+BAA+B,CAAC,IAAI,IAAI,CACxE,CAAC;IACJ,CAAC;IAED,IAAY,oBAAoB;QAC9B,OAAO,CACL,IAAI,CAAC,UAAU,EAAE,aAAa,CAC5B,iDAAiD,IAAI,CAAC,yBAAyB,IAAI,CACpF,IAAI,IAAI,CACV,CAAC;IACJ,CAAC;IAED,IAAY,yBAAyB;QACnC,OAAO,CACL,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,CAC1E,CAAC;IACJ,CAAC;IAEO,oBAAoB;QAC1B,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QAE7B,MAAM,YAAY,GAAG,IAAI,CAAC,yBAAyB,CAAC;QACpD,IAAI,YAAY;YAAE,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACK,eAAe,CAAC,OAAoB;QAC1C,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,UAAU;YAAE,OAAO;QAExB,MAAM,aAAa,GAAG,UAAU,CAAC,qBAAqB,EAAE,CAAC;QACzD,MAAM,SAAS,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;QAClD,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,GAAG,IAAI,CAAC,mBAAmB,CAAC;QAEpE,MAAM,gBAAgB,GAAG,SAAS,CAAC,MAAM,GAAG,aAAa,CAAC,GAAG,GAAG,WAAW,CAAC;QAC5E,MAAM,gBAAgB,GAAG,SAAS,CAAC,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC;QAC3D,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB;YAAE,OAAO;QAEnD,IAAI,CAAC,cAAc,CACjB,SAAS,CAAC,GAAG;YACX,aAAa,CAAC,GAAG;YACjB,UAAU,CAAC,SAAS;YACpB,IAAI,CAAC,gBAAgB,CACxB,CAAC;IACJ,CAAC;IAEO,kBAAkB;QACxB,MAAM,aAAa,GAAG,IAAI,CAAC,yBAAyB,CAAC;QACrD,IAAI,CAAC,aAAa;YAAE,OAAO;QAE3B,MAAM,MAAM,GAAG,aAAa,CAAC,UAAgC,CAAC;QAC9D,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,IAAI,CAAC,aAAa;YAChB,aAAa,CAAC,qBAAqB,EAAE,CAAC,GAAG;gBACzC,MAAM,CAAC,qBAAqB,EAAE,CAAC,GAAG,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACK,cAAc,CAAC,MAAc;QACnC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,UAAU;YAAE,OAAO;QAExB,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAE7B,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;QAC9B,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAEpC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAU,EAAE,CAC7C,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;QAE5D,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,MAAM,OAAO,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;YACvD,oEAAoE;YACpE,wBAAwB;YACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,uBAAuB,EAAE,CAAC,CAAC,CAAC;YAEhE,UAAU,CAAC,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;YAEhE,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;gBACjB,IAAI,CAAC,iBAAiB,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;YAC1D,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACrC,CAAC;QACH,CAAC,CAAC;QAEF,OAAO,EAAE,CAAC;IACZ,CAAC;IAEO,qBAAqB;QAC3B,IAAI,IAAI,CAAC,iBAAiB,KAAK,SAAS;YAAE,OAAO;QAEjD,oBAAoB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC7C,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;IACrC,CAAC;IAED,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAuMT,CAAC;IACJ,CAAC;CACF,CAAA;AAzkB6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gDAA2B;AAG1B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;qDAAiB;AAGhB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0DAAuB;AAGtB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6DAA0B;AAGxB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;oDAAmB;AAGnB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;mEAA+B;AAG7B;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;0DAA0B;AAG1B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0DAA0B;AAEpC;IAAhB,KAAK,EAAE;uDAA2B;AAElB;IAAhB,KAAK,EAAE;wDAAsD;AAE1B;IAAnC,KAAK,CAAC,mBAAmB,CAAC;oDAAyC;AA7BzD,gBAAgB;IAD5B,aAAa,CAAC,oBAAoB,CAAC;GACvB,gBAAgB,CA2kB5B","sourcesContent":["import {\n css,\n html,\n LitElement,\n nothing,\n type CSSResultGroup,\n type PropertyValues,\n type TemplateResult,\n} from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { customElement } from '@src/util/custom-element';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { msg } from '@lit/localize';\n\nimport { formatDuration } from './duration-formatter';\nimport type { TranscriptConfig, TranscriptEntryConfig } from './models';\nimport type { IATranscriptEntry } from './ia-transcript-entry';\n\nimport './ia-transcript-entry';\n\n/**\n * Event names emitted by this component\n */\nconst Events = {\n TranscriptEntrySelected: 'transcriptEntrySelected',\n CurrentEntriesUpdated: 'currentEntriesUpdated',\n AutoScrollChanged: 'autoScrollChanged',\n};\n\n/** How long a scroll animation runs, in seconds */\nconst SCROLL_DURATION_SECONDS = 1;\n\n/**\n * A scrolling transcript that follows playback.\n *\n * It keeps itself scrolled to whatever is being spoken, steps aside when the\n * listener scrolls by hand, and picks the job back up once they've stopped.\n */\n@customElement('ia-transcript-view')\nexport class IATranscriptView extends LitElement {\n /** The transcript to render */\n @property({ type: Object }) config?: TranscriptConfig;\n\n /** Playback position, in seconds into the track */\n @property({ type: Number }) currentTime = 0;\n\n /** How much room to leave above the entry being spoken, in pixels */\n @property({ type: Number }) topContextHeight = 50;\n\n /** How much room to leave below the entry being spoken, in pixels */\n @property({ type: Number }) bottomContextHeight = 50;\n\n /** Whether the transcript follows playback */\n @property({ type: Boolean }) autoScroll = true;\n\n /** Which search result is currently being looked at */\n @property({ type: Number }) selectedSearchResultIndex = 0;\n\n /** Whether to outline the context zones, for working on the scrolling */\n @property({ type: Boolean }) showContextZones = false;\n\n /** How long to wait after a manual scroll before following playback again */\n @property({ type: Number }) scrollTimerDelay = 15000;\n\n @state() private timeScrollTop = 0;\n\n @state() private currentEntries: TranscriptEntryConfig[] = [];\n\n @query('#scroll-container') private scrollView?: HTMLElement | null;\n\n private scrollResumeTimerId?: ReturnType<typeof setTimeout>;\n\n private scrollAnimationId?: number;\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n clearTimeout(this.scrollResumeTimerId);\n this.cancelScrollAnimation();\n }\n\n render(): TemplateResult {\n return html`\n <div class=\"container\">\n ${this.showContextZones ? this.contextZoneTemplates : nothing}\n\n <div\n class=\"scroll-container\"\n id=\"scroll-container\"\n @wheel=${this.didScroll}\n @touchmove=${this.didScroll}\n >\n <div class=\"col time\">${this.timeDisplayTemplate}</div>\n\n <div class=\"col\">\n ${this.autoScrollButtonTemplate}\n ${this.transcriptEntries.map((entry) =>\n this.transcriptEntryTemplate(entry),\n )}\n </div>\n </div>\n </div>\n `;\n }\n\n /** Scrolls the selected search result into view. */\n scrollToSelectedSearchResult(): void {\n const { selectedSearchResult } = this;\n if (!selectedSearchResult) return;\n\n this.autoScroll = false;\n this.scrollToElement(selectedSearchResult);\n }\n\n /** The id of the entry starting closest to a given time, if there is one. */\n entryIdentifierClosestToTime(time: number): number | null {\n const entries = this.transcriptEntries;\n if (entries.length === 0) return null;\n\n let closest = entries[0];\n let smallestDelta = Math.abs(time - closest.start);\n\n for (const entry of entries) {\n const delta = Math.abs(time - entry.start);\n if (delta < smallestDelta) {\n smallestDelta = delta;\n closest = entry;\n }\n }\n\n return closest.id;\n }\n\n private get autoScrollButtonTemplate(): TemplateResult {\n return html`\n <button\n type=\"button\"\n class=\"auto-scroll-button ${this.autoScroll ? 'hidden' : ''}\"\n @click=${this.enableAutoScroll}\n >\n ${msg('Scroll text with audio')}\n </button>\n `;\n }\n\n private get timeDisplayTemplate(): TemplateResult {\n return html`\n <div class=\"time-display\" style=\"top: ${this.timeScrollTop}px\">\n ${formatDuration(this.currentTime)}\n </div>\n `;\n }\n\n private transcriptEntryTemplate(\n entry: TranscriptEntryConfig,\n ): TemplateResult {\n const isActive = this.currentEntries.some(\n (currentEntry) => currentEntry.id === entry.id,\n );\n\n return html`\n <ia-transcript-entry\n .entry=${entry}\n ?isActive=${isActive}\n ?isSelected=${entry.searchMatchIndex === this.selectedSearchResultIndex}\n ?isSearchResult=${entry.searchMatchIndex !== undefined}\n ?isMusicEntry=${entry.isMusic}\n isClickable\n data-search-result-index=${ifDefined(entry.searchMatchIndex)}\n data-identifier=${entry.id}\n @click=${this.transcriptEntrySelected}\n ></ia-transcript-entry>\n `;\n }\n\n private get contextZoneTemplates(): TemplateResult {\n return html`\n <div\n class=\"top context-overlay\"\n style=\"height: ${this.topContextHeight}px\"\n ></div>\n <div\n class=\"bottom context-overlay\"\n style=\"height: ${this.bottomContextHeight}px\"\n ></div>\n `;\n }\n\n private get transcriptEntries(): TranscriptEntryConfig[] {\n return this.config?.entries ?? [];\n }\n\n updated(changedProperties: PropertyValues): void {\n if (changedProperties.has('currentTime')) this.handleCurrentTimeChange();\n if (changedProperties.has('selectedSearchResultIndex')) {\n this.scrollToSelectedSearchResult();\n }\n if (changedProperties.has('currentEntries')) {\n this.scrollToClosestEntry();\n this.updateTimePosition();\n }\n if (changedProperties.has('autoScroll')) {\n this.dispatchEvent(\n new CustomEvent<{ autoScroll: boolean }>(Events.AutoScrollChanged, {\n detail: { autoScroll: this.autoScroll },\n }),\n );\n }\n if (changedProperties.has('config')) {\n this.selectedSearchResultIndex = 0;\n this.scrollToSelectedSearchResult();\n }\n }\n\n private transcriptEntrySelected(e: Event): void {\n const { entry } = e.currentTarget as IATranscriptEntry;\n if (!entry) return;\n\n this.dispatchEvent(\n new CustomEvent<{ entry: TranscriptEntryConfig }>(\n Events.TranscriptEntrySelected,\n { detail: { entry } },\n ),\n );\n\n if (entry.searchMatchIndex !== undefined) {\n this.selectedSearchResultIndex = entry.searchMatchIndex;\n }\n this.autoScroll = false;\n }\n\n /**\n * Works out which entries are being spoken now.\n *\n * Runs on every time update, several times a second, so it only touches the\n * rendered state when the set of entries has actually changed.\n */\n private handleCurrentTimeChange(): void {\n const entries = this.transcriptEntries;\n if (entries.length === 0) return;\n\n const activeEntries = entries.filter(\n (entry) =>\n this.currentTime >= entry.start && this.currentTime <= entry.end,\n );\n\n if (IATranscriptView.entryArraysMatch(activeEntries, this.currentEntries)) {\n return;\n }\n\n this.dispatchEvent(new Event(Events.CurrentEntriesUpdated));\n this.currentEntries = activeEntries;\n }\n\n private static entryArraysMatch(\n a: TranscriptEntryConfig[],\n b: TranscriptEntryConfig[],\n ): boolean {\n if (a.length !== b.length) return false;\n\n const aIds = a.map((entry) => entry.id).sort((x, y) => x - y);\n const bIds = b.map((entry) => entry.id).sort((x, y) => x - y);\n\n return aIds.every((id, index) => bIds[index] === id);\n }\n\n private elementClosestToTime(time: number): HTMLElement | null {\n const closestIdentifier = this.entryIdentifierClosestToTime(time);\n // Compared against null rather than tested for truthiness, so an entry\n // whose id is 0 is still found.\n if (closestIdentifier === null) return null;\n\n return this.elementForIdentifier(closestIdentifier);\n }\n\n private elementForIdentifier(identifier: number): HTMLElement | null {\n return (\n this.shadowRoot?.querySelector(\n `ia-transcript-entry[data-identifier=\"${identifier}\"]`,\n ) ?? null\n );\n }\n\n /**\n * Steps auto-scroll aside when the listener scrolls by hand, and arranges to\n * pick it back up once they've left it alone for a while.\n *\n * A wheel that the transcript cannot act on, such as a wheel-up when it is\n * already at the top, is ignored: the listener sees nothing move, so taking\n * auto-scroll away from them reads as the page misbehaving.\n */\n private didScroll(event: Event): void {\n if (event instanceof WheelEvent && !this.canScrollBy(event.deltaY)) return;\n\n this.autoScroll = false;\n\n clearTimeout(this.scrollResumeTimerId);\n this.scrollResumeTimerId = setTimeout(() => {\n this.autoScroll = true;\n }, this.scrollTimerDelay);\n }\n\n /** Whether the transcript has anywhere left to go in `deltaY`'s direction. */\n private canScrollBy(deltaY: number): boolean {\n const { scrollView } = this;\n if (!scrollView) return false;\n\n const { scrollTop, scrollHeight, clientHeight } = scrollView;\n if (deltaY < 0) return scrollTop > 0;\n if (deltaY > 0) return Math.ceil(scrollTop + clientHeight) < scrollHeight;\n return false;\n }\n\n private enableAutoScroll(): void {\n this.autoScroll = true;\n this.scrollToClosestEntry();\n }\n\n private get activeTranscriptEntry(): HTMLElement | null {\n return (\n this.shadowRoot?.querySelector('ia-transcript-entry[isActive]') ?? null\n );\n }\n\n private get selectedSearchResult(): HTMLElement | null {\n return (\n this.shadowRoot?.querySelector(\n `ia-transcript-entry[data-search-result-index=\"${this.selectedSearchResultIndex}\"]`,\n ) ?? null\n );\n }\n\n private get closestEntryToCurrentTime(): HTMLElement | null {\n return (\n this.activeTranscriptEntry ?? this.elementClosestToTime(this.currentTime)\n );\n }\n\n private scrollToClosestEntry(): void {\n if (!this.autoScroll) return;\n\n const closestEntry = this.closestEntryToCurrentTime;\n if (closestEntry) this.scrollToElement(closestEntry);\n }\n\n /**\n * Scrolls an entry to the top of the focus area, if it isn't in there\n * already.\n */\n private scrollToElement(element: HTMLElement): void {\n const { scrollView } = this;\n if (!scrollView) return;\n\n const containerRect = scrollView.getBoundingClientRect();\n const entryRect = element.getBoundingClientRect();\n const focusBottom = containerRect.height - this.bottomContextHeight;\n\n const isBelowFocusArea = entryRect.bottom > containerRect.top + focusBottom;\n const isAboveFocusArea = entryRect.top < containerRect.top;\n if (!isBelowFocusArea && !isAboveFocusArea) return;\n\n this.scrollToOffset(\n entryRect.top -\n containerRect.top +\n scrollView.scrollTop -\n this.topContextHeight,\n );\n }\n\n private updateTimePosition(): void {\n const scrollToEntry = this.closestEntryToCurrentTime;\n if (!scrollToEntry) return;\n\n const parent = scrollToEntry.parentNode as HTMLElement | null;\n if (!parent) return;\n\n this.timeScrollTop =\n scrollToEntry.getBoundingClientRect().top -\n parent.getBoundingClientRect().top;\n }\n\n /**\n * Eases the scroll container to an offset.\n *\n * Only one animation runs at a time: playback ticks arrive faster than an\n * animation finishes, and two loops writing `scrollTop` fight each other.\n */\n private scrollToOffset(offset: number): void {\n const { scrollView } = this;\n if (!scrollView) return;\n\n this.cancelScrollAnimation();\n\n const start = scrollView.scrollTop;\n const change = offset - start;\n const startTime = performance.now();\n\n const easeInOutQuad = (time: number): number =>\n time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time;\n\n const animate = (): void => {\n const elapsed = (performance.now() - startTime) / 1000;\n // Clamped so the last frame lands exactly on the target rather than\n // overshooting past it.\n const progress = Math.min(elapsed / SCROLL_DURATION_SECONDS, 1);\n\n scrollView.scrollTop = start + change * easeInOutQuad(progress);\n\n if (progress < 1) {\n this.scrollAnimationId = requestAnimationFrame(animate);\n } else {\n this.scrollAnimationId = undefined;\n }\n };\n\n animate();\n }\n\n private cancelScrollAnimation(): void {\n if (this.scrollAnimationId === undefined) return;\n\n cancelAnimationFrame(this.scrollAnimationId);\n this.scrollAnimationId = undefined;\n }\n\n static get styles(): CSSResultGroup {\n return css`\n :host {\n --transcript-height--: var(--ia-theme-transcript-height, 200px);\n\n --transcript-normal-text-color--: var(\n --ia-theme-transcript-normal-text-color,\n gray\n );\n --transcript-active-text-color--: var(\n --ia-theme-transcript-active-text-color,\n white\n );\n --transcript-hover-text-color--: var(\n --ia-theme-transcript-hover-text-color,\n silver\n );\n\n --transcript-music-normal-text-color--: var(\n --ia-theme-transcript-music-normal-text-color,\n gray\n );\n --transcript-music-active-text-color--: var(\n --ia-theme-transcript-music-active-text-color,\n white\n );\n --transcript-music-hover-text-color--: var(\n --ia-theme-transcript-music-hover-text-color,\n silver\n );\n\n --transcript-search-result-inactive-border-color--: var(\n --ia-theme-transcript-search-result-inactive-border-color,\n gray\n );\n --transcript-search-result-active-border-color--: var(\n --ia-theme-transcript-search-result-active-border-color,\n green\n );\n\n --transcript-time-color--: var(--ia-theme-transcript-time-color, white);\n --transcript-time-column-width--: var(\n --ia-theme-transcript-time-column-width,\n 3rem\n );\n --transcript-time-font-size--: var(\n --ia-theme-transcript-time-font-size,\n 1em\n );\n --transcript-time-line-height--: var(\n --ia-theme-transcript-time-line-height,\n 1em\n );\n --transcript-time-display--: var(\n --ia-theme-transcript-time-display,\n block\n );\n\n --transcript-auto-scroll-button-color--: var(\n --ia-theme-transcript-auto-scroll-button-color,\n black\n );\n --transcript-auto-scroll-button-background--: var(\n --ia-theme-transcript-auto-scroll-button-background,\n white\n );\n --transcript-auto-scroll-button-width--: var(\n --ia-theme-transcript-auto-scroll-button-width,\n 12rem\n );\n --transcript-auto-scroll-button-font-size--: var(\n --ia-theme-transcript-auto-scroll-button-font-size,\n 1em\n );\n\n color: var(--transcript-normal-text-color--);\n }\n\n .container {\n position: relative;\n }\n\n .auto-scroll-button {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 1rem;\n margin: auto;\n width: var(--transcript-auto-scroll-button-width--);\n border-radius: 1em;\n border: 0;\n display: inline-block;\n color: var(--transcript-auto-scroll-button-color--);\n background-color: var(--transcript-auto-scroll-button-background--);\n font-size: var(--transcript-auto-scroll-button-font-size--);\n cursor: pointer;\n z-index: 10;\n }\n\n .auto-scroll-button.hidden {\n display: none;\n }\n\n .context-overlay {\n position: absolute;\n left: 0;\n width: 100%;\n height: 0;\n /* Purely a guide. It sits over the top and bottom of the scroll area,\n so without this it would swallow the wheel and the entry clicks\n there, breaking the scrolling it exists to help you look at. */\n pointer-events: none;\n }\n\n .context-overlay.top {\n top: 0;\n border-bottom: 1px solid green;\n }\n\n .context-overlay.bottom {\n bottom: 0;\n border-top: 1px solid green;\n }\n\n .time {\n display: var(--transcript-time-display--);\n flex: 0 0 var(--transcript-time-column-width--);\n color: var(--transcript-time-color--);\n position: relative;\n }\n\n .time-display {\n position: absolute;\n top: 0;\n font-size: var(--transcript-time-font-size--);\n line-height: var(--transcript-time-line-height--);\n transition: top 1s;\n }\n\n .scroll-container {\n display: flex;\n overflow-y: auto;\n -ms-overflow-style: none;\n scrollbar-width: none;\n height: var(--transcript-height--);\n }\n\n .scroll-container::-webkit-scrollbar {\n display: none;\n }\n\n ia-transcript-entry {\n cursor: pointer;\n }\n\n ia-transcript-entry:hover {\n color: var(--transcript-hover-text-color--);\n }\n\n ia-transcript-entry[ismusicentry] {\n color: var(--transcript-music-normal-text-color--);\n display: block;\n font-style: italic;\n }\n\n ia-transcript-entry[ismusicentry]:hover {\n color: var(--transcript-music-hover-text-color--);\n }\n\n ia-transcript-entry[ismusicentry][isactive] {\n color: var(--transcript-music-active-text-color--);\n }\n\n ia-transcript-entry[isactive] {\n color: var(--transcript-active-text-color--);\n }\n\n ia-transcript-entry[issearchresult] {\n /* Inline-block, or the outline adds a space to the right of the text */\n display: inline-block;\n padding: 0 5px;\n position: relative;\n }\n\n ia-transcript-entry[issearchresult]:after {\n content: '';\n display: block;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n border: 2px solid\n var(--transcript-search-result-inactive-border-color--);\n border-radius: 5px;\n }\n\n ia-transcript-entry[issearchresult][isselected]:after {\n border: 2px solid var(--transcript-search-result-active-border-color--);\n }\n `;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ia-waveform-progress.d.ts","sourceRoot":"","sources":["../../../../src/elements/ia-waveform-progress/ia-waveform-progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,UAAU,EAEV,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"ia-waveform-progress.d.ts","sourceRoot":"","sources":["../../../../src/elements/ia-waveform-progress/ia-waveform-progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,UAAU,EAEV,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,KAAK,CAAC;AAIb,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAS9C;;;;;;GAMG;AACH,qBACa,kBAAmB,SAAQ,UAAU;IAChD,wEAAwE;IAC5C,eAAe,SAAK;IAEhD,0CAA0C;IACd,WAAW,SAAM;IAE7C,4DAA4D;IAC/B,WAAW,UAAS;IAEjD,oEAAoE;IACzC,cAAc,EAAE,aAAa,EAAE,CAAM;IAEhE;;;;;;;OAOG;IACM,OAAO,CAAC,gBAAgB,CAAK;IAEtC,OAAO,CAAC,iBAAiB,CAAS;IAEb,OAAO,CAAC,SAAS,CAAC,CAAqB;IAE5D,MAAM,IAAI,cAAc;IAWxB,OAAO,KAAK,sBAAsB,GAYjC;IAED,OAAO,KAAK,wBAAwB,GAcnC;IAED,OAAO,CAAC,iBAAiB,EAAE,cAAc,GAAG,IAAI;IAQhD,OAAO,CAAC,IAAI;IAKZ;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IAOjB;;;;;;OAMG;IACH,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,sBAAsB;IAqB9B;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IAKxB,MAAM,KAAK,MAAM,IAAI,cAAc,CAsDlC;CACF"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
var IAWaveformProgress_1;
|
|
2
2
|
import { __decorate } from "tslib";
|
|
3
3
|
import { css, html, LitElement, nothing, } from 'lit';
|
|
4
|
-
import {
|
|
4
|
+
import { property, query, state } from 'lit/decorators.js';
|
|
5
|
+
import { customElement } from '../../util/custom-element.js';
|
|
5
6
|
/**
|
|
6
7
|
* Event names emitted by this component
|
|
7
8
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ia-waveform-progress.js","sourceRoot":"","sources":["../../../../src/elements/ia-waveform-progress/ia-waveform-progress.ts"],"names":[],"mappings":";;AAAA,OAAO,EACL,GAAG,EACH,IAAI,EACJ,UAAU,EACV,OAAO,GAIR,MAAM,KAAK,CAAC;AACb,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ia-waveform-progress.js","sourceRoot":"","sources":["../../../../src/elements/ia-waveform-progress/ia-waveform-progress.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n css,\n html,\n LitElement,\n nothing,\n type CSSResultGroup,\n type PropertyValues,\n type TemplateResult,\n} from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { customElement } from '@src/util/custom-element';\n\nimport type { ZoneOfSilence } from './models';\n\n/**\n * Event names emitted by this component\n */\nconst Events = {\n ValueChange: 'valuechange',\n};\n\n/**\n * Renders a waveform image with a progress fill over it, optionally marking\n * out the stretches of silence.\n *\n * When `interactive` is set, dragging anywhere across the waveform scrubs, and\n * the element emits `valuechange` with the new percentage.\n */\n@customElement('ia-waveform-progress')\nexport class IAWaveformProgress extends LitElement {\n /** How far through the track playback is, as a percentage (0 to 100) */\n @property({ type: Number }) percentComplete = 0;\n\n /** URL of the waveform image to render */\n @property({ type: String }) waveformUrl = '';\n\n /** Whether dragging across the waveform scrubs the track */\n @property({ type: Boolean }) interactive = false;\n\n /** Stretches of the track with no audio, to mark on the waveform */\n @property({ type: Array }) zonesOfSilence: ZoneOfSilence[] = [];\n\n /**\n * The percentage actually rendered.\n *\n * `percentComplete` is driven from outside by whatever is playing the audio,\n * but while the listener is dragging, their position wins. Keeping the two\n * apart is what lets the drag survive the playback updates arriving\n * underneath it.\n */\n @state() private displayedPercent = 0;\n\n private userIsInteracting = false;\n\n @query('.container') private container?: HTMLElement | null;\n\n render(): TemplateResult {\n return html`\n <div class=\"container\">\n <div id=\"fill\" style=\"width: ${this.displayedPercent}%\"></div>\n <img class=\"waveform-image\" src=${this.waveformUrl} alt=\"\" />\n ${this.zonesOfSilenceTemplate}\n ${this.interactive ? this.interactionCoverTemplate : nothing}\n </div>\n `;\n }\n\n private get zonesOfSilenceTemplate(): TemplateResult {\n return html`\n ${this.zonesOfSilence.map(\n (zone) => html`\n <div\n class=\"zone-of-silence\"\n style=\"left: ${zone.startPercent}%; width: ${zone.endPercent -\n zone.startPercent}%\"\n ></div>\n `,\n )}\n `;\n }\n\n private get interactionCoverTemplate(): TemplateResult {\n return html`\n <div\n id=\"dragcover\"\n @mousedown=${this.dragStart}\n @mouseup=${this.dragEnd}\n @mouseleave=${this.dragEnd}\n @mousemove=${this.drag}\n @touchstart=${this.dragStart}\n @touchend=${this.dragEnd}\n @touchcancel=${this.dragEnd}\n @touchmove=${this.drag}\n ></div>\n `;\n }\n\n updated(changedProperties: PropertyValues): void {\n if (!changedProperties.has('percentComplete') || this.userIsInteracting) {\n return;\n }\n\n this.displayedPercent = this.percentComplete;\n }\n\n private drag(e: MouseEvent | TouchEvent): void {\n if (!this.userIsInteracting) return;\n this.updateDisplayedPercent(e);\n }\n\n /**\n * Only the primary mouse button scrubs.\n *\n * A right-click would otherwise seek the track on its way to opening the\n * context menu, and the menu swallows the `mouseup`, so the drag would stay\n * latched on afterwards.\n */\n private dragStart(e: MouseEvent | TouchEvent): void {\n if ('button' in e && e.button !== 0) return;\n\n this.userIsInteracting = true;\n this.updateDisplayedPercent(e);\n }\n\n /**\n * Ends the drag.\n *\n * Bound to `touchcancel` as well as `touchend`, because a touch taken over by\n * the system (an incoming call, a browser gesture) never delivers `touchend`,\n * and a drag left latched on would ignore playback updates from then on.\n */\n private dragEnd(): void {\n this.userIsInteracting = false;\n }\n\n private updateDisplayedPercent(e: MouseEvent | TouchEvent): void {\n const pageX = IAWaveformProgress.pageXFrom(e);\n if (pageX === undefined || !this.container) return;\n\n const bounds = this.container.getBoundingClientRect();\n if (bounds.width === 0) return;\n\n // `pageX` is measured from the document origin, so the container's own\n // viewport position has to be put back into document space before the two\n // can be subtracted.\n const offsetX = pageX - (bounds.left + window.scrollX);\n const percent = (offsetX / bounds.width) * 100;\n\n this.displayedPercent = Math.min(Math.max(percent, 0), 100);\n this.dispatchEvent(\n new CustomEvent<{ value: number }>(Events.ValueChange, {\n detail: { value: this.displayedPercent },\n }),\n );\n }\n\n /**\n * The horizontal page position of a pointer, from either flavour of event.\n *\n * A `TouchEvent` carries no `pageX` of its own, so the first touch supplies\n * it. A `touchend` has no touches left to read, which is why this can come\n * back undefined.\n */\n private static pageXFrom(e: MouseEvent | TouchEvent): number | undefined {\n if ('touches' in e) return e.touches[0]?.pageX;\n return e.pageX;\n }\n\n static get styles(): CSSResultGroup {\n return css`\n :host {\n --waveform-fill-color--: var(--ia-theme-waveform-fill-color, #3272b6);\n --waveform-zone-of-silence-color--: var(\n --ia-theme-waveform-zone-of-silence-color,\n #f6e652\n );\n --waveform-side-margin--: var(--ia-theme-waveform-side-margin, 10px);\n\n display: inline-block;\n }\n\n #dragcover {\n width: 100%;\n height: 100%;\n position: absolute;\n touch-action: none;\n }\n\n .container {\n display: block;\n position: relative;\n background-color: white;\n height: 100%;\n margin-left: var(--waveform-side-margin--);\n margin-right: var(--waveform-side-margin--);\n }\n\n .waveform-image {\n width: 100%;\n height: 100%;\n position: absolute;\n }\n\n .zone-of-silence {\n position: absolute;\n top: 0;\n bottom: 0;\n background: linear-gradient(\n #000,\n #000 47%,\n var(--waveform-zone-of-silence-color--) 50%,\n #000 53%,\n #000 100%\n );\n }\n\n #fill {\n position: absolute;\n height: 100%;\n background-color: var(--waveform-fill-color--);\n }\n `;\n }\n}\n"]}
|
|
@@ -6,6 +6,7 @@ export * from './ia-dropdown-search-bar/ia-dropdown-search-bar.js';
|
|
|
6
6
|
export * from './ia-expandable-search-bar/ia-expandable-search-bar.js';
|
|
7
7
|
export * from './ia-expandable-search-bar/ia-quick-search.js';
|
|
8
8
|
export * from './ia-expandable-search-bar/models.js';
|
|
9
|
+
export * from './ia-image-viewer/ia-image-viewer.js';
|
|
9
10
|
export * from './ia-item-navigator/ia-item-navigator.js';
|
|
10
11
|
export * from './ia-item-navigator/menus/ia-itemnav-viewable-files-panel.js';
|
|
11
12
|
export * from './ia-item-navigator/menus/ia-itemnav-sort-files-button.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iDAAiD,CAAC;AAChE,cAAc,qDAAqD,CAAC;AACpE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,mCAAmC,CAAC;AAClD,cAAc,uCAAuC,CAAC;AACtD,cAAc,2DAA2D,CAAC;AAC1E,cAAc,wDAAwD,CAAC;AACvE,cAAc,kDAAkD,CAAC;AACjE,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,0BAA0B,CAAC;AACzC,cAAc,4DAA4D,CAAC;AAC3E,cAAc,6DAA6D,CAAC;AAC5E,cAAc,wDAAwD,CAAC;AACvE,cAAc,kDAAkD,CAAC;AACjE,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,wCAAwC,CAAC;AACvD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,0BAA0B,CAAC;AACzC,cAAc,yCAAyC,CAAC;AACxD,cAAc,0CAA0C,CAAC;AACzD,cAAc,yCAAyC,CAAC;AACxD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iDAAiD,CAAC;AAChE,cAAc,qDAAqD,CAAC;AACpE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,mCAAmC,CAAC;AAClD,cAAc,mCAAmC,CAAC;AAClD,cAAc,uCAAuC,CAAC;AACtD,cAAc,2DAA2D,CAAC;AAC1E,cAAc,wDAAwD,CAAC;AACvE,cAAc,kDAAkD,CAAC;AACjE,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,0BAA0B,CAAC;AACzC,cAAc,4DAA4D,CAAC;AAC3E,cAAc,6DAA6D,CAAC;AAC5E,cAAc,wDAAwD,CAAC;AACvE,cAAc,kDAAkD,CAAC;AACjE,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,wCAAwC,CAAC;AACvD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,0BAA0B,CAAC;AACzC,cAAc,yCAAyC,CAAC;AACxD,cAAc,0CAA0C,CAAC;AACzD,cAAc,yCAAyC,CAAC;AACxD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+BAA+B,CAAC"}
|
|
@@ -6,6 +6,7 @@ export * from './ia-dropdown-search-bar/ia-dropdown-search-bar.js';
|
|
|
6
6
|
export * from './ia-expandable-search-bar/ia-expandable-search-bar.js';
|
|
7
7
|
export * from './ia-expandable-search-bar/ia-quick-search.js';
|
|
8
8
|
export * from './ia-expandable-search-bar/models.js';
|
|
9
|
+
export * from './ia-image-viewer/ia-image-viewer.js';
|
|
9
10
|
export * from './ia-item-navigator/ia-item-navigator.js';
|
|
10
11
|
export * from './ia-item-navigator/menus/ia-itemnav-viewable-files-panel.js';
|
|
11
12
|
export * from './ia-item-navigator/menus/ia-itemnav-sort-files-button.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/elements/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iDAAiD,CAAC;AAChE,cAAc,qDAAqD,CAAC;AACpE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,mCAAmC,CAAC;AAClD,cAAc,uCAAuC,CAAC;AACtD,cAAc,2DAA2D,CAAC;AAC1E,cAAc,wDAAwD,CAAC;AACvE,cAAc,kDAAkD,CAAC;AACjE,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,0BAA0B,CAAC;AACzC,cAAc,4DAA4D,CAAC;AAC3E,cAAc,6DAA6D,CAAC;AAC5E,cAAc,wDAAwD,CAAC;AACvE,cAAc,kDAAkD,CAAC;AACjE,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,wCAAwC,CAAC;AACvD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,0BAA0B,CAAC;AACzC,cAAc,yCAAyC,CAAC;AACxD,cAAc,0CAA0C,CAAC;AACzD,cAAc,yCAAyC,CAAC;AACxD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+BAA+B,CAAC","sourcesContent":["export * from './ia-audio-element/ia-audio-element';\nexport * from './ia-audio-element/models';\nexport * from './ia-button/ia-button';\nexport * from './ia-combo-box/ia-combo-box';\nexport * from './ia-dropdown-search-bar/ia-dropdown-search-bar';\nexport * from './ia-expandable-search-bar/ia-expandable-search-bar';\nexport * from './ia-expandable-search-bar/ia-quick-search';\nexport * from './ia-expandable-search-bar/models';\nexport * from './ia-item-navigator/ia-item-navigator';\nexport * from './ia-item-navigator/menus/ia-itemnav-viewable-files-panel';\nexport * from './ia-item-navigator/menus/ia-itemnav-sort-files-button';\nexport * from './ia-item-navigator/menus/ia-itemnav-share-panel';\nexport * from './ia-playback-controls/ia-playback-controls';\nexport * from './ia-playback-controls/models';\nexport * from './ia-radio-player/ia-radio-player';\nexport * from './ia-radio-player/ia-search-results-switcher';\nexport * from './ia-radio-player/models';\nexport * from './ia-radio-player/search/backends/full-text-search-backend';\nexport * from './ia-radio-player/search/backends/full-text-search-response';\nexport * from './ia-radio-player/search/backends/local-search-backend';\nexport * from './ia-radio-player/search/backends/search-backend';\nexport * from './ia-radio-player/search/models';\nexport * from './ia-radio-player/search/search-handler';\nexport * from './ia-radio-player/search/search-helper';\nexport * from './ia-radio-player/search/transcript-index';\nexport * from './ia-scrubber-bar/ia-scrubber-bar';\nexport * from './ia-scrubber-bar/ia-section-marker';\nexport * from './ia-scrubber-bar/models';\nexport * from './ia-transcript-view/duration-formatter';\nexport * from './ia-transcript-view/ia-transcript-entry';\nexport * from './ia-transcript-view/ia-transcript-view';\nexport * from './ia-transcript-view/models';\nexport * from './ia-waveform-progress/ia-waveform-progress';\nexport * from './ia-waveform-progress/models';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/elements/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iDAAiD,CAAC;AAChE,cAAc,qDAAqD,CAAC;AACpE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,mCAAmC,CAAC;AAClD,cAAc,mCAAmC,CAAC;AAClD,cAAc,uCAAuC,CAAC;AACtD,cAAc,2DAA2D,CAAC;AAC1E,cAAc,wDAAwD,CAAC;AACvE,cAAc,kDAAkD,CAAC;AACjE,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,0BAA0B,CAAC;AACzC,cAAc,4DAA4D,CAAC;AAC3E,cAAc,6DAA6D,CAAC;AAC5E,cAAc,wDAAwD,CAAC;AACvE,cAAc,kDAAkD,CAAC;AACjE,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,wCAAwC,CAAC;AACvD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,0BAA0B,CAAC;AACzC,cAAc,yCAAyC,CAAC;AACxD,cAAc,0CAA0C,CAAC;AACzD,cAAc,yCAAyC,CAAC;AACxD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+BAA+B,CAAC","sourcesContent":["export * from './ia-audio-element/ia-audio-element';\nexport * from './ia-audio-element/models';\nexport * from './ia-button/ia-button';\nexport * from './ia-combo-box/ia-combo-box';\nexport * from './ia-dropdown-search-bar/ia-dropdown-search-bar';\nexport * from './ia-expandable-search-bar/ia-expandable-search-bar';\nexport * from './ia-expandable-search-bar/ia-quick-search';\nexport * from './ia-expandable-search-bar/models';\nexport * from './ia-image-viewer/ia-image-viewer';\nexport * from './ia-item-navigator/ia-item-navigator';\nexport * from './ia-item-navigator/menus/ia-itemnav-viewable-files-panel';\nexport * from './ia-item-navigator/menus/ia-itemnav-sort-files-button';\nexport * from './ia-item-navigator/menus/ia-itemnav-share-panel';\nexport * from './ia-playback-controls/ia-playback-controls';\nexport * from './ia-playback-controls/models';\nexport * from './ia-radio-player/ia-radio-player';\nexport * from './ia-radio-player/ia-search-results-switcher';\nexport * from './ia-radio-player/models';\nexport * from './ia-radio-player/search/backends/full-text-search-backend';\nexport * from './ia-radio-player/search/backends/full-text-search-response';\nexport * from './ia-radio-player/search/backends/local-search-backend';\nexport * from './ia-radio-player/search/backends/search-backend';\nexport * from './ia-radio-player/search/models';\nexport * from './ia-radio-player/search/search-handler';\nexport * from './ia-radio-player/search/search-helper';\nexport * from './ia-radio-player/search/transcript-index';\nexport * from './ia-scrubber-bar/ia-scrubber-bar';\nexport * from './ia-scrubber-bar/ia-section-marker';\nexport * from './ia-scrubber-bar/models';\nexport * from './ia-transcript-view/duration-formatter';\nexport * from './ia-transcript-view/ia-transcript-entry';\nexport * from './ia-transcript-view/ia-transcript-view';\nexport * from './ia-transcript-view/models';\nexport * from './ia-waveform-progress/ia-waveform-progress';\nexport * from './ia-waveform-progress/models';\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { css, html, LitElement, } from 'lit';
|
|
3
3
|
import { property } from 'lit/decorators.js';
|
|
4
|
-
import { customElement } from '
|
|
4
|
+
import { customElement } from '../../util/custom-element.js';
|
|
5
5
|
import { state } from 'lit/decorators/state.js';
|
|
6
6
|
import flakeIcon from './flake.svg';
|
|
7
7
|
import { lazyLoadTemplate, } from '../../util/lazy-load-template.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ia-snow.js","sourceRoot":"","sources":["../../../../src/labs/ia-snow/ia-snow.ts"],"names":[],"mappings":";AAAA,OAAO,EACL,GAAG,EACH,IAAI,EACJ,UAAU,GAGX,MAAM,KAAK,CAAC;AACb,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ia-snow.js","sourceRoot":"","sources":["../../../../src/labs/ia-snow/ia-snow.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n css,\n html,\n LitElement,\n type CSSResultGroup,\n type PropertyValues,\n} from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { customElement } from '@src/util/custom-element';\nimport { state } from 'lit/decorators/state.js';\n\nimport type Snowflakes from 'magic-snowflakes';\nimport type { SnowflakesParams } from 'magic-snowflakes';\n\nimport flakeIcon from './flake.svg';\nimport {\n lazyLoadTemplate,\n type LazyLoadedTemplate,\n} from '@src/util/lazy-load-template';\n\n/**\n * An element that shows snowflakes to demo the elements library\n */\n@customElement('ia-snow')\nexport class IASnow extends LitElement {\n @property({ type: Object }) snowConfig?: SnowflakesParams;\n\n @state()\n private snowing = false;\n\n private snowflakes?: Snowflakes;\n\n render() {\n return html`\n ${this.startButtonTemplate} ${this.clearButtonTemplate}\n <img src=${flakeIcon} alt=\"Snowflakes icon\" />\n `;\n }\n\n protected willUpdate(_changedProperties: PropertyValues): void {\n if (_changedProperties.has('snowConfig')) {\n this.snowflakes?.destroy();\n this.snowflakes = undefined;\n this.startSnowing();\n }\n }\n\n // Consider lazy loading external templates if they are large,\n // below the fold or not needed immediately. This will reduce the initial\n // bundle size.\n //\n // Note: In this case, ia-button is visible immediately so it's not a great\n // example, but it demonstrates the lazy loading pattern.\n private get startButtonTemplate(): LazyLoadedTemplate {\n return lazyLoadTemplate(\n async () => {\n await import('@src/elements/ia-button/ia-button');\n },\n () => html`\n <ia-button\n @click=${() => {\n if (this.snowing) {\n this.stopSnowing();\n } else {\n this.startSnowing();\n }\n }}\n >\n ${this.snowing ? 'Stop Snowflakes' : 'Start Snowflakes'}\n </ia-button>\n `,\n );\n }\n\n private get clearButtonTemplate(): LazyLoadedTemplate {\n return lazyLoadTemplate(\n async () => {\n await import('@src/elements/ia-button/ia-button');\n },\n () => html`\n <ia-button\n @click=${() => {\n this.snowflakes?.destroy();\n }}\n >\n Clear Snowflakes\n </ia-button>\n `,\n );\n }\n\n private async startSnowing() {\n if (!this.snowflakes) {\n // lazy load dependencies when possible to reduce initial bundle size\n const SnowflakesModule = await import('magic-snowflakes');\n const Snowflakes = SnowflakesModule.default;\n this.snowflakes = new Snowflakes(this.snowConfig);\n }\n this.snowflakes?.start();\n this.snowing = true;\n }\n\n private stopSnowing() {\n this.snowflakes?.stop();\n this.snowing = false;\n }\n\n static get styles(): CSSResultGroup {\n return css`\n img {\n width: 16px;\n filter: invert(1);\n vertical-align: middle;\n }\n `;\n }\n}\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Allow for custom element classes with private constructors.
|
|
3
|
+
*/
|
|
4
|
+
type CustomElementClass = Omit<typeof HTMLElement, 'new'>;
|
|
5
|
+
/**
|
|
6
|
+
* Class decorator factory that registers the decorated class as a custom
|
|
7
|
+
* element, unless something has already claimed the tag name.
|
|
8
|
+
*
|
|
9
|
+
* Each element subpath is served to non-bundler consumers as a self-contained
|
|
10
|
+
* bundle, so a component several elements share, such as
|
|
11
|
+
* `ia-status-indicator`, is built into every entry point that imports it. A
|
|
12
|
+
* page pulling in two of those subpaths therefore evaluates two copies of the
|
|
13
|
+
* shared component and registers the same tag twice. `customElements.define`
|
|
14
|
+
* throws on the second attempt, and because that happens while the module is
|
|
15
|
+
* still evaluating it takes down the rest of the bundle with it, so the
|
|
16
|
+
* element the page actually asked for never registers.
|
|
17
|
+
*
|
|
18
|
+
* Skipping a duplicate keeps the first copy registered and lets the rest of
|
|
19
|
+
* the module finish. The copies are interchangeable: they are built from the
|
|
20
|
+
* same source, and nothing narrows a shared element by class identity.
|
|
21
|
+
*
|
|
22
|
+
* A skip is also how a page ends up on an element it did not mean to use:
|
|
23
|
+
* load two versions of the package together, or let a host page claim one of
|
|
24
|
+
* these tag names, and whichever registered first is what the page gets,
|
|
25
|
+
* which looks like the expected element's behaviour going missing. Nothing
|
|
26
|
+
* here can tell that apart from a matched-version duplicate, since two builds
|
|
27
|
+
* of the same element differ in nothing observable at this point, so a skip
|
|
28
|
+
* warns and leaves the reader to tell the cases apart.
|
|
29
|
+
*
|
|
30
|
+
* ```ts
|
|
31
|
+
* @customElement('ia-example')
|
|
32
|
+
* class IAExample extends LitElement {}
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @param tagName The tag name to register the element under.
|
|
36
|
+
*/
|
|
37
|
+
export declare function customElement(tagName: string): (classOrTarget: CustomElementClass, context?: ClassDecoratorContext<new () => HTMLElement>) => void;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=custom-element.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-element.d.ts","sourceRoot":"","sources":["../../../src/util/custom-element.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,KAAK,kBAAkB,GAAG,IAAI,CAAC,OAAO,WAAW,EAAE,KAAK,CAAC,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,IAEzC,eAAe,kBAAkB,EACjC,UAAU,qBAAqB,CAAC,UAAU,WAAW,CAAC,KACrD,IAAI,CAgBR"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Class decorator factory that registers the decorated class as a custom
|
|
3
|
+
* element, unless something has already claimed the tag name.
|
|
4
|
+
*
|
|
5
|
+
* Each element subpath is served to non-bundler consumers as a self-contained
|
|
6
|
+
* bundle, so a component several elements share, such as
|
|
7
|
+
* `ia-status-indicator`, is built into every entry point that imports it. A
|
|
8
|
+
* page pulling in two of those subpaths therefore evaluates two copies of the
|
|
9
|
+
* shared component and registers the same tag twice. `customElements.define`
|
|
10
|
+
* throws on the second attempt, and because that happens while the module is
|
|
11
|
+
* still evaluating it takes down the rest of the bundle with it, so the
|
|
12
|
+
* element the page actually asked for never registers.
|
|
13
|
+
*
|
|
14
|
+
* Skipping a duplicate keeps the first copy registered and lets the rest of
|
|
15
|
+
* the module finish. The copies are interchangeable: they are built from the
|
|
16
|
+
* same source, and nothing narrows a shared element by class identity.
|
|
17
|
+
*
|
|
18
|
+
* A skip is also how a page ends up on an element it did not mean to use:
|
|
19
|
+
* load two versions of the package together, or let a host page claim one of
|
|
20
|
+
* these tag names, and whichever registered first is what the page gets,
|
|
21
|
+
* which looks like the expected element's behaviour going missing. Nothing
|
|
22
|
+
* here can tell that apart from a matched-version duplicate, since two builds
|
|
23
|
+
* of the same element differ in nothing observable at this point, so a skip
|
|
24
|
+
* warns and leaves the reader to tell the cases apart.
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* @customElement('ia-example')
|
|
28
|
+
* class IAExample extends LitElement {}
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @param tagName The tag name to register the element under.
|
|
32
|
+
*/
|
|
33
|
+
export function customElement(tagName) {
|
|
34
|
+
return (classOrTarget, context) => {
|
|
35
|
+
const define = () => {
|
|
36
|
+
if (customElements.get(tagName)) {
|
|
37
|
+
console.warn(`[elements] <${tagName}> is already registered, so this definition was skipped and whatever registered first stays in use. Harmless when a page loads two element subpaths that share a component. Otherwise look for a second copy of the package, or an unrelated element using the same name.`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
customElements.define(tagName, classOrTarget);
|
|
41
|
+
};
|
|
42
|
+
// Standard decorators defer registration to an initializer; the legacy
|
|
43
|
+
// decorators this project compiles with hand over the class directly.
|
|
44
|
+
if (context)
|
|
45
|
+
context.addInitializer(define);
|
|
46
|
+
else
|
|
47
|
+
define();
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=custom-element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-element.js","sourceRoot":"","sources":["../../../src/util/custom-element.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,OAAO,CACL,aAAiC,EACjC,OAAsD,EAChD,EAAE;QACR,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,IAAI,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAChC,OAAO,CAAC,IAAI,CACV,eAAe,OAAO,2QAA2Q,CAClS,CAAC;gBACF,OAAO;YACT,CAAC;YACD,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,aAAyC,CAAC,CAAC;QAC5E,CAAC,CAAC;QAEF,uEAAuE;QACvE,sEAAsE;QACtE,IAAI,OAAO;YAAE,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;;YACvC,MAAM,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Allow for custom element classes with private constructors.\n */\ntype CustomElementClass = Omit<typeof HTMLElement, 'new'>;\n\n/**\n * Class decorator factory that registers the decorated class as a custom\n * element, unless something has already claimed the tag name.\n *\n * Each element subpath is served to non-bundler consumers as a self-contained\n * bundle, so a component several elements share, such as\n * `ia-status-indicator`, is built into every entry point that imports it. A\n * page pulling in two of those subpaths therefore evaluates two copies of the\n * shared component and registers the same tag twice. `customElements.define`\n * throws on the second attempt, and because that happens while the module is\n * still evaluating it takes down the rest of the bundle with it, so the\n * element the page actually asked for never registers.\n *\n * Skipping a duplicate keeps the first copy registered and lets the rest of\n * the module finish. The copies are interchangeable: they are built from the\n * same source, and nothing narrows a shared element by class identity.\n *\n * A skip is also how a page ends up on an element it did not mean to use:\n * load two versions of the package together, or let a host page claim one of\n * these tag names, and whichever registered first is what the page gets,\n * which looks like the expected element's behaviour going missing. Nothing\n * here can tell that apart from a matched-version duplicate, since two builds\n * of the same element differ in nothing observable at this point, so a skip\n * warns and leaves the reader to tell the cases apart.\n *\n * ```ts\n * @customElement('ia-example')\n * class IAExample extends LitElement {}\n * ```\n *\n * @param tagName The tag name to register the element under.\n */\nexport function customElement(tagName: string) {\n return (\n classOrTarget: CustomElementClass,\n context?: ClassDecoratorContext<new () => HTMLElement>,\n ): void => {\n const define = (): void => {\n if (customElements.get(tagName)) {\n console.warn(\n `[elements] <${tagName}> is already registered, so this definition was skipped and whatever registered first stays in use. Harmless when a page loads two element subpaths that share a component. Otherwise look for a second copy of the package, or an unrelated element using the same name.`,\n );\n return;\n }\n customElements.define(tagName, classOrTarget as CustomElementConstructor);\n };\n\n // Standard decorators defer registration to an initializer; the legacy\n // decorators this project compiles with hand over the class directly.\n if (context) context.addInitializer(define);\n else define();\n };\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the user has asked the system for reduced motion.
|
|
3
|
+
*
|
|
4
|
+
* Read at the moment an animation would start rather than cached, so changing
|
|
5
|
+
* the system setting takes effect without a reload. CSS handles the purely
|
|
6
|
+
* decorative animations on its own; this is for the places where JavaScript
|
|
7
|
+
* schedules or waits on one.
|
|
8
|
+
*/
|
|
9
|
+
export declare function prefersReducedMotion(): boolean;
|
|
10
|
+
//# sourceMappingURL=prefers-reduced-motion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefers-reduced-motion.d.ts","sourceRoot":"","sources":["../../../src/util/prefers-reduced-motion.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAI9C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the user has asked the system for reduced motion.
|
|
3
|
+
*
|
|
4
|
+
* Read at the moment an animation would start rather than cached, so changing
|
|
5
|
+
* the system setting takes effect without a reload. CSS handles the purely
|
|
6
|
+
* decorative animations on its own; this is for the places where JavaScript
|
|
7
|
+
* schedules or waits on one.
|
|
8
|
+
*/
|
|
9
|
+
export function prefersReducedMotion() {
|
|
10
|
+
return (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? false);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=prefers-reduced-motion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefers-reduced-motion.js","sourceRoot":"","sources":["../../../src/util/prefers-reduced-motion.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,CACL,MAAM,CAAC,UAAU,EAAE,CAAC,kCAAkC,CAAC,CAAC,OAAO,IAAI,KAAK,CACzE,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Whether the user has asked the system for reduced motion.\n *\n * Read at the moment an animation would start rather than cached, so changing\n * the system setting takes effect without a reload. CSS handles the purely\n * decorative animations on its own; this is for the places where JavaScript\n * schedules or waits on one.\n */\nexport function prefersReducedMotion(): boolean {\n return (\n window.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? false\n );\n}\n"]}
|