@threadlabs/looma 0.23.14 → 0.23.16
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/components/ui-icon-button/ui-icon-button.html +27 -0
- package/components/ui-input/ui-input.html +6 -1
- package/components/ui-tree-item/ui-tree-item.html +50 -1
- package/components/ui-tree-item/ui-tree-item.js +2 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/styles/ui-icon-button.css +28 -0
- package/styles/ui-input.css +6 -1
- package/styles/ui-tree-item.css +54 -2
- package/vanilla/UiIconButton.d.ts +1 -0
- package/vanilla/UiIconButton.js +4 -1
- package/vue/UiIconButton.d.ts +9 -0
- package/vue/UiIconButton.vue +46 -0
- package/vue/UiInput.vue +6 -1
- package/vue/UiTreeItem.vue +59 -1
- package/vue/chunks/UiIconButton.js +24 -1
- package/vue/chunks/UiInput.js +1 -1
- package/vue/chunks/UiTreeItem.js +1 -1
- package/vue/components.css +216 -140
- package/vue/editor/LoomaEditor.d.ts +3 -2
- package/vue/editor/index.js +2 -2
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
<prop name="size" type="keyword" values="sm, md, lg" default="md"
|
|
12
12
|
>Button and icon size together: sm is 1.75rem with a small icon, md is 2rem, and lg is 2.5rem with a large icon. On touch, every size gets an invisible hit
|
|
13
13
|
area of at least 44px.</prop>
|
|
14
|
+
<prop name="matchButton" type="boolean" default="false"
|
|
15
|
+
>Matches a boxed Button of the same size when the two share a flex row. Uses the control-size theme tokens and stretches to the row's height, including
|
|
16
|
+
touch-sized controls. Leave it off for compact toolbar and inline icon buttons.</prop>
|
|
14
17
|
<prop name="variant" type="keyword" values="ghost, outline, solid" default="ghost"
|
|
15
18
|
>Emphasis. ghost shows only the icon until it is hovered, for toolbars and dense rows; outline adds a border on the default surface; solid fills with the
|
|
16
19
|
accent colour, for the one primary action in a group.</prop>
|
|
@@ -23,6 +26,7 @@
|
|
|
23
26
|
from:disabled="disabled"
|
|
24
27
|
type="button"
|
|
25
28
|
from:aria-label="label"
|
|
29
|
+
from:data-match-button="matchButton"
|
|
26
30
|
from:aria-disabled="{ true: 'true', false: null }[format('%s', loading or pending)]"
|
|
27
31
|
from:aria-busy="loading or pending"
|
|
28
32
|
>
|
|
@@ -245,6 +249,29 @@
|
|
|
245
249
|
min-block-size: var(--ui-icon-button-size, var(--_size));
|
|
246
250
|
}
|
|
247
251
|
|
|
252
|
+
/* A text button's companion uses control geometry; compact icon buttons keep their own density. */
|
|
253
|
+
:host-state([matchButton]) {
|
|
254
|
+
--_size: var(--ui-control-size-md);
|
|
255
|
+
block-size: auto;
|
|
256
|
+
align-self: stretch;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
:host-state([matchButton][size="sm"]) {
|
|
260
|
+
--_size: var(--ui-control-size-sm);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
:host-state([matchButton][size="lg"]) {
|
|
264
|
+
--_size: var(--ui-control-size-lg);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
@media (pointer: coarse) {
|
|
268
|
+
:host-state([matchButton]) {
|
|
269
|
+
inline-size: max(var(--ui-icon-button-size, var(--_size)), var(--ui-control-min-block-size));
|
|
270
|
+
min-inline-size: max(var(--ui-icon-button-size, var(--_size)), var(--ui-control-min-block-size));
|
|
271
|
+
min-block-size: max(var(--ui-icon-button-size, var(--_size)), var(--ui-control-min-block-size));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
248
275
|
:host-state([round]) {
|
|
249
276
|
border-radius: var(--ui-radius-round);
|
|
250
277
|
}
|
|
@@ -133,9 +133,14 @@
|
|
|
133
133
|
/* Under touch a small field is still a touch-sized target, as a small button is, and keeps
|
|
134
134
|
body-size text: below 16px, iOS zooms the page into the focused field. */
|
|
135
135
|
@media (pointer: coarse) {
|
|
136
|
+
:host,
|
|
137
|
+
:host-state([size="sm"]),
|
|
138
|
+
:host-state([size="lg"]) {
|
|
139
|
+
font-size: var(--ui-font-size-md);
|
|
140
|
+
}
|
|
141
|
+
|
|
136
142
|
:host-state([size="sm"]) {
|
|
137
143
|
min-block-size: var(--ui-input-min-block-size, var(--_ui-default-input-min-block-size, var(--ui-control-min-block-size)));
|
|
138
|
-
font-size: inherit;
|
|
139
144
|
}
|
|
140
145
|
}
|
|
141
146
|
|
|
@@ -470,7 +470,7 @@
|
|
|
470
470
|
}
|
|
471
471
|
|
|
472
472
|
/* Without hover there is no reveal, so the controls keep their own column. */
|
|
473
|
-
@media (hover: none) {
|
|
473
|
+
@media (hover: none), (pointer: coarse) {
|
|
474
474
|
.row {
|
|
475
475
|
grid-template-columns: var(--_tree-disclosure-size) auto minmax(0, 1fr) auto;
|
|
476
476
|
}
|
|
@@ -484,6 +484,37 @@
|
|
|
484
484
|
opacity: 1;
|
|
485
485
|
pointer-events: auto;
|
|
486
486
|
}
|
|
487
|
+
|
|
488
|
+
.row:is(:hover, :focus-within) > .label,
|
|
489
|
+
.row:is(:hover, :focus-within) > .label:dir(rtl),
|
|
490
|
+
:host[data-move-source] > .row > .label,
|
|
491
|
+
:host[data-move-source] > .row > .label:dir(rtl) {
|
|
492
|
+
mask-image: none;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
.row[data-ui-marquee] > .label {
|
|
496
|
+
mask-image: linear-gradient(
|
|
497
|
+
to right,
|
|
498
|
+
transparent var(--_marquee-icon-width, 0px),
|
|
499
|
+
#000 calc(var(--_marquee-lead, 0px) + var(--_ui-tree-item-label-padding-inline, var(--ui-space-2)))
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.row[data-ui-marquee] > .label:dir(rtl) {
|
|
504
|
+
mask-image: linear-gradient(
|
|
505
|
+
to left,
|
|
506
|
+
transparent var(--_marquee-icon-width, 0px),
|
|
507
|
+
#000 calc(var(--_marquee-lead, 0px) + var(--_ui-tree-item-label-padding-inline, var(--ui-space-2)))
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
:host[data-selection-mode="multiple"] > .row {
|
|
512
|
+
grid-template-columns: var(--_tree-disclosure-size) 1.25rem auto minmax(0, 1fr) auto;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
:host[data-selection-mode="multiple"] > .row > .actions {
|
|
516
|
+
grid-column: 5;
|
|
517
|
+
}
|
|
487
518
|
}
|
|
488
519
|
|
|
489
520
|
/* The handle sits beside what it drags. A leaf row has no disclosure, so the handle takes that
|
|
@@ -625,6 +656,24 @@
|
|
|
625
656
|
grid-column: 5;
|
|
626
657
|
}
|
|
627
658
|
|
|
659
|
+
@media (hover: none), (pointer: coarse) {
|
|
660
|
+
html[data-ui-input-modality="touch"] :host .row {
|
|
661
|
+
grid-template-columns: 44px var(--_tree-disclosure-size) auto minmax(0, 1fr) auto;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
html[data-ui-input-modality="touch"] :host .actions {
|
|
665
|
+
grid-column: 5;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
html[data-ui-input-modality="touch"] :host[data-selection-mode="multiple"] > .row {
|
|
669
|
+
grid-template-columns: 44px var(--_tree-disclosure-size) 44px auto minmax(0, 1fr) auto;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
html[data-ui-input-modality="touch"] :host[data-selection-mode="multiple"] > .row > .actions {
|
|
673
|
+
grid-column: 6;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
628
677
|
@media (prefers-reduced-motion: reduce) {
|
|
629
678
|
.row,
|
|
630
679
|
.disclosure-icon,
|
|
@@ -143,7 +143,8 @@ export default function controller(host) {
|
|
|
143
143
|
labelText.style.flex = labelText.style.inlineSize = "";
|
|
144
144
|
const cell = label.getBoundingClientRect();
|
|
145
145
|
const icon = leading?.getBoundingClientRect();
|
|
146
|
-
const
|
|
146
|
+
const overlayActions = actions && getComputedStyle(actions).position === "absolute";
|
|
147
|
+
const stop = overlayActions ? actions.offsetWidth + parseFloat(getComputedStyle(label).columnGap) : 0;
|
|
147
148
|
const distance = Math.ceil(rightToLeft ? cell.left + stop - end : end - (cell.right - stop));
|
|
148
149
|
if (distance <= 0) return;
|
|
149
150
|
const lead = icon?.width ? (rightToLeft ? icon.right - cell.right : cell.left - icon.left) : 0;
|