@tartaguti/ui-components 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +192 -2
- package/THIRD-PARTY-NOTICES.md +29 -0
- package/custom-elements.json +16899 -0
- package/dist/accordion/tt-accordion-item.d.ts +32 -0
- package/dist/accordion/tt-accordion-item.d.ts.map +1 -0
- package/dist/accordion/tt-accordion-item.js +247 -0
- package/dist/accordion/tt-accordion-item.js.map +1 -0
- package/dist/accordion/tt-accordion.d.ts +28 -0
- package/dist/accordion/tt-accordion.d.ts.map +1 -0
- package/dist/accordion/tt-accordion.js +148 -0
- package/dist/accordion/tt-accordion.js.map +1 -0
- package/dist/bento/tt-bento-item.d.ts +35 -0
- package/dist/bento/tt-bento-item.d.ts.map +1 -0
- package/dist/bento/tt-bento-item.js +201 -0
- package/dist/bento/tt-bento-item.js.map +1 -0
- package/dist/bento/tt-bento.d.ts +25 -0
- package/dist/bento/tt-bento.d.ts.map +1 -0
- package/dist/bento/tt-bento.js +314 -0
- package/dist/bento/tt-bento.js.map +1 -0
- package/dist/floating.d.ts +61 -0
- package/dist/floating.d.ts.map +1 -0
- package/dist/floating.js +120 -0
- package/dist/floating.js.map +1 -0
- package/dist/index.d.ts +92 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +96 -0
- package/dist/index.js.map +1 -0
- package/dist/interaction/tt-draggable.d.ts +29 -0
- package/dist/interaction/tt-draggable.d.ts.map +1 -0
- package/dist/interaction/tt-draggable.js +66 -0
- package/dist/interaction/tt-draggable.js.map +1 -0
- package/dist/interaction/tt-droppable.d.ts +37 -0
- package/dist/interaction/tt-droppable.d.ts.map +1 -0
- package/dist/interaction/tt-droppable.js +108 -0
- package/dist/interaction/tt-droppable.js.map +1 -0
- package/dist/interaction/tt-resizable.d.ts +45 -0
- package/dist/interaction/tt-resizable.d.ts.map +1 -0
- package/dist/interaction/tt-resizable.js +210 -0
- package/dist/interaction/tt-resizable.js.map +1 -0
- package/dist/interaction/tt-reveal.d.ts +54 -0
- package/dist/interaction/tt-reveal.d.ts.map +1 -0
- package/dist/interaction/tt-reveal.js +302 -0
- package/dist/interaction/tt-reveal.js.map +1 -0
- package/dist/motion.d.ts +8 -0
- package/dist/motion.d.ts.map +1 -0
- package/dist/motion.js +49 -0
- package/dist/motion.js.map +1 -0
- package/dist/overlay.d.ts +7 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +121 -0
- package/dist/overlay.js.map +1 -0
- package/dist/safe-url.d.ts +14 -0
- package/dist/safe-url.d.ts.map +1 -0
- package/dist/safe-url.js +46 -0
- package/dist/safe-url.js.map +1 -0
- package/dist/scroll-lock.d.ts +22 -0
- package/dist/scroll-lock.d.ts.map +1 -0
- package/dist/scroll-lock.js +56 -0
- package/dist/scroll-lock.js.map +1 -0
- package/dist/sidebar/tt-menu-group.d.ts +69 -0
- package/dist/sidebar/tt-menu-group.d.ts.map +1 -0
- package/dist/sidebar/tt-menu-group.js +358 -0
- package/dist/sidebar/tt-menu-group.js.map +1 -0
- package/dist/sidebar/tt-menu-item.d.ts +70 -0
- package/dist/sidebar/tt-menu-item.d.ts.map +1 -0
- package/dist/sidebar/tt-menu-item.js +502 -0
- package/dist/sidebar/tt-menu-item.js.map +1 -0
- package/dist/sidebar/tt-sidebar-footer.d.ts +39 -0
- package/dist/sidebar/tt-sidebar-footer.d.ts.map +1 -0
- package/dist/sidebar/tt-sidebar-footer.js +205 -0
- package/dist/sidebar/tt-sidebar-footer.js.map +1 -0
- package/dist/sidebar/tt-sidebar-header.d.ts +31 -0
- package/dist/sidebar/tt-sidebar-header.d.ts.map +1 -0
- package/dist/sidebar/tt-sidebar-header.js +150 -0
- package/dist/sidebar/tt-sidebar-header.js.map +1 -0
- package/dist/sidebar/tt-sidebar.d.ts +72 -0
- package/dist/sidebar/tt-sidebar.d.ts.map +1 -0
- package/dist/sidebar/tt-sidebar.js +539 -0
- package/dist/sidebar/tt-sidebar.js.map +1 -0
- package/dist/sr-only.d.ts +15 -0
- package/dist/sr-only.d.ts.map +1 -0
- package/dist/sr-only.js +27 -0
- package/dist/sr-only.js.map +1 -0
- package/dist/tokens.css +1124 -0
- package/dist/tt-alert.d.ts +26 -0
- package/dist/tt-alert.d.ts.map +1 -0
- package/dist/tt-alert.js +165 -0
- package/dist/tt-alert.js.map +1 -0
- package/dist/tt-aspect-ratio.d.ts +40 -0
- package/dist/tt-aspect-ratio.d.ts.map +1 -0
- package/dist/tt-aspect-ratio.js +98 -0
- package/dist/tt-aspect-ratio.js.map +1 -0
- package/dist/tt-auth.d.ts +75 -0
- package/dist/tt-auth.d.ts.map +1 -0
- package/dist/tt-auth.js +520 -0
- package/dist/tt-auth.js.map +1 -0
- package/dist/tt-avatar.d.ts +26 -0
- package/dist/tt-avatar.d.ts.map +1 -0
- package/dist/tt-avatar.js +169 -0
- package/dist/tt-avatar.js.map +1 -0
- package/dist/tt-badge.d.ts +36 -0
- package/dist/tt-badge.d.ts.map +1 -0
- package/dist/tt-badge.js +135 -0
- package/dist/tt-badge.js.map +1 -0
- package/dist/tt-breadcrumbs.d.ts +22 -0
- package/dist/tt-breadcrumbs.d.ts.map +1 -0
- package/dist/tt-breadcrumbs.js +144 -0
- package/dist/tt-breadcrumbs.js.map +1 -0
- package/dist/tt-button-group.d.ts +32 -0
- package/dist/tt-button-group.d.ts.map +1 -0
- package/dist/tt-button-group.js +132 -0
- package/dist/tt-button-group.js.map +1 -0
- package/dist/tt-button.d.ts +31 -0
- package/dist/tt-button.d.ts.map +1 -0
- package/dist/tt-button.js +483 -0
- package/dist/tt-button.js.map +1 -0
- package/dist/tt-card.d.ts +26 -0
- package/dist/tt-card.d.ts.map +1 -0
- package/dist/tt-card.js +429 -0
- package/dist/tt-card.js.map +1 -0
- package/dist/tt-chart.d.ts +36 -0
- package/dist/tt-chart.d.ts.map +1 -0
- package/dist/tt-chart.js +332 -0
- package/dist/tt-chart.js.map +1 -0
- package/dist/tt-checkbox-group.d.ts +38 -0
- package/dist/tt-checkbox-group.d.ts.map +1 -0
- package/dist/tt-checkbox-group.js +243 -0
- package/dist/tt-checkbox-group.js.map +1 -0
- package/dist/tt-checkbox.d.ts +35 -0
- package/dist/tt-checkbox.d.ts.map +1 -0
- package/dist/tt-checkbox.js +354 -0
- package/dist/tt-checkbox.js.map +1 -0
- package/dist/tt-code-block.d.ts +37 -0
- package/dist/tt-code-block.d.ts.map +1 -0
- package/dist/tt-code-block.js +409 -0
- package/dist/tt-code-block.js.map +1 -0
- package/dist/tt-collapsible.d.ts +71 -0
- package/dist/tt-collapsible.d.ts.map +1 -0
- package/dist/tt-collapsible.js +206 -0
- package/dist/tt-collapsible.js.map +1 -0
- package/dist/tt-combobox.d.ts +107 -0
- package/dist/tt-combobox.d.ts.map +1 -0
- package/dist/tt-combobox.js +816 -0
- package/dist/tt-combobox.js.map +1 -0
- package/dist/tt-company-card.d.ts +30 -0
- package/dist/tt-company-card.d.ts.map +1 -0
- package/dist/tt-company-card.js +382 -0
- package/dist/tt-company-card.js.map +1 -0
- package/dist/tt-comparison-table.d.ts +59 -0
- package/dist/tt-comparison-table.d.ts.map +1 -0
- package/dist/tt-comparison-table.js +441 -0
- package/dist/tt-comparison-table.js.map +1 -0
- package/dist/tt-component-doc.d.ts +63 -0
- package/dist/tt-component-doc.d.ts.map +1 -0
- package/dist/tt-component-doc.js +585 -0
- package/dist/tt-component-doc.js.map +1 -0
- package/dist/tt-confirm.d.ts +45 -0
- package/dist/tt-confirm.d.ts.map +1 -0
- package/dist/tt-confirm.js +151 -0
- package/dist/tt-confirm.js.map +1 -0
- package/dist/tt-contact-list.d.ts +18 -0
- package/dist/tt-contact-list.d.ts.map +1 -0
- package/dist/tt-contact-list.js +101 -0
- package/dist/tt-contact-list.js.map +1 -0
- package/dist/tt-copy-button.d.ts +25 -0
- package/dist/tt-copy-button.d.ts.map +1 -0
- package/dist/tt-copy-button.js +194 -0
- package/dist/tt-copy-button.js.map +1 -0
- package/dist/tt-data-table.d.ts +96 -0
- package/dist/tt-data-table.d.ts.map +1 -0
- package/dist/tt-data-table.js +812 -0
- package/dist/tt-data-table.js.map +1 -0
- package/dist/tt-divider.d.ts +19 -0
- package/dist/tt-divider.d.ts.map +1 -0
- package/dist/tt-divider.js +104 -0
- package/dist/tt-divider.js.map +1 -0
- package/dist/tt-drawer.d.ts +38 -0
- package/dist/tt-drawer.d.ts.map +1 -0
- package/dist/tt-drawer.js +433 -0
- package/dist/tt-drawer.js.map +1 -0
- package/dist/tt-dropdown-menu.d.ts +57 -0
- package/dist/tt-dropdown-menu.d.ts.map +1 -0
- package/dist/tt-dropdown-menu.js +631 -0
- package/dist/tt-dropdown-menu.js.map +1 -0
- package/dist/tt-empty-state.d.ts +13 -0
- package/dist/tt-empty-state.d.ts.map +1 -0
- package/dist/tt-empty-state.js +94 -0
- package/dist/tt-empty-state.js.map +1 -0
- package/dist/tt-example.d.ts +33 -0
- package/dist/tt-example.d.ts.map +1 -0
- package/dist/tt-example.js +250 -0
- package/dist/tt-example.js.map +1 -0
- package/dist/tt-file-upload.d.ts +85 -0
- package/dist/tt-file-upload.d.ts.map +1 -0
- package/dist/tt-file-upload.js +662 -0
- package/dist/tt-file-upload.js.map +1 -0
- package/dist/tt-filter.d.ts +62 -0
- package/dist/tt-filter.d.ts.map +1 -0
- package/dist/tt-filter.js +393 -0
- package/dist/tt-filter.js.map +1 -0
- package/dist/tt-form.d.ts +33 -0
- package/dist/tt-form.d.ts.map +1 -0
- package/dist/tt-form.js +202 -0
- package/dist/tt-form.js.map +1 -0
- package/dist/tt-grid.d.ts +22 -0
- package/dist/tt-grid.d.ts.map +1 -0
- package/dist/tt-grid.js +106 -0
- package/dist/tt-grid.js.map +1 -0
- package/dist/tt-icon.d.ts +20 -0
- package/dist/tt-icon.d.ts.map +1 -0
- package/dist/tt-icon.js +510 -0
- package/dist/tt-icon.js.map +1 -0
- package/dist/tt-image.d.ts +59 -0
- package/dist/tt-image.d.ts.map +1 -0
- package/dist/tt-image.js +314 -0
- package/dist/tt-image.js.map +1 -0
- package/dist/tt-inbox.d.ts +45 -0
- package/dist/tt-inbox.d.ts.map +1 -0
- package/dist/tt-inbox.js +275 -0
- package/dist/tt-inbox.js.map +1 -0
- package/dist/tt-input.d.ts +43 -0
- package/dist/tt-input.d.ts.map +1 -0
- package/dist/tt-input.js +476 -0
- package/dist/tt-input.js.map +1 -0
- package/dist/tt-kbd.d.ts +39 -0
- package/dist/tt-kbd.d.ts.map +1 -0
- package/dist/tt-kbd.js +145 -0
- package/dist/tt-kbd.js.map +1 -0
- package/dist/tt-key-values.d.ts +17 -0
- package/dist/tt-key-values.d.ts.map +1 -0
- package/dist/tt-key-values.js +126 -0
- package/dist/tt-key-values.js.map +1 -0
- package/dist/tt-knowledge-doc.d.ts +24 -0
- package/dist/tt-knowledge-doc.d.ts.map +1 -0
- package/dist/tt-knowledge-doc.js +120 -0
- package/dist/tt-knowledge-doc.js.map +1 -0
- package/dist/tt-layout.d.ts +36 -0
- package/dist/tt-layout.d.ts.map +1 -0
- package/dist/tt-layout.js +318 -0
- package/dist/tt-layout.js.map +1 -0
- package/dist/tt-modal.d.ts +32 -0
- package/dist/tt-modal.d.ts.map +1 -0
- package/dist/tt-modal.js +553 -0
- package/dist/tt-modal.js.map +1 -0
- package/dist/tt-navbar.d.ts +33 -0
- package/dist/tt-navbar.d.ts.map +1 -0
- package/dist/tt-navbar.js +390 -0
- package/dist/tt-navbar.js.map +1 -0
- package/dist/tt-page-header.d.ts +28 -0
- package/dist/tt-page-header.d.ts.map +1 -0
- package/dist/tt-page-header.js +166 -0
- package/dist/tt-page-header.js.map +1 -0
- package/dist/tt-page.d.ts +14 -0
- package/dist/tt-page.d.ts.map +1 -0
- package/dist/tt-page.js +163 -0
- package/dist/tt-page.js.map +1 -0
- package/dist/tt-pagination.d.ts +27 -0
- package/dist/tt-pagination.d.ts.map +1 -0
- package/dist/tt-pagination.js +194 -0
- package/dist/tt-pagination.js.map +1 -0
- package/dist/tt-preview.d.ts +11 -0
- package/dist/tt-preview.d.ts.map +1 -0
- package/dist/tt-preview.js +68 -0
- package/dist/tt-preview.js.map +1 -0
- package/dist/tt-product.d.ts +40 -0
- package/dist/tt-product.d.ts.map +1 -0
- package/dist/tt-product.js +590 -0
- package/dist/tt-product.js.map +1 -0
- package/dist/tt-profile-card.d.ts +23 -0
- package/dist/tt-profile-card.d.ts.map +1 -0
- package/dist/tt-profile-card.js +199 -0
- package/dist/tt-profile-card.js.map +1 -0
- package/dist/tt-progress.d.ts +26 -0
- package/dist/tt-progress.d.ts.map +1 -0
- package/dist/tt-progress.js +156 -0
- package/dist/tt-progress.js.map +1 -0
- package/dist/tt-quantity.d.ts +36 -0
- package/dist/tt-quantity.d.ts.map +1 -0
- package/dist/tt-quantity.js +396 -0
- package/dist/tt-quantity.js.map +1 -0
- package/dist/tt-radio-group.d.ts +50 -0
- package/dist/tt-radio-group.d.ts.map +1 -0
- package/dist/tt-radio-group.js +372 -0
- package/dist/tt-radio-group.js.map +1 -0
- package/dist/tt-rating.d.ts +54 -0
- package/dist/tt-rating.d.ts.map +1 -0
- package/dist/tt-rating.js +312 -0
- package/dist/tt-rating.js.map +1 -0
- package/dist/tt-search.d.ts +47 -0
- package/dist/tt-search.d.ts.map +1 -0
- package/dist/tt-search.js +360 -0
- package/dist/tt-search.js.map +1 -0
- package/dist/tt-section.d.ts +13 -0
- package/dist/tt-section.d.ts.map +1 -0
- package/dist/tt-section.js +98 -0
- package/dist/tt-section.js.map +1 -0
- package/dist/tt-select.d.ts +62 -0
- package/dist/tt-select.d.ts.map +1 -0
- package/dist/tt-select.js +662 -0
- package/dist/tt-select.js.map +1 -0
- package/dist/tt-skeleton.d.ts +20 -0
- package/dist/tt-skeleton.d.ts.map +1 -0
- package/dist/tt-skeleton.js +143 -0
- package/dist/tt-skeleton.js.map +1 -0
- package/dist/tt-slider.d.ts +74 -0
- package/dist/tt-slider.d.ts.map +1 -0
- package/dist/tt-slider.js +426 -0
- package/dist/tt-slider.js.map +1 -0
- package/dist/tt-social-links.d.ts +34 -0
- package/dist/tt-social-links.d.ts.map +1 -0
- package/dist/tt-social-links.js +242 -0
- package/dist/tt-social-links.js.map +1 -0
- package/dist/tt-sparkline.d.ts +19 -0
- package/dist/tt-sparkline.d.ts.map +1 -0
- package/dist/tt-sparkline.js +191 -0
- package/dist/tt-sparkline.js.map +1 -0
- package/dist/tt-spinner.d.ts +19 -0
- package/dist/tt-spinner.d.ts.map +1 -0
- package/dist/tt-spinner.js +93 -0
- package/dist/tt-spinner.js.map +1 -0
- package/dist/tt-stack.d.ts +42 -0
- package/dist/tt-stack.d.ts.map +1 -0
- package/dist/tt-stack.js +158 -0
- package/dist/tt-stack.js.map +1 -0
- package/dist/tt-stat.d.ts +17 -0
- package/dist/tt-stat.d.ts.map +1 -0
- package/dist/tt-stat.js +134 -0
- package/dist/tt-stat.js.map +1 -0
- package/dist/tt-switch.d.ts +39 -0
- package/dist/tt-switch.d.ts.map +1 -0
- package/dist/tt-switch.js +254 -0
- package/dist/tt-switch.js.map +1 -0
- package/dist/tt-switcher.d.ts +23 -0
- package/dist/tt-switcher.d.ts.map +1 -0
- package/dist/tt-switcher.js +203 -0
- package/dist/tt-switcher.js.map +1 -0
- package/dist/tt-table-cell.d.ts +26 -0
- package/dist/tt-table-cell.d.ts.map +1 -0
- package/dist/tt-table-cell.js +121 -0
- package/dist/tt-table-cell.js.map +1 -0
- package/dist/tt-table-row.d.ts +31 -0
- package/dist/tt-table-row.d.ts.map +1 -0
- package/dist/tt-table-row.js +72 -0
- package/dist/tt-table-row.js.map +1 -0
- package/dist/tt-table.d.ts +44 -0
- package/dist/tt-table.d.ts.map +1 -0
- package/dist/tt-table.js +270 -0
- package/dist/tt-table.js.map +1 -0
- package/dist/tt-tabs.d.ts +31 -0
- package/dist/tt-tabs.d.ts.map +1 -0
- package/dist/tt-tabs.js +223 -0
- package/dist/tt-tabs.js.map +1 -0
- package/dist/tt-tag-list.d.ts +19 -0
- package/dist/tt-tag-list.d.ts.map +1 -0
- package/dist/tt-tag-list.js +136 -0
- package/dist/tt-tag-list.js.map +1 -0
- package/dist/tt-text.d.ts +52 -0
- package/dist/tt-text.d.ts.map +1 -0
- package/dist/tt-text.js +337 -0
- package/dist/tt-text.js.map +1 -0
- package/dist/tt-textarea.d.ts +43 -0
- package/dist/tt-textarea.d.ts.map +1 -0
- package/dist/tt-textarea.js +356 -0
- package/dist/tt-textarea.js.map +1 -0
- package/dist/tt-thread.d.ts +62 -0
- package/dist/tt-thread.d.ts.map +1 -0
- package/dist/tt-thread.js +374 -0
- package/dist/tt-thread.js.map +1 -0
- package/dist/tt-toast.d.ts +49 -0
- package/dist/tt-toast.d.ts.map +1 -0
- package/dist/tt-toast.js +440 -0
- package/dist/tt-toast.js.map +1 -0
- package/dist/tt-toggle-group.d.ts +73 -0
- package/dist/tt-toggle-group.d.ts.map +1 -0
- package/dist/tt-toggle-group.js +273 -0
- package/dist/tt-toggle-group.js.map +1 -0
- package/dist/tt-toggle.d.ts +54 -0
- package/dist/tt-toggle.d.ts.map +1 -0
- package/dist/tt-toggle.js +232 -0
- package/dist/tt-toggle.js.map +1 -0
- package/dist/tt-toolbar.d.ts +26 -0
- package/dist/tt-toolbar.d.ts.map +1 -0
- package/dist/tt-toolbar.js +164 -0
- package/dist/tt-toolbar.js.map +1 -0
- package/dist/tt-tooltip.d.ts +42 -0
- package/dist/tt-tooltip.d.ts.map +1 -0
- package/dist/tt-tooltip.js +299 -0
- package/dist/tt-tooltip.js.map +1 -0
- package/package.json +84 -4
- package/vscode.html-custom-data.json +2911 -0
package/dist/tt-image.js
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { LitElement, html, css, nothing } from "lit";
|
|
8
|
+
import { customElement, property, state, query } from "lit/decorators.js";
|
|
9
|
+
import { ifDefined } from "lit/directives/if-defined.js";
|
|
10
|
+
import "./tt-icon.js";
|
|
11
|
+
/**
|
|
12
|
+
* An image in a box the PARENT sizes.
|
|
13
|
+
*
|
|
14
|
+
* Six properties, and each one answers a question you actually have when
|
|
15
|
+
* you place an image: how big is the box (ratio), what happens to a photo
|
|
16
|
+
* that is not that shape (fit), what are the corners (radius), and is
|
|
17
|
+
* this the one image worth loading early (priority).
|
|
18
|
+
*
|
|
19
|
+
* There is deliberately no size scale. The host is a block that fills its
|
|
20
|
+
* container, so a card wanting a 34px logo says 34px in its own CSS and
|
|
21
|
+
* wins, because rules from the tree that owns an element beat that
|
|
22
|
+
* element's :host. A fixed scale here (icon, profile, small, medium,
|
|
23
|
+
* large) was five pixel values from one app baked into a library meant
|
|
24
|
+
* for apps that do not exist yet, and three consumers ended up reaching
|
|
25
|
+
* through ::part just to undo it.
|
|
26
|
+
*
|
|
27
|
+
* The other half of the job is that real images fail, arrive late, or
|
|
28
|
+
* arrive already cached, so the load is treated as state: a skeleton
|
|
29
|
+
* while it downloads, a fallback if it never arrives.
|
|
30
|
+
*
|
|
31
|
+
* @fires tt-load - When the image has loaded.
|
|
32
|
+
* @fires tt-error - { src } when it failed and the fallback is showing.
|
|
33
|
+
* (Declared here because the analyzer does not see dispatches inside
|
|
34
|
+
* arrow-function fields, so the manifest left both out.)
|
|
35
|
+
*/
|
|
36
|
+
let TTImage = class TTImage extends LitElement {
|
|
37
|
+
constructor() {
|
|
38
|
+
super(...arguments);
|
|
39
|
+
this.src = "";
|
|
40
|
+
/** Describe the picture, or pass "" when it is decorative. */
|
|
41
|
+
this.alt = "";
|
|
42
|
+
/** Any CSS aspect-ratio: "16 / 9", "4 / 5", "1". Empty means intrinsic. */
|
|
43
|
+
this.ratio = "";
|
|
44
|
+
this.fit = "cover";
|
|
45
|
+
this.radius = "medium";
|
|
46
|
+
/**
|
|
47
|
+
* Above the fold. Loads eagerly and asks the browser to prioritise the
|
|
48
|
+
* fetch, which a hero image needs and a thumbnail never does.
|
|
49
|
+
*/
|
|
50
|
+
this.priority = false;
|
|
51
|
+
this.status = "loading";
|
|
52
|
+
this.handleLoad = () => {
|
|
53
|
+
this.status = "loaded";
|
|
54
|
+
this.dispatchEvent(new CustomEvent("tt-load", { bubbles: true, composed: true }));
|
|
55
|
+
};
|
|
56
|
+
this.handleError = () => {
|
|
57
|
+
this.status = "error";
|
|
58
|
+
this.dispatchEvent(new CustomEvent("tt-error", {
|
|
59
|
+
detail: { src: this.src },
|
|
60
|
+
bubbles: true,
|
|
61
|
+
composed: true,
|
|
62
|
+
}));
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
get showFallback() {
|
|
66
|
+
return this.src === "" || this.status === "error";
|
|
67
|
+
}
|
|
68
|
+
willUpdate(changed) {
|
|
69
|
+
/*
|
|
70
|
+
A new source is a new load. Without this one broken URL would
|
|
71
|
+
poison every image that element ever showed afterwards.
|
|
72
|
+
|
|
73
|
+
No source at all is not "loading", it is already settled: there is
|
|
74
|
+
nothing on its way and the fallback is the final answer. Saying
|
|
75
|
+
loading there left the frame wearing the loading class forever,
|
|
76
|
+
which is a lie any consumer styling on it would inherit.
|
|
77
|
+
*/
|
|
78
|
+
if (changed.has("src")) {
|
|
79
|
+
this.status = this.src === "" ? "loaded" : "loading";
|
|
80
|
+
}
|
|
81
|
+
if (changed.has("ratio")) {
|
|
82
|
+
this.style.setProperty("--_ratio", this.ratio || "auto");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
updated() {
|
|
86
|
+
/*
|
|
87
|
+
A cached image can finish decoding before Lit attaches the load
|
|
88
|
+
listener, so the event never fires and the skeleton stays up
|
|
89
|
+
forever. `complete` is the browser saying it already happened.
|
|
90
|
+
|
|
91
|
+
Through the handlers, not by assigning status: setting it here
|
|
92
|
+
would fix the visuals and silently skip tt-load / tt-error, so a
|
|
93
|
+
caller waiting on the event would hang on exactly the images that
|
|
94
|
+
resolved fastest.
|
|
95
|
+
*/
|
|
96
|
+
const img = this.img;
|
|
97
|
+
if (img?.complete && this.status === "loading") {
|
|
98
|
+
if (img.naturalWidth > 0)
|
|
99
|
+
this.handleLoad();
|
|
100
|
+
else
|
|
101
|
+
this.handleError();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
static { this.styles = css `
|
|
105
|
+
/* The browser's own [hidden] rule loses to any :host display, so a
|
|
106
|
+
hidden element would still show. Important, so it always wins. */
|
|
107
|
+
:host([hidden]) {
|
|
108
|
+
display: none !important;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
:host {
|
|
112
|
+
display: block;
|
|
113
|
+
width: 100%;
|
|
114
|
+
|
|
115
|
+
/*
|
|
116
|
+
The ratio lives on the HOST, not on the frame inside it. On the
|
|
117
|
+
frame it was height:100%, so as soon as anything gave the host a
|
|
118
|
+
definite height the frame's height became definite too, and
|
|
119
|
+
aspect-ratio is ignored once both axes already resolve.
|
|
120
|
+
|
|
121
|
+
Here it behaves the way a caller would predict: set only a width
|
|
122
|
+
and the ratio decides the height; set a height as well and the
|
|
123
|
+
height wins, because at that point you said it twice.
|
|
124
|
+
*/
|
|
125
|
+
aspect-ratio: var(--_ratio, auto);
|
|
126
|
+
|
|
127
|
+
--_radius: var(--tt-radius-md);
|
|
128
|
+
|
|
129
|
+
/*
|
|
130
|
+
The corners live on the host, and the frame inherits them. A rule
|
|
131
|
+
from outside beats :host, so a container that shapes its image
|
|
132
|
+
wins: tt-card's image slot rounds only the top, to the card's own
|
|
133
|
+
curve. On the frame alone, the frame kept its all-round radius
|
|
134
|
+
there and left a notch at each bottom corner.
|
|
135
|
+
*/
|
|
136
|
+
border-radius: var(--_radius);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
:host([radius="none"]) {
|
|
140
|
+
--_radius: 0;
|
|
141
|
+
}
|
|
142
|
+
:host([radius="small"]) {
|
|
143
|
+
--_radius: var(--tt-radius-sm);
|
|
144
|
+
}
|
|
145
|
+
:host([radius="large"]) {
|
|
146
|
+
--_radius: var(--tt-radius-lg);
|
|
147
|
+
}
|
|
148
|
+
:host([radius="xlarge"]) {
|
|
149
|
+
--_radius: var(--tt-radius-xl);
|
|
150
|
+
}
|
|
151
|
+
:host([radius="2xlarge"]) {
|
|
152
|
+
--_radius: var(--tt-radius-2xl);
|
|
153
|
+
}
|
|
154
|
+
:host([radius="full"]) {
|
|
155
|
+
--_radius: var(--tt-radius-full);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.frame {
|
|
159
|
+
position: relative;
|
|
160
|
+
|
|
161
|
+
display: block;
|
|
162
|
+
overflow: hidden;
|
|
163
|
+
|
|
164
|
+
width: 100%;
|
|
165
|
+
height: 100%;
|
|
166
|
+
|
|
167
|
+
border-radius: inherit;
|
|
168
|
+
|
|
169
|
+
background: var(--tt-muted);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
img {
|
|
173
|
+
display: block;
|
|
174
|
+
|
|
175
|
+
width: 100%;
|
|
176
|
+
height: 100%;
|
|
177
|
+
|
|
178
|
+
object-fit: cover;
|
|
179
|
+
|
|
180
|
+
/* Fades in over the skeleton rather than replacing it in one frame. */
|
|
181
|
+
opacity: 0;
|
|
182
|
+
transition: opacity var(--tt-duration-normal) var(--tt-ease);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
:host([fit="contain"]) img {
|
|
186
|
+
object-fit: contain;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.loaded img {
|
|
190
|
+
opacity: 1;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/*
|
|
194
|
+
Drawn here rather than by composing tt-skeleton: it has to sit
|
|
195
|
+
absolutely inside this frame and carries no semantics, which makes
|
|
196
|
+
it a background, not a component.
|
|
197
|
+
*/
|
|
198
|
+
.skeleton {
|
|
199
|
+
position: absolute;
|
|
200
|
+
inset: 0;
|
|
201
|
+
|
|
202
|
+
background: linear-gradient(
|
|
203
|
+
90deg,
|
|
204
|
+
var(--tt-muted) 0%,
|
|
205
|
+
var(--tt-accent) 50%,
|
|
206
|
+
var(--tt-muted) 100%
|
|
207
|
+
);
|
|
208
|
+
background-size: 200% 100%;
|
|
209
|
+
|
|
210
|
+
animation: shimmer 1200ms linear infinite;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
@keyframes shimmer {
|
|
214
|
+
from {
|
|
215
|
+
background-position: 200% 0;
|
|
216
|
+
}
|
|
217
|
+
to {
|
|
218
|
+
background-position: -200% 0;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.fallback {
|
|
223
|
+
position: absolute;
|
|
224
|
+
inset: 0;
|
|
225
|
+
|
|
226
|
+
display: flex;
|
|
227
|
+
align-items: center;
|
|
228
|
+
justify-content: center;
|
|
229
|
+
|
|
230
|
+
background: var(--tt-muted);
|
|
231
|
+
color: var(--tt-muted-foreground);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
@media (prefers-reduced-motion: reduce) {
|
|
235
|
+
img {
|
|
236
|
+
transition: none;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.skeleton {
|
|
240
|
+
animation: none;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
`; }
|
|
244
|
+
render() {
|
|
245
|
+
return html `
|
|
246
|
+
<div part="frame" class="frame ${this.status}">
|
|
247
|
+
${this.status === "loading" && !this.showFallback
|
|
248
|
+
? html `<div class="skeleton" part="skeleton" aria-hidden="true"></div>`
|
|
249
|
+
: nothing}
|
|
250
|
+
${this.showFallback
|
|
251
|
+
? html `
|
|
252
|
+
<!--
|
|
253
|
+
A decorative image whose source failed is still decorative,
|
|
254
|
+
so it announces nothing. One that meant something keeps its
|
|
255
|
+
description, because the meaning did not go away with the
|
|
256
|
+
pixels.
|
|
257
|
+
-->
|
|
258
|
+
<div
|
|
259
|
+
class="fallback"
|
|
260
|
+
part="fallback"
|
|
261
|
+
role=${ifDefined(this.alt ? "img" : undefined)}
|
|
262
|
+
aria-label=${this.alt || nothing}
|
|
263
|
+
aria-hidden=${ifDefined(this.alt ? undefined : "true")}
|
|
264
|
+
>
|
|
265
|
+
<slot name="fallback">
|
|
266
|
+
<tt-icon name="image" size="24px"></tt-icon>
|
|
267
|
+
</slot>
|
|
268
|
+
</div>
|
|
269
|
+
`
|
|
270
|
+
: html `
|
|
271
|
+
<img
|
|
272
|
+
part="image"
|
|
273
|
+
src=${this.src}
|
|
274
|
+
alt=${this.alt}
|
|
275
|
+
loading=${this.priority ? "eager" : "lazy"}
|
|
276
|
+
.fetchPriority=${this.priority ? "high" : "auto"}
|
|
277
|
+
decoding="async"
|
|
278
|
+
@load=${this.handleLoad}
|
|
279
|
+
@error=${this.handleError}
|
|
280
|
+
/>
|
|
281
|
+
`}
|
|
282
|
+
</div>
|
|
283
|
+
`;
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
__decorate([
|
|
287
|
+
property({ type: String })
|
|
288
|
+
], TTImage.prototype, "src", void 0);
|
|
289
|
+
__decorate([
|
|
290
|
+
property({ type: String })
|
|
291
|
+
], TTImage.prototype, "alt", void 0);
|
|
292
|
+
__decorate([
|
|
293
|
+
property({ type: String })
|
|
294
|
+
], TTImage.prototype, "ratio", void 0);
|
|
295
|
+
__decorate([
|
|
296
|
+
property({ type: String, reflect: true })
|
|
297
|
+
], TTImage.prototype, "fit", void 0);
|
|
298
|
+
__decorate([
|
|
299
|
+
property({ type: String, reflect: true })
|
|
300
|
+
], TTImage.prototype, "radius", void 0);
|
|
301
|
+
__decorate([
|
|
302
|
+
property({ type: Boolean })
|
|
303
|
+
], TTImage.prototype, "priority", void 0);
|
|
304
|
+
__decorate([
|
|
305
|
+
state()
|
|
306
|
+
], TTImage.prototype, "status", void 0);
|
|
307
|
+
__decorate([
|
|
308
|
+
query('img[part="image"]')
|
|
309
|
+
], TTImage.prototype, "img", void 0);
|
|
310
|
+
TTImage = __decorate([
|
|
311
|
+
customElement("tt-image")
|
|
312
|
+
], TTImage);
|
|
313
|
+
export { TTImage };
|
|
314
|
+
//# sourceMappingURL=tt-image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tt-image.js","sourceRoot":"","sources":["../src/tt-image.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,cAAc,CAAC;AAgBtB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEI,IAAM,OAAO,GAAb,MAAM,OAAQ,SAAQ,UAAU;IAAhC;;QACuB,QAAG,GAAG,EAAE,CAAC;QAErC,8DAA8D;QAClC,QAAG,GAAG,EAAE,CAAC;QAErC,2EAA2E;QAC/C,UAAK,GAAG,EAAE,CAAC;QAEI,QAAG,GAAa,OAAO,CAAC;QAExB,WAAM,GAAgB,QAAQ,CAAC;QAE1E;;;WAGG;QAC0B,aAAQ,GAAG,KAAK,CAAC;QAE7B,WAAM,GAAW,SAAS,CAAC;QAiDpC,eAAU,GAAG,GAAG,EAAE;YACxB,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;YACvB,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAC9D,CAAC;QACJ,CAAC,CAAC;QAEM,gBAAW,GAAG,GAAG,EAAE;YACzB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;YACtB,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,UAAU,EAAE;gBAC1B,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;gBACzB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;aACf,CAAC,CACH,CAAC;QACJ,CAAC,CAAC;IAwLJ,CAAC;IAjPC,IAAY,YAAY;QACtB,OAAO,IAAI,CAAC,GAAG,KAAK,EAAE,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC;IACpD,CAAC;IAED,UAAU,CAAC,OAAuB;QAChC;;;;;;;;UAQE;QACF,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QACvD,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,OAAO;QACL;;;;;;;;;UASE;QACF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACrB,IAAI,GAAG,EAAE,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/C,IAAI,GAAG,CAAC,YAAY,GAAG,CAAC;gBAAE,IAAI,CAAC,UAAU,EAAE,CAAC;;gBACvC,IAAI,CAAC,WAAW,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;aAoBM,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2IlB,AA3IY,CA2IX;IAEF,MAAM;QACJ,OAAO,IAAI,CAAA;uCACwB,IAAI,CAAC,MAAM;UACxC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,YAAY;YAC/C,CAAC,CAAC,IAAI,CAAA,iEAAiE;YACvE,CAAC,CAAC,OAAO;UACT,IAAI,CAAC,YAAY;YACjB,CAAC,CAAC,IAAI,CAAA;;;;;;;;;;uBAUO,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;6BACjC,IAAI,CAAC,GAAG,IAAI,OAAO;8BAClB,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;;;;;;aAMzD;YACH,CAAC,CAAC,IAAI,CAAA;;;sBAGM,IAAI,CAAC,GAAG;sBACR,IAAI,CAAC,GAAG;0BACJ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;iCACzB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;;wBAExC,IAAI,CAAC,UAAU;yBACd,IAAI,CAAC,WAAW;;aAE5B;;KAER,CAAC;IACJ,CAAC;;AA1Q2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oCAAU;AAGT;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oCAAU;AAGT;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sCAAY;AAEI;IAA1C,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;oCAAyB;AAExB;IAA1C,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;uCAAgC;AAM7C;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;yCAAkB;AAE7B;IAAhB,KAAK,EAAE;uCAAoC;AAMR;IAAnC,KAAK,CAAC,mBAAmB,CAAC;oCAAgC;AAzBhD,OAAO;IADnB,aAAa,CAAC,UAAU,CAAC;GACb,OAAO,CA4QnB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { LitElement } from "lit";
|
|
2
|
+
import "./tt-avatar.js";
|
|
3
|
+
import "./tt-empty-state.js";
|
|
4
|
+
export interface Conversation {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
avatar?: string;
|
|
8
|
+
subject?: string;
|
|
9
|
+
preview?: string;
|
|
10
|
+
timestamp?: string;
|
|
11
|
+
unread?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The list side of a messaging surface: who wrote, about what, when, and
|
|
15
|
+
* whether it has been read.
|
|
16
|
+
*
|
|
17
|
+
* Pairs with tt-thread, which is the reading side. Split in two because
|
|
18
|
+
* they live in different places on screen - side by side on a desktop,
|
|
19
|
+
* two separate routes on a phone - and a single component would have to
|
|
20
|
+
* own that layout decision on the app's behalf.
|
|
21
|
+
*
|
|
22
|
+
* It owns nothing. `selected` comes in, `tt-conversation-select` goes out.
|
|
23
|
+
* That matters more here than usual: which conversation is open is the
|
|
24
|
+
* kind of state that belongs in the URL, so a thread can be linked to.
|
|
25
|
+
*
|
|
26
|
+
* UNREAD IS THE ONLY THING IT EMPHASISES. An inbox is read by scanning
|
|
27
|
+
* for what is new, so unread rows carry weight and a dot, and everything
|
|
28
|
+
* else stays quiet. Styling the sender, the subject and the time all
|
|
29
|
+
* strongly would leave nothing for the eye to catch.
|
|
30
|
+
*/
|
|
31
|
+
export declare class TTInbox extends LitElement {
|
|
32
|
+
conversations: Conversation[];
|
|
33
|
+
selected: string;
|
|
34
|
+
emptyHeading: string;
|
|
35
|
+
emptyDescription: string;
|
|
36
|
+
private select;
|
|
37
|
+
static styles: import("lit").CSSResult[];
|
|
38
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
39
|
+
}
|
|
40
|
+
declare global {
|
|
41
|
+
interface HTMLElementTagNameMap {
|
|
42
|
+
"tt-inbox": TTInbox;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=tt-inbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tt-inbox.d.ts","sourceRoot":"","sources":["../src/tt-inbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAG5C,OAAO,gBAAgB,CAAC;AAExB,OAAO,qBAAqB,CAAC;AAE7B,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBACa,OAAQ,SAAQ,UAAU;IACV,aAAa,EAAE,YAAY,EAAE,CAAM;IAElC,QAAQ,SAAM;IAEc,YAAY,SAAiB;IAEzB,gBAAgB,SAAM;IAElF,OAAO,CAAC,MAAM;IAUd,MAAM,CAAC,MAAM,4BAgJV;IAEH,MAAM;CAsEP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,OAAO,CAAC;KACrB;CACF"}
|
package/dist/tt-inbox.js
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { LitElement, html, css } from "lit";
|
|
8
|
+
import { customElement, property } from "lit/decorators.js";
|
|
9
|
+
import "./tt-avatar.js";
|
|
10
|
+
import { srOnly } from "./sr-only.js";
|
|
11
|
+
import "./tt-empty-state.js";
|
|
12
|
+
/**
|
|
13
|
+
* The list side of a messaging surface: who wrote, about what, when, and
|
|
14
|
+
* whether it has been read.
|
|
15
|
+
*
|
|
16
|
+
* Pairs with tt-thread, which is the reading side. Split in two because
|
|
17
|
+
* they live in different places on screen - side by side on a desktop,
|
|
18
|
+
* two separate routes on a phone - and a single component would have to
|
|
19
|
+
* own that layout decision on the app's behalf.
|
|
20
|
+
*
|
|
21
|
+
* It owns nothing. `selected` comes in, `tt-conversation-select` goes out.
|
|
22
|
+
* That matters more here than usual: which conversation is open is the
|
|
23
|
+
* kind of state that belongs in the URL, so a thread can be linked to.
|
|
24
|
+
*
|
|
25
|
+
* UNREAD IS THE ONLY THING IT EMPHASISES. An inbox is read by scanning
|
|
26
|
+
* for what is new, so unread rows carry weight and a dot, and everything
|
|
27
|
+
* else stays quiet. Styling the sender, the subject and the time all
|
|
28
|
+
* strongly would leave nothing for the eye to catch.
|
|
29
|
+
*/
|
|
30
|
+
let TTInbox = class TTInbox extends LitElement {
|
|
31
|
+
constructor() {
|
|
32
|
+
super(...arguments);
|
|
33
|
+
this.conversations = [];
|
|
34
|
+
this.selected = "";
|
|
35
|
+
this.emptyHeading = "No messages";
|
|
36
|
+
this.emptyDescription = "";
|
|
37
|
+
}
|
|
38
|
+
select(conversation) {
|
|
39
|
+
this.dispatchEvent(new CustomEvent("tt-conversation-select", {
|
|
40
|
+
detail: { id: conversation.id },
|
|
41
|
+
bubbles: true,
|
|
42
|
+
composed: true,
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
static { this.styles = [srOnly, css `
|
|
46
|
+
/* The browser's own [hidden] rule loses to any :host display, so a
|
|
47
|
+
hidden element would still show. Important, so it always wins. */
|
|
48
|
+
:host([hidden]) {
|
|
49
|
+
display: none !important;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:host {
|
|
53
|
+
display: block;
|
|
54
|
+
font-family: var(--tt-font-sans);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
ul {
|
|
58
|
+
margin: 0;
|
|
59
|
+
padding: 0;
|
|
60
|
+
list-style: none;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/*
|
|
64
|
+
A real button per row. A div with a click handler is invisible to
|
|
65
|
+
the keyboard, and an inbox is exactly the surface people drive with
|
|
66
|
+
arrow keys and Enter.
|
|
67
|
+
*/
|
|
68
|
+
.row {
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: flex-start;
|
|
71
|
+
gap: var(--tt-space-3);
|
|
72
|
+
|
|
73
|
+
width: 100%;
|
|
74
|
+
box-sizing: border-box;
|
|
75
|
+
|
|
76
|
+
padding: var(--tt-space-3) var(--tt-space-4);
|
|
77
|
+
|
|
78
|
+
border: none;
|
|
79
|
+
border-bottom: 1px solid var(--tt-border);
|
|
80
|
+
border-left: 2px solid transparent;
|
|
81
|
+
|
|
82
|
+
background: transparent;
|
|
83
|
+
color: inherit;
|
|
84
|
+
|
|
85
|
+
font: inherit;
|
|
86
|
+
text-align: left;
|
|
87
|
+
cursor: pointer;
|
|
88
|
+
|
|
89
|
+
transition: background var(--tt-duration-fast) var(--tt-ease);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.row:hover {
|
|
93
|
+
background: var(--tt-accent);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.row:focus-visible {
|
|
97
|
+
outline: var(--tt-ring-width) solid var(--tt-ring);
|
|
98
|
+
outline-offset: calc(var(--tt-ring-width) * -1);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* The open conversation is marked on the leading edge rather than by
|
|
102
|
+
a fill, so it stays distinguishable from hover. */
|
|
103
|
+
.row.selected {
|
|
104
|
+
background: var(--tt-accent);
|
|
105
|
+
border-left-color: var(--tt-primary);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.body {
|
|
109
|
+
flex: 1;
|
|
110
|
+
min-width: 0;
|
|
111
|
+
|
|
112
|
+
display: flex;
|
|
113
|
+
flex-direction: column;
|
|
114
|
+
gap: 2px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.top {
|
|
118
|
+
display: flex;
|
|
119
|
+
align-items: baseline;
|
|
120
|
+
gap: var(--tt-space-2);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/*
|
|
124
|
+
min-width:0 plus the ellipsis is what keeps a long name from pushing
|
|
125
|
+
the timestamp off the row. Flex items will not shrink below their
|
|
126
|
+
content without it.
|
|
127
|
+
*/
|
|
128
|
+
.name {
|
|
129
|
+
flex: 1;
|
|
130
|
+
min-width: 0;
|
|
131
|
+
|
|
132
|
+
font-size: var(--tt-text-sm);
|
|
133
|
+
font-weight: var(--tt-weight-medium);
|
|
134
|
+
color: var(--tt-foreground);
|
|
135
|
+
|
|
136
|
+
overflow: hidden;
|
|
137
|
+
text-overflow: ellipsis;
|
|
138
|
+
white-space: nowrap;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.row.unread .name {
|
|
142
|
+
font-weight: var(--tt-weight-bold);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.time {
|
|
146
|
+
flex: 0 0 auto;
|
|
147
|
+
font-size: var(--tt-text-xs);
|
|
148
|
+
color: var(--tt-muted-foreground);
|
|
149
|
+
font-variant-numeric: tabular-nums;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.subject {
|
|
153
|
+
font-size: var(--tt-text-sm);
|
|
154
|
+
color: var(--tt-foreground);
|
|
155
|
+
|
|
156
|
+
overflow: hidden;
|
|
157
|
+
text-overflow: ellipsis;
|
|
158
|
+
white-space: nowrap;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.row.unread .subject {
|
|
162
|
+
font-weight: var(--tt-weight-semibold);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.preview {
|
|
166
|
+
font-size: var(--tt-text-xs);
|
|
167
|
+
color: var(--tt-muted-foreground);
|
|
168
|
+
|
|
169
|
+
overflow: hidden;
|
|
170
|
+
text-overflow: ellipsis;
|
|
171
|
+
white-space: nowrap;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.dot {
|
|
175
|
+
flex: 0 0 auto;
|
|
176
|
+
|
|
177
|
+
width: 8px;
|
|
178
|
+
height: 8px;
|
|
179
|
+
margin-top: 6px;
|
|
180
|
+
|
|
181
|
+
border-radius: var(--tt-radius-full);
|
|
182
|
+
background: var(--tt-primary);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.state {
|
|
186
|
+
padding: var(--tt-space-8) var(--tt-space-4);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
`]; }
|
|
190
|
+
render() {
|
|
191
|
+
if (this.conversations.length === 0) {
|
|
192
|
+
return html `
|
|
193
|
+
<div class="state">
|
|
194
|
+
<tt-empty-state
|
|
195
|
+
heading=${this.emptyHeading}
|
|
196
|
+
description=${this.emptyDescription}
|
|
197
|
+
>
|
|
198
|
+
<slot name="empty-actions" slot="actions"></slot>
|
|
199
|
+
</tt-empty-state>
|
|
200
|
+
</div>
|
|
201
|
+
`;
|
|
202
|
+
}
|
|
203
|
+
return html `
|
|
204
|
+
<!--
|
|
205
|
+
A list of buttons, not a listbox. role="listbox" promises ONE Tab
|
|
206
|
+
stop with arrow keys between options, and every row here is its
|
|
207
|
+
own button in the Tab order. A screen reader user following the
|
|
208
|
+
listbox instructions pressed arrows and got nothing. The selected
|
|
209
|
+
conversation is the current one, which aria-current says natively.
|
|
210
|
+
-->
|
|
211
|
+
<ul part="list" aria-label="Conversations">
|
|
212
|
+
${this.conversations.map((conversation) => {
|
|
213
|
+
const isSelected = conversation.id === this.selected;
|
|
214
|
+
return html `
|
|
215
|
+
<li>
|
|
216
|
+
<button
|
|
217
|
+
class="row ${isSelected ? "selected" : ""} ${conversation.unread
|
|
218
|
+
? "unread"
|
|
219
|
+
: ""}"
|
|
220
|
+
part="row"
|
|
221
|
+
type="button"
|
|
222
|
+
aria-current=${isSelected ? "true" : "false"}
|
|
223
|
+
@click=${() => this.select(conversation)}
|
|
224
|
+
>
|
|
225
|
+
<tt-avatar
|
|
226
|
+
size="small"
|
|
227
|
+
src=${conversation.avatar ?? ""}
|
|
228
|
+
name=${conversation.name}
|
|
229
|
+
></tt-avatar>
|
|
230
|
+
|
|
231
|
+
<span class="body">
|
|
232
|
+
<span class="top">
|
|
233
|
+
<span class="name">${conversation.name}</span>
|
|
234
|
+
${conversation.timestamp
|
|
235
|
+
? html `<span class="time">${conversation.timestamp}</span>`
|
|
236
|
+
: ""}
|
|
237
|
+
</span>
|
|
238
|
+
|
|
239
|
+
${conversation.subject
|
|
240
|
+
? html `<span class="subject">${conversation.subject}</span>`
|
|
241
|
+
: ""}
|
|
242
|
+
${conversation.preview
|
|
243
|
+
? html `<span class="preview">${conversation.preview}</span>`
|
|
244
|
+
: ""}
|
|
245
|
+
</span>
|
|
246
|
+
|
|
247
|
+
${conversation.unread
|
|
248
|
+
? html `<span class="dot" aria-hidden="true"></span
|
|
249
|
+
><span class="sr-only">Unread</span>`
|
|
250
|
+
: ""}
|
|
251
|
+
</button>
|
|
252
|
+
</li>
|
|
253
|
+
`;
|
|
254
|
+
})}
|
|
255
|
+
</ul>
|
|
256
|
+
`;
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
__decorate([
|
|
260
|
+
property({ type: Array })
|
|
261
|
+
], TTInbox.prototype, "conversations", void 0);
|
|
262
|
+
__decorate([
|
|
263
|
+
property({ type: String })
|
|
264
|
+
], TTInbox.prototype, "selected", void 0);
|
|
265
|
+
__decorate([
|
|
266
|
+
property({ type: String, attribute: "empty-heading" })
|
|
267
|
+
], TTInbox.prototype, "emptyHeading", void 0);
|
|
268
|
+
__decorate([
|
|
269
|
+
property({ type: String, attribute: "empty-description" })
|
|
270
|
+
], TTInbox.prototype, "emptyDescription", void 0);
|
|
271
|
+
TTInbox = __decorate([
|
|
272
|
+
customElement("tt-inbox")
|
|
273
|
+
], TTInbox);
|
|
274
|
+
export { TTInbox };
|
|
275
|
+
//# sourceMappingURL=tt-inbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tt-inbox.js","sourceRoot":"","sources":["../src/tt-inbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { LitElement } from "lit";
|
|
2
|
+
import type { PropertyValues } from "lit";
|
|
3
|
+
export type InputSize = "small" | "medium" | "large";
|
|
4
|
+
export type AutoCompleteToken = "on" | "off" | "name" | "given-name" | "family-name" | "nickname" | "username" | "new-password" | "current-password" | "organization" | "organization-title" | "street-address" | "address-line1" | "address-line2" | "address-level1" | "address-level2" | "country" | "country-name" | "postal-code" | "email" | "tel" | "url" | "bday" | "cc-name" | "cc-number" | "cc-exp" | "cc-csc";
|
|
5
|
+
export type InputType = "text" | "email" | "password" | "search" | "tel" | "url" | "number" | "date" | "time" | "datetime-local" | "month" | "week";
|
|
6
|
+
export declare class TTInput extends LitElement {
|
|
7
|
+
static formAssociated: boolean;
|
|
8
|
+
private internals;
|
|
9
|
+
label: string;
|
|
10
|
+
placeholder: string;
|
|
11
|
+
value: string;
|
|
12
|
+
name: string;
|
|
13
|
+
type: InputType;
|
|
14
|
+
autocomplete?: AutoCompleteToken;
|
|
15
|
+
size: InputSize;
|
|
16
|
+
disabled: boolean;
|
|
17
|
+
required: boolean;
|
|
18
|
+
fullWidth: boolean;
|
|
19
|
+
error: string;
|
|
20
|
+
labelHidden: boolean;
|
|
21
|
+
private inputId;
|
|
22
|
+
get form(): HTMLFormElement | null;
|
|
23
|
+
get validity(): ValidityState;
|
|
24
|
+
checkValidity(): boolean;
|
|
25
|
+
reportValidity(): boolean;
|
|
26
|
+
connectedCallback(): void;
|
|
27
|
+
updated(changed: PropertyValues): void;
|
|
28
|
+
private syncFormState;
|
|
29
|
+
formResetCallback(): void;
|
|
30
|
+
formStateRestoreCallback(state: string): void;
|
|
31
|
+
private handleInput;
|
|
32
|
+
private handleChange;
|
|
33
|
+
focus(options?: FocusOptions): void;
|
|
34
|
+
private focusFromBox;
|
|
35
|
+
static styles: import("lit").CSSResult[];
|
|
36
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
37
|
+
}
|
|
38
|
+
declare global {
|
|
39
|
+
interface HTMLElementTagNameMap {
|
|
40
|
+
"tt-input": TTInput;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=tt-input.d.ts.map
|