@tartaguti/ui-components 0.1.0 → 0.3.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 +43 -0
- package/README.md +12 -0
- package/custom-elements.json +2887 -823
- package/dist/accordion/tt-accordion-item.d.ts.map +1 -1
- package/dist/accordion/tt-accordion-item.js +5 -2
- package/dist/accordion/tt-accordion-item.js.map +1 -1
- package/dist/bento/tt-bento-item.d.ts.map +1 -1
- package/dist/bento/tt-bento-item.js +7 -13
- package/dist/bento/tt-bento-item.js.map +1 -1
- package/dist/docs.d.ts +7 -0
- package/dist/docs.d.ts.map +1 -0
- package/dist/docs.js +15 -0
- package/dist/docs.js.map +1 -0
- package/dist/index.d.ts +4 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -7
- package/dist/index.js.map +1 -1
- package/dist/sidebar/tt-menu-group.d.ts.map +1 -1
- package/dist/sidebar/tt-menu-group.js +16 -5
- package/dist/sidebar/tt-menu-group.js.map +1 -1
- package/dist/sidebar/tt-menu-item.d.ts.map +1 -1
- package/dist/sidebar/tt-menu-item.js +24 -11
- package/dist/sidebar/tt-menu-item.js.map +1 -1
- package/dist/sidebar/tt-sidebar-footer.d.ts.map +1 -1
- package/dist/sidebar/tt-sidebar-footer.js +7 -3
- package/dist/sidebar/tt-sidebar-footer.js.map +1 -1
- package/dist/sidebar/tt-sidebar.d.ts +8 -3
- package/dist/sidebar/tt-sidebar.d.ts.map +1 -1
- package/dist/sidebar/tt-sidebar.js +196 -44
- package/dist/sidebar/tt-sidebar.js.map +1 -1
- package/dist/strings.d.ts +64 -0
- package/dist/strings.d.ts.map +1 -0
- package/dist/strings.js +68 -0
- package/dist/strings.js.map +1 -0
- package/dist/tokens.css +30 -6
- package/dist/tt-alert.d.ts.map +1 -1
- package/dist/tt-alert.js +5 -2
- package/dist/tt-alert.js.map +1 -1
- package/dist/tt-auth.d.ts +5 -1
- package/dist/tt-auth.d.ts.map +1 -1
- package/dist/tt-auth.js +72 -10
- package/dist/tt-auth.js.map +1 -1
- package/dist/tt-breadcrumbs.d.ts.map +1 -1
- package/dist/tt-breadcrumbs.js +6 -3
- package/dist/tt-breadcrumbs.js.map +1 -1
- package/dist/tt-button-group.d.ts.map +1 -1
- package/dist/tt-button-group.js +7 -1
- package/dist/tt-button-group.js.map +1 -1
- package/dist/tt-button.d.ts.map +1 -1
- package/dist/tt-button.js +37 -28
- package/dist/tt-button.js.map +1 -1
- package/dist/tt-card.d.ts.map +1 -1
- package/dist/tt-card.js +9 -6
- package/dist/tt-card.js.map +1 -1
- package/dist/tt-chart.d.ts +10 -2
- package/dist/tt-chart.d.ts.map +1 -1
- package/dist/tt-chart.js +167 -29
- package/dist/tt-chart.js.map +1 -1
- package/dist/tt-checkbox.d.ts.map +1 -1
- package/dist/tt-checkbox.js +5 -2
- package/dist/tt-checkbox.js.map +1 -1
- package/dist/tt-code-block.d.ts +4 -5
- package/dist/tt-code-block.d.ts.map +1 -1
- package/dist/tt-code-block.js +53 -17
- package/dist/tt-code-block.js.map +1 -1
- package/dist/tt-combobox.d.ts +14 -0
- package/dist/tt-combobox.d.ts.map +1 -1
- package/dist/tt-combobox.js +234 -31
- package/dist/tt-combobox.js.map +1 -1
- package/dist/tt-company-card.d.ts +18 -0
- package/dist/tt-company-card.d.ts.map +1 -1
- package/dist/tt-company-card.js +73 -4
- package/dist/tt-company-card.js.map +1 -1
- package/dist/tt-comparison-table.d.ts.map +1 -1
- package/dist/tt-comparison-table.js +6 -3
- package/dist/tt-comparison-table.js.map +1 -1
- package/dist/tt-component-doc.d.ts.map +1 -1
- package/dist/tt-component-doc.js +6 -3
- package/dist/tt-component-doc.js.map +1 -1
- package/dist/tt-contact-list.d.ts +17 -2
- package/dist/tt-contact-list.d.ts.map +1 -1
- package/dist/tt-contact-list.js +68 -10
- package/dist/tt-contact-list.js.map +1 -1
- package/dist/tt-copy-button.d.ts.map +1 -1
- package/dist/tt-copy-button.js +6 -3
- package/dist/tt-copy-button.js.map +1 -1
- package/dist/tt-data-table.d.ts +32 -1
- package/dist/tt-data-table.d.ts.map +1 -1
- package/dist/tt-data-table.js +302 -16
- package/dist/tt-data-table.js.map +1 -1
- package/dist/tt-dock-item.d.ts +53 -0
- package/dist/tt-dock-item.d.ts.map +1 -0
- package/dist/tt-dock-item.js +270 -0
- package/dist/tt-dock-item.js.map +1 -0
- package/dist/tt-dock.d.ts +59 -0
- package/dist/tt-dock.d.ts.map +1 -0
- package/dist/tt-dock.js +337 -0
- package/dist/tt-dock.js.map +1 -0
- package/dist/tt-drawer.d.ts +4 -0
- package/dist/tt-drawer.d.ts.map +1 -1
- package/dist/tt-drawer.js +14 -4
- package/dist/tt-drawer.js.map +1 -1
- package/dist/tt-dropdown-menu.d.ts +5 -0
- package/dist/tt-dropdown-menu.d.ts.map +1 -1
- package/dist/tt-dropdown-menu.js +34 -8
- package/dist/tt-dropdown-menu.js.map +1 -1
- package/dist/tt-file-upload.d.ts +35 -0
- package/dist/tt-file-upload.d.ts.map +1 -1
- package/dist/tt-file-upload.js +210 -21
- package/dist/tt-file-upload.js.map +1 -1
- package/dist/tt-filter.d.ts.map +1 -1
- package/dist/tt-filter.js +10 -5
- package/dist/tt-filter.js.map +1 -1
- package/dist/tt-form.d.ts +25 -1
- package/dist/tt-form.d.ts.map +1 -1
- package/dist/tt-form.js +151 -12
- package/dist/tt-form.js.map +1 -1
- package/dist/tt-grid.d.ts +10 -1
- package/dist/tt-grid.d.ts.map +1 -1
- package/dist/tt-grid.js +38 -9
- package/dist/tt-grid.js.map +1 -1
- package/dist/tt-icon.d.ts.map +1 -1
- package/dist/tt-icon.js +5 -0
- package/dist/tt-icon.js.map +1 -1
- package/dist/tt-inbox.d.ts +4 -0
- package/dist/tt-inbox.d.ts.map +1 -1
- package/dist/tt-inbox.js +13 -3
- package/dist/tt-inbox.js.map +1 -1
- package/dist/tt-input.d.ts.map +1 -1
- package/dist/tt-input.js +15 -5
- package/dist/tt-input.js.map +1 -1
- package/dist/tt-key-values.d.ts +2 -0
- package/dist/tt-key-values.d.ts.map +1 -1
- package/dist/tt-key-values.js +45 -2
- package/dist/tt-key-values.js.map +1 -1
- package/dist/tt-layout.d.ts +53 -2
- package/dist/tt-layout.d.ts.map +1 -1
- package/dist/tt-layout.js +233 -27
- package/dist/tt-layout.js.map +1 -1
- package/dist/tt-modal.d.ts +4 -0
- package/dist/tt-modal.d.ts.map +1 -1
- package/dist/tt-modal.js +14 -4
- package/dist/tt-modal.js.map +1 -1
- package/dist/tt-navbar.d.ts +4 -0
- package/dist/tt-navbar.d.ts.map +1 -1
- package/dist/tt-navbar.js +42 -7
- package/dist/tt-navbar.js.map +1 -1
- package/dist/tt-pagination.d.ts +4 -0
- package/dist/tt-pagination.d.ts.map +1 -1
- package/dist/tt-pagination.js +8 -1
- package/dist/tt-pagination.js.map +1 -1
- package/dist/tt-product.d.ts +67 -15
- package/dist/tt-product.d.ts.map +1 -1
- package/dist/tt-product.js +447 -366
- package/dist/tt-product.js.map +1 -1
- package/dist/tt-progress.d.ts +1 -0
- package/dist/tt-progress.d.ts.map +1 -1
- package/dist/tt-progress.js +26 -7
- package/dist/tt-progress.js.map +1 -1
- package/dist/tt-quantity.d.ts.map +1 -1
- package/dist/tt-quantity.js +5 -2
- package/dist/tt-quantity.js.map +1 -1
- package/dist/tt-radio-group.d.ts.map +1 -1
- package/dist/tt-radio-group.js +5 -2
- package/dist/tt-radio-group.js.map +1 -1
- package/dist/tt-scroller.d.ts +76 -0
- package/dist/tt-scroller.d.ts.map +1 -0
- package/dist/tt-scroller.js +525 -0
- package/dist/tt-scroller.js.map +1 -0
- package/dist/tt-search.d.ts.map +1 -1
- package/dist/tt-search.js +10 -5
- package/dist/tt-search.js.map +1 -1
- package/dist/tt-select.d.ts +9 -0
- package/dist/tt-select.d.ts.map +1 -1
- package/dist/tt-select.js +99 -14
- package/dist/tt-select.js.map +1 -1
- package/dist/tt-slider.d.ts.map +1 -1
- package/dist/tt-slider.js +13 -2
- package/dist/tt-slider.js.map +1 -1
- package/dist/tt-social-links.d.ts.map +1 -1
- package/dist/tt-social-links.js +7 -4
- package/dist/tt-social-links.js.map +1 -1
- package/dist/tt-switcher.d.ts +2 -0
- package/dist/tt-switcher.d.ts.map +1 -1
- package/dist/tt-switcher.js +24 -76
- package/dist/tt-switcher.js.map +1 -1
- package/dist/tt-table-row.d.ts.map +1 -1
- package/dist/tt-table-row.js +5 -2
- package/dist/tt-table-row.js.map +1 -1
- package/dist/tt-table.d.ts.map +1 -1
- package/dist/tt-table.js +5 -2
- package/dist/tt-table.js.map +1 -1
- package/dist/tt-tabs.d.ts.map +1 -1
- package/dist/tt-tabs.js +5 -2
- package/dist/tt-tabs.js.map +1 -1
- package/dist/tt-tag-list.d.ts.map +1 -1
- package/dist/tt-tag-list.js +6 -3
- package/dist/tt-tag-list.js.map +1 -1
- package/dist/tt-textarea.d.ts.map +1 -1
- package/dist/tt-textarea.js +5 -2
- package/dist/tt-textarea.js.map +1 -1
- package/dist/tt-toast.d.ts +4 -1
- package/dist/tt-toast.d.ts.map +1 -1
- package/dist/tt-toast.js +40 -6
- package/dist/tt-toast.js.map +1 -1
- package/dist/tt-toggle-group.d.ts.map +1 -1
- package/dist/tt-toggle-group.js +7 -1
- package/dist/tt-toggle-group.js.map +1 -1
- package/dist/tt-toggle.d.ts.map +1 -1
- package/dist/tt-toggle.js +14 -9
- package/dist/tt-toggle.js.map +1 -1
- package/package.json +1 -1
- package/vscode.html-custom-data.json +241 -66
|
@@ -0,0 +1,270 @@
|
|
|
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, query } from "lit/decorators.js";
|
|
9
|
+
import { ifDefined } from "lit/directives/if-defined.js";
|
|
10
|
+
import { safeUrl } from "./safe-url.js";
|
|
11
|
+
/**
|
|
12
|
+
* One target in a tt-dock: an icon over a short label, a link or a button.
|
|
13
|
+
*
|
|
14
|
+
* ---------------------------------------------------------------------
|
|
15
|
+
* THE DOCK KEEPS THE STATE, THE ITEM ONLY ASKS.
|
|
16
|
+
*
|
|
17
|
+
* A click sends `tt-dock-select` and changes nothing here. The dock
|
|
18
|
+
* hears it, moves `active` (the current page) and sends its own
|
|
19
|
+
* `tt-dock-select`. Only the
|
|
20
|
+
* dock can know that choosing one item un-chooses another, the same
|
|
21
|
+
* reason tt-accordion owns its items' open state.
|
|
22
|
+
*
|
|
23
|
+
* ---------------------------------------------------------------------
|
|
24
|
+
* HOW THE DOCK STYLES IT.
|
|
25
|
+
*
|
|
26
|
+
* The dock decides the shape (a bar, a floating pill, a column) and
|
|
27
|
+
* whether labels show. It says so through inherited custom properties
|
|
28
|
+
* (`--tt-dock-item-*`, `--tt-dock-label-*`), read below with the
|
|
29
|
+
* bar's values as fallbacks, so an item has no props for any of it and
|
|
30
|
+
* one used outside a dock still looks right.
|
|
31
|
+
*/
|
|
32
|
+
let TTDockItem = class TTDockItem extends LitElement {
|
|
33
|
+
constructor() {
|
|
34
|
+
super(...arguments);
|
|
35
|
+
/**
|
|
36
|
+
* The current page, announced as aria-current="page". The dock moves
|
|
37
|
+
* it when an item is chosen; set it for the start.
|
|
38
|
+
*/
|
|
39
|
+
this.active = false;
|
|
40
|
+
this.disabled = false;
|
|
41
|
+
/** Makes the item a link. Empty: a button that tells your app it was chosen. */
|
|
42
|
+
this.href = "";
|
|
43
|
+
/** Names this item in `tt-dock-select`. Empty: the label text is sent. */
|
|
44
|
+
this.value = "";
|
|
45
|
+
}
|
|
46
|
+
/** Focuses the link or button inside. */
|
|
47
|
+
focus(options) {
|
|
48
|
+
this.control?.focus(options);
|
|
49
|
+
}
|
|
50
|
+
get text() {
|
|
51
|
+
return (this.textContent ?? "").trim();
|
|
52
|
+
}
|
|
53
|
+
onClick(event) {
|
|
54
|
+
if (this.disabled) {
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// A link opened in a new tab or window is not a choice made here.
|
|
59
|
+
if (this.href && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey))
|
|
60
|
+
return;
|
|
61
|
+
this.dispatchEvent(new CustomEvent("tt-dock-select", {
|
|
62
|
+
detail: { value: this.value || this.text },
|
|
63
|
+
bubbles: true,
|
|
64
|
+
composed: true,
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
/*
|
|
68
|
+
With the label hidden (the dock's labels-hidden), a mouse still gets
|
|
69
|
+
the name as a hint. Asked at the moment the pointer arrives, from the
|
|
70
|
+
label's own style, because only the dock knows whether labels show.
|
|
71
|
+
A screen reader never needs it: the label is still there for it.
|
|
72
|
+
*/
|
|
73
|
+
onPointerEnter() {
|
|
74
|
+
const control = this.control;
|
|
75
|
+
const label = this.labelEl;
|
|
76
|
+
if (!control || !label)
|
|
77
|
+
return;
|
|
78
|
+
const hidden = getComputedStyle(label).position === "absolute";
|
|
79
|
+
if (hidden && this.text)
|
|
80
|
+
control.setAttribute("title", this.text);
|
|
81
|
+
else
|
|
82
|
+
control.removeAttribute("title");
|
|
83
|
+
}
|
|
84
|
+
static { this.styles = css `
|
|
85
|
+
/* The browser's own [hidden] rule loses to any :host display. */
|
|
86
|
+
:host([hidden]) {
|
|
87
|
+
display: none !important;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
:host {
|
|
91
|
+
display: block;
|
|
92
|
+
min-width: 0;
|
|
93
|
+
|
|
94
|
+
font-family: var(--tt-font-sans);
|
|
95
|
+
-webkit-font-smoothing: antialiased;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.item {
|
|
99
|
+
position: relative;
|
|
100
|
+
|
|
101
|
+
display: flex;
|
|
102
|
+
flex-direction: column;
|
|
103
|
+
align-items: center;
|
|
104
|
+
justify-content: center;
|
|
105
|
+
gap: var(--tt-space-1);
|
|
106
|
+
|
|
107
|
+
box-sizing: border-box;
|
|
108
|
+
width: 100%;
|
|
109
|
+
/* The target: 56px with a label, 48px without (the dock sets it).
|
|
110
|
+
Both clear 44px, and 48px on a touch screen. */
|
|
111
|
+
min-width: var(--tt-dock-item-min-width, 4rem);
|
|
112
|
+
min-height: var(--tt-dock-item-height, 3.5rem);
|
|
113
|
+
padding: var(--tt-space-1) var(--tt-space-2);
|
|
114
|
+
|
|
115
|
+
border: 0;
|
|
116
|
+
border-radius: var(--tt-dock-item-radius, var(--tt-radius-lg));
|
|
117
|
+
background: none;
|
|
118
|
+
color: var(--tt-muted-foreground);
|
|
119
|
+
|
|
120
|
+
font: inherit;
|
|
121
|
+
font-size: var(--tt-text-xs);
|
|
122
|
+
font-weight: var(--tt-weight-medium);
|
|
123
|
+
line-height: var(--tt-leading-tight);
|
|
124
|
+
text-decoration: none;
|
|
125
|
+
|
|
126
|
+
cursor: pointer;
|
|
127
|
+
user-select: none;
|
|
128
|
+
-webkit-user-select: none;
|
|
129
|
+
/* A long press on a link would open the phone's link menu. */
|
|
130
|
+
-webkit-touch-callout: none;
|
|
131
|
+
|
|
132
|
+
transition: color var(--tt-duration-fast) var(--tt-ease-out);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* Inset, so a ring at the end of a row is not cut off by the row. */
|
|
136
|
+
.item:focus-visible {
|
|
137
|
+
outline: var(--tt-ring-width) solid var(--tt-ring);
|
|
138
|
+
outline-offset: calc(var(--tt-ring-width) * -1);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/*
|
|
142
|
+
The indicator: a pill behind the icon, the shape a current item
|
|
143
|
+
takes (as in Material's navigation bar). Behind the icon only, so
|
|
144
|
+
the target can be wide while the mark stays small and steady.
|
|
145
|
+
*/
|
|
146
|
+
.icon {
|
|
147
|
+
position: relative;
|
|
148
|
+
|
|
149
|
+
display: grid;
|
|
150
|
+
place-items: center;
|
|
151
|
+
|
|
152
|
+
width: var(--tt-dock-indicator-width, 3.5rem);
|
|
153
|
+
max-width: 100%;
|
|
154
|
+
height: 2rem;
|
|
155
|
+
|
|
156
|
+
border-radius: var(--tt-radius-full);
|
|
157
|
+
|
|
158
|
+
--tt-icon-size: 1.375rem;
|
|
159
|
+
|
|
160
|
+
transition: background var(--tt-duration-fast) var(--tt-ease-out);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.label {
|
|
164
|
+
max-width: 100%;
|
|
165
|
+
overflow: hidden;
|
|
166
|
+
white-space: nowrap;
|
|
167
|
+
text-overflow: ellipsis;
|
|
168
|
+
|
|
169
|
+
/* Hidden by the dock's labels-hidden: off screen, still the name. */
|
|
170
|
+
position: var(--tt-dock-label-position, static);
|
|
171
|
+
width: var(--tt-dock-label-size, auto);
|
|
172
|
+
height: var(--tt-dock-label-size, auto);
|
|
173
|
+
clip-path: var(--tt-dock-label-clip, none);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.active {
|
|
177
|
+
color: var(--tt-foreground);
|
|
178
|
+
font-weight: var(--tt-weight-semibold);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.active .icon {
|
|
182
|
+
background: var(--tt-accent);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.item:active:not(.disabled) .icon {
|
|
186
|
+
background: var(--tt-accent);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
@media (hover: hover) {
|
|
190
|
+
.item:hover:not(.disabled) {
|
|
191
|
+
color: var(--tt-foreground);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.item:hover:not(.disabled):not(.active) .icon {
|
|
195
|
+
background: var(--tt-muted);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.disabled {
|
|
200
|
+
opacity: var(--tt-opacity-disabled);
|
|
201
|
+
cursor: not-allowed;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
::slotted(tt-icon) {
|
|
205
|
+
flex-shrink: 0;
|
|
206
|
+
}
|
|
207
|
+
`; }
|
|
208
|
+
render() {
|
|
209
|
+
const classes = `item ${this.active ? "active" : ""} ${this.disabled ? "disabled" : ""}`;
|
|
210
|
+
const current = this.active ? "page" : undefined;
|
|
211
|
+
const inner = html `
|
|
212
|
+
<span class="icon" part="icon">
|
|
213
|
+
<slot name="icon"></slot>
|
|
214
|
+
</span>
|
|
215
|
+
<span class="label" part="label"><slot></slot></span>
|
|
216
|
+
`;
|
|
217
|
+
if (this.href) {
|
|
218
|
+
// An unsafe address never reaches the DOM: the item is then a link with no href.
|
|
219
|
+
const href = this.disabled ? null : safeUrl(this.href);
|
|
220
|
+
return html `
|
|
221
|
+
<a
|
|
222
|
+
class=${classes}
|
|
223
|
+
part="item"
|
|
224
|
+
href=${ifDefined(href ?? undefined)}
|
|
225
|
+
aria-current=${ifDefined(current)}
|
|
226
|
+
aria-disabled=${ifDefined(this.disabled ? "true" : undefined)}
|
|
227
|
+
@click=${this.onClick}
|
|
228
|
+
@pointerenter=${this.onPointerEnter}
|
|
229
|
+
>${inner}</a
|
|
230
|
+
>
|
|
231
|
+
`;
|
|
232
|
+
}
|
|
233
|
+
return html `
|
|
234
|
+
<button
|
|
235
|
+
type="button"
|
|
236
|
+
class=${classes}
|
|
237
|
+
part="item"
|
|
238
|
+
?disabled=${this.disabled}
|
|
239
|
+
aria-current=${ifDefined(current)}
|
|
240
|
+
@click=${this.onClick}
|
|
241
|
+
@pointerenter=${this.onPointerEnter}
|
|
242
|
+
>
|
|
243
|
+
${inner}
|
|
244
|
+
</button>
|
|
245
|
+
`;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
__decorate([
|
|
249
|
+
property({ type: Boolean, reflect: true })
|
|
250
|
+
], TTDockItem.prototype, "active", void 0);
|
|
251
|
+
__decorate([
|
|
252
|
+
property({ type: Boolean, reflect: true })
|
|
253
|
+
], TTDockItem.prototype, "disabled", void 0);
|
|
254
|
+
__decorate([
|
|
255
|
+
property({ type: String })
|
|
256
|
+
], TTDockItem.prototype, "href", void 0);
|
|
257
|
+
__decorate([
|
|
258
|
+
property({ type: String })
|
|
259
|
+
], TTDockItem.prototype, "value", void 0);
|
|
260
|
+
__decorate([
|
|
261
|
+
query(".item")
|
|
262
|
+
], TTDockItem.prototype, "control", void 0);
|
|
263
|
+
__decorate([
|
|
264
|
+
query(".label")
|
|
265
|
+
], TTDockItem.prototype, "labelEl", void 0);
|
|
266
|
+
TTDockItem = __decorate([
|
|
267
|
+
customElement("tt-dock-item")
|
|
268
|
+
], TTDockItem);
|
|
269
|
+
export { TTDockItem };
|
|
270
|
+
//# sourceMappingURL=tt-dock-item.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tt-dock-item.js","sourceRoot":"","sources":["../src/tt-dock-item.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { LitElement } from "lit";
|
|
2
|
+
import "./tt-scroller.js";
|
|
3
|
+
import "./tt-dock-item.js";
|
|
4
|
+
export type DockVariant = "bar" | "floating";
|
|
5
|
+
export type DockPosition = "bottom" | "top" | "left" | "right";
|
|
6
|
+
/**
|
|
7
|
+
* A few big targets on one edge of the screen: a phone's tab bar, a
|
|
8
|
+
* floating dock on a desktop, or a column down the side. Holds
|
|
9
|
+
* tt-dock-item children and renders a <nav>.
|
|
10
|
+
*
|
|
11
|
+
* ---------------------------------------------------------------------
|
|
12
|
+
* WHY A DOCK IS NOT A NAVBAR.
|
|
13
|
+
*
|
|
14
|
+
* A navbar is the top of a site: a brand, links, actions, all sizes. A
|
|
15
|
+
* dock is three to five equal targets in thumb reach. Different job,
|
|
16
|
+
* different shape, so a different component.
|
|
17
|
+
*
|
|
18
|
+
* ---------------------------------------------------------------------
|
|
19
|
+
* IT TAKES ITS OWN SPACE, SO IT NEVER COVERS THE PAGE.
|
|
20
|
+
*
|
|
21
|
+
* It is sticky: it sits where you put it and pins to that edge of
|
|
22
|
+
* whatever scrolls (the window, a preview frame, a builder canvas,
|
|
23
|
+
* tt-layout's page). Put a bottom dock last, a top dock first, and a
|
|
24
|
+
* side dock beside the content in a row, where it is one screen tall
|
|
25
|
+
* like a sticky sidebar. Being in the flow is what keeps the last line
|
|
26
|
+
* of content clear of it: at the end of the page the dock sits after
|
|
27
|
+
* the content, not over it.
|
|
28
|
+
*
|
|
29
|
+
* ---------------------------------------------------------------------
|
|
30
|
+
* THE DOCK OWNS WHICH ITEM IS CURRENT.
|
|
31
|
+
*
|
|
32
|
+
* An item's click only asks (tt-dock-select from the item). The dock
|
|
33
|
+
* moves `active` to it, off the others, and sends its own
|
|
34
|
+
* tt-dock-select, so a dock with no listener (a pasted snippet, a
|
|
35
|
+
* generated component) still shows the right current page, and a page
|
|
36
|
+
* hears one event, not two. A page that sets `active` itself still wins.
|
|
37
|
+
*
|
|
38
|
+
* @fires tt-dock-select - An item was chosen and is now the current one. detail: { value }.
|
|
39
|
+
*/
|
|
40
|
+
export declare class TTDock extends LitElement {
|
|
41
|
+
/** bar: across the whole edge. floating: a pill held off the edge. */
|
|
42
|
+
variant: DockVariant;
|
|
43
|
+
/** The edge it sits on. Top and bottom lay the items in a row; left and right in a column. */
|
|
44
|
+
position: DockPosition;
|
|
45
|
+
/** Icons only. Each label stays as the item's name for a screen reader, and a hint for a mouse. */
|
|
46
|
+
labelsHidden: boolean;
|
|
47
|
+
/** Names the navigation for a screen reader, beside any other on the page. */
|
|
48
|
+
label: string;
|
|
49
|
+
private items;
|
|
50
|
+
private onSelect;
|
|
51
|
+
static styles: import("lit").CSSResult;
|
|
52
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
53
|
+
}
|
|
54
|
+
declare global {
|
|
55
|
+
interface HTMLElementTagNameMap {
|
|
56
|
+
"tt-dock": TTDock;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=tt-dock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tt-dock.d.ts","sourceRoot":"","sources":["../src/tt-dock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,MAAM,KAAK,CAAC;AAGrD,OAAO,kBAAkB,CAAC;AAC1B,OAAO,mBAAmB,CAAC;AAG3B,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,UAAU,CAAC;AAC7C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAI/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBACa,MAAO,SAAQ,UAAU;IACpC,sEAAsE;IAC3B,OAAO,EAAE,WAAW,CAAS;IAExE,8FAA8F;IACnD,QAAQ,EAAE,YAAY,CAAY;IAE7E,mGAAmG;IAC3B,YAAY,UAAS;IAE7F,8EAA8E;IAClD,KAAK,SAAM;IAEc,OAAO,CAAC,KAAK,CAAgB;IAOlF,OAAO,CAAC,QAAQ,CAed;IAEF,MAAM,CAAC,MAAM,0BA6NX;IAEF,MAAM;CAsBP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
|
package/dist/tt-dock.js
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
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, queryAssignedElements } from "lit/decorators.js";
|
|
9
|
+
import "./tt-scroller.js";
|
|
10
|
+
import "./tt-dock-item.js";
|
|
11
|
+
const sideways = (position) => position === "left" || position === "right";
|
|
12
|
+
/**
|
|
13
|
+
* A few big targets on one edge of the screen: a phone's tab bar, a
|
|
14
|
+
* floating dock on a desktop, or a column down the side. Holds
|
|
15
|
+
* tt-dock-item children and renders a <nav>.
|
|
16
|
+
*
|
|
17
|
+
* ---------------------------------------------------------------------
|
|
18
|
+
* WHY A DOCK IS NOT A NAVBAR.
|
|
19
|
+
*
|
|
20
|
+
* A navbar is the top of a site: a brand, links, actions, all sizes. A
|
|
21
|
+
* dock is three to five equal targets in thumb reach. Different job,
|
|
22
|
+
* different shape, so a different component.
|
|
23
|
+
*
|
|
24
|
+
* ---------------------------------------------------------------------
|
|
25
|
+
* IT TAKES ITS OWN SPACE, SO IT NEVER COVERS THE PAGE.
|
|
26
|
+
*
|
|
27
|
+
* It is sticky: it sits where you put it and pins to that edge of
|
|
28
|
+
* whatever scrolls (the window, a preview frame, a builder canvas,
|
|
29
|
+
* tt-layout's page). Put a bottom dock last, a top dock first, and a
|
|
30
|
+
* side dock beside the content in a row, where it is one screen tall
|
|
31
|
+
* like a sticky sidebar. Being in the flow is what keeps the last line
|
|
32
|
+
* of content clear of it: at the end of the page the dock sits after
|
|
33
|
+
* the content, not over it.
|
|
34
|
+
*
|
|
35
|
+
* ---------------------------------------------------------------------
|
|
36
|
+
* THE DOCK OWNS WHICH ITEM IS CURRENT.
|
|
37
|
+
*
|
|
38
|
+
* An item's click only asks (tt-dock-select from the item). The dock
|
|
39
|
+
* moves `active` to it, off the others, and sends its own
|
|
40
|
+
* tt-dock-select, so a dock with no listener (a pasted snippet, a
|
|
41
|
+
* generated component) still shows the right current page, and a page
|
|
42
|
+
* hears one event, not two. A page that sets `active` itself still wins.
|
|
43
|
+
*
|
|
44
|
+
* @fires tt-dock-select - An item was chosen and is now the current one. detail: { value }.
|
|
45
|
+
*/
|
|
46
|
+
let TTDock = class TTDock extends LitElement {
|
|
47
|
+
constructor() {
|
|
48
|
+
super(...arguments);
|
|
49
|
+
/** bar: across the whole edge. floating: a pill held off the edge. */
|
|
50
|
+
this.variant = "bar";
|
|
51
|
+
/** The edge it sits on. Top and bottom lay the items in a row; left and right in a column. */
|
|
52
|
+
this.position = "bottom";
|
|
53
|
+
/** Icons only. Each label stays as the item's name for a screen reader, and a hint for a mouse. */
|
|
54
|
+
this.labelsHidden = false;
|
|
55
|
+
/** Names the navigation for a screen reader, beside any other on the page. */
|
|
56
|
+
this.label = "";
|
|
57
|
+
/*
|
|
58
|
+
An item asks; the dock answers. The chosen item becomes the current
|
|
59
|
+
one and the others stop being it, then one tt-dock-select from the
|
|
60
|
+
dock. The item's own is stopped, so a page hears it once.
|
|
61
|
+
*/
|
|
62
|
+
this.onSelect = (event) => {
|
|
63
|
+
const item = event.target;
|
|
64
|
+
if (!this.items.includes(item))
|
|
65
|
+
return;
|
|
66
|
+
event.stopPropagation();
|
|
67
|
+
for (const other of this.items)
|
|
68
|
+
other.active = other === item;
|
|
69
|
+
const { value } = event.detail;
|
|
70
|
+
this.dispatchEvent(new CustomEvent("tt-dock-select", {
|
|
71
|
+
detail: { value },
|
|
72
|
+
bubbles: true,
|
|
73
|
+
composed: true,
|
|
74
|
+
}));
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
static { this.styles = css `
|
|
78
|
+
/* The browser's own [hidden] rule loses to any :host display. */
|
|
79
|
+
:host([hidden]) {
|
|
80
|
+
display: none !important;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
:host {
|
|
84
|
+
display: block;
|
|
85
|
+
|
|
86
|
+
/* Pinned to the edge it sits on (below), over the content that
|
|
87
|
+
scrolls under it. */
|
|
88
|
+
position: sticky;
|
|
89
|
+
bottom: 0;
|
|
90
|
+
z-index: var(--tt-z-sticky);
|
|
91
|
+
|
|
92
|
+
/* In a row beside the content: never squeezed by it. */
|
|
93
|
+
flex-shrink: 0;
|
|
94
|
+
min-width: 0;
|
|
95
|
+
|
|
96
|
+
color: var(--tt-foreground);
|
|
97
|
+
font-family: var(--tt-font-sans);
|
|
98
|
+
-webkit-font-smoothing: antialiased;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* In a column at least a screen tall (an app's page, tt-layout's
|
|
102
|
+
content), a bottom dock goes to its end even when the page above
|
|
103
|
+
is short. An auto margin is 0 anywhere else. */
|
|
104
|
+
:host([position="bottom"]) {
|
|
105
|
+
margin-top: auto;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
:host([position="top"]) {
|
|
109
|
+
top: 0;
|
|
110
|
+
bottom: auto;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* A column one screen tall beside the content, like a sticky
|
|
114
|
+
sidebar: the builder sets the screen's height on its canvas. */
|
|
115
|
+
:host([position="left"]),
|
|
116
|
+
:host([position="right"]) {
|
|
117
|
+
top: 0;
|
|
118
|
+
bottom: auto;
|
|
119
|
+
align-self: flex-start;
|
|
120
|
+
height: var(--tt-viewport-height, 100dvh);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* ---- the bar, or the clear region a pill floats in ---- */
|
|
124
|
+
|
|
125
|
+
.dock {
|
|
126
|
+
box-sizing: border-box;
|
|
127
|
+
display: flex;
|
|
128
|
+
margin: 0;
|
|
129
|
+
|
|
130
|
+
/* Sizes for the items, inherited into their shadow roots. A target
|
|
131
|
+
of 56px with a label, 48px without: both clear 44px, and 48px on
|
|
132
|
+
a touch screen. */
|
|
133
|
+
--tt-dock-item-min-width: 4rem;
|
|
134
|
+
--tt-dock-item-height: 3.5rem;
|
|
135
|
+
--tt-dock-indicator-width: 3.5rem;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.horizontal {
|
|
139
|
+
flex-direction: row;
|
|
140
|
+
justify-content: center;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.vertical {
|
|
144
|
+
flex-direction: column;
|
|
145
|
+
justify-content: flex-start;
|
|
146
|
+
height: 100%;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.labels-hidden {
|
|
150
|
+
--tt-dock-item-min-width: 3rem;
|
|
151
|
+
--tt-dock-item-height: 3rem;
|
|
152
|
+
--tt-dock-indicator-width: 2.5rem;
|
|
153
|
+
--tt-dock-label-position: absolute;
|
|
154
|
+
--tt-dock-label-size: 1px;
|
|
155
|
+
--tt-dock-label-clip: inset(50%);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/* A bar: the surface across the whole edge, clear of the notch and
|
|
159
|
+
the home indicator on the edge it touches. */
|
|
160
|
+
.bar {
|
|
161
|
+
background: var(--tt-card);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.bar.bottom {
|
|
165
|
+
border-top: 1px solid var(--tt-border);
|
|
166
|
+
padding: 0 env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px)
|
|
167
|
+
env(safe-area-inset-left, 0px);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.bar.top {
|
|
171
|
+
border-bottom: 1px solid var(--tt-border);
|
|
172
|
+
padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) 0
|
|
173
|
+
env(safe-area-inset-left, 0px);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.bar.left {
|
|
177
|
+
border-right: 1px solid var(--tt-border);
|
|
178
|
+
padding: env(safe-area-inset-top, 0px) 0 env(safe-area-inset-bottom, 0px)
|
|
179
|
+
env(safe-area-inset-left, 0px);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.bar.right {
|
|
183
|
+
border-left: 1px solid var(--tt-border);
|
|
184
|
+
padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px)
|
|
185
|
+
env(safe-area-inset-bottom, 0px) 0;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* Floating: the region is clear and only the pill takes clicks, so
|
|
189
|
+
content scrolling past the pill's sides stays usable. */
|
|
190
|
+
.floating {
|
|
191
|
+
--_inset: var(--tt-space-3);
|
|
192
|
+
--tt-dock-item-radius: var(--tt-radius-full);
|
|
193
|
+
|
|
194
|
+
pointer-events: none;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.floating.bottom {
|
|
198
|
+
padding: var(--tt-space-2) calc(var(--_inset) + env(safe-area-inset-right, 0px))
|
|
199
|
+
calc(var(--_inset) + env(safe-area-inset-bottom, 0px))
|
|
200
|
+
calc(var(--_inset) + env(safe-area-inset-left, 0px));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.floating.top {
|
|
204
|
+
padding: calc(var(--_inset) + env(safe-area-inset-top, 0px))
|
|
205
|
+
calc(var(--_inset) + env(safe-area-inset-right, 0px)) var(--tt-space-2)
|
|
206
|
+
calc(var(--_inset) + env(safe-area-inset-left, 0px));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.floating.left {
|
|
210
|
+
justify-content: center;
|
|
211
|
+
padding: var(--_inset) var(--tt-space-2) var(--_inset)
|
|
212
|
+
calc(var(--_inset) + env(safe-area-inset-left, 0px));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.floating.right {
|
|
216
|
+
justify-content: center;
|
|
217
|
+
padding: var(--_inset) calc(var(--_inset) + env(safe-area-inset-right, 0px)) var(--_inset)
|
|
218
|
+
var(--tt-space-2);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/* ---- the surface: the bar's content box, or the pill ---- */
|
|
222
|
+
|
|
223
|
+
.surface {
|
|
224
|
+
display: flex;
|
|
225
|
+
min-width: 0;
|
|
226
|
+
min-height: 0;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.bar .surface {
|
|
230
|
+
flex: 1;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.vertical .surface {
|
|
234
|
+
flex-direction: column;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* The second elevation rung: a raised surface paired with its shadow. */
|
|
238
|
+
.floating .surface {
|
|
239
|
+
pointer-events: auto;
|
|
240
|
+
box-sizing: border-box;
|
|
241
|
+
max-width: 100%;
|
|
242
|
+
max-height: 100%;
|
|
243
|
+
padding: var(--tt-space-1);
|
|
244
|
+
|
|
245
|
+
border: 1px solid var(--tt-border);
|
|
246
|
+
border-radius: var(--tt-radius-full);
|
|
247
|
+
background: var(--tt-popover);
|
|
248
|
+
box-shadow: var(--tt-elevation-2);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/* ---- the items ---- */
|
|
252
|
+
|
|
253
|
+
/* A row is a tt-scroller: more items than fit scroll sideways, with
|
|
254
|
+
no scrollbar and a fade on the side that has more. */
|
|
255
|
+
.row {
|
|
256
|
+
flex: 1 1 auto;
|
|
257
|
+
min-width: 0;
|
|
258
|
+
/* The scroller keeps room above and below for a focus ring that
|
|
259
|
+
sticks out. An item's ring is inset, so that room is not needed,
|
|
260
|
+
and left alone it hangs below the bar and lengthens the page. */
|
|
261
|
+
overflow: clip;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* On a wide bar the items keep to a phone's spread, centred. */
|
|
265
|
+
.bar .row {
|
|
266
|
+
max-width: 40rem;
|
|
267
|
+
margin-inline: auto;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/* A column scrolls down. Its scrollbar stays: a desktop wheel scrolls
|
|
271
|
+
it, and nothing else would say there is more. */
|
|
272
|
+
.column {
|
|
273
|
+
display: flex;
|
|
274
|
+
flex-direction: column;
|
|
275
|
+
gap: var(--tt-space-1);
|
|
276
|
+
min-height: 0;
|
|
277
|
+
padding: var(--tt-space-2);
|
|
278
|
+
overflow-x: hidden;
|
|
279
|
+
overflow-y: auto;
|
|
280
|
+
scrollbar-width: thin;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.floating .column {
|
|
284
|
+
padding: 0;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/* A bar shares its width out equally; a pill and a column take each
|
|
288
|
+
item at its own size. Items never shrink below a target. */
|
|
289
|
+
.bar.horizontal ::slotted(*) {
|
|
290
|
+
flex: 1 1 0;
|
|
291
|
+
min-width: var(--tt-dock-item-min-width);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.floating.horizontal ::slotted(*),
|
|
295
|
+
.vertical ::slotted(*) {
|
|
296
|
+
flex: 0 0 auto;
|
|
297
|
+
}
|
|
298
|
+
`; }
|
|
299
|
+
render() {
|
|
300
|
+
const vertical = sideways(this.position);
|
|
301
|
+
const classes = `dock ${this.variant} ${this.position} ${vertical ? "vertical" : "horizontal"} ${this.labelsHidden ? "labels-hidden" : ""}`;
|
|
302
|
+
const slot = html `<slot></slot>`;
|
|
303
|
+
const items = vertical
|
|
304
|
+
? html `<div class="column" part="row">${slot}</div>`
|
|
305
|
+
: html `<tt-scroller class="row" part="row" gap="none" controls>${slot}</tt-scroller>`;
|
|
306
|
+
return html `
|
|
307
|
+
<nav
|
|
308
|
+
class=${classes}
|
|
309
|
+
part="dock"
|
|
310
|
+
aria-label=${this.label || nothing}
|
|
311
|
+
@tt-dock-select=${this.onSelect}
|
|
312
|
+
>
|
|
313
|
+
<div class="surface" part="surface">${items}</div>
|
|
314
|
+
</nav>
|
|
315
|
+
`;
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
__decorate([
|
|
319
|
+
property({ type: String, reflect: true })
|
|
320
|
+
], TTDock.prototype, "variant", void 0);
|
|
321
|
+
__decorate([
|
|
322
|
+
property({ type: String, reflect: true })
|
|
323
|
+
], TTDock.prototype, "position", void 0);
|
|
324
|
+
__decorate([
|
|
325
|
+
property({ type: Boolean, reflect: true, attribute: "labels-hidden" })
|
|
326
|
+
], TTDock.prototype, "labelsHidden", void 0);
|
|
327
|
+
__decorate([
|
|
328
|
+
property({ type: String })
|
|
329
|
+
], TTDock.prototype, "label", void 0);
|
|
330
|
+
__decorate([
|
|
331
|
+
queryAssignedElements({ selector: "tt-dock-item" })
|
|
332
|
+
], TTDock.prototype, "items", void 0);
|
|
333
|
+
TTDock = __decorate([
|
|
334
|
+
customElement("tt-dock")
|
|
335
|
+
], TTDock);
|
|
336
|
+
export { TTDock };
|
|
337
|
+
//# sourceMappingURL=tt-dock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tt-dock.js","sourceRoot":"","sources":["../src/tt-dock.ts"],"names":[],"mappings":"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"}
|