@ixfx/components 0.8.2 → 0.8.3
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/bundle/index.d.ts +274 -93
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +2135 -637
- package/bundle/index.js.map +1 -1
- package/dist/ac-text.js +2 -2
- package/dist/ac-token.js +2 -2
- package/dist/checkbox.js +1 -1
- package/dist/{colour-picker-Ddsk-7E_.js → colour-picker-CSxwUmtE.js} +2 -2
- package/dist/{colour-picker-Ddsk-7E_.js.map → colour-picker-CSxwUmtE.js.map} +1 -1
- package/dist/colour-picker.js +1 -1
- package/dist/crumbs.js +2 -2
- package/dist/data-display.js +1 -1
- package/dist/data-grid-D-z7bx5-.d.ts.map +1 -1
- package/dist/data-grid.js +7 -4
- package/dist/data-grid.js.map +1 -1
- package/dist/detail-list-_ZJHYEBr.d.ts.map +1 -1
- package/dist/detail-list.js +67 -4
- package/dist/detail-list.js.map +1 -1
- package/dist/editable-label.js +1 -1
- package/dist/{fallbacks-DNI9xt0F.js → fallbacks-BcKGq-2F.js} +17 -1
- package/dist/{fallbacks-DNI9xt0F.js.map → fallbacks-BcKGq-2F.js.map} +1 -1
- package/dist/{grid-list-bmBWq6P-.js → grid-list-BXfY3XXX.js} +486 -13
- package/dist/grid-list-BXfY3XXX.js.map +1 -0
- package/dist/{grid-list-C1T6WlEp.d.ts → grid-list-x550wJ0X.d.ts} +97 -2
- package/dist/grid-list-x550wJ0X.d.ts.map +1 -0
- package/dist/grid-list.d.ts +2 -2
- package/dist/grid-list.js +1 -1
- package/dist/handle-BPOxBOKf.js +219 -0
- package/dist/handle-BPOxBOKf.js.map +1 -0
- package/dist/{icon-DcEEGQa_.js → icon-Dy33gu4Z.js} +2 -2
- package/dist/{icon-DcEEGQa_.js.map → icon-Dy33gu4Z.js.map} +1 -1
- package/dist/icons.js +1 -1
- package/dist/{index-BeuCXtiO.d.ts → index-DV3iaUBW.d.ts} +2 -2
- package/dist/{index-BeuCXtiO.d.ts.map → index-DV3iaUBW.d.ts.map} +1 -1
- package/dist/index.d.ts +130 -48
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +551 -203
- package/dist/index.js.map +1 -1
- package/dist/labelled-radial-input.js +2 -2
- package/dist/{labelled-slider-input-BInB5GKL.js → labelled-slider-input-BCH9968c.js} +3 -3
- package/dist/{labelled-slider-input-BInB5GKL.js.map → labelled-slider-input-BCH9968c.js.map} +1 -1
- package/dist/labelled-slider-input.js +1 -1
- package/dist/list-selection-controller-SA4piSBi.js +589 -0
- package/dist/list-selection-controller-SA4piSBi.js.map +1 -0
- package/dist/{menu-BDrTh6oo.js → menu-HMoxCPY2.js} +4 -4
- package/dist/{menu-BDrTh6oo.js.map → menu-HMoxCPY2.js.map} +1 -1
- package/dist/{menu-item-B6pKg2Qq.js → menu-item-BQDYxk5A.js} +3 -3
- package/dist/{menu-item-B6pKg2Qq.js.map → menu-item-BQDYxk5A.js.map} +1 -1
- package/dist/menu.js +2 -2
- package/dist/miller.js +1 -1
- package/dist/narrowed-text.js +1 -1
- package/dist/notifier.js +1 -1
- package/dist/panel.d.ts +1 -1
- package/dist/panel.js +1 -1
- package/dist/polar-pad.js +1 -1
- package/dist/{radial-input-BfA3GO0H.js → radial-input-DyxfbNzD.js} +2 -2
- package/dist/{radial-input-BfA3GO0H.js.map → radial-input-DyxfbNzD.js.map} +1 -1
- package/dist/radial-input.js +1 -1
- package/dist/range-input.js +1 -1
- package/dist/range.js +1 -1
- package/dist/select-horiz.js +1 -1
- package/dist/{slider-input-Bl1hFE89.js → slider-input-WR8_RwHg.js} +2 -2
- package/dist/{slider-input-Bl1hFE89.js.map → slider-input-WR8_RwHg.js.map} +1 -1
- package/dist/slider-input.js +1 -1
- package/dist/snackbar.js +1 -1
- package/dist/{split-layout-BFSbUZQv.js → split-layout-CA5jbNbG.js} +22 -33
- package/dist/split-layout-CA5jbNbG.js.map +1 -0
- package/dist/split-layout-JK3xWVX2.d.ts.map +1 -1
- package/dist/split-layout.js +1 -1
- package/dist/swipe.js +1 -1
- package/dist/tabs.js +1 -1
- package/dist/{timeline-B2fgDL4U.js → timeline-THyvH8xy.js} +14 -8
- package/dist/timeline-THyvH8xy.js.map +1 -0
- package/dist/timeline.d.ts +1 -1
- package/dist/timeline.js +1 -1
- package/dist/{titlebar-YQ-jVQoS.d.ts → titlebar-Tqu-VvMU.d.ts} +5 -1
- package/dist/titlebar-Tqu-VvMU.d.ts.map +1 -0
- package/dist/titlebar.d.ts +1 -1
- package/dist/titlebar.js +5 -3
- package/dist/titlebar.js.map +1 -1
- package/dist/{tree-4Jv28Nig.js → tree-DTQon838.js} +2 -2
- package/dist/{tree-4Jv28Nig.js.map → tree-DTQon838.js.map} +1 -1
- package/dist/tree.js +1 -1
- package/dist/vertical-list-CFuFDygi.d.ts.map +1 -1
- package/dist/vertical-list.js +67 -3
- package/dist/vertical-list.js.map +1 -1
- package/dist/xy-pad.js +1 -1
- package/docs-user/data-grid.md +1 -1
- package/docs-user/detail-list.md +4 -0
- package/docs-user/dock.md +6 -3
- package/docs-user/grid-list.md +4 -0
- package/docs-user/index.json +2 -2
- package/docs-user/split-layout.md +2 -4
- package/docs-user/twosplit-layout.md +14 -16
- package/docs-user/vertical-list.md +4 -0
- package/package.json +1 -1
- package/dist/grid-list-C1T6WlEp.d.ts.map +0 -1
- package/dist/grid-list-bmBWq6P-.js.map +0 -1
- package/dist/list-selection-controller-DTFI40li.js +0 -264
- package/dist/list-selection-controller-DTFI40li.js.map +0 -1
- package/dist/split-layout-BFSbUZQv.js.map +0 -1
- package/dist/timeline-B2fgDL4U.js.map +0 -1
- package/dist/titlebar-YQ-jVQoS.d.ts.map +0 -1
package/bundle/index.js
CHANGED
|
@@ -3,8 +3,8 @@ import { customElement, eventOptions, property, query, queryAssignedElements, st
|
|
|
3
3
|
import { styleMap } from "lit/directives/style-map.js";
|
|
4
4
|
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
5
5
|
import { Fzf } from "fzf";
|
|
6
|
-
import { Colour } from "@ixfx/visual";
|
|
7
6
|
import { createCommandRegistry } from "@clinth/ui-commands";
|
|
7
|
+
import { Colour } from "@ixfx/visual";
|
|
8
8
|
import { Trees } from "@ixfx/collections";
|
|
9
9
|
import { clamp, clamper, rangeStream, round, scaler } from "@ixfx/numbers";
|
|
10
10
|
import { repeat } from "lit/directives/repeat.js";
|
|
@@ -1290,6 +1290,22 @@ const _themeFallbacksCss = i$3`
|
|
|
1290
1290
|
inherits: true;
|
|
1291
1291
|
initial-value: 0 4px 24px rgba(0, 0, 0, 0.5);
|
|
1292
1292
|
}
|
|
1293
|
+
@property --deboss-3 {
|
|
1294
|
+
syntax: '*';
|
|
1295
|
+
inherits: true;
|
|
1296
|
+
initial-value:
|
|
1297
|
+
inset 1px 1px 1px 1px color-mix(in oklch, oklch(8% 0.02 240) 60%, transparent),
|
|
1298
|
+
inset -1px -1px 1px 1px color-mix(in oklch, oklch(15% 0.02 240) 50%, transparent),
|
|
1299
|
+
-2px -2px 1px 0px color-mix(in oklch, oklch(12% 0.02 240) 30%, transparent);
|
|
1300
|
+
}
|
|
1301
|
+
@property --emboss-3 {
|
|
1302
|
+
syntax: '*';
|
|
1303
|
+
inherits: true;
|
|
1304
|
+
initial-value:
|
|
1305
|
+
inset 1px 1px 1px 1px color-mix(in oklch, oklch(22% 0.02 240) 30%, transparent),
|
|
1306
|
+
inset -1px -1px 1px 1px color-mix(in oklch, oklch(12% 0.02 240) 20%, transparent),
|
|
1307
|
+
2px 2px 1px 0px color-mix(in oklch, oklch(12% 0.02 240) 30%, transparent);
|
|
1308
|
+
}
|
|
1293
1309
|
@property --item-bg {
|
|
1294
1310
|
syntax: '<color>';
|
|
1295
1311
|
inherits: true;
|
|
@@ -3896,6 +3912,1123 @@ __decorate([state()], AcTokenElement.prototype, "_selectedTokenIndex", void 0);
|
|
|
3896
3912
|
__decorate([state()], AcTokenElement.prototype, "_isOpen", void 0);
|
|
3897
3913
|
AcTokenElement = __decorate([safeCustomElement(`ixfx-ac-token`)], AcTokenElement);
|
|
3898
3914
|
//#endregion
|
|
3915
|
+
//#region src/styles/handle.ts
|
|
3916
|
+
/**
|
|
3917
|
+
* Shared drag / resize **handle** styling.
|
|
3918
|
+
*
|
|
3919
|
+
* A handle is the grab affordance for moving or resizing an object. Apply the
|
|
3920
|
+
* `.ixfx-handle` class to a small decorative element inside your drag / resize
|
|
3921
|
+
* hit-zone and choose a look with two independent attributes:
|
|
3922
|
+
*
|
|
3923
|
+
* - `data-handle` — texture: `flat` (default) · `dotted` · `dimpled` · `grated`
|
|
3924
|
+
* - `data-shape` — topology: `horizontal` (default) · `vertical` · `spot`
|
|
3925
|
+
*
|
|
3926
|
+
* - **flat** — a solid rounded capsule (bar) or dot (`spot`), filled with
|
|
3927
|
+
* `--ixfx-handle-color`.
|
|
3928
|
+
* - **dotted** — marks in the [Lucide *grip*](https://lucide.dev/icons/grip)
|
|
3929
|
+
* arrangement: three in a row (`horizontal`), three in a column (`vertical`) or a
|
|
3930
|
+
* 3×3 block (`spot`). Tinted by `--ixfx-handle-color`. Each mark's corner
|
|
3931
|
+
* rounding is `--ixfx-handle-radius` (→ the theme `--radius-l`), so a flat,
|
|
3932
|
+
* squared-off theme renders them as **squares** instead of circles.
|
|
3933
|
+
* - **dimpled** — that same layout, but each bar mark is pressed in: a lighter
|
|
3934
|
+
* copy peeking out above-left and a darker copy below-right of the base mark.
|
|
3935
|
+
* - **grated** — fine 45° knurling: each ridge is a lit edge, the base colour,
|
|
3936
|
+
* then a shaded edge. `spot` is the same hatch on a square crop.
|
|
3937
|
+
*
|
|
3938
|
+
* `dotted` / `dimpled` / `grated` are texture only — no plate, box or border; the
|
|
3939
|
+
* gaps are transparent so the surface behind shows through. The base colour is
|
|
3940
|
+
* `--ixfx-handle-color` (a theme token); the deboss edges default to that colour
|
|
3941
|
+
* lightened / darkened.
|
|
3942
|
+
*
|
|
3943
|
+
* The handle is `pointer-events: none` — bind pointer handlers to the surrounding
|
|
3944
|
+
* hit-zone. It reaches its "active" look (`--ixfx-handle-opacity-active`, and for
|
|
3945
|
+
* `flat` / `dotted` the `--ixfx-handle-color-active` tint) when its immediate
|
|
3946
|
+
* parent (the hit-zone) is `:hover` / `:focus-visible` / `[data-active]`, or when
|
|
3947
|
+
* the handle itself is. Set `[data-active]` on the hit-zone yourself while a drag
|
|
3948
|
+
* is live so the handle stays lit after the pointer leaves it.
|
|
3949
|
+
*
|
|
3950
|
+
* ```ts
|
|
3951
|
+
* import { handleStyles } from '../styles/handle.js';
|
|
3952
|
+
*
|
|
3953
|
+
* static styles = [themeFallbacks, handleStyles, css`...`];
|
|
3954
|
+
* ```
|
|
3955
|
+
* ```html
|
|
3956
|
+
* <div class="hit-zone" @pointerdown=${this.#onDown}>
|
|
3957
|
+
* <span class="ixfx-handle" data-handle="dotted" data-shape="spot" part="handle"></span>
|
|
3958
|
+
* </div>
|
|
3959
|
+
* ```
|
|
3960
|
+
*
|
|
3961
|
+
* ## CSS variables (defaults shown; override on the element or any ancestor)
|
|
3962
|
+
* - `--ixfx-handle-color` `var(--surface-muted-text)` — `flat` / `dotted` fill
|
|
3963
|
+
* - `--ixfx-handle-color-active` `var(--accent)` — `flat` / `dotted` hover / focus
|
|
3964
|
+
* - `--ixfx-handle-thickness` `6px` — cross-axis size of a bar
|
|
3965
|
+
* - `--ixfx-handle-length` `44px` — long-axis size of a bar (`100%` to fill)
|
|
3966
|
+
* - `--ixfx-handle-spot-size` `14px` — width = height of a `spot`
|
|
3967
|
+
* - `--ixfx-handle-radius` `var(--radius-l)` — `flat` capsule / dotted & dimpled mark rounding
|
|
3968
|
+
* - `--ixfx-handle-opacity` `0.55` — rest opacity
|
|
3969
|
+
* - `--ixfx-handle-opacity-active` `1`
|
|
3970
|
+
* - `--ixfx-handle-dot-size` `3px` — mark size (dotted / dimpled)
|
|
3971
|
+
* - `--ixfx-handle-dot-gap` `length/4` (bar) · `spot/3` — mark centre-to-centre step
|
|
3972
|
+
* - `--ixfx-handle-tile` `5px` — knurl period (grated)
|
|
3973
|
+
* - `--ixfx-handle-highlight` `color-mix(currentColor 35%, #fff)` — lit deboss edge
|
|
3974
|
+
* - `--ixfx-handle-shadow` `color-mix(currentColor 60%, #000)` — shaded deboss edge
|
|
3975
|
+
*/
|
|
3976
|
+
const handleStyles = i$3`
|
|
3977
|
+
.ixfx-handle {
|
|
3978
|
+
/* Bridge: public --ixfx-handle-* (element or ancestor) → internal alias → fallback. */
|
|
3979
|
+
--_handle-color: var(--ixfx-handle-color, var(--surface-3-text));
|
|
3980
|
+
--_handle-color-active: var(--ixfx-handle-color-active, var(--surface-3-text));
|
|
3981
|
+
--_handle-thickness: var(--ixfx-handle-thickness, 6px);
|
|
3982
|
+
--_handle-length: var(--ixfx-handle-length, 44px);
|
|
3983
|
+
--_handle-spot: var(--ixfx-handle-spot-size, 14px);
|
|
3984
|
+
--_handle-radius: var(--ixfx-handle-radius, var(--radius-l));
|
|
3985
|
+
--_handle-opacity: var(--ixfx-handle-opacity, 0.55);
|
|
3986
|
+
--_handle-opacity-active: var(--ixfx-handle-opacity-active, 1);
|
|
3987
|
+
--_handle-dot: var(--ixfx-handle-dot-size, 3px);
|
|
3988
|
+
--_handle-tile: var(--ixfx-handle-tile, 5px);
|
|
3989
|
+
/* Centre-to-centre step of the dotted / dimpled marks (a length). Defaults to
|
|
3990
|
+
a share of the long axis; a bar shows ~3 marks. */
|
|
3991
|
+
--_handle-gap: var(--ixfx-handle-dot-gap, calc(var(--_handle-length) / 4));
|
|
3992
|
+
/* How far a dimpled mark's highlight / shadow copy is offset. */
|
|
3993
|
+
--_dimple-off: calc(var(--_handle-dot) * 0.15);
|
|
3994
|
+
/* The mark colour lightened / darkened for the two deboss edges. */
|
|
3995
|
+
--_handle-hi: var(--ixfx-handle-highlight, color-mix(in oklch, var(--surface-4) 50%, var(--_handle-color)));
|
|
3996
|
+
--_handle-lo: var(--ixfx-handle-shadow, color-mix(in oklch, var(--surface-2) 40%, var(--_handle-color)));
|
|
3997
|
+
|
|
3998
|
+
box-sizing: border-box;
|
|
3999
|
+
display: inline-block;
|
|
4000
|
+
flex: none;
|
|
4001
|
+
width: var(--_handle-length);
|
|
4002
|
+
height: var(--_handle-thickness);
|
|
4003
|
+
color: var(--_handle-color);
|
|
4004
|
+
opacity: var(--_handle-opacity);
|
|
4005
|
+
pointer-events: none;
|
|
4006
|
+
transition:
|
|
4007
|
+
color var(--transition, 0.15s ease-out),
|
|
4008
|
+
opacity var(--transition, 0.15s ease-out);
|
|
4009
|
+
}
|
|
4010
|
+
|
|
4011
|
+
.ixfx-handle[data-shape='vertical'] {
|
|
4012
|
+
width: var(--_handle-thickness);
|
|
4013
|
+
height: var(--_handle-length);
|
|
4014
|
+
}
|
|
4015
|
+
|
|
4016
|
+
.ixfx-handle[data-shape='spot'] {
|
|
4017
|
+
width: var(--_handle-spot);
|
|
4018
|
+
height: var(--_handle-spot);
|
|
4019
|
+
--_handle-gap: var(--ixfx-handle-dot-gap, calc(var(--_handle-spot) / 3));
|
|
4020
|
+
}
|
|
4021
|
+
|
|
4022
|
+
.ixfx-handle:hover,
|
|
4023
|
+
.ixfx-handle:focus-visible,
|
|
4024
|
+
.ixfx-handle[data-active],
|
|
4025
|
+
:hover > .ixfx-handle,
|
|
4026
|
+
:focus-visible > .ixfx-handle,
|
|
4027
|
+
[data-active] > .ixfx-handle {
|
|
4028
|
+
color: var(--_handle-color-active);
|
|
4029
|
+
opacity: var(--_handle-opacity-active);
|
|
4030
|
+
}
|
|
4031
|
+
|
|
4032
|
+
/* ── flat: solid capsule / dot ────────────────────────────────────────── */
|
|
4033
|
+
.ixfx-handle[data-handle='flat'] {
|
|
4034
|
+
background: currentColor;
|
|
4035
|
+
border-radius: var(--_handle-radius);
|
|
4036
|
+
}
|
|
4037
|
+
.ixfx-handle[data-handle='flat'][data-shape='spot'] {
|
|
4038
|
+
border-radius: 50%;
|
|
4039
|
+
}
|
|
4040
|
+
|
|
4041
|
+
/* ── dotted / dimpled: 3 marks in a row / column (or 3×3 for spot), drawn as
|
|
4042
|
+
one ::before mark whose border-radius follows the theme — round normally,
|
|
4043
|
+
square in a flat / squared-off theme (--radius-l: 0). box-shadow paints
|
|
4044
|
+
the rest of the marks. ─────────────────────────────────────────────── */
|
|
4045
|
+
.ixfx-handle[data-handle='dotted'],
|
|
4046
|
+
.ixfx-handle[data-handle='dimpled'] {
|
|
4047
|
+
position: relative;
|
|
4048
|
+
}
|
|
4049
|
+
.ixfx-handle[data-handle='dotted']::before,
|
|
4050
|
+
.ixfx-handle[data-handle='dimpled']::before {
|
|
4051
|
+
content: '';
|
|
4052
|
+
position: absolute;
|
|
4053
|
+
top: 50%;
|
|
4054
|
+
left: 50%;
|
|
4055
|
+
width: var(--_handle-dot);
|
|
4056
|
+
height: var(--_handle-dot);
|
|
4057
|
+
transform: translate(-50%, -50%);
|
|
4058
|
+
border-radius: var(--_handle-radius);
|
|
4059
|
+
background: currentColor;
|
|
4060
|
+
}
|
|
4061
|
+
|
|
4062
|
+
/* dotted — the two other marks are plain copies along the axis. */
|
|
4063
|
+
.ixfx-handle[data-handle='dotted']::before {
|
|
4064
|
+
box-shadow:
|
|
4065
|
+
calc(-1 * var(--_handle-gap)) 0 0 0 currentColor,
|
|
4066
|
+
var(--_handle-gap) 0 0 0 currentColor;
|
|
4067
|
+
}
|
|
4068
|
+
.ixfx-handle[data-handle='dotted'][data-shape='vertical']::before {
|
|
4069
|
+
box-shadow:
|
|
4070
|
+
0 calc(-1 * var(--_handle-gap)) 0 0 currentColor,
|
|
4071
|
+
0 var(--_handle-gap) 0 0 currentColor;
|
|
4072
|
+
}
|
|
4073
|
+
.ixfx-handle[data-handle='dotted'][data-shape='spot']::before,
|
|
4074
|
+
.ixfx-handle[data-handle='dimpled'][data-shape='spot']::before {
|
|
4075
|
+
box-shadow:
|
|
4076
|
+
calc(-1 * var(--_handle-gap)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
|
|
4077
|
+
0 calc(-1 * var(--_handle-gap)) 0 0 currentColor,
|
|
4078
|
+
var(--_handle-gap) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
|
|
4079
|
+
calc(-1 * var(--_handle-gap)) 0 0 0 currentColor,
|
|
4080
|
+
var(--_handle-gap) 0 0 0 currentColor,
|
|
4081
|
+
calc(-1 * var(--_handle-gap)) var(--_handle-gap) 0 0 currentColor,
|
|
4082
|
+
0 var(--_handle-gap) 0 0 currentColor,
|
|
4083
|
+
var(--_handle-gap) var(--_handle-gap) 0 0 currentColor;
|
|
4084
|
+
}
|
|
4085
|
+
|
|
4086
|
+
/* dimpled — each bar mark also gets a lighter copy up-left and a darker copy
|
|
4087
|
+
down-right (spot stays plain — the 3D is imperceptible at that size). */
|
|
4088
|
+
.ixfx-handle[data-handle='dimpled']:not([data-shape='spot'])::before {
|
|
4089
|
+
box-shadow:
|
|
4090
|
+
calc(-1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
|
|
4091
|
+
var(--_dimple-off) var(--_dimple-off) 0 0 var(--_handle-lo),
|
|
4092
|
+
calc(-1 * var(--_handle-gap)) 0 0 0 currentColor,
|
|
4093
|
+
calc(-1 * var(--_handle-gap) - var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
|
|
4094
|
+
calc(-1 * var(--_handle-gap) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
|
|
4095
|
+
var(--_handle-gap) 0 0 0 currentColor,
|
|
4096
|
+
calc(var(--_handle-gap) - var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
|
|
4097
|
+
calc(var(--_handle-gap) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo);
|
|
4098
|
+
}
|
|
4099
|
+
.ixfx-handle[data-handle='dimpled'][data-shape='vertical']::before {
|
|
4100
|
+
box-shadow:
|
|
4101
|
+
calc(-1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
|
|
4102
|
+
var(--_dimple-off) var(--_dimple-off) 0 0 var(--_handle-lo),
|
|
4103
|
+
0 calc(-1 * var(--_handle-gap)) 0 0 currentColor,
|
|
4104
|
+
calc(-1 * var(--_dimple-off)) calc(-1 * var(--_handle-gap) - var(--_dimple-off)) 0 0 var(--_handle-hi),
|
|
4105
|
+
var(--_dimple-off) calc(-1 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
|
|
4106
|
+
0 var(--_handle-gap) 0 0 currentColor,
|
|
4107
|
+
calc(-1 * var(--_dimple-off)) calc(var(--_handle-gap) - var(--_dimple-off)) 0 0 var(--_handle-hi),
|
|
4108
|
+
var(--_dimple-off) calc(var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo);
|
|
4109
|
+
}
|
|
4110
|
+
|
|
4111
|
+
/* ── grated: fine 45° knurling — each ridge is a lit edge, the base colour,
|
|
4112
|
+
then a shaded edge. Same hatch at every shape (spot is a square crop). ── */
|
|
4113
|
+
.ixfx-handle[data-handle='grated'] {
|
|
4114
|
+
background-image: repeating-linear-gradient(
|
|
4115
|
+
45deg,
|
|
4116
|
+
var(--_handle-hi) 0 0.9px,
|
|
4117
|
+
currentColor 0.9px 1.6px,
|
|
4118
|
+
var(--_handle-lo) 1.6px 2.5px,
|
|
4119
|
+
transparent 2.5px var(--_handle-tile)
|
|
4120
|
+
);
|
|
4121
|
+
}
|
|
4122
|
+
|
|
4123
|
+
@media (prefers-reduced-motion: reduce) {
|
|
4124
|
+
.ixfx-handle {
|
|
4125
|
+
transition: none;
|
|
4126
|
+
}
|
|
4127
|
+
}
|
|
4128
|
+
`;
|
|
4129
|
+
//#endregion
|
|
4130
|
+
//#region src/titlebar/titlebar.ts
|
|
4131
|
+
let TitlebarElement = class TitlebarElement extends i {
|
|
4132
|
+
constructor(..._args) {
|
|
4133
|
+
super(..._args);
|
|
4134
|
+
this.title = ``;
|
|
4135
|
+
this.iconName = ``;
|
|
4136
|
+
this.orientation = `horizontal`;
|
|
4137
|
+
this.variant = `titlebar`;
|
|
4138
|
+
this.closable = false;
|
|
4139
|
+
this.collapsible = false;
|
|
4140
|
+
this.collapsed = false;
|
|
4141
|
+
this.toggleInteraction = `implicit`;
|
|
4142
|
+
}
|
|
4143
|
+
_onToggleClick() {
|
|
4144
|
+
if (!this.collapsible) return;
|
|
4145
|
+
this.collapsed = !this.collapsed;
|
|
4146
|
+
this.dispatchEvent(new CustomEvent(`toggle`, {
|
|
4147
|
+
detail: { collapsed: this.collapsed },
|
|
4148
|
+
bubbles: true,
|
|
4149
|
+
composed: true
|
|
4150
|
+
}));
|
|
4151
|
+
}
|
|
4152
|
+
_onCloseClick() {
|
|
4153
|
+
this.dispatchEvent(new CustomEvent(`close`, {
|
|
4154
|
+
bubbles: true,
|
|
4155
|
+
composed: true
|
|
4156
|
+
}));
|
|
4157
|
+
}
|
|
4158
|
+
_getCaretIcon() {
|
|
4159
|
+
return `chevron-down`;
|
|
4160
|
+
}
|
|
4161
|
+
render() {
|
|
4162
|
+
const caretIcon = this._getCaretIcon();
|
|
4163
|
+
const isVertical = this.orientation === `vertical`;
|
|
4164
|
+
const showCaret = this.collapsible && this.toggleInteraction !== `disabled`;
|
|
4165
|
+
const implicitToggle = this.collapsible && this.toggleInteraction === `implicit`;
|
|
4166
|
+
const caretRotation = isVertical ? this.collapsed ? `` : `-90deg` : this.collapsed ? `-90deg` : ``;
|
|
4167
|
+
const treeVariant = this.variant === `tree`;
|
|
4168
|
+
return b`
|
|
4169
|
+
<div
|
|
4170
|
+
class="bar"
|
|
4171
|
+
role="toolbar"
|
|
4172
|
+
@click=${implicitToggle ? this._onToggleClick : A}
|
|
4173
|
+
>
|
|
4174
|
+
${treeVariant && showCaret ? b`
|
|
4175
|
+
<button
|
|
4176
|
+
class="caret-btn"
|
|
4177
|
+
type="button"
|
|
4178
|
+
aria-label=${this.collapsed ? `Expand panel` : `Collapse panel`}
|
|
4179
|
+
@click=${this._onToggleClick}
|
|
4180
|
+
>
|
|
4181
|
+
<ixfx-icon name=${caretIcon} prominence .rotate=${caretRotation.length > 0 ? caretRotation : A}></ixfx-icon>
|
|
4182
|
+
</button>
|
|
4183
|
+
` : A}
|
|
4184
|
+
<div class="title-text-wrapper">
|
|
4185
|
+
${this.iconName ? b`<ixfx-icon class="title-icon" name=${this.iconName}></ixfx-icon>` : A}
|
|
4186
|
+
<span class="title-text">${this.title}</span>
|
|
4187
|
+
</div>
|
|
4188
|
+
|
|
4189
|
+
<div class="toolbar" @click=${(e) => e.stopPropagation()}>
|
|
4190
|
+
<slot name="toolbar"></slot>
|
|
4191
|
+
${this.closable ? b`
|
|
4192
|
+
<button
|
|
4193
|
+
class="close-btn"
|
|
4194
|
+
type="button"
|
|
4195
|
+
aria-label="Close panel"
|
|
4196
|
+
@click=${this._onCloseClick}
|
|
4197
|
+
>
|
|
4198
|
+
<ixfx-icon name="close"></ixfx-icon>
|
|
4199
|
+
</button>
|
|
4200
|
+
` : A}
|
|
4201
|
+
${!treeVariant && showCaret ? b`
|
|
4202
|
+
<button
|
|
4203
|
+
class="caret-btn"
|
|
4204
|
+
type="button"
|
|
4205
|
+
aria-label=${this.collapsed ? `Expand panel` : `Collapse panel`}
|
|
4206
|
+
@click=${this._onToggleClick}
|
|
4207
|
+
>
|
|
4208
|
+
<ixfx-icon name=${caretIcon} prominence .rotate=${caretRotation.length > 0 ? caretRotation : A}></ixfx-icon>
|
|
4209
|
+
</button>
|
|
4210
|
+
` : A}
|
|
4211
|
+
</div>
|
|
4212
|
+
</div>
|
|
4213
|
+
`;
|
|
4214
|
+
}
|
|
4215
|
+
static {
|
|
4216
|
+
this.styles = [themeFallbacks, i$3`
|
|
4217
|
+
:host {
|
|
4218
|
+
--titlebar-background: var(--surface-4);
|
|
4219
|
+
|
|
4220
|
+
display: block;
|
|
4221
|
+
box-sizing: border-box;
|
|
4222
|
+
}
|
|
4223
|
+
|
|
4224
|
+
.bar {
|
|
4225
|
+
display: flex;
|
|
4226
|
+
flex-direction: row;
|
|
4227
|
+
align-items: center;
|
|
4228
|
+
padding: var(--space-s) var(--space-m);
|
|
4229
|
+
background: var(--titlebar-background);
|
|
4230
|
+
color: var(--surface-3-text);
|
|
4231
|
+
min-height: 2em;
|
|
4232
|
+
height: 100%;
|
|
4233
|
+
flex-shrink: 0;
|
|
4234
|
+
box-sizing: border-box;
|
|
4235
|
+
}
|
|
4236
|
+
|
|
4237
|
+
:host([orientation="vertical"]) .bar {
|
|
4238
|
+
flex-direction: row;
|
|
4239
|
+
min-width: 2em;
|
|
4240
|
+
writing-mode: vertical-rl;
|
|
4241
|
+
text-orientation: mixed;
|
|
4242
|
+
}
|
|
4243
|
+
|
|
4244
|
+
.caret-btn,
|
|
4245
|
+
.close-btn {
|
|
4246
|
+
display: inline-flex;
|
|
4247
|
+
align-items: center;
|
|
4248
|
+
justify-content: center;
|
|
4249
|
+
background: none;
|
|
4250
|
+
border: none;
|
|
4251
|
+
padding: var(--space-xs);
|
|
4252
|
+
margin: 0;
|
|
4253
|
+
cursor: pointer;
|
|
4254
|
+
color: inherit;
|
|
4255
|
+
border-radius: var(--radius-s);
|
|
4256
|
+
transition: background var(--transition);
|
|
4257
|
+
opacity: var(--prominence-idle-opacity);
|
|
4258
|
+
}
|
|
4259
|
+
|
|
4260
|
+
.caret-btn:hover,
|
|
4261
|
+
.close-btn:hover {
|
|
4262
|
+
background: var(--surface-5);
|
|
4263
|
+
opacity: var(--prominence-tickled-opacity);
|
|
4264
|
+
}
|
|
4265
|
+
|
|
4266
|
+
.caret-btn:focus-visible,
|
|
4267
|
+
.close-btn:focus-visible {
|
|
4268
|
+
outline: 2px solid var(--accent);
|
|
4269
|
+
outline-offset: 1px;
|
|
4270
|
+
}
|
|
4271
|
+
|
|
4272
|
+
ixfx-icon {
|
|
4273
|
+
width: 1.25em;
|
|
4274
|
+
height: 1.25em;
|
|
4275
|
+
transition: transform var(--transition);
|
|
4276
|
+
}
|
|
4277
|
+
|
|
4278
|
+
.title-icon {
|
|
4279
|
+
flex-shrink: 0;
|
|
4280
|
+
}
|
|
4281
|
+
|
|
4282
|
+
.title-text {
|
|
4283
|
+
flex: 1;
|
|
4284
|
+
padding-left: 1ch;
|
|
4285
|
+
font-family: var(--font-family);
|
|
4286
|
+
font-size: var(--text-m);
|
|
4287
|
+
font-weight: var(--font-weight-bold, 600);
|
|
4288
|
+
white-space: nowrap;
|
|
4289
|
+
overflow: hidden;
|
|
4290
|
+
align-self: center;
|
|
4291
|
+
text-overflow: ellipsis;
|
|
4292
|
+
user-select: none;
|
|
4293
|
+
-webkit-user-select: none;
|
|
4294
|
+
}
|
|
4295
|
+
|
|
4296
|
+
:host([collapsible][toggle-interaction="implicit"]) .bar {
|
|
4297
|
+
cursor: pointer;
|
|
4298
|
+
}
|
|
4299
|
+
|
|
4300
|
+
:host([orientation="vertical"]) .title-text {
|
|
4301
|
+
writing-mode: vertical-rl;
|
|
4302
|
+
padding-left: 0;
|
|
4303
|
+
padding-bottom: 1ch;
|
|
4304
|
+
text-orientation: mixed;
|
|
4305
|
+
transform: rotate(180deg);
|
|
4306
|
+
}
|
|
4307
|
+
|
|
4308
|
+
.toolbar {
|
|
4309
|
+
display: flex;
|
|
4310
|
+
align-items: center;
|
|
4311
|
+
gap: var(--space-xs);
|
|
4312
|
+
margin-left: auto;
|
|
4313
|
+
}
|
|
4314
|
+
|
|
4315
|
+
:host([orientation="vertical"]) .toolbar {
|
|
4316
|
+
flex-direction: column;
|
|
4317
|
+
margin-left: 0;
|
|
4318
|
+
margin-top: auto;
|
|
4319
|
+
writing-mode: horizontal-tb;
|
|
4320
|
+
}
|
|
4321
|
+
|
|
4322
|
+
slot[name="toolbar"] {
|
|
4323
|
+
display: contents;
|
|
4324
|
+
}
|
|
4325
|
+
|
|
4326
|
+
::slotted(slot[name="toolbar"]) {
|
|
4327
|
+
display: contents;
|
|
4328
|
+
}
|
|
4329
|
+
|
|
4330
|
+
.title-text-wrapper {
|
|
4331
|
+
display: flex;
|
|
4332
|
+
padding: 0 var(--space-s);
|
|
4333
|
+
}
|
|
4334
|
+
|
|
4335
|
+
/* === Midline variant === */
|
|
4336
|
+
|
|
4337
|
+
:host([variant="midline"]) .bar {
|
|
4338
|
+
background: transparent;
|
|
4339
|
+
padding: var(--space-xs) var(--space-m);
|
|
4340
|
+
min-height: unset;
|
|
4341
|
+
position: relative;
|
|
4342
|
+
}
|
|
4343
|
+
|
|
4344
|
+
:host([variant="midline"][orientation="vertical"]) .bar {
|
|
4345
|
+
padding: var(--space-m) var(--space-xs);
|
|
4346
|
+
min-width: unset;
|
|
4347
|
+
}
|
|
4348
|
+
|
|
4349
|
+
:host([variant="midline"]) .title-text-wrapper {
|
|
4350
|
+
position: relative;
|
|
4351
|
+
z-index: 1;
|
|
4352
|
+
display: flex;
|
|
4353
|
+
align-items: center;
|
|
4354
|
+
gap: var(--space-s);
|
|
4355
|
+
background: var(--surface-3);
|
|
4356
|
+
}
|
|
4357
|
+
|
|
4358
|
+
:host([variant="midline"]) .title-text {
|
|
4359
|
+
font-weight: normal;
|
|
4360
|
+
color: var(--surface-3-text);
|
|
4361
|
+
padding: 0 0.5ch 0 0.5ch;
|
|
4362
|
+
background: transparent;
|
|
4363
|
+
box-shadow: none;
|
|
4364
|
+
flex: unset;
|
|
4365
|
+
width: auto;
|
|
4366
|
+
white-space: nowrap;
|
|
4367
|
+
}
|
|
4368
|
+
|
|
4369
|
+
:host([variant="midline"]) .title-icon {
|
|
4370
|
+
background: transparent;
|
|
4371
|
+
flex-shrink: 0;
|
|
4372
|
+
}
|
|
4373
|
+
|
|
4374
|
+
:host([variant="midline"]) .caret-btn {
|
|
4375
|
+
position: relative;
|
|
4376
|
+
z-index: 1;
|
|
4377
|
+
background: var(--surface-3);
|
|
4378
|
+
opacity: 1;
|
|
4379
|
+
}
|
|
4380
|
+
|
|
4381
|
+
:host([variant="midline"][orientation="vertical"]) .title-text {
|
|
4382
|
+
transform: rotate(180deg);
|
|
4383
|
+
padding: 0.5ch 0 0.5ch 0ch;
|
|
4384
|
+
}
|
|
4385
|
+
|
|
4386
|
+
:host([variant="midline"]) .toolbar {
|
|
4387
|
+
position: relative;
|
|
4388
|
+
z-index: 2;
|
|
4389
|
+
background: var(--surface-3);
|
|
4390
|
+
margin-left: 0;
|
|
4391
|
+
}
|
|
4392
|
+
|
|
4393
|
+
:host([variant="midline"][orientation="horizontal"]) .toolbar {
|
|
4394
|
+
margin-left: auto;
|
|
4395
|
+
}
|
|
4396
|
+
|
|
4397
|
+
/* Debossed line runs from after title-text to before toolbar */
|
|
4398
|
+
:host([variant="midline"]) .bar::after {
|
|
4399
|
+
content: '';
|
|
4400
|
+
position: absolute;
|
|
4401
|
+
top: 50%;
|
|
4402
|
+
left: 0;
|
|
4403
|
+
right: 0;
|
|
4404
|
+
height: 1px;
|
|
4405
|
+
transform: translateY(-50%);
|
|
4406
|
+
background: var(--surface-2);
|
|
4407
|
+
box-shadow:
|
|
4408
|
+
0 -1px 0 var(--surface-5),
|
|
4409
|
+
0 1px 0 var(--surface-1);
|
|
4410
|
+
z-index: 0;
|
|
4411
|
+
}
|
|
4412
|
+
|
|
4413
|
+
/* For vertical midline, line runs vertically */
|
|
4414
|
+
:host([variant="midline"][orientation="vertical"]) .bar::after {
|
|
4415
|
+
top: 0;
|
|
4416
|
+
bottom: 0;
|
|
4417
|
+
left: 50%;
|
|
4418
|
+
right: unset;
|
|
4419
|
+
width: 1px;
|
|
4420
|
+
height: 100%;
|
|
4421
|
+
transform: translateX(-50%);
|
|
4422
|
+
box-shadow:
|
|
4423
|
+
-1px 0 0 var(--surface-5),
|
|
4424
|
+
1px 0 0 var(--surface-1);
|
|
4425
|
+
}
|
|
4426
|
+
|
|
4427
|
+
/* === Tree variant: VS Code explorer / Outline style === */
|
|
4428
|
+
:host([variant="tree"]) .bar {
|
|
4429
|
+
background: transparent;
|
|
4430
|
+
padding: 0 var(--space-xs);
|
|
4431
|
+
min-height: unset;
|
|
4432
|
+
gap: var(--space-xs);
|
|
4433
|
+
}
|
|
4434
|
+
|
|
4435
|
+
:host([variant="tree"][orientation="vertical"]) .bar {
|
|
4436
|
+
padding: var(--space-xs) 0;
|
|
4437
|
+
flex-direction: column;
|
|
4438
|
+
min-width: unset;
|
|
4439
|
+
writing-mode: horizontal-tb;
|
|
4440
|
+
}
|
|
4441
|
+
|
|
4442
|
+
:host([variant="tree"]) .title-text-wrapper {
|
|
4443
|
+
display: inline-flex;
|
|
4444
|
+
align-items: center;
|
|
4445
|
+
gap: var(--space-xs);
|
|
4446
|
+
padding: 0;
|
|
4447
|
+
background: transparent;
|
|
4448
|
+
}
|
|
4449
|
+
|
|
4450
|
+
:host([variant="tree"]) .title-icon {
|
|
4451
|
+
background: transparent;
|
|
4452
|
+
flex-shrink: 0;
|
|
4453
|
+
}
|
|
4454
|
+
|
|
4455
|
+
:host([variant="tree"]) .title-text {
|
|
4456
|
+
font-weight: normal;
|
|
4457
|
+
color: var(--surface-3-text);
|
|
4458
|
+
padding: 0;
|
|
4459
|
+
background: transparent;
|
|
4460
|
+
box-shadow: none;
|
|
4461
|
+
flex: unset;
|
|
4462
|
+
width: auto;
|
|
4463
|
+
white-space: nowrap;
|
|
4464
|
+
}
|
|
4465
|
+
|
|
4466
|
+
:host([variant="tree"][orientation="vertical"]) .title-text {
|
|
4467
|
+
writing-mode: vertical-rl;
|
|
4468
|
+
transform: rotate(180deg);
|
|
4469
|
+
padding: 0;
|
|
4470
|
+
}
|
|
4471
|
+
|
|
4472
|
+
:host([variant="tree"]) .caret-btn {
|
|
4473
|
+
background: transparent;
|
|
4474
|
+
opacity: var(--prominence-idle-opacity);
|
|
4475
|
+
padding: 0;
|
|
4476
|
+
}
|
|
4477
|
+
|
|
4478
|
+
:host([variant="tree"]) .caret-btn:hover {
|
|
4479
|
+
background: transparent;
|
|
4480
|
+
opacity: var(--prominence-tickled-opacity);
|
|
4481
|
+
}
|
|
4482
|
+
|
|
4483
|
+
:host([variant="tree"]) .toolbar {
|
|
4484
|
+
margin-left: auto;
|
|
4485
|
+
}
|
|
4486
|
+
|
|
4487
|
+
:host([variant="tree"][orientation="vertical"]) .toolbar {
|
|
4488
|
+
flex-direction: row;
|
|
4489
|
+
margin-left: 0;
|
|
4490
|
+
margin-top: auto;
|
|
4491
|
+
}
|
|
4492
|
+
|
|
4493
|
+
:host([variant="tree"]) ixfx-icon {
|
|
4494
|
+
width: 1em;
|
|
4495
|
+
height: 1em;
|
|
4496
|
+
}
|
|
4497
|
+
`];
|
|
4498
|
+
}
|
|
4499
|
+
};
|
|
4500
|
+
__decorate([property({ type: String })], TitlebarElement.prototype, "title", void 0);
|
|
4501
|
+
__decorate([property({
|
|
4502
|
+
type: String,
|
|
4503
|
+
attribute: `icon-name`
|
|
4504
|
+
})], TitlebarElement.prototype, "iconName", void 0);
|
|
4505
|
+
__decorate([property({
|
|
4506
|
+
type: String,
|
|
4507
|
+
attribute: `orientation`,
|
|
4508
|
+
reflect: true
|
|
4509
|
+
})], TitlebarElement.prototype, "orientation", void 0);
|
|
4510
|
+
__decorate([property({
|
|
4511
|
+
type: String,
|
|
4512
|
+
attribute: `variant`,
|
|
4513
|
+
reflect: true
|
|
4514
|
+
})], TitlebarElement.prototype, "variant", void 0);
|
|
4515
|
+
__decorate([property({ type: Boolean })], TitlebarElement.prototype, "closable", void 0);
|
|
4516
|
+
__decorate([property({
|
|
4517
|
+
type: Boolean,
|
|
4518
|
+
reflect: true
|
|
4519
|
+
})], TitlebarElement.prototype, "collapsible", void 0);
|
|
4520
|
+
__decorate([property({
|
|
4521
|
+
type: Boolean,
|
|
4522
|
+
reflect: true
|
|
4523
|
+
})], TitlebarElement.prototype, "collapsed", void 0);
|
|
4524
|
+
__decorate([property({
|
|
4525
|
+
type: String,
|
|
4526
|
+
attribute: `toggle-interaction`
|
|
4527
|
+
})], TitlebarElement.prototype, "toggleInteraction", void 0);
|
|
4528
|
+
TitlebarElement = __decorate([safeCustomElement(`ixfx-titlebar`)], TitlebarElement);
|
|
4529
|
+
//#endregion
|
|
4530
|
+
//#region src/bottom-drawer/bottom-drawer.ts
|
|
4531
|
+
/** Builds the command id for a named drawer's command, e.g. `inspector.expand`. */
|
|
4532
|
+
function bottomDrawerCommandId(name, command) {
|
|
4533
|
+
return `${name.trim()}.${command}`;
|
|
4534
|
+
}
|
|
4535
|
+
function clampRange(value, min, max) {
|
|
4536
|
+
return Math.min(max, Math.max(min, value));
|
|
4537
|
+
}
|
|
4538
|
+
let BottomDrawerElement = class BottomDrawerElement extends i {
|
|
4539
|
+
constructor(..._args) {
|
|
4540
|
+
super(..._args);
|
|
4541
|
+
this.open = false;
|
|
4542
|
+
this.height = 320;
|
|
4543
|
+
this.minHeight = 160;
|
|
4544
|
+
this.dismissThreshold = 96;
|
|
4545
|
+
this.maxHeightRatio = .85;
|
|
4546
|
+
this.label = `Drawer`;
|
|
4547
|
+
this.iconName = ``;
|
|
4548
|
+
this.closable = true;
|
|
4549
|
+
this.collapsible = true;
|
|
4550
|
+
this.maintainHandle = false;
|
|
4551
|
+
this.name = ``;
|
|
4552
|
+
this.#dragStartY = 0;
|
|
4553
|
+
this.#dragStartHeight = 0;
|
|
4554
|
+
this.#collapsedDragging = false;
|
|
4555
|
+
this.#commandName = ``;
|
|
4556
|
+
this.#commandIds = [];
|
|
4557
|
+
this.#onResizeStart = (event) => {
|
|
4558
|
+
if (event.button !== 0) return;
|
|
4559
|
+
event.preventDefault();
|
|
4560
|
+
const edge = event.currentTarget;
|
|
4561
|
+
edge.setPointerCapture(event.pointerId);
|
|
4562
|
+
if (!this.open) {
|
|
4563
|
+
this.#collapsedDragging = false;
|
|
4564
|
+
this.#dragStartY = event.clientY;
|
|
4565
|
+
this.#dragStartHeight = this.dismissThreshold;
|
|
4566
|
+
edge.addEventListener(`pointermove`, this.#onTabPointerMove);
|
|
4567
|
+
edge.addEventListener(`pointerup`, this.#onTabPointerUp, { once: true });
|
|
4568
|
+
edge.addEventListener(`pointercancel`, this.#onTabPointerUp, { once: true });
|
|
4569
|
+
return;
|
|
4570
|
+
}
|
|
4571
|
+
this.#dragStartY = event.clientY;
|
|
4572
|
+
this.#dragStartHeight = this.#displayHeight();
|
|
4573
|
+
this._dragHeight = this.#dragStartHeight;
|
|
4574
|
+
this.toggleAttribute(`resizing`, true);
|
|
4575
|
+
edge.addEventListener(`pointermove`, this.#onResizeMove);
|
|
4576
|
+
edge.addEventListener(`pointerup`, this.#onResizeEnd, { once: true });
|
|
4577
|
+
edge.addEventListener(`pointercancel`, this.#onResizeEnd, { once: true });
|
|
4578
|
+
};
|
|
4579
|
+
this.#onResizeMove = (event) => {
|
|
4580
|
+
this._dragHeight = clampRange(this.#dragStartHeight + this.#dragStartY - event.clientY, 0, this.#maxHeight());
|
|
4581
|
+
};
|
|
4582
|
+
this.#onResizeEnd = (event) => {
|
|
4583
|
+
const edge = event.currentTarget;
|
|
4584
|
+
edge.removeEventListener(`pointermove`, this.#onResizeMove);
|
|
4585
|
+
edge.removeEventListener(`pointerup`, this.#onResizeEnd);
|
|
4586
|
+
edge.removeEventListener(`pointercancel`, this.#onResizeEnd);
|
|
4587
|
+
if (edge.hasPointerCapture(event.pointerId)) edge.releasePointerCapture(event.pointerId);
|
|
4588
|
+
this.toggleAttribute(`resizing`, false);
|
|
4589
|
+
const height = this._dragHeight ?? this.height;
|
|
4590
|
+
this._dragHeight = void 0;
|
|
4591
|
+
if (height < this.dismissThreshold) {
|
|
4592
|
+
this.close();
|
|
4593
|
+
return;
|
|
4594
|
+
}
|
|
4595
|
+
this.#setHeight(height);
|
|
4596
|
+
};
|
|
4597
|
+
this.#onResizeKeyDown = (event) => {
|
|
4598
|
+
if (!this.open) {
|
|
4599
|
+
if (event.key === `ArrowUp` || event.key === `Enter` || event.key === ` ` || event.key === `Home` || event.key === `End`) {
|
|
4600
|
+
event.preventDefault();
|
|
4601
|
+
this.show();
|
|
4602
|
+
}
|
|
4603
|
+
return;
|
|
4604
|
+
}
|
|
4605
|
+
const delta = event.shiftKey ? 64 : 16;
|
|
4606
|
+
if (event.key === `ArrowUp`) {
|
|
4607
|
+
event.preventDefault();
|
|
4608
|
+
this.#setHeight(this.height + delta);
|
|
4609
|
+
} else if (event.key === `ArrowDown`) {
|
|
4610
|
+
event.preventDefault();
|
|
4611
|
+
if (this.height - delta < this.dismissThreshold) this.close();
|
|
4612
|
+
else this.#setHeight(this.height - delta);
|
|
4613
|
+
} else if (event.key === `Home`) {
|
|
4614
|
+
event.preventDefault();
|
|
4615
|
+
this.#setHeight(this.minHeight);
|
|
4616
|
+
} else if (event.key === `End`) {
|
|
4617
|
+
event.preventDefault();
|
|
4618
|
+
this.#setHeight(this.#maxHeight());
|
|
4619
|
+
}
|
|
4620
|
+
};
|
|
4621
|
+
this.#onTabPointerMove = (event) => {
|
|
4622
|
+
const delta = this.#dragStartY - event.clientY;
|
|
4623
|
+
if (!this.#collapsedDragging) {
|
|
4624
|
+
if (delta < 4) return;
|
|
4625
|
+
this.#collapsedDragging = true;
|
|
4626
|
+
this.show();
|
|
4627
|
+
this.toggleAttribute(`resizing`, true);
|
|
4628
|
+
}
|
|
4629
|
+
this._dragHeight = clampRange(this.#dragStartHeight + this.#dragStartY - event.clientY, 0, this.#maxHeight());
|
|
4630
|
+
};
|
|
4631
|
+
this.#onTabPointerUp = (event) => {
|
|
4632
|
+
const target = event.currentTarget;
|
|
4633
|
+
target.removeEventListener(`pointermove`, this.#onTabPointerMove);
|
|
4634
|
+
target.removeEventListener(`pointerup`, this.#onTabPointerUp);
|
|
4635
|
+
target.removeEventListener(`pointercancel`, this.#onTabPointerUp);
|
|
4636
|
+
if (target.hasPointerCapture(event.pointerId)) target.releasePointerCapture(event.pointerId);
|
|
4637
|
+
if (!this.#collapsedDragging) {
|
|
4638
|
+
this.show();
|
|
4639
|
+
return;
|
|
4640
|
+
}
|
|
4641
|
+
this.#collapsedDragging = false;
|
|
4642
|
+
this.toggleAttribute(`resizing`, false);
|
|
4643
|
+
const height = this._dragHeight ?? this.height;
|
|
4644
|
+
this._dragHeight = void 0;
|
|
4645
|
+
if (height < this.dismissThreshold) {
|
|
4646
|
+
this.close();
|
|
4647
|
+
return;
|
|
4648
|
+
}
|
|
4649
|
+
this.#setHeight(height);
|
|
4650
|
+
};
|
|
4651
|
+
this.#onDrawerKeyDown = (event) => {
|
|
4652
|
+
if (event.key !== `Escape`) return;
|
|
4653
|
+
event.preventDefault();
|
|
4654
|
+
event.stopPropagation();
|
|
4655
|
+
this.close();
|
|
4656
|
+
};
|
|
4657
|
+
}
|
|
4658
|
+
static {
|
|
4659
|
+
this.styles = [
|
|
4660
|
+
themeFallbacks,
|
|
4661
|
+
handleStyles,
|
|
4662
|
+
i$3`
|
|
4663
|
+
:host {
|
|
4664
|
+
--bottom-drawer-background: color-mix(in srgb, var(--surface-2) 84%, transparent);
|
|
4665
|
+
--bottom-drawer-border: 1px solid color-mix(in srgb, var(--surface-2-text) 14%, transparent);
|
|
4666
|
+
--bottom-drawer-radius: var(--radius-l);
|
|
4667
|
+
--bottom-drawer-blur: 18px;
|
|
4668
|
+
--bottom-drawer-shadow: var(--shadow-l);
|
|
4669
|
+
--bottom-drawer-collapsed-width: 96px;
|
|
4670
|
+
|
|
4671
|
+
display: block;
|
|
4672
|
+
position: relative;
|
|
4673
|
+
height: 100%;
|
|
4674
|
+
min-width: 0;
|
|
4675
|
+
min-height: 0;
|
|
4676
|
+
overflow: hidden;
|
|
4677
|
+
}
|
|
4678
|
+
.content {
|
|
4679
|
+
position: absolute;
|
|
4680
|
+
inset: 0;
|
|
4681
|
+
min-width: 0;
|
|
4682
|
+
min-height: 0;
|
|
4683
|
+
}
|
|
4684
|
+
.content ::slotted(*) {
|
|
4685
|
+
width: 100%;
|
|
4686
|
+
height: 100%;
|
|
4687
|
+
}
|
|
4688
|
+
.drawer {
|
|
4689
|
+
--m: 0;
|
|
4690
|
+
position: absolute;
|
|
4691
|
+
z-index: 2;
|
|
4692
|
+
right: calc(var(--m) * (50% - var(--bottom-drawer-collapsed-width) / 2));
|
|
4693
|
+
bottom: 0;
|
|
4694
|
+
left: calc(var(--m) * (50% - var(--bottom-drawer-collapsed-width) / 2));
|
|
4695
|
+
display: flex;
|
|
4696
|
+
flex-direction: column;
|
|
4697
|
+
box-sizing: border-box;
|
|
4698
|
+
height: var(--bottom-drawer-height);
|
|
4699
|
+
max-height: 100%;
|
|
4700
|
+
min-height: 0;
|
|
4701
|
+
color: var(--surface-2-text);
|
|
4702
|
+
background: var(--bottom-drawer-background);
|
|
4703
|
+
border: var(--bottom-drawer-border);
|
|
4704
|
+
border-bottom: 0;
|
|
4705
|
+
border-radius: var(--bottom-drawer-radius) var(--bottom-drawer-radius) 0 0;
|
|
4706
|
+
box-shadow: var(--bottom-drawer-shadow);
|
|
4707
|
+
backdrop-filter: blur(var(--bottom-drawer-blur)) saturate(1.15);
|
|
4708
|
+
-webkit-backdrop-filter: blur(var(--bottom-drawer-blur)) saturate(1.15);
|
|
4709
|
+
opacity: 0;
|
|
4710
|
+
transform: translateY(100%);
|
|
4711
|
+
visibility: hidden;
|
|
4712
|
+
transition:
|
|
4713
|
+
transform var(--transition),
|
|
4714
|
+
opacity var(--transition),
|
|
4715
|
+
left var(--transition),
|
|
4716
|
+
right var(--transition),
|
|
4717
|
+
height var(--transition),
|
|
4718
|
+
visibility 0s linear 0.16s;
|
|
4719
|
+
will-change: transform, opacity;
|
|
4720
|
+
}
|
|
4721
|
+
:host([open]) .drawer {
|
|
4722
|
+
opacity: var(--bottom-drawer-opacity, 1);
|
|
4723
|
+
transform: translateY(0);
|
|
4724
|
+
visibility: visible;
|
|
4725
|
+
transition:
|
|
4726
|
+
transform var(--transition),
|
|
4727
|
+
opacity var(--transition),
|
|
4728
|
+
left var(--transition),
|
|
4729
|
+
right var(--transition),
|
|
4730
|
+
height var(--transition);
|
|
4731
|
+
}
|
|
4732
|
+
:host([resizing]) {
|
|
4733
|
+
cursor: ns-resize;
|
|
4734
|
+
user-select: none;
|
|
4735
|
+
}
|
|
4736
|
+
:host([resizing]) .drawer {
|
|
4737
|
+
transition: none;
|
|
4738
|
+
}
|
|
4739
|
+
.resize-edge {
|
|
4740
|
+
position: absolute;
|
|
4741
|
+
z-index: 1;
|
|
4742
|
+
top: -5px;
|
|
4743
|
+
right: 0;
|
|
4744
|
+
left: 0;
|
|
4745
|
+
height: 11px;
|
|
4746
|
+
cursor: ns-resize;
|
|
4747
|
+
touch-action: none;
|
|
4748
|
+
outline: none;
|
|
4749
|
+
}
|
|
4750
|
+
.resize-edge .ixfx-handle {
|
|
4751
|
+
position: absolute;
|
|
4752
|
+
top: 7px;
|
|
4753
|
+
left: 50%;
|
|
4754
|
+
transform: translateX(-50%);
|
|
4755
|
+
--ixfx-handle-length: 44px;
|
|
4756
|
+
--ixfx-handle-thickness: 3px;
|
|
4757
|
+
--ixfx-handle-radius: 999px;
|
|
4758
|
+
}
|
|
4759
|
+
/* Inner content fades as the drawer morphs into its collapsed tab. */
|
|
4760
|
+
ixfx-titlebar,
|
|
4761
|
+
.body {
|
|
4762
|
+
opacity: calc(1 - var(--m, 0));
|
|
4763
|
+
transition: opacity var(--transition);
|
|
4764
|
+
}
|
|
4765
|
+
:host([resizing]) ixfx-titlebar,
|
|
4766
|
+
:host([resizing]) .body {
|
|
4767
|
+
transition: none;
|
|
4768
|
+
}
|
|
4769
|
+
/* Collapsed tab: docked to the bottom edge, narrowed to handle width. */
|
|
4770
|
+
:host([maintain-handle]:not([open])) .drawer {
|
|
4771
|
+
--m: 1;
|
|
4772
|
+
height: 20px;
|
|
4773
|
+
opacity: 1;
|
|
4774
|
+
transform: translateY(0);
|
|
4775
|
+
visibility: visible;
|
|
4776
|
+
transition:
|
|
4777
|
+
transform var(--transition),
|
|
4778
|
+
opacity var(--transition),
|
|
4779
|
+
left var(--transition),
|
|
4780
|
+
right var(--transition),
|
|
4781
|
+
height var(--transition);
|
|
4782
|
+
}
|
|
4783
|
+
:host([maintain-handle]:not([open])) ixfx-titlebar,
|
|
4784
|
+
:host([maintain-handle]:not([open])) .body {
|
|
4785
|
+
display: none;
|
|
4786
|
+
}
|
|
4787
|
+
:host([maintain-handle]:not([open])) .resize-edge {
|
|
4788
|
+
top: 0;
|
|
4789
|
+
height: 100%;
|
|
4790
|
+
}
|
|
4791
|
+
:host([maintain-handle]:not([open])) .resize-edge .ixfx-handle {
|
|
4792
|
+
top: 50%;
|
|
4793
|
+
transform: translate(-50%, -50%);
|
|
4794
|
+
}
|
|
4795
|
+
ixfx-titlebar {
|
|
4796
|
+
flex: none;
|
|
4797
|
+
--titlebar-background: var(--bottom-drawer-title-background, transparent);
|
|
4798
|
+
border-bottom: 1px solid color-mix(in srgb, var(--surface-2-text) 10%, transparent);
|
|
4799
|
+
}
|
|
4800
|
+
.body {
|
|
4801
|
+
flex: 1;
|
|
4802
|
+
min-height: 0;
|
|
4803
|
+
overflow: auto;
|
|
4804
|
+
overscroll-behavior: contain;
|
|
4805
|
+
}
|
|
4806
|
+
.body ::slotted(*) {
|
|
4807
|
+
box-sizing: border-box;
|
|
4808
|
+
}
|
|
4809
|
+
@media (prefers-reduced-motion: reduce) {
|
|
4810
|
+
.drawer,
|
|
4811
|
+
ixfx-titlebar,
|
|
4812
|
+
.body {
|
|
4813
|
+
transition-duration: 0s;
|
|
4814
|
+
}
|
|
4815
|
+
}
|
|
4816
|
+
`
|
|
4817
|
+
];
|
|
4818
|
+
}
|
|
4819
|
+
#dragStartY;
|
|
4820
|
+
#dragStartHeight;
|
|
4821
|
+
#collapsedDragging;
|
|
4822
|
+
#ownedRegistry;
|
|
4823
|
+
#commandTarget;
|
|
4824
|
+
#commandName;
|
|
4825
|
+
#commandIds;
|
|
4826
|
+
connectedCallback() {
|
|
4827
|
+
super.connectedCallback();
|
|
4828
|
+
this.#syncCommands();
|
|
4829
|
+
}
|
|
4830
|
+
disconnectedCallback() {
|
|
4831
|
+
super.disconnectedCallback();
|
|
4832
|
+
this.#teardownCommands();
|
|
4833
|
+
if (this.#ownedRegistry !== void 0) {
|
|
4834
|
+
if (this.registry === this.#ownedRegistry) this.registry = void 0;
|
|
4835
|
+
this.#ownedRegistry = void 0;
|
|
4836
|
+
}
|
|
4837
|
+
}
|
|
4838
|
+
updated(changed) {
|
|
4839
|
+
super.updated(changed);
|
|
4840
|
+
if (changed.has(`name`) || changed.has(`registry`)) this.#syncCommands();
|
|
4841
|
+
}
|
|
4842
|
+
show() {
|
|
4843
|
+
this.open = true;
|
|
4844
|
+
}
|
|
4845
|
+
close() {
|
|
4846
|
+
if (!this.open) return;
|
|
4847
|
+
this.open = false;
|
|
4848
|
+
this.dispatchEvent(new CustomEvent(`drawer-close`, {
|
|
4849
|
+
bubbles: true,
|
|
4850
|
+
composed: true
|
|
4851
|
+
}));
|
|
4852
|
+
}
|
|
4853
|
+
toggle() {
|
|
4854
|
+
if (this.open) this.close();
|
|
4855
|
+
else this.show();
|
|
4856
|
+
}
|
|
4857
|
+
#syncCommands() {
|
|
4858
|
+
const name = this.name.trim();
|
|
4859
|
+
const target = this.registry ?? this.#ownedRegistry;
|
|
4860
|
+
if (name !== `` && this.isConnected && target !== void 0 && this.#commandTarget === target && this.#commandName === name) return;
|
|
4861
|
+
this.#teardownCommands();
|
|
4862
|
+
if (name === `` || !this.isConnected) return;
|
|
4863
|
+
const resolved = this.registry ?? (this.#ownedRegistry ??= createCommandRegistry());
|
|
4864
|
+
if (this.#ownedRegistry !== void 0 && resolved !== this.#ownedRegistry) this.#ownedRegistry = void 0;
|
|
4865
|
+
if (this.registry === void 0) this.registry = resolved;
|
|
4866
|
+
const registered = [];
|
|
4867
|
+
const commands = [
|
|
4868
|
+
{
|
|
4869
|
+
command: `expand`,
|
|
4870
|
+
label: `Expand ${this.label}`,
|
|
4871
|
+
description: `Open the ${this.label} drawer`,
|
|
4872
|
+
execute: () => this.show()
|
|
4873
|
+
},
|
|
4874
|
+
{
|
|
4875
|
+
command: `collapse`,
|
|
4876
|
+
label: `Collapse ${this.label}`,
|
|
4877
|
+
description: `Close the ${this.label} drawer`,
|
|
4878
|
+
execute: () => this.close()
|
|
4879
|
+
},
|
|
4880
|
+
{
|
|
4881
|
+
command: `toggle`,
|
|
4882
|
+
label: `Toggle ${this.label}`,
|
|
4883
|
+
description: `Open the ${this.label} drawer if closed, close it if open`,
|
|
4884
|
+
execute: () => this.toggle()
|
|
4885
|
+
}
|
|
4886
|
+
];
|
|
4887
|
+
for (const { command, label, description, execute } of commands) {
|
|
4888
|
+
const id = bottomDrawerCommandId(name, command);
|
|
4889
|
+
if (resolved.has(id)) continue;
|
|
4890
|
+
resolved.register({
|
|
4891
|
+
id,
|
|
4892
|
+
label,
|
|
4893
|
+
description,
|
|
4894
|
+
execute
|
|
4895
|
+
});
|
|
4896
|
+
registered.push(id);
|
|
4897
|
+
}
|
|
4898
|
+
this.#commandTarget = resolved;
|
|
4899
|
+
this.#commandName = name;
|
|
4900
|
+
this.#commandIds = registered;
|
|
4901
|
+
}
|
|
4902
|
+
#teardownCommands() {
|
|
4903
|
+
if (this.#commandTarget !== void 0) {
|
|
4904
|
+
for (const id of this.#commandIds) this.#commandTarget.unregister(id);
|
|
4905
|
+
this.#commandTarget = void 0;
|
|
4906
|
+
this.#commandName = ``;
|
|
4907
|
+
this.#commandIds = [];
|
|
4908
|
+
}
|
|
4909
|
+
}
|
|
4910
|
+
_onTitlebarToggle(event) {
|
|
4911
|
+
event.stopPropagation();
|
|
4912
|
+
if (event.detail.collapsed) this.close();
|
|
4913
|
+
else this.open = true;
|
|
4914
|
+
}
|
|
4915
|
+
_onTitlebarClose(event) {
|
|
4916
|
+
event.stopPropagation();
|
|
4917
|
+
this.close();
|
|
4918
|
+
}
|
|
4919
|
+
render() {
|
|
4920
|
+
const raw = this.#displayHeight();
|
|
4921
|
+
const max = this.#maxHeight();
|
|
4922
|
+
const morph = this.#morphProgress(raw);
|
|
4923
|
+
const height = this.open ? raw * (1 - morph) + 20 * morph : 20;
|
|
4924
|
+
const opacity = this.maintainHandle && this.open ? 1 : this.#dragOpacity(raw);
|
|
4925
|
+
return b`
|
|
4926
|
+
<div class="content"><slot></slot></div>
|
|
4927
|
+
<section
|
|
4928
|
+
class="drawer"
|
|
4929
|
+
style=${`--bottom-drawer-height: ${height}px; --bottom-drawer-opacity: ${opacity}; --m: ${morph}`}
|
|
4930
|
+
role="region"
|
|
4931
|
+
aria-label=${this.label}
|
|
4932
|
+
@keydown=${this.#onDrawerKeyDown}
|
|
4933
|
+
>
|
|
4934
|
+
<div
|
|
4935
|
+
class="resize-edge"
|
|
4936
|
+
role="separator"
|
|
4937
|
+
tabindex="0"
|
|
4938
|
+
aria-label=${`${this.open ? `Resize` : `Expand`} ${this.label}`}
|
|
4939
|
+
aria-orientation="horizontal"
|
|
4940
|
+
aria-valuemin=${this.minHeight}
|
|
4941
|
+
aria-valuemax=${max}
|
|
4942
|
+
aria-valuenow=${Math.round(raw)}
|
|
4943
|
+
@pointerdown=${this.#onResizeStart}
|
|
4944
|
+
@keydown=${this.#onResizeKeyDown}
|
|
4945
|
+
><span class="ixfx-handle" data-handle="dimpled" data-shape="horizontal" part="handle"></span></div>
|
|
4946
|
+
<ixfx-titlebar
|
|
4947
|
+
.title=${this.label}
|
|
4948
|
+
.iconName=${this.iconName}
|
|
4949
|
+
.closable=${this.closable}
|
|
4950
|
+
.collapsible=${this.collapsible}
|
|
4951
|
+
.collapsed=${!this.open}
|
|
4952
|
+
?inert=${!this.open}
|
|
4953
|
+
@toggle=${this._onTitlebarToggle}
|
|
4954
|
+
@close=${this._onTitlebarClose}
|
|
4955
|
+
>
|
|
4956
|
+
<slot name="toolbar" slot="toolbar"></slot>
|
|
4957
|
+
</ixfx-titlebar>
|
|
4958
|
+
<div class="body" ?inert=${!this.open}><slot name="drawer"></slot></div>
|
|
4959
|
+
</section>
|
|
4960
|
+
`;
|
|
4961
|
+
}
|
|
4962
|
+
#maxHeight() {
|
|
4963
|
+
const availableHeight = this.clientHeight || this.height;
|
|
4964
|
+
return Math.max(this.minHeight, availableHeight * clampRange(this.maxHeightRatio, 0, 1));
|
|
4965
|
+
}
|
|
4966
|
+
#displayHeight() {
|
|
4967
|
+
return clampRange(this._dragHeight ?? this.height, 0, this.#maxHeight());
|
|
4968
|
+
}
|
|
4969
|
+
#dragOpacity(height) {
|
|
4970
|
+
if (this._dragHeight === void 0 || height >= this.minHeight) return 1;
|
|
4971
|
+
const fadeRange = this.minHeight - this.dismissThreshold;
|
|
4972
|
+
if (fadeRange <= 0) return height >= this.dismissThreshold ? 1 : 0;
|
|
4973
|
+
return clampRange((height - this.dismissThreshold) / fadeRange, 0, 1);
|
|
4974
|
+
}
|
|
4975
|
+
#morphProgress(raw) {
|
|
4976
|
+
if (!this.open) return this.maintainHandle ? 1 : 0;
|
|
4977
|
+
if (this._dragHeight === void 0 || !this.maintainHandle) return 0;
|
|
4978
|
+
const range = this.minHeight - this.dismissThreshold;
|
|
4979
|
+
if (range <= 0) return raw < this.dismissThreshold ? 1 : 0;
|
|
4980
|
+
return clampRange((this.minHeight - raw) / range, 0, 1);
|
|
4981
|
+
}
|
|
4982
|
+
#setHeight(height) {
|
|
4983
|
+
this.height = clampRange(height, this.minHeight, this.#maxHeight());
|
|
4984
|
+
this.dispatchEvent(new CustomEvent(`drawer-resize`, {
|
|
4985
|
+
detail: { height: this.height },
|
|
4986
|
+
bubbles: true,
|
|
4987
|
+
composed: true
|
|
4988
|
+
}));
|
|
4989
|
+
}
|
|
4990
|
+
#onResizeStart;
|
|
4991
|
+
#onResizeMove;
|
|
4992
|
+
#onResizeEnd;
|
|
4993
|
+
#onResizeKeyDown;
|
|
4994
|
+
#onTabPointerMove;
|
|
4995
|
+
#onTabPointerUp;
|
|
4996
|
+
#onDrawerKeyDown;
|
|
4997
|
+
};
|
|
4998
|
+
__decorate([property({
|
|
4999
|
+
type: Boolean,
|
|
5000
|
+
reflect: true
|
|
5001
|
+
})], BottomDrawerElement.prototype, "open", void 0);
|
|
5002
|
+
__decorate([property({ type: Number })], BottomDrawerElement.prototype, "height", void 0);
|
|
5003
|
+
__decorate([property({
|
|
5004
|
+
type: Number,
|
|
5005
|
+
attribute: `min-height`
|
|
5006
|
+
})], BottomDrawerElement.prototype, "minHeight", void 0);
|
|
5007
|
+
__decorate([property({
|
|
5008
|
+
type: Number,
|
|
5009
|
+
attribute: `dismiss-threshold`
|
|
5010
|
+
})], BottomDrawerElement.prototype, "dismissThreshold", void 0);
|
|
5011
|
+
__decorate([property({
|
|
5012
|
+
type: Number,
|
|
5013
|
+
attribute: `max-height-ratio`
|
|
5014
|
+
})], BottomDrawerElement.prototype, "maxHeightRatio", void 0);
|
|
5015
|
+
__decorate([property({ type: String })], BottomDrawerElement.prototype, "label", void 0);
|
|
5016
|
+
__decorate([property({
|
|
5017
|
+
type: String,
|
|
5018
|
+
attribute: `icon-name`
|
|
5019
|
+
})], BottomDrawerElement.prototype, "iconName", void 0);
|
|
5020
|
+
__decorate([property({ type: Boolean })], BottomDrawerElement.prototype, "closable", void 0);
|
|
5021
|
+
__decorate([property({ type: Boolean })], BottomDrawerElement.prototype, "collapsible", void 0);
|
|
5022
|
+
__decorate([property({
|
|
5023
|
+
type: Boolean,
|
|
5024
|
+
attribute: `maintain-handle`,
|
|
5025
|
+
reflect: true
|
|
5026
|
+
})], BottomDrawerElement.prototype, "maintainHandle", void 0);
|
|
5027
|
+
__decorate([property({ type: String })], BottomDrawerElement.prototype, "name", void 0);
|
|
5028
|
+
__decorate([property({ attribute: false })], BottomDrawerElement.prototype, "registry", void 0);
|
|
5029
|
+
__decorate([state()], BottomDrawerElement.prototype, "_dragHeight", void 0);
|
|
5030
|
+
BottomDrawerElement = __decorate([safeCustomElement(`ixfx-bottom-drawer`)], BottomDrawerElement);
|
|
5031
|
+
//#endregion
|
|
3899
5032
|
//#region src/icons/defaults.ts
|
|
3900
5033
|
/**
|
|
3901
5034
|
* Chevron pointing down. Used for split-button dropdown toggle.
|
|
@@ -4562,6 +5695,306 @@ __decorate([state()], RadioGroup.prototype, "_icons", void 0);
|
|
|
4562
5695
|
__decorate([query(`slot`)], RadioGroup.prototype, "_slot", void 0);
|
|
4563
5696
|
RadioGroup = __decorate([safeCustomElement(`ixfx-radio-group`)], RadioGroup);
|
|
4564
5697
|
//#endregion
|
|
5698
|
+
//#region src/interaction/list-drag-select-controller.ts
|
|
5699
|
+
const DEFAULT_POINTER_TYPES = [`mouse`, `pen`];
|
|
5700
|
+
const DEFAULT_THRESHOLD = 4;
|
|
5701
|
+
/** Pointer distance (px) from an edge that triggers auto-scroll. */
|
|
5702
|
+
const EDGE_ZONE = 28;
|
|
5703
|
+
/** Max auto-scroll speed in px per frame. */
|
|
5704
|
+
const MAX_SCROLL_SPEED = 16;
|
|
5705
|
+
/**
|
|
5706
|
+
* Shared pointer-drag (marquee / rubber-band) selection for list components.
|
|
5707
|
+
*
|
|
5708
|
+
* Owns all pointer plumbing and rectangle state; knows nothing about DOM
|
|
5709
|
+
* geometry or the selection model — those are host callbacks. Mirrors the
|
|
5710
|
+
* `TickledController` attach pattern (`new ListDragSelectController(this, …)`).
|
|
5711
|
+
*
|
|
5712
|
+
* Behaviour: `pointerdown` on the surface records a start point; once the
|
|
5713
|
+
* pointer moves past `threshold`, the surface captures the pointer and every
|
|
5714
|
+
* move recomputes the rect, hit-tests, and calls `onPreview`. On release the
|
|
5715
|
+
* final set is delivered once via `onCommit`. A press that never crosses the
|
|
5716
|
+
* threshold does nothing (the normal `@click` path runs).
|
|
5717
|
+
*/
|
|
5718
|
+
var ListDragSelectController = class {
|
|
5719
|
+
#host;
|
|
5720
|
+
#config;
|
|
5721
|
+
#boundSurface;
|
|
5722
|
+
#pointerId;
|
|
5723
|
+
#startClientX = 0;
|
|
5724
|
+
#startClientY = 0;
|
|
5725
|
+
#startX = 0;
|
|
5726
|
+
#startY = 0;
|
|
5727
|
+
#currentClientX = 0;
|
|
5728
|
+
#currentClientY = 0;
|
|
5729
|
+
#lastModifiers = {
|
|
5730
|
+
shiftKey: false,
|
|
5731
|
+
ctrlKey: false,
|
|
5732
|
+
metaKey: false
|
|
5733
|
+
};
|
|
5734
|
+
#dragging = false;
|
|
5735
|
+
#suppressClick = false;
|
|
5736
|
+
/** Selection as it was when the drag started — the combine baseline. */
|
|
5737
|
+
#base = /* @__PURE__ */ new Set();
|
|
5738
|
+
/** Combine mode of the most recent preview (drives the commit flag). */
|
|
5739
|
+
#lastMode = `replace`;
|
|
5740
|
+
#preview = /* @__PURE__ */ new Set();
|
|
5741
|
+
#raf = 0;
|
|
5742
|
+
constructor(host, config) {
|
|
5743
|
+
this.#host = host;
|
|
5744
|
+
this.#config = config;
|
|
5745
|
+
host.addController(this);
|
|
5746
|
+
}
|
|
5747
|
+
/** `true` while a drag is in progress or its trailing click is still pending. */
|
|
5748
|
+
get isDragging() {
|
|
5749
|
+
return this.#dragging || this.#suppressClick;
|
|
5750
|
+
}
|
|
5751
|
+
/** `true` once the press has crossed the threshold and a rect is live. */
|
|
5752
|
+
get isActive() {
|
|
5753
|
+
return this.#dragging;
|
|
5754
|
+
}
|
|
5755
|
+
hostConnected() {
|
|
5756
|
+
this.#bindSurface();
|
|
5757
|
+
window.addEventListener(`pointermove`, this.#onPointerMove);
|
|
5758
|
+
window.addEventListener(`pointerup`, this.#onPointerUp);
|
|
5759
|
+
window.addEventListener(`pointercancel`, this.#onPointerCancel);
|
|
5760
|
+
}
|
|
5761
|
+
hostDisconnected() {
|
|
5762
|
+
this.#unbindSurface();
|
|
5763
|
+
window.removeEventListener(`pointermove`, this.#onPointerMove);
|
|
5764
|
+
window.removeEventListener(`pointerup`, this.#onPointerUp);
|
|
5765
|
+
window.removeEventListener(`pointercancel`, this.#onPointerCancel);
|
|
5766
|
+
this.#stopAutoScroll();
|
|
5767
|
+
this.#reset();
|
|
5768
|
+
}
|
|
5769
|
+
/** Re-bind when the surface element appears/changes (e.g. first render). */
|
|
5770
|
+
hostUpdated() {
|
|
5771
|
+
if ((this.#safeSurface() ?? this.#host) !== this.#boundSurface) this.#bindSurface();
|
|
5772
|
+
}
|
|
5773
|
+
#safeSurface() {
|
|
5774
|
+
try {
|
|
5775
|
+
return this.#config.getSurface();
|
|
5776
|
+
} catch {
|
|
5777
|
+
return;
|
|
5778
|
+
}
|
|
5779
|
+
}
|
|
5780
|
+
#bindSurface() {
|
|
5781
|
+
const next = this.#safeSurface() ?? this.#host;
|
|
5782
|
+
if (next === this.#boundSurface) return;
|
|
5783
|
+
this.#unbindSurface();
|
|
5784
|
+
this.#boundSurface = next;
|
|
5785
|
+
next.addEventListener(`pointerdown`, this.#onPointerDown);
|
|
5786
|
+
}
|
|
5787
|
+
#unbindSurface() {
|
|
5788
|
+
this.#boundSurface?.removeEventListener(`pointerdown`, this.#onPointerDown);
|
|
5789
|
+
this.#boundSurface = void 0;
|
|
5790
|
+
}
|
|
5791
|
+
#enabledTypes() {
|
|
5792
|
+
return this.#config.pointerTypes ?? DEFAULT_POINTER_TYPES;
|
|
5793
|
+
}
|
|
5794
|
+
#threshold() {
|
|
5795
|
+
return this.#config.threshold ?? DEFAULT_THRESHOLD;
|
|
5796
|
+
}
|
|
5797
|
+
#onPointerDown = (event) => {
|
|
5798
|
+
if (event.button !== 0) return;
|
|
5799
|
+
if (!this.#enabledTypes().includes(event.pointerType)) return;
|
|
5800
|
+
let enabled = false;
|
|
5801
|
+
try {
|
|
5802
|
+
enabled = this.#config.isEnabled();
|
|
5803
|
+
} catch {
|
|
5804
|
+
return;
|
|
5805
|
+
}
|
|
5806
|
+
if (!enabled) return;
|
|
5807
|
+
const target = event.target;
|
|
5808
|
+
if (target instanceof Element && typeof target.closest === `function`) {
|
|
5809
|
+
if (target.closest(`input,button,a,select,textarea,[contenteditable]`)) return;
|
|
5810
|
+
}
|
|
5811
|
+
if (this.#config.shouldStart) try {
|
|
5812
|
+
if (!this.#config.shouldStart(event)) return;
|
|
5813
|
+
} catch {
|
|
5814
|
+
return;
|
|
5815
|
+
}
|
|
5816
|
+
const box = (this.#safeSurface() ?? this.#host).getBoundingClientRect();
|
|
5817
|
+
this.#pointerId = event.pointerId;
|
|
5818
|
+
this.#startClientX = event.clientX;
|
|
5819
|
+
this.#startClientY = event.clientY;
|
|
5820
|
+
this.#currentClientX = event.clientX;
|
|
5821
|
+
this.#currentClientY = event.clientY;
|
|
5822
|
+
this.#startX = Math.min(Math.max(event.clientX - box.left, 0), Math.max(0, box.width));
|
|
5823
|
+
this.#startY = Math.min(Math.max(event.clientY - box.top, 0), Math.max(0, box.height));
|
|
5824
|
+
this.#dragging = false;
|
|
5825
|
+
this.#suppressClick = false;
|
|
5826
|
+
this.#base = /* @__PURE__ */ new Set();
|
|
5827
|
+
this.#lastMode = `replace`;
|
|
5828
|
+
this.#lastModifiers = {
|
|
5829
|
+
shiftKey: event.shiftKey,
|
|
5830
|
+
ctrlKey: event.ctrlKey,
|
|
5831
|
+
metaKey: event.metaKey
|
|
5832
|
+
};
|
|
5833
|
+
};
|
|
5834
|
+
/** Combine mode for the current modifiers: Shift adds, Cmd/Ctrl inverts. */
|
|
5835
|
+
#modeFor(modifiers) {
|
|
5836
|
+
if (modifiers.metaKey || modifiers.ctrlKey) return `invert`;
|
|
5837
|
+
if (modifiers.shiftKey) return `add`;
|
|
5838
|
+
return `replace`;
|
|
5839
|
+
}
|
|
5840
|
+
#onPointerMove = (event) => {
|
|
5841
|
+
if (this.#pointerId === void 0 || event.pointerId !== this.#pointerId) return;
|
|
5842
|
+
this.#currentClientX = event.clientX;
|
|
5843
|
+
this.#currentClientY = event.clientY;
|
|
5844
|
+
this.#lastModifiers = {
|
|
5845
|
+
shiftKey: event.shiftKey,
|
|
5846
|
+
ctrlKey: event.ctrlKey,
|
|
5847
|
+
metaKey: event.metaKey
|
|
5848
|
+
};
|
|
5849
|
+
const moved = Math.hypot(event.clientX - this.#startClientX, event.clientY - this.#startClientY);
|
|
5850
|
+
if (!this.#dragging) {
|
|
5851
|
+
if (moved < this.#threshold()) return;
|
|
5852
|
+
this.#dragging = true;
|
|
5853
|
+
try {
|
|
5854
|
+
this.#base = new Set(this.#config.getBaseSelection());
|
|
5855
|
+
} catch {
|
|
5856
|
+
this.#base = /* @__PURE__ */ new Set();
|
|
5857
|
+
}
|
|
5858
|
+
const surface = this.#safeSurface() ?? this.#host;
|
|
5859
|
+
try {
|
|
5860
|
+
if (typeof surface.setPointerCapture === `function`) surface.setPointerCapture(event.pointerId);
|
|
5861
|
+
} catch {}
|
|
5862
|
+
}
|
|
5863
|
+
try {
|
|
5864
|
+
event.preventDefault?.();
|
|
5865
|
+
} catch {}
|
|
5866
|
+
this.#updatePreview();
|
|
5867
|
+
this.#kickAutoScroll();
|
|
5868
|
+
};
|
|
5869
|
+
#surfaceBox() {
|
|
5870
|
+
const surface = this.#safeSurface() ?? this.#host;
|
|
5871
|
+
try {
|
|
5872
|
+
return surface.getBoundingClientRect();
|
|
5873
|
+
} catch {
|
|
5874
|
+
return;
|
|
5875
|
+
}
|
|
5876
|
+
}
|
|
5877
|
+
#currentRect() {
|
|
5878
|
+
const box = this.#surfaceBox();
|
|
5879
|
+
if (!box) return void 0;
|
|
5880
|
+
const cx = Math.min(Math.max(this.#currentClientX - box.left, 0), Math.max(0, box.width));
|
|
5881
|
+
const cy = Math.min(Math.max(this.#currentClientY - box.top, 0), Math.max(0, box.height));
|
|
5882
|
+
return {
|
|
5883
|
+
x: Math.min(this.#startX, cx),
|
|
5884
|
+
y: Math.min(this.#startY, cy),
|
|
5885
|
+
width: Math.abs(cx - this.#startX),
|
|
5886
|
+
height: Math.abs(cy - this.#startY)
|
|
5887
|
+
};
|
|
5888
|
+
}
|
|
5889
|
+
#updatePreview() {
|
|
5890
|
+
const rect = this.#currentRect();
|
|
5891
|
+
if (!rect) return;
|
|
5892
|
+
let hit = [];
|
|
5893
|
+
try {
|
|
5894
|
+
hit = this.#config.hitTest(rect);
|
|
5895
|
+
} catch {
|
|
5896
|
+
hit = [];
|
|
5897
|
+
}
|
|
5898
|
+
const mode = this.#modeFor(this.#lastModifiers);
|
|
5899
|
+
this.#lastMode = mode;
|
|
5900
|
+
const hitSet = new Set(hit);
|
|
5901
|
+
let preview;
|
|
5902
|
+
if (mode === `add`) preview = /* @__PURE__ */ new Set([...this.#base, ...hitSet]);
|
|
5903
|
+
else if (mode === `invert`) {
|
|
5904
|
+
const toggled = new Set(this.#base);
|
|
5905
|
+
for (const item of hitSet) if (toggled.has(item)) toggled.delete(item);
|
|
5906
|
+
else toggled.add(item);
|
|
5907
|
+
preview = toggled;
|
|
5908
|
+
} else preview = hitSet;
|
|
5909
|
+
this.#preview = preview;
|
|
5910
|
+
try {
|
|
5911
|
+
this.#config.onPreview(preview, rect);
|
|
5912
|
+
} catch {}
|
|
5913
|
+
}
|
|
5914
|
+
#onPointerUp = (event) => {
|
|
5915
|
+
if (this.#pointerId === void 0 || event.pointerId !== this.#pointerId) return;
|
|
5916
|
+
this.#lastModifiers = {
|
|
5917
|
+
shiftKey: event.shiftKey,
|
|
5918
|
+
ctrlKey: event.ctrlKey,
|
|
5919
|
+
metaKey: event.metaKey
|
|
5920
|
+
};
|
|
5921
|
+
const wasDragging = this.#dragging;
|
|
5922
|
+
const surface = this.#safeSurface() ?? this.#host;
|
|
5923
|
+
try {
|
|
5924
|
+
if (typeof surface.hasPointerCapture === `function` && typeof surface.releasePointerCapture === `function` && surface.hasPointerCapture(event.pointerId)) surface.releasePointerCapture(event.pointerId);
|
|
5925
|
+
} catch {}
|
|
5926
|
+
this.#stopAutoScroll();
|
|
5927
|
+
this.#pointerId = void 0;
|
|
5928
|
+
if (!wasDragging) {
|
|
5929
|
+
this.#reset();
|
|
5930
|
+
return;
|
|
5931
|
+
}
|
|
5932
|
+
this.#dragging = false;
|
|
5933
|
+
const final = this.#preview;
|
|
5934
|
+
try {
|
|
5935
|
+
this.#config.onCommit(final, { additive: this.#lastMode !== `replace` });
|
|
5936
|
+
} catch {}
|
|
5937
|
+
try {
|
|
5938
|
+
this.#config.onPreview(/* @__PURE__ */ new Set(), void 0);
|
|
5939
|
+
} catch {}
|
|
5940
|
+
this.#preview = /* @__PURE__ */ new Set();
|
|
5941
|
+
this.#suppressClick = true;
|
|
5942
|
+
window.setTimeout(() => {
|
|
5943
|
+
this.#suppressClick = false;
|
|
5944
|
+
}, 0);
|
|
5945
|
+
};
|
|
5946
|
+
#onPointerCancel = (event) => {
|
|
5947
|
+
if (this.#pointerId === void 0 || event.pointerId !== this.#pointerId) return;
|
|
5948
|
+
this.#stopAutoScroll();
|
|
5949
|
+
this.#pointerId = void 0;
|
|
5950
|
+
this.#dragging = false;
|
|
5951
|
+
this.#preview = /* @__PURE__ */ new Set();
|
|
5952
|
+
try {
|
|
5953
|
+
this.#config.onPreview(/* @__PURE__ */ new Set(), void 0);
|
|
5954
|
+
} catch {}
|
|
5955
|
+
this.#suppressClick = false;
|
|
5956
|
+
};
|
|
5957
|
+
#kickAutoScroll() {
|
|
5958
|
+
if (!this.#config.autoScroll || this.#raf !== 0) return;
|
|
5959
|
+
this.#raf = requestAnimationFrame(this.#autoScrollTick);
|
|
5960
|
+
}
|
|
5961
|
+
#autoScrollTick = () => {
|
|
5962
|
+
this.#raf = 0;
|
|
5963
|
+
if (!this.#dragging || this.#pointerId === void 0) return;
|
|
5964
|
+
const box = this.#surfaceBox();
|
|
5965
|
+
if (!box) return;
|
|
5966
|
+
const px = this.#currentClientX - box.left;
|
|
5967
|
+
const py = this.#currentClientY - box.top;
|
|
5968
|
+
let dx = 0;
|
|
5969
|
+
let dy = 0;
|
|
5970
|
+
if (px < EDGE_ZONE) dx = -Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, px) / EDGE_ZONE));
|
|
5971
|
+
else if (px > box.width - EDGE_ZONE) dx = Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, box.width - px) / EDGE_ZONE));
|
|
5972
|
+
if (py < EDGE_ZONE) dy = -Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, py) / EDGE_ZONE));
|
|
5973
|
+
else if (py > box.height - EDGE_ZONE) dy = Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, box.height - py) / EDGE_ZONE));
|
|
5974
|
+
if (dx === 0 && dy === 0) return;
|
|
5975
|
+
const autoScroll = this.#config.autoScroll;
|
|
5976
|
+
if (!autoScroll) return;
|
|
5977
|
+
try {
|
|
5978
|
+
autoScroll(dx, dy);
|
|
5979
|
+
} catch {}
|
|
5980
|
+
this.#updatePreview();
|
|
5981
|
+
this.#raf = requestAnimationFrame(this.#autoScrollTick);
|
|
5982
|
+
};
|
|
5983
|
+
#stopAutoScroll() {
|
|
5984
|
+
if (this.#raf !== 0) {
|
|
5985
|
+
cancelAnimationFrame(this.#raf);
|
|
5986
|
+
this.#raf = 0;
|
|
5987
|
+
}
|
|
5988
|
+
}
|
|
5989
|
+
#reset() {
|
|
5990
|
+
this.#dragging = false;
|
|
5991
|
+
this.#suppressClick = false;
|
|
5992
|
+
this.#base = /* @__PURE__ */ new Set();
|
|
5993
|
+
this.#lastMode = `replace`;
|
|
5994
|
+
this.#preview = /* @__PURE__ */ new Set();
|
|
5995
|
+
}
|
|
5996
|
+
};
|
|
5997
|
+
//#endregion
|
|
4565
5998
|
//#region src/interaction/list-item-animation.ts
|
|
4566
5999
|
/**
|
|
4567
6000
|
* Shared insertion / removal animation for the list & tree components.
|
|
@@ -4800,6 +6233,31 @@ var ListSelectionController = class {
|
|
|
4800
6233
|
this.#anchor = [...next].at(-1);
|
|
4801
6234
|
this.#apply(next);
|
|
4802
6235
|
}
|
|
6236
|
+
/**
|
|
6237
|
+
* Whether a drag / marquee gesture may build a selection in the current
|
|
6238
|
+
* modes: `selectionMode="multiple"`, or a multi interaction mode
|
|
6239
|
+
* (`checked` / `sticky` / `vscode`) outside `selectionMode="none"`.
|
|
6240
|
+
* Stricter than `canSelectMultiple()` — `single` + `standard` does not
|
|
6241
|
+
* qualify (a drag there would be a surprising multi-select).
|
|
6242
|
+
*/
|
|
6243
|
+
canDragSelect() {
|
|
6244
|
+
return this.#config.getModes().selectionMode !== `none` && this.#effectiveMulti();
|
|
6245
|
+
}
|
|
6246
|
+
/**
|
|
6247
|
+
* Replace the selection with `items` from a drag / marquee gesture. Like
|
|
6248
|
+
* `selectMany` but gated on `canDragSelect()` instead of throwing, and a
|
|
6249
|
+
* no-op in single/none modes. Non-selectable items are dropped; the anchor
|
|
6250
|
+
* moves to the last item. Fires `onChange` once. An empty result clears a
|
|
6251
|
+
* non-empty selection (e.g. a Cmd-drag that toggles everything off) but is
|
|
6252
|
+
* a no-op when nothing is selected.
|
|
6253
|
+
*/
|
|
6254
|
+
applyDragSelection(items) {
|
|
6255
|
+
if (!this.canDragSelect()) return;
|
|
6256
|
+
const next = new Set([...items].filter((t) => this.#config.isSelectable(t)));
|
|
6257
|
+
if (next.size === 0 && this.#selected.size === 0) return;
|
|
6258
|
+
this.#anchor = [...next].at(-1);
|
|
6259
|
+
this.#apply(next);
|
|
6260
|
+
}
|
|
4803
6261
|
/** Remove a single item from the selection. */
|
|
4804
6262
|
deselect(item) {
|
|
4805
6263
|
if (!this.#selected.has(item)) return;
|
|
@@ -11892,6 +13350,7 @@ let DataGridElement = class DataGridElement extends i {
|
|
|
11892
13350
|
static {
|
|
11893
13351
|
this.styles = [
|
|
11894
13352
|
themeFallbacks,
|
|
13353
|
+
handleStyles,
|
|
11895
13354
|
tickledStyles,
|
|
11896
13355
|
tickledItemStyles,
|
|
11897
13356
|
listItemFadeKeyframes,
|
|
@@ -11935,7 +13394,8 @@ let DataGridElement = class DataGridElement extends i {
|
|
|
11935
13394
|
.header-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
11936
13395
|
.sort-icon { font-size: 10px; opacity: 0.7; }
|
|
11937
13396
|
.resize-handle { position: absolute; right: 0; top: 0; bottom: 0; width: 8px; cursor: col-resize; z-index: 1; }
|
|
11938
|
-
.reorder-handle { cursor: grab; opacity: 0.5; padding: 0 2px; }
|
|
13397
|
+
.reorder-handle { cursor: grab; opacity: 0.5; padding: 0 2px; display: inline-flex; align-items: center; }
|
|
13398
|
+
.reorder-handle .ixfx-handle { --ixfx-handle-spot-size: 14px; --ixfx-handle-dot-size: 3px; }
|
|
11939
13399
|
.flyout-trigger { flex-shrink: 0; width: 36px; display: flex; align-items: center; justify-content: center; cursor: pointer; border-left: var(--border-subtle); background: var(--data-grid-header-bg); }
|
|
11940
13400
|
.viewport { flex: 1; overflow: auto; position: relative; }
|
|
11941
13401
|
.spacer { position: relative; }
|
|
@@ -12841,7 +14301,7 @@ let DataGridElement = class DataGridElement extends i {
|
|
|
12841
14301
|
@pointerenter=${() => this._tickled.handlePointerEnter(col.key)}>
|
|
12842
14302
|
${col.reorderable !== false ? b`<span class="reorder-handle" draggable="false"
|
|
12843
14303
|
@pointerdown=${(e) => this._beginHeaderDrag(e, col, idx)}
|
|
12844
|
-
|
|
14304
|
+
><span class="ixfx-handle" data-handle="dotted" data-shape="spot" part="reorder-handle"></span></span>` : A}
|
|
12845
14305
|
<span class="header-label">${col.label}</span>
|
|
12846
14306
|
${this.sortState?.key === col.key ? b`<span class="sort-icon">${this.sortState.direction === `asc` ? `▲` : `▼`}</span>` : A}
|
|
12847
14307
|
${col.resizable !== false ? b`<span class="resize-handle" @pointerdown=${(e) => this._onResizePointerDown(e, col)} @click=${(e) => e.stopPropagation()} @dblclick=${(e) => {
|
|
@@ -13429,7 +14889,28 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
13429
14889
|
if (id !== void 0) this._dispatch(`list-tickle`, { item: id });
|
|
13430
14890
|
},
|
|
13431
14891
|
onStateChange: () => this._syncItemStates(),
|
|
13432
|
-
itemWrap: this.itemWrap
|
|
14892
|
+
itemWrap: this.itemWrap,
|
|
14893
|
+
hoverDisabled: () => this.#dragSelect.isDragging
|
|
14894
|
+
});
|
|
14895
|
+
this.#dragSelect = new ListDragSelectController(this, {
|
|
14896
|
+
getSurface: () => this.renderRoot.querySelector(`.container`),
|
|
14897
|
+
isEnabled: () => this.selection.canDragSelect() && this._getVisibleItems().length > 0 && !this.hasAttribute(`disable-drag-select`),
|
|
14898
|
+
hitTest: (rect) => this.#marqueeHitTest(rect),
|
|
14899
|
+
getBaseSelection: () => this.selection.selected,
|
|
14900
|
+
onPreview: (preview, rect) => {
|
|
14901
|
+
this.#marqueeRect = rect;
|
|
14902
|
+
for (const el of this._getVisibleItems()) el.toggleAttribute(`data-marquee`, preview.has(el));
|
|
14903
|
+
this.requestUpdate();
|
|
14904
|
+
},
|
|
14905
|
+
onCommit: (finalSet) => {
|
|
14906
|
+
this.selection.applyDragSelection(finalSet);
|
|
14907
|
+
for (const el of this._getVisibleItems()) el.removeAttribute(`data-marquee`);
|
|
14908
|
+
this.#marqueeRect = void 0;
|
|
14909
|
+
this.requestUpdate();
|
|
14910
|
+
},
|
|
14911
|
+
autoScroll: (dx, _dy) => {
|
|
14912
|
+
if (this._listEl) this._listEl.scrollLeft += dx;
|
|
14913
|
+
}
|
|
13433
14914
|
});
|
|
13434
14915
|
this.search = new ListSearchController(this, { adapter: createElementListSearchAdapter(this, {
|
|
13435
14916
|
itemSelector: ITEM_SELECTOR$3,
|
|
@@ -13506,6 +14987,7 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
13506
14987
|
}
|
|
13507
14988
|
};
|
|
13508
14989
|
this._onClick = (e) => {
|
|
14990
|
+
if (this.#dragSelect.isDragging) return;
|
|
13509
14991
|
const item = this._findListItem(e.composedPath());
|
|
13510
14992
|
if (!item) return;
|
|
13511
14993
|
this.focus();
|
|
@@ -13532,6 +15014,30 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
13532
15014
|
#builtFromProvider;
|
|
13533
15015
|
#providerBuilt;
|
|
13534
15016
|
#data;
|
|
15017
|
+
/** Live drag-select preview rect (surface-relative); the covered items carry `data-marquee`. */
|
|
15018
|
+
#marqueeRect;
|
|
15019
|
+
#dragSelect;
|
|
15020
|
+
/** Collect visible items whose surface-relative box intersects `rect`. */
|
|
15021
|
+
#marqueeHitTest(rect) {
|
|
15022
|
+
const surface = this.renderRoot.querySelector(`.container`);
|
|
15023
|
+
if (!surface) return [];
|
|
15024
|
+
const box = surface.getBoundingClientRect();
|
|
15025
|
+
const rx0 = rect.x;
|
|
15026
|
+
const ry0 = rect.y;
|
|
15027
|
+
const rx1 = rect.x + rect.width;
|
|
15028
|
+
const ry1 = rect.y + rect.height;
|
|
15029
|
+
const out = [];
|
|
15030
|
+
for (const el of this._getVisibleItems()) {
|
|
15031
|
+
const r = el.getBoundingClientRect();
|
|
15032
|
+
const left = r.left - box.left;
|
|
15033
|
+
const top = r.top - box.top;
|
|
15034
|
+
if (left <= rx1 && left + r.width >= rx0 && top <= ry1 && top + r.height >= ry0) out.push(el);
|
|
15035
|
+
}
|
|
15036
|
+
return out;
|
|
15037
|
+
}
|
|
15038
|
+
#marqueeStyle(rect) {
|
|
15039
|
+
return `left:${rect.x}px;top:${rect.y}px;width:${Math.max(0, rect.width)}px;height:${Math.max(0, rect.height)}px`;
|
|
15040
|
+
}
|
|
13535
15041
|
#searchRegistry;
|
|
13536
15042
|
#unregisterSearchCommands;
|
|
13537
15043
|
/** Command registry carrying this list's `list.search.*` commands. */
|
|
@@ -14304,6 +15810,22 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
14304
15810
|
outline-offset: -2px;
|
|
14305
15811
|
}
|
|
14306
15812
|
|
|
15813
|
+
/* Drag-select (marquee) rectangle + covered-row preview.
|
|
15814
|
+
Style hooks: part="marquee", --detail-list-marquee-border,
|
|
15815
|
+
--detail-list-marquee-fill. */
|
|
15816
|
+
.marquee {
|
|
15817
|
+
position: absolute;
|
|
15818
|
+
pointer-events: none;
|
|
15819
|
+
z-index: 5;
|
|
15820
|
+
border: 1px solid var(--detail-list-marquee-border, var(--accent));
|
|
15821
|
+
background: var(--detail-list-marquee-fill, color-mix(in srgb, var(--accent) 15%, transparent));
|
|
15822
|
+
}
|
|
15823
|
+
|
|
15824
|
+
::slotted([data-marquee]) {
|
|
15825
|
+
background: var(--item-bg-selected);
|
|
15826
|
+
color: var(--item-text-selected);
|
|
15827
|
+
}
|
|
15828
|
+
|
|
14307
15829
|
/* checked mode: the injected checkbox communicates selection — suppress bg */
|
|
14308
15830
|
:host([interaction-mode="checked"]) ::slotted([data-selected]) {
|
|
14309
15831
|
background: transparent;
|
|
@@ -14344,6 +15866,7 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
14344
15866
|
<ul part="list" class="scroll-fade-x">
|
|
14345
15867
|
<slot></slot>
|
|
14346
15868
|
</ul>
|
|
15869
|
+
${this.#marqueeRect ? b`<div class="marquee" part="marquee" style=${this.#marqueeStyle(this.#marqueeRect)}></div>` : ``}
|
|
14347
15870
|
<div class="loading" part="loading" ?hidden=${!loading}>
|
|
14348
15871
|
${loading ? progress !== void 0 ? `${Math.round(progress * 100)}%` : `loading…` : A}
|
|
14349
15872
|
</div>
|
|
@@ -15997,16 +17520,20 @@ let SplitLayoutElement = class SplitLayoutElement extends i {
|
|
|
15997
17520
|
style="cursor: ${cursor}; grid-column: ${gridColumn}; grid-row: ${gridRow};"
|
|
15998
17521
|
@pointerdown=${(e) => this._onGutterPointerDown(e, groupId, index)}
|
|
15999
17522
|
>
|
|
16000
|
-
<
|
|
16001
|
-
|
|
16002
|
-
|
|
16003
|
-
|
|
16004
|
-
|
|
17523
|
+
<span
|
|
17524
|
+
class="ixfx-handle"
|
|
17525
|
+
part="grip"
|
|
17526
|
+
data-handle="dimpled"
|
|
17527
|
+
data-shape=${isRow ? `vertical` : `horizontal`}
|
|
17528
|
+
></span>
|
|
16005
17529
|
</div>
|
|
16006
17530
|
`;
|
|
16007
17531
|
}
|
|
16008
17532
|
static {
|
|
16009
|
-
this.styles = [
|
|
17533
|
+
this.styles = [
|
|
17534
|
+
themeFallbacks,
|
|
17535
|
+
handleStyles,
|
|
17536
|
+
i$3`
|
|
16010
17537
|
:host {
|
|
16011
17538
|
display: block;
|
|
16012
17539
|
width: 100%;
|
|
@@ -16017,10 +17544,10 @@ let SplitLayoutElement = class SplitLayoutElement extends i {
|
|
|
16017
17544
|
--split-gutter-active-color: var(--accent);
|
|
16018
17545
|
--split-collapsed-size: 0px;
|
|
16019
17546
|
--split-snap: 24px;
|
|
16020
|
-
|
|
16021
|
-
|
|
16022
|
-
--
|
|
16023
|
-
--
|
|
17547
|
+
|
|
17548
|
+
/* Gutter grip — shared handle primitive (docs/infra-handle.md). */
|
|
17549
|
+
--ixfx-handle-length: 16px;
|
|
17550
|
+
--ixfx-handle-thickness: 8px;
|
|
16024
17551
|
}
|
|
16025
17552
|
|
|
16026
17553
|
* {
|
|
@@ -16082,31 +17609,15 @@ let SplitLayoutElement = class SplitLayoutElement extends i {
|
|
|
16082
17609
|
user-select: none;
|
|
16083
17610
|
}
|
|
16084
17611
|
|
|
16085
|
-
.
|
|
16086
|
-
width: var(--split-grab-dot-size);
|
|
16087
|
-
height: var(--split-grab-dot-size);
|
|
16088
|
-
border-radius: 50%;
|
|
16089
|
-
background: var(--split-grab-color);
|
|
16090
|
-
}
|
|
16091
|
-
|
|
16092
|
-
:host([direction="row"]) .grab-handle {
|
|
16093
|
-
flex-direction: column;
|
|
16094
|
-
gap: var(--split-grab-dot-size);
|
|
16095
|
-
}
|
|
16096
|
-
|
|
16097
|
-
:host([direction="column"]) .grab-handle {
|
|
16098
|
-
flex-direction: row;
|
|
16099
|
-
gap: var(--split-grab-dot-size);
|
|
16100
|
-
}
|
|
16101
|
-
|
|
16102
|
-
:host([data-dragging]) .grab-handle {
|
|
17612
|
+
:host([data-dragging]) .gutter .ixfx-handle {
|
|
16103
17613
|
display: none;
|
|
16104
17614
|
}
|
|
16105
17615
|
|
|
16106
|
-
:host(:not([data-dragging])) .gutter:hover .
|
|
16107
|
-
display:
|
|
17616
|
+
:host(:not([data-dragging])) .gutter:hover .ixfx-handle {
|
|
17617
|
+
display: none;
|
|
16108
17618
|
}
|
|
16109
|
-
`
|
|
17619
|
+
`
|
|
17620
|
+
];
|
|
16110
17621
|
}
|
|
16111
17622
|
};
|
|
16112
17623
|
__decorate([property({
|
|
@@ -17053,404 +18564,6 @@ __decorate([state()], TabListItemElement.prototype, "_compact", void 0);
|
|
|
17053
18564
|
__decorate([state()], TabListItemElement.prototype, "_hasToolbarContent", void 0);
|
|
17054
18565
|
TabListItemElement = __decorate([safeCustomElement(`ixfx-tab-list-item`)], TabListItemElement);
|
|
17055
18566
|
//#endregion
|
|
17056
|
-
//#region src/titlebar/titlebar.ts
|
|
17057
|
-
let TitlebarElement = class TitlebarElement extends i {
|
|
17058
|
-
constructor(..._args) {
|
|
17059
|
-
super(..._args);
|
|
17060
|
-
this.title = ``;
|
|
17061
|
-
this.iconName = ``;
|
|
17062
|
-
this.orientation = `horizontal`;
|
|
17063
|
-
this.variant = `titlebar`;
|
|
17064
|
-
this.closable = false;
|
|
17065
|
-
this.collapsible = false;
|
|
17066
|
-
this.collapsed = false;
|
|
17067
|
-
this.toggleInteraction = `implicit`;
|
|
17068
|
-
}
|
|
17069
|
-
_onToggleClick() {
|
|
17070
|
-
if (!this.collapsible) return;
|
|
17071
|
-
this.collapsed = !this.collapsed;
|
|
17072
|
-
this.dispatchEvent(new CustomEvent(`toggle`, {
|
|
17073
|
-
detail: { collapsed: this.collapsed },
|
|
17074
|
-
bubbles: true,
|
|
17075
|
-
composed: true
|
|
17076
|
-
}));
|
|
17077
|
-
}
|
|
17078
|
-
_onCloseClick() {
|
|
17079
|
-
this.dispatchEvent(new CustomEvent(`close`, {
|
|
17080
|
-
bubbles: true,
|
|
17081
|
-
composed: true
|
|
17082
|
-
}));
|
|
17083
|
-
}
|
|
17084
|
-
_getCaretIcon() {
|
|
17085
|
-
return `chevron-down`;
|
|
17086
|
-
}
|
|
17087
|
-
render() {
|
|
17088
|
-
const caretIcon = this._getCaretIcon();
|
|
17089
|
-
const isVertical = this.orientation === `vertical`;
|
|
17090
|
-
const showCaret = this.collapsible && this.toggleInteraction !== `disabled`;
|
|
17091
|
-
const implicitToggle = this.collapsible && this.toggleInteraction === `implicit`;
|
|
17092
|
-
const caretRotation = isVertical ? this.collapsed ? `` : `-90deg` : this.collapsed ? `-90deg` : ``;
|
|
17093
|
-
const treeVariant = this.variant === `tree`;
|
|
17094
|
-
return b`
|
|
17095
|
-
<div
|
|
17096
|
-
class="bar"
|
|
17097
|
-
role="toolbar"
|
|
17098
|
-
@click=${implicitToggle ? this._onToggleClick : A}
|
|
17099
|
-
>
|
|
17100
|
-
${treeVariant && showCaret ? b`
|
|
17101
|
-
<button
|
|
17102
|
-
class="caret-btn"
|
|
17103
|
-
type="button"
|
|
17104
|
-
aria-label=${this.collapsed ? `Expand panel` : `Collapse panel`}
|
|
17105
|
-
@click=${this._onToggleClick}
|
|
17106
|
-
>
|
|
17107
|
-
<ixfx-icon name=${caretIcon} prominence .rotate=${caretRotation.length > 0 ? caretRotation : A}></ixfx-icon>
|
|
17108
|
-
</button>
|
|
17109
|
-
` : A}
|
|
17110
|
-
<div class="title-text-wrapper">
|
|
17111
|
-
${this.iconName ? b`<ixfx-icon class="title-icon" name=${this.iconName}></ixfx-icon>` : A}
|
|
17112
|
-
<span class="title-text">${this.title}</span>
|
|
17113
|
-
</div>
|
|
17114
|
-
|
|
17115
|
-
<div class="toolbar" @click=${(e) => e.stopPropagation()}>
|
|
17116
|
-
<slot name="toolbar"></slot>
|
|
17117
|
-
${this.closable ? b`
|
|
17118
|
-
<button
|
|
17119
|
-
class="close-btn"
|
|
17120
|
-
type="button"
|
|
17121
|
-
aria-label="Close panel"
|
|
17122
|
-
@click=${this._onCloseClick}
|
|
17123
|
-
>
|
|
17124
|
-
<ixfx-icon name="close"></ixfx-icon>
|
|
17125
|
-
</button>
|
|
17126
|
-
` : A}
|
|
17127
|
-
${!treeVariant && showCaret ? b`
|
|
17128
|
-
<button
|
|
17129
|
-
class="caret-btn"
|
|
17130
|
-
type="button"
|
|
17131
|
-
aria-label=${this.collapsed ? `Expand panel` : `Collapse panel`}
|
|
17132
|
-
@click=${this._onToggleClick}
|
|
17133
|
-
>
|
|
17134
|
-
<ixfx-icon name=${caretIcon} prominence .rotate=${caretRotation.length > 0 ? caretRotation : A}></ixfx-icon>
|
|
17135
|
-
</button>
|
|
17136
|
-
` : A}
|
|
17137
|
-
</div>
|
|
17138
|
-
</div>
|
|
17139
|
-
`;
|
|
17140
|
-
}
|
|
17141
|
-
static {
|
|
17142
|
-
this.styles = [themeFallbacks, i$3`
|
|
17143
|
-
:host {
|
|
17144
|
-
display: block;
|
|
17145
|
-
box-sizing: border-box;
|
|
17146
|
-
}
|
|
17147
|
-
|
|
17148
|
-
.bar {
|
|
17149
|
-
display: flex;
|
|
17150
|
-
flex-direction: row;
|
|
17151
|
-
align-items: center;
|
|
17152
|
-
padding: var(--space-s) var(--space-m);
|
|
17153
|
-
background: var(--surface-4);
|
|
17154
|
-
color: var(--surface-3-text);
|
|
17155
|
-
min-height: 2em;
|
|
17156
|
-
height: 100%;
|
|
17157
|
-
flex-shrink: 0;
|
|
17158
|
-
box-sizing: border-box;
|
|
17159
|
-
}
|
|
17160
|
-
|
|
17161
|
-
:host([orientation="vertical"]) .bar {
|
|
17162
|
-
flex-direction: row;
|
|
17163
|
-
min-width: 2em;
|
|
17164
|
-
writing-mode: vertical-rl;
|
|
17165
|
-
text-orientation: mixed;
|
|
17166
|
-
}
|
|
17167
|
-
|
|
17168
|
-
.caret-btn,
|
|
17169
|
-
.close-btn {
|
|
17170
|
-
display: inline-flex;
|
|
17171
|
-
align-items: center;
|
|
17172
|
-
justify-content: center;
|
|
17173
|
-
background: none;
|
|
17174
|
-
border: none;
|
|
17175
|
-
padding: var(--space-xs);
|
|
17176
|
-
margin: 0;
|
|
17177
|
-
cursor: pointer;
|
|
17178
|
-
color: inherit;
|
|
17179
|
-
border-radius: var(--radius-s);
|
|
17180
|
-
transition: background var(--transition);
|
|
17181
|
-
opacity: var(--prominence-idle-opacity);
|
|
17182
|
-
}
|
|
17183
|
-
|
|
17184
|
-
.caret-btn:hover,
|
|
17185
|
-
.close-btn:hover {
|
|
17186
|
-
background: var(--surface-5);
|
|
17187
|
-
opacity: var(--prominence-tickled-opacity);
|
|
17188
|
-
}
|
|
17189
|
-
|
|
17190
|
-
.caret-btn:focus-visible,
|
|
17191
|
-
.close-btn:focus-visible {
|
|
17192
|
-
outline: 2px solid var(--accent);
|
|
17193
|
-
outline-offset: 1px;
|
|
17194
|
-
}
|
|
17195
|
-
|
|
17196
|
-
ixfx-icon {
|
|
17197
|
-
width: 1.25em;
|
|
17198
|
-
height: 1.25em;
|
|
17199
|
-
transition: transform var(--transition);
|
|
17200
|
-
}
|
|
17201
|
-
|
|
17202
|
-
.title-icon {
|
|
17203
|
-
flex-shrink: 0;
|
|
17204
|
-
}
|
|
17205
|
-
|
|
17206
|
-
.title-text {
|
|
17207
|
-
flex: 1;
|
|
17208
|
-
padding-left: 1ch;
|
|
17209
|
-
font-family: var(--font-family);
|
|
17210
|
-
font-size: var(--text-m);
|
|
17211
|
-
font-weight: var(--font-weight-bold, 600);
|
|
17212
|
-
white-space: nowrap;
|
|
17213
|
-
overflow: hidden;
|
|
17214
|
-
align-self: center;
|
|
17215
|
-
text-overflow: ellipsis;
|
|
17216
|
-
user-select: none;
|
|
17217
|
-
-webkit-user-select: none;
|
|
17218
|
-
}
|
|
17219
|
-
|
|
17220
|
-
:host([collapsible][toggle-interaction="implicit"]) .bar {
|
|
17221
|
-
cursor: pointer;
|
|
17222
|
-
}
|
|
17223
|
-
|
|
17224
|
-
:host([orientation="vertical"]) .title-text {
|
|
17225
|
-
writing-mode: vertical-rl;
|
|
17226
|
-
padding-left: 0;
|
|
17227
|
-
padding-bottom: 1ch;
|
|
17228
|
-
text-orientation: mixed;
|
|
17229
|
-
transform: rotate(180deg);
|
|
17230
|
-
}
|
|
17231
|
-
|
|
17232
|
-
.toolbar {
|
|
17233
|
-
display: flex;
|
|
17234
|
-
align-items: center;
|
|
17235
|
-
gap: var(--space-xs);
|
|
17236
|
-
margin-left: auto;
|
|
17237
|
-
}
|
|
17238
|
-
|
|
17239
|
-
:host([orientation="vertical"]) .toolbar {
|
|
17240
|
-
flex-direction: column;
|
|
17241
|
-
margin-left: 0;
|
|
17242
|
-
margin-top: auto;
|
|
17243
|
-
writing-mode: horizontal-tb;
|
|
17244
|
-
}
|
|
17245
|
-
|
|
17246
|
-
slot[name="toolbar"] {
|
|
17247
|
-
display: contents;
|
|
17248
|
-
}
|
|
17249
|
-
|
|
17250
|
-
::slotted(slot[name="toolbar"]) {
|
|
17251
|
-
display: contents;
|
|
17252
|
-
}
|
|
17253
|
-
|
|
17254
|
-
.title-text-wrapper {
|
|
17255
|
-
display: flex;
|
|
17256
|
-
padding: 0 var(--space-s);
|
|
17257
|
-
}
|
|
17258
|
-
|
|
17259
|
-
/* === Midline variant === */
|
|
17260
|
-
|
|
17261
|
-
:host([variant="midline"]) .bar {
|
|
17262
|
-
background: transparent;
|
|
17263
|
-
padding: var(--space-xs) var(--space-m);
|
|
17264
|
-
min-height: unset;
|
|
17265
|
-
position: relative;
|
|
17266
|
-
}
|
|
17267
|
-
|
|
17268
|
-
:host([variant="midline"][orientation="vertical"]) .bar {
|
|
17269
|
-
padding: var(--space-m) var(--space-xs);
|
|
17270
|
-
min-width: unset;
|
|
17271
|
-
}
|
|
17272
|
-
|
|
17273
|
-
:host([variant="midline"]) .title-text-wrapper {
|
|
17274
|
-
position: relative;
|
|
17275
|
-
z-index: 1;
|
|
17276
|
-
display: flex;
|
|
17277
|
-
align-items: center;
|
|
17278
|
-
gap: var(--space-s);
|
|
17279
|
-
background: var(--surface-3);
|
|
17280
|
-
}
|
|
17281
|
-
|
|
17282
|
-
:host([variant="midline"]) .title-text {
|
|
17283
|
-
font-weight: normal;
|
|
17284
|
-
color: var(--surface-3-text);
|
|
17285
|
-
padding: 0 0.5ch 0 0.5ch;
|
|
17286
|
-
background: transparent;
|
|
17287
|
-
box-shadow: none;
|
|
17288
|
-
flex: unset;
|
|
17289
|
-
width: auto;
|
|
17290
|
-
white-space: nowrap;
|
|
17291
|
-
}
|
|
17292
|
-
|
|
17293
|
-
:host([variant="midline"]) .title-icon {
|
|
17294
|
-
background: transparent;
|
|
17295
|
-
flex-shrink: 0;
|
|
17296
|
-
}
|
|
17297
|
-
|
|
17298
|
-
:host([variant="midline"]) .caret-btn {
|
|
17299
|
-
position: relative;
|
|
17300
|
-
z-index: 1;
|
|
17301
|
-
background: var(--surface-3);
|
|
17302
|
-
opacity: 1;
|
|
17303
|
-
}
|
|
17304
|
-
|
|
17305
|
-
:host([variant="midline"][orientation="vertical"]) .title-text {
|
|
17306
|
-
transform: rotate(180deg);
|
|
17307
|
-
padding: 0.5ch 0 0.5ch 0ch;
|
|
17308
|
-
}
|
|
17309
|
-
|
|
17310
|
-
:host([variant="midline"]) .toolbar {
|
|
17311
|
-
position: relative;
|
|
17312
|
-
z-index: 2;
|
|
17313
|
-
background: var(--surface-3);
|
|
17314
|
-
margin-left: 0;
|
|
17315
|
-
}
|
|
17316
|
-
|
|
17317
|
-
:host([variant="midline"][orientation="horizontal"]) .toolbar {
|
|
17318
|
-
margin-left: auto;
|
|
17319
|
-
}
|
|
17320
|
-
|
|
17321
|
-
/* Debossed line runs from after title-text to before toolbar */
|
|
17322
|
-
:host([variant="midline"]) .bar::after {
|
|
17323
|
-
content: '';
|
|
17324
|
-
position: absolute;
|
|
17325
|
-
top: 50%;
|
|
17326
|
-
left: 0;
|
|
17327
|
-
right: 0;
|
|
17328
|
-
height: 1px;
|
|
17329
|
-
transform: translateY(-50%);
|
|
17330
|
-
background: var(--surface-2);
|
|
17331
|
-
box-shadow:
|
|
17332
|
-
0 -1px 0 var(--surface-5),
|
|
17333
|
-
0 1px 0 var(--surface-1);
|
|
17334
|
-
z-index: 0;
|
|
17335
|
-
}
|
|
17336
|
-
|
|
17337
|
-
/* For vertical midline, line runs vertically */
|
|
17338
|
-
:host([variant="midline"][orientation="vertical"]) .bar::after {
|
|
17339
|
-
top: 0;
|
|
17340
|
-
bottom: 0;
|
|
17341
|
-
left: 50%;
|
|
17342
|
-
right: unset;
|
|
17343
|
-
width: 1px;
|
|
17344
|
-
height: 100%;
|
|
17345
|
-
transform: translateX(-50%);
|
|
17346
|
-
box-shadow:
|
|
17347
|
-
-1px 0 0 var(--surface-5),
|
|
17348
|
-
1px 0 0 var(--surface-1);
|
|
17349
|
-
}
|
|
17350
|
-
|
|
17351
|
-
/* === Tree variant: VS Code explorer / Outline style === */
|
|
17352
|
-
:host([variant="tree"]) .bar {
|
|
17353
|
-
background: transparent;
|
|
17354
|
-
padding: 0 var(--space-xs);
|
|
17355
|
-
min-height: unset;
|
|
17356
|
-
gap: var(--space-xs);
|
|
17357
|
-
}
|
|
17358
|
-
|
|
17359
|
-
:host([variant="tree"][orientation="vertical"]) .bar {
|
|
17360
|
-
padding: var(--space-xs) 0;
|
|
17361
|
-
flex-direction: column;
|
|
17362
|
-
min-width: unset;
|
|
17363
|
-
writing-mode: horizontal-tb;
|
|
17364
|
-
}
|
|
17365
|
-
|
|
17366
|
-
:host([variant="tree"]) .title-text-wrapper {
|
|
17367
|
-
display: inline-flex;
|
|
17368
|
-
align-items: center;
|
|
17369
|
-
gap: var(--space-xs);
|
|
17370
|
-
padding: 0;
|
|
17371
|
-
background: transparent;
|
|
17372
|
-
}
|
|
17373
|
-
|
|
17374
|
-
:host([variant="tree"]) .title-icon {
|
|
17375
|
-
background: transparent;
|
|
17376
|
-
flex-shrink: 0;
|
|
17377
|
-
}
|
|
17378
|
-
|
|
17379
|
-
:host([variant="tree"]) .title-text {
|
|
17380
|
-
font-weight: normal;
|
|
17381
|
-
color: var(--surface-3-text);
|
|
17382
|
-
padding: 0;
|
|
17383
|
-
background: transparent;
|
|
17384
|
-
box-shadow: none;
|
|
17385
|
-
flex: unset;
|
|
17386
|
-
width: auto;
|
|
17387
|
-
white-space: nowrap;
|
|
17388
|
-
}
|
|
17389
|
-
|
|
17390
|
-
:host([variant="tree"][orientation="vertical"]) .title-text {
|
|
17391
|
-
writing-mode: vertical-rl;
|
|
17392
|
-
transform: rotate(180deg);
|
|
17393
|
-
padding: 0;
|
|
17394
|
-
}
|
|
17395
|
-
|
|
17396
|
-
:host([variant="tree"]) .caret-btn {
|
|
17397
|
-
background: transparent;
|
|
17398
|
-
opacity: var(--prominence-idle-opacity);
|
|
17399
|
-
padding: 0;
|
|
17400
|
-
}
|
|
17401
|
-
|
|
17402
|
-
:host([variant="tree"]) .caret-btn:hover {
|
|
17403
|
-
background: transparent;
|
|
17404
|
-
opacity: var(--prominence-tickled-opacity);
|
|
17405
|
-
}
|
|
17406
|
-
|
|
17407
|
-
:host([variant="tree"]) .toolbar {
|
|
17408
|
-
margin-left: auto;
|
|
17409
|
-
}
|
|
17410
|
-
|
|
17411
|
-
:host([variant="tree"][orientation="vertical"]) .toolbar {
|
|
17412
|
-
flex-direction: row;
|
|
17413
|
-
margin-left: 0;
|
|
17414
|
-
margin-top: auto;
|
|
17415
|
-
}
|
|
17416
|
-
|
|
17417
|
-
:host([variant="tree"]) ixfx-icon {
|
|
17418
|
-
width: 1em;
|
|
17419
|
-
height: 1em;
|
|
17420
|
-
}
|
|
17421
|
-
`];
|
|
17422
|
-
}
|
|
17423
|
-
};
|
|
17424
|
-
__decorate([property({ type: String })], TitlebarElement.prototype, "title", void 0);
|
|
17425
|
-
__decorate([property({
|
|
17426
|
-
type: String,
|
|
17427
|
-
attribute: `icon-name`
|
|
17428
|
-
})], TitlebarElement.prototype, "iconName", void 0);
|
|
17429
|
-
__decorate([property({
|
|
17430
|
-
type: String,
|
|
17431
|
-
attribute: `orientation`,
|
|
17432
|
-
reflect: true
|
|
17433
|
-
})], TitlebarElement.prototype, "orientation", void 0);
|
|
17434
|
-
__decorate([property({
|
|
17435
|
-
type: String,
|
|
17436
|
-
attribute: `variant`,
|
|
17437
|
-
reflect: true
|
|
17438
|
-
})], TitlebarElement.prototype, "variant", void 0);
|
|
17439
|
-
__decorate([property({ type: Boolean })], TitlebarElement.prototype, "closable", void 0);
|
|
17440
|
-
__decorate([property({
|
|
17441
|
-
type: Boolean,
|
|
17442
|
-
reflect: true
|
|
17443
|
-
})], TitlebarElement.prototype, "collapsible", void 0);
|
|
17444
|
-
__decorate([property({
|
|
17445
|
-
type: Boolean,
|
|
17446
|
-
reflect: true
|
|
17447
|
-
})], TitlebarElement.prototype, "collapsed", void 0);
|
|
17448
|
-
__decorate([property({
|
|
17449
|
-
type: String,
|
|
17450
|
-
attribute: `toggle-interaction`
|
|
17451
|
-
})], TitlebarElement.prototype, "toggleInteraction", void 0);
|
|
17452
|
-
TitlebarElement = __decorate([safeCustomElement(`ixfx-titlebar`)], TitlebarElement);
|
|
17453
|
-
//#endregion
|
|
17454
18567
|
//#region src/dock/dock-panel.ts
|
|
17455
18568
|
/** Pointer movement threshold before a titlebar press becomes a dock drag. */
|
|
17456
18569
|
const DRAG_THRESHOLD_PX$3 = 5;
|
|
@@ -18690,7 +19803,7 @@ let DockHostElement = class DockHostElement extends i {
|
|
|
18690
19803
|
role="separator"
|
|
18691
19804
|
aria-label="Resize adjacent panels"
|
|
18692
19805
|
@pointerdown=${(e) => this._onJunctionPointerDown(e, junction)}
|
|
18693
|
-
></div>
|
|
19806
|
+
><span class="ixfx-handle" data-handle="dotted" data-shape="spot" part="junction-handle"></span></div>
|
|
18694
19807
|
`)}
|
|
18695
19808
|
</div>
|
|
18696
19809
|
<slot @slotchange=${this._onPoolSlotChange}></slot>
|
|
@@ -18784,7 +19897,10 @@ let DockHostElement = class DockHostElement extends i {
|
|
|
18784
19897
|
};
|
|
18785
19898
|
}
|
|
18786
19899
|
static {
|
|
18787
|
-
this.styles = [
|
|
19900
|
+
this.styles = [
|
|
19901
|
+
themeFallbacks,
|
|
19902
|
+
handleStyles,
|
|
19903
|
+
i$3`
|
|
18788
19904
|
:host {
|
|
18789
19905
|
display: block;
|
|
18790
19906
|
width: 100%;
|
|
@@ -18912,26 +20028,23 @@ let DockHostElement = class DockHostElement extends i {
|
|
|
18912
20028
|
border-radius: 50%;
|
|
18913
20029
|
cursor: nwse-resize;
|
|
18914
20030
|
pointer-events: auto;
|
|
20031
|
+
display: flex;
|
|
20032
|
+
align-items: center;
|
|
20033
|
+
justify-content: center;
|
|
18915
20034
|
}
|
|
18916
20035
|
|
|
18917
|
-
.junction-handle
|
|
18918
|
-
|
|
18919
|
-
|
|
18920
|
-
|
|
18921
|
-
|
|
18922
|
-
background: var(--dock-junction-color, var(--accent));
|
|
18923
|
-
opacity: 0;
|
|
18924
|
-
transition: opacity var(--transition);
|
|
18925
|
-
}
|
|
18926
|
-
|
|
18927
|
-
.junction-handle:hover::after {
|
|
18928
|
-
opacity: 0.9;
|
|
20036
|
+
.junction-handle .ixfx-handle {
|
|
20037
|
+
--ixfx-handle-spot-size: 12px;
|
|
20038
|
+
--ixfx-handle-dot-size: 3px;
|
|
20039
|
+
--ixfx-handle-opacity: 0;
|
|
20040
|
+
--ixfx-handle-opacity-active: 0.9;
|
|
18929
20041
|
}
|
|
18930
20042
|
|
|
18931
20043
|
slot:not([name]) {
|
|
18932
20044
|
display: none;
|
|
18933
20045
|
}
|
|
18934
|
-
`
|
|
20046
|
+
`
|
|
20047
|
+
];
|
|
18935
20048
|
}
|
|
18936
20049
|
};
|
|
18937
20050
|
__decorate([property({
|
|
@@ -20401,6 +21514,233 @@ var DataGridListSource = class {
|
|
|
20401
21514
|
}
|
|
20402
21515
|
};
|
|
20403
21516
|
//#endregion
|
|
21517
|
+
//#region src/pan-text/pan-text.ts
|
|
21518
|
+
const SPEED = 45;
|
|
21519
|
+
const END_PADDING = 4;
|
|
21520
|
+
const START_DELAY = 300;
|
|
21521
|
+
const END_DWELL = 2e3;
|
|
21522
|
+
const RESET_DURATION = 400;
|
|
21523
|
+
const PAN_EASING = `cubic-bezier(0.25, 0.46, 0.45, 0.94)`;
|
|
21524
|
+
let PanTextElement = class PanTextElement extends i {
|
|
21525
|
+
constructor(..._args) {
|
|
21526
|
+
super(..._args);
|
|
21527
|
+
this.direction = `end`;
|
|
21528
|
+
this.disabled = false;
|
|
21529
|
+
this.mode = `hover`;
|
|
21530
|
+
this._isOverflowing = false;
|
|
21531
|
+
this._isHovering = false;
|
|
21532
|
+
this._loopActive = false;
|
|
21533
|
+
this._loopAtEnd = false;
|
|
21534
|
+
this._overflow = 0;
|
|
21535
|
+
this._resizeObserver = null;
|
|
21536
|
+
this._loopTimer = 0;
|
|
21537
|
+
this._onMouseEnter = () => {
|
|
21538
|
+
this._isHovering = true;
|
|
21539
|
+
};
|
|
21540
|
+
this._onMouseLeave = () => {
|
|
21541
|
+
this._isHovering = false;
|
|
21542
|
+
};
|
|
21543
|
+
this._measure = () => {
|
|
21544
|
+
if (this._isHovering || this._loopAtEnd) return;
|
|
21545
|
+
const el = this._textEl;
|
|
21546
|
+
if (!el) return;
|
|
21547
|
+
this._overflow = Math.max(0, el.scrollWidth - el.clientWidth);
|
|
21548
|
+
const overflowing = this._overflow > 0;
|
|
21549
|
+
this.classList.toggle(`is-overflowing`, overflowing);
|
|
21550
|
+
if (overflowing !== this._isOverflowing) this._isOverflowing = overflowing;
|
|
21551
|
+
if (this._loopActive && this.mode === `loop` && !this.disabled && overflowing && this._loopTimer === 0) this._scheduleLoopPan(START_DELAY);
|
|
21552
|
+
if (!overflowing && this._loopAtEnd) {
|
|
21553
|
+
this._loopAtEnd = false;
|
|
21554
|
+
this.requestUpdate();
|
|
21555
|
+
}
|
|
21556
|
+
};
|
|
21557
|
+
}
|
|
21558
|
+
connectedCallback() {
|
|
21559
|
+
super.connectedCallback();
|
|
21560
|
+
this._resizeObserver = new ResizeObserver(() => this._measure());
|
|
21561
|
+
this.addEventListener(`mouseenter`, this._onMouseEnter);
|
|
21562
|
+
this.addEventListener(`mouseleave`, this._onMouseLeave);
|
|
21563
|
+
}
|
|
21564
|
+
disconnectedCallback() {
|
|
21565
|
+
super.disconnectedCallback();
|
|
21566
|
+
this._clearLoopTimer();
|
|
21567
|
+
this._loopActive = false;
|
|
21568
|
+
this._loopAtEnd = false;
|
|
21569
|
+
this._resizeObserver?.disconnect();
|
|
21570
|
+
this._resizeObserver = null;
|
|
21571
|
+
this.removeEventListener(`mouseenter`, this._onMouseEnter);
|
|
21572
|
+
this.removeEventListener(`mouseleave`, this._onMouseLeave);
|
|
21573
|
+
}
|
|
21574
|
+
firstUpdated() {
|
|
21575
|
+
this._measure();
|
|
21576
|
+
this._resizeObserver?.observe(this);
|
|
21577
|
+
document.fonts?.ready.then(() => this._measure());
|
|
21578
|
+
if (this.mode === `loop`) this.startLoop();
|
|
21579
|
+
}
|
|
21580
|
+
updated(changed) {
|
|
21581
|
+
if (changed.has(`mode`)) {
|
|
21582
|
+
if (this.mode === `loop`) this.startLoop();
|
|
21583
|
+
else this.stopLoop();
|
|
21584
|
+
}
|
|
21585
|
+
if (changed.has(`disabled`) && this.disabled) this.stopLoop();
|
|
21586
|
+
this._measure();
|
|
21587
|
+
}
|
|
21588
|
+
/**
|
|
21589
|
+
* Whether a loop pan is currently active (between `startLoop()` and `stopLoop()`).
|
|
21590
|
+
*/
|
|
21591
|
+
get looping() {
|
|
21592
|
+
return this._loopActive;
|
|
21593
|
+
}
|
|
21594
|
+
/**
|
|
21595
|
+
* Begin looping: pan to the end, dwell there for 2 seconds, reset to the
|
|
21596
|
+
* start and pan again, repeating until `stopLoop()` is called. A no-op when
|
|
21597
|
+
* `disabled`, when there is nothing to reveal, or under reduced-motion.
|
|
21598
|
+
*/
|
|
21599
|
+
startLoop() {
|
|
21600
|
+
if (this.disabled || this._prefersReducedMotion()) return;
|
|
21601
|
+
this._loopActive = true;
|
|
21602
|
+
this._loopAtEnd = false;
|
|
21603
|
+
this.requestUpdate();
|
|
21604
|
+
if (this._isOverflowing && this._loopTimer === 0) this._scheduleLoopPan(START_DELAY);
|
|
21605
|
+
}
|
|
21606
|
+
/**
|
|
21607
|
+
* Stop a loop started with `startLoop()` and snap back to the rest position.
|
|
21608
|
+
*/
|
|
21609
|
+
stopLoop() {
|
|
21610
|
+
if (!this._loopActive && !this._loopAtEnd && this._loopTimer === 0) return;
|
|
21611
|
+
this._clearLoopTimer();
|
|
21612
|
+
this._loopActive = false;
|
|
21613
|
+
this._loopAtEnd = false;
|
|
21614
|
+
this.requestUpdate();
|
|
21615
|
+
}
|
|
21616
|
+
_prefersReducedMotion() {
|
|
21617
|
+
return globalThis.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches ?? false;
|
|
21618
|
+
}
|
|
21619
|
+
_panDuration() {
|
|
21620
|
+
return Math.max(1.5, (this._overflow + END_PADDING) / SPEED);
|
|
21621
|
+
}
|
|
21622
|
+
_clearLoopTimer() {
|
|
21623
|
+
if (this._loopTimer !== 0) {
|
|
21624
|
+
clearTimeout(this._loopTimer);
|
|
21625
|
+
this._loopTimer = 0;
|
|
21626
|
+
}
|
|
21627
|
+
}
|
|
21628
|
+
_scheduleLoopPan(delay) {
|
|
21629
|
+
this._clearLoopTimer();
|
|
21630
|
+
this._loopTimer = window.setTimeout(() => {
|
|
21631
|
+
this._loopTimer = 0;
|
|
21632
|
+
if (!this._loopActive || this.disabled || !this._isOverflowing) return;
|
|
21633
|
+
this._loopAtEnd = true;
|
|
21634
|
+
this.requestUpdate();
|
|
21635
|
+
const dwell = this._panDuration() * 1e3 + END_DWELL;
|
|
21636
|
+
this._loopTimer = window.setTimeout(() => {
|
|
21637
|
+
this._loopTimer = 0;
|
|
21638
|
+
if (!this._loopActive) return;
|
|
21639
|
+
this._loopAtEnd = false;
|
|
21640
|
+
this.requestUpdate();
|
|
21641
|
+
this._scheduleLoopPan(700);
|
|
21642
|
+
}, dwell);
|
|
21643
|
+
}, delay);
|
|
21644
|
+
}
|
|
21645
|
+
_textStyle() {
|
|
21646
|
+
if (!this._isOverflowing) return ``;
|
|
21647
|
+
const distance = this._overflow + END_PADDING;
|
|
21648
|
+
const duration = Math.max(1.5, distance / SPEED);
|
|
21649
|
+
const revealEnd = this.direction === `end`;
|
|
21650
|
+
const restX = revealEnd ? 0 : -distance;
|
|
21651
|
+
const hoverX = revealEnd ? -distance : 0;
|
|
21652
|
+
if (this._loopActive && this.mode === `loop`) {
|
|
21653
|
+
if (this._loopAtEnd) return [
|
|
21654
|
+
`transform: translateX(${hoverX}px)`,
|
|
21655
|
+
`transition: transform ${duration}s ${PAN_EASING}`,
|
|
21656
|
+
`overflow: visible`,
|
|
21657
|
+
`text-overflow: clip`
|
|
21658
|
+
].join(`; `);
|
|
21659
|
+
return [
|
|
21660
|
+
`transform: translateX(${restX}px)`,
|
|
21661
|
+
`transition: transform ${RESET_DURATION}ms ${PAN_EASING}`,
|
|
21662
|
+
revealEnd ? `` : `overflow: visible; text-overflow: clip`
|
|
21663
|
+
].filter(Boolean).join(`; `);
|
|
21664
|
+
}
|
|
21665
|
+
if (this._isHovering) return [
|
|
21666
|
+
`transform: translateX(${hoverX}px)`,
|
|
21667
|
+
`transition: transform ${duration}s ${PAN_EASING} ${START_DELAY}ms`,
|
|
21668
|
+
`overflow: visible`,
|
|
21669
|
+
`text-overflow: clip`
|
|
21670
|
+
].join(`; `);
|
|
21671
|
+
return [
|
|
21672
|
+
`transform: translateX(${restX}px)`,
|
|
21673
|
+
`transition: transform 400ms ${PAN_EASING}`,
|
|
21674
|
+
revealEnd ? `` : `overflow: visible; text-overflow: clip`
|
|
21675
|
+
].filter(Boolean).join(`; `);
|
|
21676
|
+
}
|
|
21677
|
+
render() {
|
|
21678
|
+
const textClasses = {
|
|
21679
|
+
"is-overflowing": this._isOverflowing,
|
|
21680
|
+
"is-hovering": this._isHovering
|
|
21681
|
+
};
|
|
21682
|
+
return b`
|
|
21683
|
+
<span class="text ${classMap(textClasses)}" part="text" style=${this._textStyle()}>
|
|
21684
|
+
<slot @slotchange=${this._measure}></slot>
|
|
21685
|
+
</span>
|
|
21686
|
+
`;
|
|
21687
|
+
}
|
|
21688
|
+
static {
|
|
21689
|
+
this.styles = [themeFallbacks, i$3`
|
|
21690
|
+
/* Renders like plain inline text: no colours, border, padding or margin
|
|
21691
|
+
of its own — it only adds the clipping needed to pan on hover. */
|
|
21692
|
+
:host {
|
|
21693
|
+
display: inline-block;
|
|
21694
|
+
overflow: hidden;
|
|
21695
|
+
white-space: nowrap;
|
|
21696
|
+
max-width: 100%;
|
|
21697
|
+
box-sizing: border-box;
|
|
21698
|
+
font: inherit;
|
|
21699
|
+
color: inherit;
|
|
21700
|
+
}
|
|
21701
|
+
|
|
21702
|
+
:host([disabled]) {
|
|
21703
|
+
opacity: var(--disabled-opacity, 0.5);
|
|
21704
|
+
pointer-events: none;
|
|
21705
|
+
}
|
|
21706
|
+
|
|
21707
|
+
.text {
|
|
21708
|
+
display: block;
|
|
21709
|
+
overflow: hidden;
|
|
21710
|
+
text-overflow: ellipsis;
|
|
21711
|
+
white-space: nowrap;
|
|
21712
|
+
will-change: transform;
|
|
21713
|
+
}
|
|
21714
|
+
|
|
21715
|
+
@media (prefers-reduced-motion: reduce) {
|
|
21716
|
+
.text {
|
|
21717
|
+
transition: none !important;
|
|
21718
|
+
transform: none !important;
|
|
21719
|
+
}
|
|
21720
|
+
}
|
|
21721
|
+
`];
|
|
21722
|
+
}
|
|
21723
|
+
};
|
|
21724
|
+
__decorate([property({
|
|
21725
|
+
type: String,
|
|
21726
|
+
attribute: `direction`
|
|
21727
|
+
})], PanTextElement.prototype, "direction", void 0);
|
|
21728
|
+
__decorate([property({
|
|
21729
|
+
type: Boolean,
|
|
21730
|
+
attribute: `disabled`
|
|
21731
|
+
})], PanTextElement.prototype, "disabled", void 0);
|
|
21732
|
+
__decorate([property({
|
|
21733
|
+
type: String,
|
|
21734
|
+
attribute: `mode`,
|
|
21735
|
+
reflect: true
|
|
21736
|
+
})], PanTextElement.prototype, "mode", void 0);
|
|
21737
|
+
__decorate([state()], PanTextElement.prototype, "_isOverflowing", void 0);
|
|
21738
|
+
__decorate([state()], PanTextElement.prototype, "_isHovering", void 0);
|
|
21739
|
+
__decorate([state()], PanTextElement.prototype, "_loopActive", void 0);
|
|
21740
|
+
__decorate([state()], PanTextElement.prototype, "_loopAtEnd", void 0);
|
|
21741
|
+
__decorate([query(`.text`)], PanTextElement.prototype, "_textEl", void 0);
|
|
21742
|
+
PanTextElement = __decorate([safeCustomElement(`ixfx-pan-text`)], PanTextElement);
|
|
21743
|
+
//#endregion
|
|
20404
21744
|
//#region src/grid-list/grid-list.ts
|
|
20405
21745
|
const ITEM_SELECTOR$1 = `:scope > *`;
|
|
20406
21746
|
const MIN_ITEM_SIZE = 16;
|
|
@@ -20496,6 +21836,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
20496
21836
|
this.captionBackdrop = `scrim`;
|
|
20497
21837
|
this.captionHeight = 24;
|
|
20498
21838
|
this.itemWrap = `stop`;
|
|
21839
|
+
this.itemsDraggable = false;
|
|
20499
21840
|
this.items = [];
|
|
20500
21841
|
this._scrollTop = 0;
|
|
20501
21842
|
this._scrollLeft = 0;
|
|
@@ -20532,11 +21873,56 @@ let GridListElement = class GridListElement extends i {
|
|
|
20532
21873
|
enabled: this.#source.isSelectable(i)
|
|
20533
21874
|
})),
|
|
20534
21875
|
onTickle: (k) => {
|
|
21876
|
+
this.#stopActiveCaptionPan();
|
|
20535
21877
|
if (k !== void 0) this.#emitItemEvent(`list-tickle`, k);
|
|
20536
21878
|
},
|
|
20537
21879
|
onStateChange: () => this._syncItemStates(),
|
|
20538
21880
|
itemWrap: this.#itemWrap,
|
|
20539
|
-
hoverDisabled: () => this.disableHoverTickle
|
|
21881
|
+
hoverDisabled: () => this.disableHoverTickle || this.#dragSelect.isDragging
|
|
21882
|
+
});
|
|
21883
|
+
this.#marqueePreview = /* @__PURE__ */ new Set();
|
|
21884
|
+
this.#nativeDragging = false;
|
|
21885
|
+
this.#dragOriginKey = void 0;
|
|
21886
|
+
this.#postDragSuppressTimer = 0;
|
|
21887
|
+
this.#activeCaptionPan = null;
|
|
21888
|
+
this.#dragSelect = new ListDragSelectController(this, {
|
|
21889
|
+
getSurface: () => this.#viewportRef.value,
|
|
21890
|
+
isEnabled: () => this.selection.canDragSelect() && this.#source.count > 0 && !this.hasAttribute(`disable-drag-select`),
|
|
21891
|
+
hitTest: (rect) => this.#marqueeHitTest(rect),
|
|
21892
|
+
getBaseSelection: () => this.selection.selected,
|
|
21893
|
+
onPreview: (preview, rect) => {
|
|
21894
|
+
this.#marqueePreview = preview;
|
|
21895
|
+
this.#marqueeRect = rect;
|
|
21896
|
+
this.requestUpdate();
|
|
21897
|
+
},
|
|
21898
|
+
onCommit: (finalSet) => {
|
|
21899
|
+
this.selection.applyDragSelection(finalSet);
|
|
21900
|
+
this.#marqueePreview = /* @__PURE__ */ new Set();
|
|
21901
|
+
this.#marqueeRect = void 0;
|
|
21902
|
+
this.requestUpdate();
|
|
21903
|
+
},
|
|
21904
|
+
autoScroll: (dx, dy) => {
|
|
21905
|
+
const vp = this.#viewportRef.value;
|
|
21906
|
+
if (!vp) return;
|
|
21907
|
+
if (dx !== 0) {
|
|
21908
|
+
vp.scrollLeft += dx;
|
|
21909
|
+
this._scrollLeft = vp.scrollLeft;
|
|
21910
|
+
}
|
|
21911
|
+
if (dy !== 0) {
|
|
21912
|
+
vp.scrollTop += dy;
|
|
21913
|
+
this._scrollTop = vp.scrollTop;
|
|
21914
|
+
}
|
|
21915
|
+
},
|
|
21916
|
+
shouldStart: (event) => {
|
|
21917
|
+
if (!this.itemsDraggable) return true;
|
|
21918
|
+
const cell = event.composedPath()[0]?.closest?.(`.cell`);
|
|
21919
|
+
if (!cell) return true;
|
|
21920
|
+
const key = cell.dataset.key;
|
|
21921
|
+
if (!key) return true;
|
|
21922
|
+
const index = this.#source.indexOfKey(key);
|
|
21923
|
+
if (index < 0) return true;
|
|
21924
|
+
return !this.#source.isSelectable(index);
|
|
21925
|
+
}
|
|
20540
21926
|
});
|
|
20541
21927
|
this.#selectedSnapshot = /* @__PURE__ */ new Set();
|
|
20542
21928
|
this.#onScroll = (e) => {
|
|
@@ -20549,6 +21935,32 @@ let GridListElement = class GridListElement extends i {
|
|
|
20549
21935
|
this.#emitViewportChange();
|
|
20550
21936
|
});
|
|
20551
21937
|
};
|
|
21938
|
+
this.#onDragStart = (e, key) => {
|
|
21939
|
+
if (!this.itemsDraggable) return;
|
|
21940
|
+
const index = this.#source.indexOfKey(key);
|
|
21941
|
+
if (index < 0 || !this.#source.isSelectable(index)) return;
|
|
21942
|
+
if (!this.selection.selectedKeys.has(key)) this.selection.replace(key);
|
|
21943
|
+
const selectedKeys = this.#source.keys().filter((k) => !isSyntheticKey(k)).filter((k) => this.selection.selectedKeys.has(k));
|
|
21944
|
+
const detail = {
|
|
21945
|
+
key,
|
|
21946
|
+
index: this.#source.indexOfKey(key),
|
|
21947
|
+
item: this.#source.resolveKeyToData(key) ?? this.#source.resolveKeyToElement(key),
|
|
21948
|
+
selectedKeys
|
|
21949
|
+
};
|
|
21950
|
+
if (!this._dispatch(`grid-list-native-drag-start`, detail, true)) {
|
|
21951
|
+
e.preventDefault();
|
|
21952
|
+
return;
|
|
21953
|
+
}
|
|
21954
|
+
this.#nativeDragging = true;
|
|
21955
|
+
this.#dragOriginKey = key;
|
|
21956
|
+
this.toggleAttribute(`data-native-dragging`, true);
|
|
21957
|
+
const count = selectedKeys.length;
|
|
21958
|
+
this.setAttribute(`aria-label`, count === 1 ? `Dragging 1 item` : `Dragging ${count} items`);
|
|
21959
|
+
};
|
|
21960
|
+
this.#onDragEnd = () => {
|
|
21961
|
+
this.#clearNativeDragState();
|
|
21962
|
+
this.#startPostDragSuppressTimer();
|
|
21963
|
+
};
|
|
20552
21964
|
this._onKeyDown = (e) => {
|
|
20553
21965
|
if ((e.ctrlKey || e.metaKey) && e.key === `f`) return;
|
|
20554
21966
|
if ((e.ctrlKey || e.metaKey) && e.key === `a`) {
|
|
@@ -20618,6 +22030,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
20618
22030
|
break;
|
|
20619
22031
|
}
|
|
20620
22032
|
case `Escape`:
|
|
22033
|
+
if (this.#nativeDragging) this.#clearNativeDragState();
|
|
20621
22034
|
this.selection.clear();
|
|
20622
22035
|
break;
|
|
20623
22036
|
default: return;
|
|
@@ -20719,6 +22132,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
20719
22132
|
align-items: center;
|
|
20720
22133
|
justify-content: center;
|
|
20721
22134
|
overflow: hidden;
|
|
22135
|
+
draggable: false;
|
|
20722
22136
|
}
|
|
20723
22137
|
.thumb ::slotted(*:empty)::after {
|
|
20724
22138
|
content: "Empty";
|
|
@@ -20768,6 +22182,18 @@ let GridListElement = class GridListElement extends i {
|
|
|
20768
22182
|
}
|
|
20769
22183
|
:host([caption-align="left"]) .caption { text-align: left; }
|
|
20770
22184
|
:host([caption-align="right"]) .caption { text-align: right; }
|
|
22185
|
+
/* Tickled captions swap their plain label for an ixfx-pan-text in loop
|
|
22186
|
+
mode so a truncated label scrolls instead of staying an ellipsis. The
|
|
22187
|
+
pan fills the caption band (flex in 'separate', block otherwise) and
|
|
22188
|
+
inherits its alignment. */
|
|
22189
|
+
.caption ixfx-pan-text {
|
|
22190
|
+
display: block;
|
|
22191
|
+
flex: 1;
|
|
22192
|
+
min-width: 0;
|
|
22193
|
+
max-width: 100%;
|
|
22194
|
+
font: inherit;
|
|
22195
|
+
color: inherit;
|
|
22196
|
+
}
|
|
20771
22197
|
|
|
20772
22198
|
/* ---- Box modes (hidden / under / overlaid): the cell is one box with a
|
|
20773
22199
|
single selection outline ---- */
|
|
@@ -20911,6 +22337,26 @@ let GridListElement = class GridListElement extends i {
|
|
|
20911
22337
|
:host([reflowing]) .cell { transition: background var(--transition), border-color var(--transition); }
|
|
20912
22338
|
.cell.entering { animation: none; }
|
|
20913
22339
|
}
|
|
22340
|
+
|
|
22341
|
+
/* Drag-select (marquee) rectangle + covered-cell preview. The preview
|
|
22342
|
+
reuses the selection wash so covered cells read as "about to be
|
|
22343
|
+
selected". Style hooks: part="marquee", --grid-list-marquee-border,
|
|
22344
|
+
--grid-list-marquee-fill. */
|
|
22345
|
+
.marquee {
|
|
22346
|
+
position: absolute;
|
|
22347
|
+
pointer-events: none;
|
|
22348
|
+
z-index: 5;
|
|
22349
|
+
border: 1px solid var(--grid-list-marquee-border, var(--accent));
|
|
22350
|
+
background: var(--grid-list-marquee-fill, color-mix(in srgb, var(--accent) 15%, transparent));
|
|
22351
|
+
}
|
|
22352
|
+
.cell.marquee .thumb::after {
|
|
22353
|
+
opacity: var(--grid-list-thumb-selection-wash-opacity, 0.18);
|
|
22354
|
+
}
|
|
22355
|
+
|
|
22356
|
+
/* Native item drag origin cell. */
|
|
22357
|
+
.cell.dragging-origin {
|
|
22358
|
+
opacity: 0.6;
|
|
22359
|
+
}
|
|
20914
22360
|
`
|
|
20915
22361
|
];
|
|
20916
22362
|
}
|
|
@@ -20943,6 +22389,62 @@ let GridListElement = class GridListElement extends i {
|
|
|
20943
22389
|
*/
|
|
20944
22390
|
#sourceElement;
|
|
20945
22391
|
#source;
|
|
22392
|
+
/** Live drag-select preview: covered keys + the surface-relative rect. */
|
|
22393
|
+
#marqueePreview;
|
|
22394
|
+
#marqueeRect;
|
|
22395
|
+
/** Native item drag state: true while a drag is active. */
|
|
22396
|
+
#nativeDragging;
|
|
22397
|
+
/** Key of the cell that originated the native drag. */
|
|
22398
|
+
#dragOriginKey;
|
|
22399
|
+
/** Timer handle for post-drag click suppression. */
|
|
22400
|
+
#postDragSuppressTimer;
|
|
22401
|
+
/**
|
|
22402
|
+
* The single caption pan-text currently scrolling. At most one caption is
|
|
22403
|
+
* a pan-text in loop mode at a time — when tickle moves, the old one is
|
|
22404
|
+
* stopped before the new one starts (see `#activateTickledPan`).
|
|
22405
|
+
*/
|
|
22406
|
+
#activeCaptionPan;
|
|
22407
|
+
#dragSelect;
|
|
22408
|
+
/**
|
|
22409
|
+
* Map a surface-relative (viewport-visible) rect to covered item keys using
|
|
22410
|
+
* the same `computeGridWindow` geometry the renderer uses — pure arithmetic,
|
|
22411
|
+
* so virtualized off-screen items are covered without DOM measurement.
|
|
22412
|
+
*/
|
|
22413
|
+
#marqueeHitTest(rect) {
|
|
22414
|
+
const count = this.#source.count;
|
|
22415
|
+
if (count === 0) return [];
|
|
22416
|
+
const horizontal = this.orientation === `row`;
|
|
22417
|
+
const win = computeGridWindow(count, this.itemSize, this.#rowHeight(), this.gap, Math.max(1, this._viewportWidth), Math.max(1, this._viewportHeight), horizontal ? this._scrollLeft : this._scrollTop, this.orientation, 0);
|
|
22418
|
+
const out = [];
|
|
22419
|
+
if (horizontal) {
|
|
22420
|
+
const x0 = rect.x + this._scrollLeft;
|
|
22421
|
+
const x1 = x0 + rect.width;
|
|
22422
|
+
const lo = Math.max(0, Math.floor(x0 / win.colStride));
|
|
22423
|
+
const hi = Math.min(count - 1, Math.floor(x1 / win.colStride));
|
|
22424
|
+
for (let i = lo; i <= hi; i++) out.push(i);
|
|
22425
|
+
} else {
|
|
22426
|
+
const x0 = rect.x + this._scrollLeft;
|
|
22427
|
+
const x1 = x0 + rect.width;
|
|
22428
|
+
const y0 = rect.y + this._scrollTop;
|
|
22429
|
+
const y1 = y0 + rect.height;
|
|
22430
|
+
const colLo = Math.max(0, Math.floor(x0 / win.colStride));
|
|
22431
|
+
const colHi = Math.min(win.cols - 1, Math.floor(x1 / win.colStride));
|
|
22432
|
+
const rowLo = Math.max(0, Math.floor(y0 / win.rowStride));
|
|
22433
|
+
const rowHi = Math.floor(y1 / win.rowStride);
|
|
22434
|
+
for (let row = rowLo; row <= rowHi; row++) for (let col = colLo; col <= colHi; col++) {
|
|
22435
|
+
const index = row * win.cols + col;
|
|
22436
|
+
if (index >= 0 && index < count) out.push(index);
|
|
22437
|
+
}
|
|
22438
|
+
}
|
|
22439
|
+
const keys = [];
|
|
22440
|
+
for (const index of out) {
|
|
22441
|
+
const key = this.#source.keyAt(index);
|
|
22442
|
+
if (!key || isSyntheticKey(key)) continue;
|
|
22443
|
+
if (!this.#source.isSelectable(index)) continue;
|
|
22444
|
+
keys.push(key);
|
|
22445
|
+
}
|
|
22446
|
+
return keys;
|
|
22447
|
+
}
|
|
20946
22448
|
#searchMode;
|
|
20947
22449
|
#searchFilterKeys;
|
|
20948
22450
|
/** (Re)build {@link search} for the current mode; a no-op if it already matches. */
|
|
@@ -21015,6 +22517,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
21015
22517
|
}
|
|
21016
22518
|
disconnectedCallback() {
|
|
21017
22519
|
super.disconnectedCallback();
|
|
22520
|
+
this.#stopActiveCaptionPan();
|
|
21018
22521
|
this.removeEventListener(`keydown`, this._onKeyDown);
|
|
21019
22522
|
this.#resizeObserver?.disconnect();
|
|
21020
22523
|
this.#resizeObserver = void 0;
|
|
@@ -21027,6 +22530,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
21027
22530
|
clearTimeout(this.#reflowTimer);
|
|
21028
22531
|
this.#reflowTimer = 0;
|
|
21029
22532
|
}
|
|
22533
|
+
if (this.#nativeDragging) this.#clearNativeDragState();
|
|
21030
22534
|
}
|
|
21031
22535
|
#onChildrenChanged(records) {
|
|
21032
22536
|
const previousLength = this.#items.length;
|
|
@@ -21214,6 +22718,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
21214
22718
|
if (Math.abs(vp.scrollLeft - this._scrollLeft) > .5) vp.scrollLeft = this._scrollLeft;
|
|
21215
22719
|
}
|
|
21216
22720
|
this.#applyZoomAnchor();
|
|
22721
|
+
this.#activateTickledPan();
|
|
21217
22722
|
}
|
|
21218
22723
|
/** Re-anchor the scroll so the item captured in `willUpdate` stays centred. */
|
|
21219
22724
|
#applyZoomAnchor() {
|
|
@@ -21544,15 +23049,19 @@ let GridListElement = class GridListElement extends i {
|
|
|
21544
23049
|
element
|
|
21545
23050
|
});
|
|
21546
23051
|
}
|
|
21547
|
-
_dispatch(name, detail) {
|
|
21548
|
-
this.dispatchEvent(new CustomEvent(name, {
|
|
23052
|
+
_dispatch(name, detail, cancelable = false) {
|
|
23053
|
+
return this.dispatchEvent(new CustomEvent(name, {
|
|
21549
23054
|
detail,
|
|
21550
23055
|
bubbles: true,
|
|
21551
|
-
composed: true
|
|
23056
|
+
composed: true,
|
|
23057
|
+
cancelable
|
|
21552
23058
|
}));
|
|
21553
23059
|
}
|
|
21554
23060
|
/** Selected keys, snapshotted once per render so the cell renderers don't each rebuild the set. */
|
|
21555
23061
|
#selectedSnapshot;
|
|
23062
|
+
#marqueeStyle(rect) {
|
|
23063
|
+
return `left:${rect.x}px;top:${rect.y}px;width:${Math.max(0, rect.width)}px;height:${Math.max(0, rect.height)}px`;
|
|
23064
|
+
}
|
|
21556
23065
|
render() {
|
|
21557
23066
|
const win = this.#currentWindow();
|
|
21558
23067
|
this.#selectedSnapshot = this.selection.selectedKeys;
|
|
@@ -21569,6 +23078,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
21569
23078
|
<div class="spacer" style=${spacerStyle}>
|
|
21570
23079
|
${this.#source instanceof DataGridListSource ? this.#renderDataCells(win) : this.#renderElementCells(win)}
|
|
21571
23080
|
</div>
|
|
23081
|
+
${this.#marqueeRect ? b`<div class="marquee" part="marquee" style=${this.#marqueeStyle(this.#marqueeRect)}></div>` : ``}
|
|
21572
23082
|
</div>
|
|
21573
23083
|
${this.search?.renderField()}
|
|
21574
23084
|
`;
|
|
@@ -21580,7 +23090,10 @@ let GridListElement = class GridListElement extends i {
|
|
|
21580
23090
|
#renderDataCell(index, win) {
|
|
21581
23091
|
const key = this.#source.keyAt(index);
|
|
21582
23092
|
const selected = this.#selectedSnapshot.has(key);
|
|
23093
|
+
const marquee = this.#marqueePreview.has(key);
|
|
21583
23094
|
const tickled = this.tickled.isTickled(key);
|
|
23095
|
+
const selectable = this.#source.isSelectable(index);
|
|
23096
|
+
const draggable = this.itemsDraggable && selectable;
|
|
21584
23097
|
const style = this.captionStyle;
|
|
21585
23098
|
const separate = style === `separate`;
|
|
21586
23099
|
const caption = style === `hidden` ? `` : this.#source.labelAt(index);
|
|
@@ -21591,24 +23104,69 @@ let GridListElement = class GridListElement extends i {
|
|
|
21591
23104
|
const captionCss = separate ? `height:${Math.max(0, this.captionHeight - 4)}px` : style === `under` ? `height:${this.captionHeight}px` : ``;
|
|
21592
23105
|
return b`
|
|
21593
23106
|
<div
|
|
21594
|
-
class="cell${selected ? ` selected` : ``}${tickled ? ` tickled` : ``}"
|
|
23107
|
+
class="cell${selected ? ` selected` : ``}${tickled ? ` tickled` : ``}${marquee ? ` marquee` : ``}${this.#nativeDragging && key === this.#dragOriginKey ? ` dragging-origin` : ``}"
|
|
21595
23108
|
part="item${selected ? ` selected` : ``}${tickled ? ` tickled` : ``}"
|
|
21596
23109
|
role="option"
|
|
21597
23110
|
aria-selected=${selected ? `true` : `false`}
|
|
21598
23111
|
style="width:${this.itemSize}px;height:${cellHeight}px;transform:translate(${x}px,${y}px)"
|
|
21599
23112
|
data-index=${index}
|
|
21600
23113
|
data-key=${key}
|
|
23114
|
+
draggable=${draggable ? `true` : `false`}
|
|
21601
23115
|
?data-selected=${selected}
|
|
21602
23116
|
?data-tickled=${tickled}
|
|
23117
|
+
?data-marquee=${marquee}
|
|
21603
23118
|
@click=${(e) => this.#onCellClick(e, key)}
|
|
21604
23119
|
@dblclick=${() => this.#onCellActivate(key)}
|
|
21605
23120
|
@pointerenter=${() => this.tickled.handlePointerEnter(key)}
|
|
23121
|
+
@dragstart=${(e) => this.#onDragStart(e, key)}
|
|
23122
|
+
@dragend=${() => this.#onDragEnd()}
|
|
21606
23123
|
>
|
|
21607
23124
|
<div class="content" part="content">${this.#source.renderCellContent(index)}</div>
|
|
21608
|
-
${showCaption ?
|
|
23125
|
+
${showCaption ? this.#renderCaption(caption, captionCss, tickled) : ``}
|
|
21609
23126
|
</div>
|
|
21610
23127
|
`;
|
|
21611
23128
|
}
|
|
23129
|
+
/**
|
|
23130
|
+
* A tickled cell swaps its plain label for an `ixfx-pan-text` in loop mode
|
|
23131
|
+
* so a truncated label scrolls instead of staying an ellipsis. Unticked
|
|
23132
|
+
* cells keep the cheap plain-text caption.
|
|
23133
|
+
*/
|
|
23134
|
+
#renderCaption(caption, captionCss, tickled) {
|
|
23135
|
+
if (tickled) return b`<div class="caption" part="caption" style=${captionCss} title=${caption}><ixfx-pan-text mode="loop">${caption}</ixfx-pan-text></div>`;
|
|
23136
|
+
return b`<div class="caption" part="caption" style=${captionCss} title=${caption}>${caption}</div>`;
|
|
23137
|
+
}
|
|
23138
|
+
/** Stop the active caption pan, if any, and forget it. */
|
|
23139
|
+
#stopActiveCaptionPan() {
|
|
23140
|
+
const active = this.#activeCaptionPan;
|
|
23141
|
+
this.#activeCaptionPan = null;
|
|
23142
|
+
try {
|
|
23143
|
+
active?.stopLoop?.();
|
|
23144
|
+
} catch {}
|
|
23145
|
+
}
|
|
23146
|
+
/**
|
|
23147
|
+
* Enforce a single scrolling caption: the tickled cell's pan-text loops,
|
|
23148
|
+
* every other pan-text is stopped. The pan-text also auto-starts when
|
|
23149
|
+
* `mode="loop"` is set; this covers the case where the element was already
|
|
23150
|
+
* connected before overflow was measured.
|
|
23151
|
+
*/
|
|
23152
|
+
#activateTickledPan() {
|
|
23153
|
+
const tickledCell = this.renderRoot.querySelector(`.cell[data-tickled]`);
|
|
23154
|
+
const pans = [...this.renderRoot.querySelectorAll(`ixfx-pan-text[mode="loop"]`)];
|
|
23155
|
+
const current = tickledCell?.querySelector(`ixfx-pan-text[mode="loop"]`) ?? null;
|
|
23156
|
+
for (const pan of pans) if (pan !== current) try {
|
|
23157
|
+
pan.stopLoop?.();
|
|
23158
|
+
} catch {}
|
|
23159
|
+
const active = this.#activeCaptionPan;
|
|
23160
|
+
if (active && active !== current) try {
|
|
23161
|
+
active.stopLoop?.();
|
|
23162
|
+
} catch {}
|
|
23163
|
+
if (!current) {
|
|
23164
|
+
this.#activeCaptionPan = null;
|
|
23165
|
+
return;
|
|
23166
|
+
}
|
|
23167
|
+
this.#activeCaptionPan = current;
|
|
23168
|
+
current.startLoop?.();
|
|
23169
|
+
}
|
|
21612
23170
|
#renderElementCells(win) {
|
|
21613
23171
|
const slice = this.#items.slice(win.startIndex, win.endIndex);
|
|
21614
23172
|
return repeat(slice, (_el, i) => this.#source.keyAt(win.startIndex + i), (el, i) => this.#renderCell(el, win.startIndex + i, win));
|
|
@@ -21616,8 +23174,11 @@ let GridListElement = class GridListElement extends i {
|
|
|
21616
23174
|
#renderCell(el, index, win) {
|
|
21617
23175
|
const key = this.#source.keyAt(index);
|
|
21618
23176
|
const selected = this.#selectedSnapshot.has(key);
|
|
23177
|
+
const marquee = this.#marqueePreview.has(key);
|
|
21619
23178
|
const tickled = this.tickled.isTickled(key);
|
|
21620
23179
|
const entering = this.#entering.has(el);
|
|
23180
|
+
const selectable = this.#source.isSelectable(index);
|
|
23181
|
+
const draggable = this.itemsDraggable && selectable;
|
|
21621
23182
|
const style = this.captionStyle;
|
|
21622
23183
|
const separate = style === `separate`;
|
|
21623
23184
|
const caption = style === `hidden` ? `` : this.#captionFor(el);
|
|
@@ -21629,23 +23190,27 @@ let GridListElement = class GridListElement extends i {
|
|
|
21629
23190
|
const captionCss = separate ? `height:${Math.max(0, this.captionHeight - 4)}px` : style === `under` ? `height:${this.captionHeight}px` : ``;
|
|
21630
23191
|
return b`
|
|
21631
23192
|
<div
|
|
21632
|
-
class="cell${selected ? ` selected` : ``}${tickled ? ` tickled` : ``}${entering ? ` entering` : ``}"
|
|
23193
|
+
class="cell${selected ? ` selected` : ``}${tickled ? ` tickled` : ``}${entering ? ` entering` : ``}${marquee ? ` marquee` : ``}${this.#nativeDragging && key === this.#dragOriginKey ? ` dragging-origin` : ``}"
|
|
21633
23194
|
part="item${selected ? ` selected` : ``}${tickled ? ` tickled` : ``}"
|
|
21634
23195
|
role="option"
|
|
21635
23196
|
aria-selected=${selected ? `true` : `false`}
|
|
21636
23197
|
style="width:${this.itemSize}px;height:${cellHeight}px;transform:translate(${x}px,${y}px)"
|
|
21637
23198
|
data-index=${index}
|
|
21638
23199
|
data-key=${key}
|
|
23200
|
+
draggable=${draggable ? `true` : `false`}
|
|
21639
23201
|
?data-selected=${selected}
|
|
21640
23202
|
?data-tickled=${tickled}
|
|
23203
|
+
?data-marquee=${marquee}
|
|
21641
23204
|
@click=${(e) => this.#onCellClick(e, key)}
|
|
21642
23205
|
@dblclick=${() => this.#onCellActivate(key)}
|
|
21643
23206
|
@pointerenter=${() => this.tickled.handlePointerEnter(key)}
|
|
23207
|
+
@dragstart=${(e) => this.#onDragStart(e, key)}
|
|
23208
|
+
@dragend=${() => this.#onDragEnd()}
|
|
21644
23209
|
>
|
|
21645
23210
|
<div class="thumb" part="thumb" style=${thumbStyle}>
|
|
21646
23211
|
${this.#source.renderCellContent(index)}
|
|
21647
23212
|
</div>
|
|
21648
|
-
${showCaption ?
|
|
23213
|
+
${showCaption ? this.#renderCaption(caption, captionCss, tickled) : ``}
|
|
21649
23214
|
</div>
|
|
21650
23215
|
`;
|
|
21651
23216
|
}
|
|
@@ -21657,9 +23222,24 @@ let GridListElement = class GridListElement extends i {
|
|
|
21657
23222
|
}
|
|
21658
23223
|
}
|
|
21659
23224
|
#onCellClick(e, key) {
|
|
23225
|
+
if (this.#dragSelect.isDragging || this.#nativeDragging || this.#postDragSuppressTimer !== 0) return;
|
|
21660
23226
|
this.selection.handleClick(key, e);
|
|
21661
23227
|
this.#emitItemEvent(`list-item-click`, key);
|
|
21662
23228
|
}
|
|
23229
|
+
#onDragStart;
|
|
23230
|
+
#onDragEnd;
|
|
23231
|
+
#startPostDragSuppressTimer() {
|
|
23232
|
+
if (this.#postDragSuppressTimer) clearTimeout(this.#postDragSuppressTimer);
|
|
23233
|
+
this.#postDragSuppressTimer = window.setTimeout(() => {
|
|
23234
|
+
this.#postDragSuppressTimer = 0;
|
|
23235
|
+
}, 0);
|
|
23236
|
+
}
|
|
23237
|
+
#clearNativeDragState() {
|
|
23238
|
+
this.#nativeDragging = false;
|
|
23239
|
+
this.#dragOriginKey = void 0;
|
|
23240
|
+
this.toggleAttribute(`data-native-dragging`, false);
|
|
23241
|
+
this.removeAttribute(`aria-label`);
|
|
23242
|
+
}
|
|
21663
23243
|
#onCellActivate(key) {
|
|
21664
23244
|
if (this.interactionMode !== `manual`) this.selection.replace(key);
|
|
21665
23245
|
this.#emitItemEvent(`list-activate`, key);
|
|
@@ -21717,6 +23297,11 @@ __decorate([property({
|
|
|
21717
23297
|
})], GridListElement.prototype, "itemWrap", void 0);
|
|
21718
23298
|
__decorate([property({ attribute: false })], GridListElement.prototype, "filterPredicate", void 0);
|
|
21719
23299
|
__decorate([property({ attribute: false })], GridListElement.prototype, "itemFilterPredicate", void 0);
|
|
23300
|
+
__decorate([property({
|
|
23301
|
+
type: Boolean,
|
|
23302
|
+
attribute: `items-draggable`,
|
|
23303
|
+
reflect: true
|
|
23304
|
+
})], GridListElement.prototype, "itemsDraggable", void 0);
|
|
21720
23305
|
__decorate([property({
|
|
21721
23306
|
type: String,
|
|
21722
23307
|
attribute: `search-modes`,
|
|
@@ -23603,7 +25188,29 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
23603
25188
|
if (id !== void 0) this._dispatch(`list-tickle`, { item: id });
|
|
23604
25189
|
},
|
|
23605
25190
|
onStateChange: () => this._syncItemStates(),
|
|
23606
|
-
itemWrap: this.itemWrap
|
|
25191
|
+
itemWrap: this.itemWrap,
|
|
25192
|
+
hoverDisabled: () => this.#dragSelect.isDragging
|
|
25193
|
+
});
|
|
25194
|
+
this.#dragSelect = new ListDragSelectController(this, {
|
|
25195
|
+
getSurface: () => this.renderRoot.querySelector(`.container`),
|
|
25196
|
+
isEnabled: () => this.selection.canDragSelect() && this._getVisibleItems().length > 0 && !this.hasAttribute(`disable-drag-select`),
|
|
25197
|
+
hitTest: (rect) => this.#marqueeHitTest(rect),
|
|
25198
|
+
getBaseSelection: () => this.selection.selected,
|
|
25199
|
+
onPreview: (preview, rect) => {
|
|
25200
|
+
this.#marqueeRect = rect;
|
|
25201
|
+
for (const el of this._getVisibleItems()) el.toggleAttribute(`data-marquee`, preview.has(el));
|
|
25202
|
+
this.requestUpdate();
|
|
25203
|
+
},
|
|
25204
|
+
onCommit: (finalSet) => {
|
|
25205
|
+
this.selection.applyDragSelection(finalSet);
|
|
25206
|
+
for (const el of this._getVisibleItems()) el.removeAttribute(`data-marquee`);
|
|
25207
|
+
this.#marqueeRect = void 0;
|
|
25208
|
+
this.requestUpdate();
|
|
25209
|
+
},
|
|
25210
|
+
autoScroll: (_dx, dy) => {
|
|
25211
|
+
const list = this.renderRoot.querySelector(`ul`);
|
|
25212
|
+
if (list) list.scrollTop += dy;
|
|
25213
|
+
}
|
|
23607
25214
|
});
|
|
23608
25215
|
this.search = new ListSearchController(this, { adapter: createElementListSearchAdapter(this, {
|
|
23609
25216
|
itemSelector: ITEM_SELECTOR,
|
|
@@ -23664,6 +25271,7 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
23664
25271
|
}
|
|
23665
25272
|
};
|
|
23666
25273
|
this._onClick = (e) => {
|
|
25274
|
+
if (this.#dragSelect.isDragging) return;
|
|
23667
25275
|
const item = this._findListItem(e.composedPath());
|
|
23668
25276
|
if (!item) return;
|
|
23669
25277
|
this._dispatch(`list-item-click`, { item });
|
|
@@ -23680,6 +25288,30 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
23680
25288
|
#itemObserver;
|
|
23681
25289
|
/** Items that have already played (or been skipped for) their enter animation. */
|
|
23682
25290
|
#animatedItems;
|
|
25291
|
+
/** Live drag-select preview rect (surface-relative); the covered items carry `data-marquee`. */
|
|
25292
|
+
#marqueeRect;
|
|
25293
|
+
#dragSelect;
|
|
25294
|
+
/** Collect visible items whose surface-relative box intersects `rect`. */
|
|
25295
|
+
#marqueeHitTest(rect) {
|
|
25296
|
+
const surface = this.renderRoot.querySelector(`.container`);
|
|
25297
|
+
if (!surface) return [];
|
|
25298
|
+
const box = surface.getBoundingClientRect();
|
|
25299
|
+
const rx0 = rect.x;
|
|
25300
|
+
const ry0 = rect.y;
|
|
25301
|
+
const rx1 = rect.x + rect.width;
|
|
25302
|
+
const ry1 = rect.y + rect.height;
|
|
25303
|
+
const out = [];
|
|
25304
|
+
for (const el of this._getVisibleItems()) {
|
|
25305
|
+
const r = el.getBoundingClientRect();
|
|
25306
|
+
const left = r.left - box.left;
|
|
25307
|
+
const top = r.top - box.top;
|
|
25308
|
+
if (left <= rx1 && left + r.width >= rx0 && top <= ry1 && top + r.height >= ry0) out.push(el);
|
|
25309
|
+
}
|
|
25310
|
+
return out;
|
|
25311
|
+
}
|
|
25312
|
+
#marqueeStyle(rect) {
|
|
25313
|
+
return `left:${rect.x}px;top:${rect.y}px;width:${Math.max(0, rect.width)}px;height:${Math.max(0, rect.height)}px`;
|
|
25314
|
+
}
|
|
23683
25315
|
#searchRegistry;
|
|
23684
25316
|
#unregisterSearchCommands;
|
|
23685
25317
|
/** Command registry carrying this list's `list.search.*` commands. */
|
|
@@ -24150,6 +25782,22 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
24150
25782
|
outline-offset: -2px;
|
|
24151
25783
|
}
|
|
24152
25784
|
|
|
25785
|
+
/* Drag-select (marquee) rectangle + covered-row preview.
|
|
25786
|
+
Style hooks: part="marquee", --vertical-list-marquee-border,
|
|
25787
|
+
--vertical-list-marquee-fill. */
|
|
25788
|
+
.marquee {
|
|
25789
|
+
position: absolute;
|
|
25790
|
+
pointer-events: none;
|
|
25791
|
+
z-index: 5;
|
|
25792
|
+
border: 1px solid var(--vertical-list-marquee-border, var(--accent));
|
|
25793
|
+
background: var(--vertical-list-marquee-fill, color-mix(in srgb, var(--accent) 15%, transparent));
|
|
25794
|
+
}
|
|
25795
|
+
|
|
25796
|
+
::slotted([data-marquee]) {
|
|
25797
|
+
background: var(--item-bg-selected);
|
|
25798
|
+
color: var(--item-text-selected);
|
|
25799
|
+
}
|
|
25800
|
+
|
|
24153
25801
|
/* checked mode: checkbox (injected into li) communicates selection — suppress bg highlight */
|
|
24154
25802
|
:host([interaction-mode="checked"]) ::slotted([data-selected]) {
|
|
24155
25803
|
background: transparent;
|
|
@@ -24171,6 +25819,7 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
24171
25819
|
<ul part="list">
|
|
24172
25820
|
<slot></slot>
|
|
24173
25821
|
</ul>
|
|
25822
|
+
${this.#marqueeRect ? b`<div class="marquee" part="marquee" style=${this.#marqueeStyle(this.#marqueeRect)}></div>` : ``}
|
|
24174
25823
|
${this.search.renderField()}
|
|
24175
25824
|
</div>
|
|
24176
25825
|
`;
|
|
@@ -30864,136 +32513,6 @@ function dismiss(id) {
|
|
|
30864
32513
|
syncRenderer();
|
|
30865
32514
|
}
|
|
30866
32515
|
//#endregion
|
|
30867
|
-
//#region src/pan-text/pan-text.ts
|
|
30868
|
-
const SPEED = 45;
|
|
30869
|
-
const END_PADDING = 4;
|
|
30870
|
-
const START_DELAY = 300;
|
|
30871
|
-
const PAN_EASING = `cubic-bezier(0.25, 0.46, 0.45, 0.94)`;
|
|
30872
|
-
let PanTextElement = class PanTextElement extends i {
|
|
30873
|
-
constructor(..._args) {
|
|
30874
|
-
super(..._args);
|
|
30875
|
-
this.direction = `end`;
|
|
30876
|
-
this.disabled = false;
|
|
30877
|
-
this._isOverflowing = false;
|
|
30878
|
-
this._isHovering = false;
|
|
30879
|
-
this._overflow = 0;
|
|
30880
|
-
this._resizeObserver = null;
|
|
30881
|
-
this._onMouseEnter = () => {
|
|
30882
|
-
this._isHovering = true;
|
|
30883
|
-
};
|
|
30884
|
-
this._onMouseLeave = () => {
|
|
30885
|
-
this._isHovering = false;
|
|
30886
|
-
};
|
|
30887
|
-
this._measure = () => {
|
|
30888
|
-
if (this._isHovering) return;
|
|
30889
|
-
const el = this._textEl;
|
|
30890
|
-
if (!el) return;
|
|
30891
|
-
this._overflow = Math.max(0, el.scrollWidth - el.clientWidth);
|
|
30892
|
-
const overflowing = this._overflow > 0;
|
|
30893
|
-
this.classList.toggle(`is-overflowing`, overflowing);
|
|
30894
|
-
if (overflowing !== this._isOverflowing) this._isOverflowing = overflowing;
|
|
30895
|
-
};
|
|
30896
|
-
}
|
|
30897
|
-
connectedCallback() {
|
|
30898
|
-
super.connectedCallback();
|
|
30899
|
-
this._resizeObserver = new ResizeObserver(() => this._measure());
|
|
30900
|
-
this.addEventListener(`mouseenter`, this._onMouseEnter);
|
|
30901
|
-
this.addEventListener(`mouseleave`, this._onMouseLeave);
|
|
30902
|
-
}
|
|
30903
|
-
disconnectedCallback() {
|
|
30904
|
-
super.disconnectedCallback();
|
|
30905
|
-
this._resizeObserver?.disconnect();
|
|
30906
|
-
this._resizeObserver = null;
|
|
30907
|
-
this.removeEventListener(`mouseenter`, this._onMouseEnter);
|
|
30908
|
-
this.removeEventListener(`mouseleave`, this._onMouseLeave);
|
|
30909
|
-
}
|
|
30910
|
-
firstUpdated() {
|
|
30911
|
-
this._measure();
|
|
30912
|
-
this._resizeObserver?.observe(this);
|
|
30913
|
-
document.fonts?.ready.then(() => this._measure());
|
|
30914
|
-
}
|
|
30915
|
-
updated() {
|
|
30916
|
-
this._measure();
|
|
30917
|
-
}
|
|
30918
|
-
_textStyle() {
|
|
30919
|
-
if (!this._isOverflowing) return ``;
|
|
30920
|
-
const distance = this._overflow + END_PADDING;
|
|
30921
|
-
const duration = Math.max(1.5, distance / SPEED);
|
|
30922
|
-
const revealEnd = this.direction === `end`;
|
|
30923
|
-
const restX = revealEnd ? 0 : -distance;
|
|
30924
|
-
const hoverX = revealEnd ? -distance : 0;
|
|
30925
|
-
if (this._isHovering) return [
|
|
30926
|
-
`transform: translateX(${hoverX}px)`,
|
|
30927
|
-
`transition: transform ${duration}s ${PAN_EASING} ${START_DELAY}ms`,
|
|
30928
|
-
`overflow: visible`,
|
|
30929
|
-
`text-overflow: clip`
|
|
30930
|
-
].join(`; `);
|
|
30931
|
-
return [
|
|
30932
|
-
`transform: translateX(${restX}px)`,
|
|
30933
|
-
`transition: transform 400ms ${PAN_EASING}`,
|
|
30934
|
-
revealEnd ? `` : `overflow: visible; text-overflow: clip`
|
|
30935
|
-
].filter(Boolean).join(`; `);
|
|
30936
|
-
}
|
|
30937
|
-
render() {
|
|
30938
|
-
const textClasses = {
|
|
30939
|
-
"is-overflowing": this._isOverflowing,
|
|
30940
|
-
"is-hovering": this._isHovering
|
|
30941
|
-
};
|
|
30942
|
-
return b`
|
|
30943
|
-
<span class="text ${classMap(textClasses)}" part="text" style=${this._textStyle()}>
|
|
30944
|
-
<slot @slotchange=${this._measure}></slot>
|
|
30945
|
-
</span>
|
|
30946
|
-
`;
|
|
30947
|
-
}
|
|
30948
|
-
static {
|
|
30949
|
-
this.styles = [themeFallbacks, i$3`
|
|
30950
|
-
/* Renders like plain inline text: no colours, border, padding or margin
|
|
30951
|
-
of its own — it only adds the clipping needed to pan on hover. */
|
|
30952
|
-
:host {
|
|
30953
|
-
display: inline-block;
|
|
30954
|
-
overflow: hidden;
|
|
30955
|
-
white-space: nowrap;
|
|
30956
|
-
max-width: 100%;
|
|
30957
|
-
box-sizing: border-box;
|
|
30958
|
-
font: inherit;
|
|
30959
|
-
color: inherit;
|
|
30960
|
-
}
|
|
30961
|
-
|
|
30962
|
-
:host([disabled]) {
|
|
30963
|
-
opacity: var(--disabled-opacity, 0.5);
|
|
30964
|
-
pointer-events: none;
|
|
30965
|
-
}
|
|
30966
|
-
|
|
30967
|
-
.text {
|
|
30968
|
-
display: block;
|
|
30969
|
-
overflow: hidden;
|
|
30970
|
-
text-overflow: ellipsis;
|
|
30971
|
-
white-space: nowrap;
|
|
30972
|
-
will-change: transform;
|
|
30973
|
-
}
|
|
30974
|
-
|
|
30975
|
-
@media (prefers-reduced-motion: reduce) {
|
|
30976
|
-
.text {
|
|
30977
|
-
transition: none !important;
|
|
30978
|
-
transform: none !important;
|
|
30979
|
-
}
|
|
30980
|
-
}
|
|
30981
|
-
`];
|
|
30982
|
-
}
|
|
30983
|
-
};
|
|
30984
|
-
__decorate([property({
|
|
30985
|
-
type: String,
|
|
30986
|
-
attribute: `direction`
|
|
30987
|
-
})], PanTextElement.prototype, "direction", void 0);
|
|
30988
|
-
__decorate([property({
|
|
30989
|
-
type: Boolean,
|
|
30990
|
-
attribute: `disabled`
|
|
30991
|
-
})], PanTextElement.prototype, "disabled", void 0);
|
|
30992
|
-
__decorate([state()], PanTextElement.prototype, "_isOverflowing", void 0);
|
|
30993
|
-
__decorate([state()], PanTextElement.prototype, "_isHovering", void 0);
|
|
30994
|
-
__decorate([query(`.text`)], PanTextElement.prototype, "_textEl", void 0);
|
|
30995
|
-
PanTextElement = __decorate([safeCustomElement(`ixfx-pan-text`)], PanTextElement);
|
|
30996
|
-
//#endregion
|
|
30997
32516
|
//#region src/panel/panel-group.ts
|
|
30998
32517
|
/** Pointer movement threshold (px) before a press becomes a drag. */
|
|
30999
32518
|
const DRAG_THRESHOLD_PX = 5;
|
|
@@ -38230,7 +39749,10 @@ let TimelineTrackTabElement = class TimelineTrackTabElement extends i {
|
|
|
38230
39749
|
};
|
|
38231
39750
|
}
|
|
38232
39751
|
static {
|
|
38233
|
-
this.styles =
|
|
39752
|
+
this.styles = [
|
|
39753
|
+
themeFallbacks,
|
|
39754
|
+
handleStyles,
|
|
39755
|
+
i$3`
|
|
38234
39756
|
:host {
|
|
38235
39757
|
display: flex;
|
|
38236
39758
|
align-items: center;
|
|
@@ -38257,13 +39779,13 @@ let TimelineTrackTabElement = class TimelineTrackTabElement extends i {
|
|
|
38257
39779
|
.handle {
|
|
38258
39780
|
display: none;
|
|
38259
39781
|
cursor: grab;
|
|
38260
|
-
|
|
38261
|
-
|
|
38262
|
-
|
|
39782
|
+
margin: 0 4px;
|
|
39783
|
+
--ixfx-handle-spot-size: 12px;
|
|
39784
|
+
--ixfx-handle-dot-size: 3px;
|
|
38263
39785
|
}
|
|
38264
39786
|
|
|
38265
39787
|
:host([reorderable]) .handle {
|
|
38266
|
-
display: block;
|
|
39788
|
+
display: inline-block;
|
|
38267
39789
|
}
|
|
38268
39790
|
|
|
38269
39791
|
.label {
|
|
@@ -38272,7 +39794,8 @@ let TimelineTrackTabElement = class TimelineTrackTabElement extends i {
|
|
|
38272
39794
|
text-overflow: ellipsis;
|
|
38273
39795
|
padding: 0 8px;
|
|
38274
39796
|
}
|
|
38275
|
-
|
|
39797
|
+
`
|
|
39798
|
+
];
|
|
38276
39799
|
}
|
|
38277
39800
|
#dragging;
|
|
38278
39801
|
#startScreenY;
|
|
@@ -38297,7 +39820,7 @@ let TimelineTrackTabElement = class TimelineTrackTabElement extends i {
|
|
|
38297
39820
|
}
|
|
38298
39821
|
render() {
|
|
38299
39822
|
return b`
|
|
38300
|
-
<span class="handle"
|
|
39823
|
+
<span class="handle ixfx-handle" data-handle="dotted" data-shape="spot" part="handle"></span>
|
|
38301
39824
|
<span class="label">${this.label}</span>
|
|
38302
39825
|
`;
|
|
38303
39826
|
}
|
|
@@ -40174,29 +41697,29 @@ let TwoSplitLayoutElement = class TwoSplitLayoutElement extends i {
|
|
|
40174
41697
|
<slot style=${sizeA} name="a"></slot>
|
|
40175
41698
|
${this._hasCorner ? b`<div class="corner-zone" @pointerdown=${this.#onCornerResizeDown}></div>` : ``}
|
|
40176
41699
|
<div @pointerdown=${this.#onResizeHandleDown} class="split-bar">
|
|
40177
|
-
${this.showGrabHandle ? b
|
|
40178
|
-
|
|
40179
|
-
|
|
40180
|
-
|
|
40181
|
-
|
|
40182
|
-
|
|
40183
|
-
` : ``}
|
|
41700
|
+
${this.showGrabHandle ? b`<span
|
|
41701
|
+
class="ixfx-handle"
|
|
41702
|
+
part="grip"
|
|
41703
|
+
data-handle="dimpled"
|
|
41704
|
+
data-shape=${this.layout === `horizontal` ? `horizontal` : `vertical`}
|
|
41705
|
+
></span>` : ``}
|
|
40184
41706
|
</div>
|
|
40185
41707
|
<slot style=${sizeB} name="b"></slot>
|
|
40186
41708
|
</div>`;
|
|
40187
41709
|
}
|
|
40188
41710
|
static {
|
|
40189
|
-
this.styles = [
|
|
41711
|
+
this.styles = [
|
|
41712
|
+
themeFallbacks,
|
|
41713
|
+
handleStyles,
|
|
41714
|
+
i$3`
|
|
40190
41715
|
:host {
|
|
40191
41716
|
--handle-size: 2px;
|
|
40192
41717
|
--handle-colour: transparent;
|
|
40193
41718
|
--handle-hover-colour: var(--surface-6);
|
|
40194
41719
|
--handle-active-colour: var(--accent);
|
|
40195
|
-
|
|
40196
|
-
--handle-
|
|
40197
|
-
--handle-
|
|
40198
|
-
--handle-grab-size: 16px;
|
|
40199
|
-
--handle-grab-thickness: 8px;
|
|
41720
|
+
/* Grip — shared handle primitive (docs/infra-handle.md). */
|
|
41721
|
+
--ixfx-handle-length: 16px;
|
|
41722
|
+
--ixfx-handle-thickness: 8px;
|
|
40200
41723
|
|
|
40201
41724
|
display: block;
|
|
40202
41725
|
box-sizing: border-box;
|
|
@@ -40239,40 +41762,14 @@ let TwoSplitLayoutElement = class TwoSplitLayoutElement extends i {
|
|
|
40239
41762
|
to { background-color: var(--handle-hover-colour); }
|
|
40240
41763
|
}
|
|
40241
41764
|
|
|
40242
|
-
.
|
|
41765
|
+
.split-bar .ixfx-handle {
|
|
40243
41766
|
position: absolute;
|
|
40244
41767
|
top: 50%;
|
|
40245
41768
|
left: 50%;
|
|
40246
41769
|
transform: translate(-50%, -50%);
|
|
40247
|
-
display: flex;
|
|
40248
|
-
align-items: center;
|
|
40249
|
-
justify-content: center;
|
|
40250
|
-
gap: var(--handle-grab-dot-size);
|
|
40251
|
-
background: var(--handle-bg);
|
|
40252
|
-
border-radius: var(--radius-s);
|
|
40253
41770
|
}
|
|
40254
41771
|
|
|
40255
|
-
.
|
|
40256
|
-
width: var(--handle-grab-dot-size);
|
|
40257
|
-
height: var(--handle-grab-dot-size);
|
|
40258
|
-
border-radius: 50%;
|
|
40259
|
-
background: var(--handle-grab-colour);
|
|
40260
|
-
flex-shrink: 0;
|
|
40261
|
-
}
|
|
40262
|
-
|
|
40263
|
-
:host([layout="vertical"]) .grab-handle {
|
|
40264
|
-
flex-direction: column;
|
|
40265
|
-
width: var(--handle-grab-thickness);
|
|
40266
|
-
height: var(--handle-grab-size);
|
|
40267
|
-
}
|
|
40268
|
-
|
|
40269
|
-
:host([layout="horizontal"]) .grab-handle {
|
|
40270
|
-
flex-direction: row;
|
|
40271
|
-
width: var(--handle-grab-size);
|
|
40272
|
-
height: var(--handle-grab-thickness);
|
|
40273
|
-
}
|
|
40274
|
-
|
|
40275
|
-
#zone.user-resizing .grab-handle {
|
|
41772
|
+
#zone.user-resizing .ixfx-handle {
|
|
40276
41773
|
display: none;
|
|
40277
41774
|
}
|
|
40278
41775
|
#zone.user-resizing {
|
|
@@ -40325,7 +41822,8 @@ let TwoSplitLayoutElement = class TwoSplitLayoutElement extends i {
|
|
|
40325
41822
|
:host([data-collapsed-b]) slot[name="b"] {
|
|
40326
41823
|
display: none;
|
|
40327
41824
|
}
|
|
40328
|
-
`
|
|
41825
|
+
`
|
|
41826
|
+
];
|
|
40329
41827
|
}
|
|
40330
41828
|
};
|
|
40331
41829
|
__decorate([property({ type: String })], TwoSplitLayoutElement.prototype, "layout", void 0);
|
|
@@ -40877,6 +42375,6 @@ function init() {
|
|
|
40877
42375
|
console.log(`Init`);
|
|
40878
42376
|
}
|
|
40879
42377
|
//#endregion
|
|
40880
|
-
export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, DataGridElement, DataTableElement, DetailListElement, DockHostElement, DockPanelElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GridListElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, KeyedElementIndex, LIST_ITEM_MOTION_MS, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, ListSearchController, ListSelectionController, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, SliderInputElement, SlidingNumberElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SplitPanelElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TextShimmerElement, TickledController, TimelineController, TimelineTrackTabElement, TitlebarElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeKeyboardNavController, TreeListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, animateListItemIn, animateListItemOut, applyAgeModification, applyHighlights, applySnapshot, attachTimelineInteractions, buildHighlightTargets, buildModel, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, computeColour, computeLeafGeoms, createAcCompletionProvider, createDataListSearchAdapter, createElementIncrSearch, createElementListSearchAdapter, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createTreeListSearchAdapter, createVerticalListAdapter, distribute, extractStack, findNode, findParentOf, findStackOf, findStackPathByName, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, iconBus, init, insertBeside, isDragging, isMultiMode, isSplit, isStack, keyForElement, listItemFadeKeyframes, listSearchStyles, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, normalise, normalize, panelGapIndex, parseColourScaleAttr, parseLayout, pointerOverAnyHost, prefersReducedMotion, readBaseColour, registerFontIcon, registerIcon, registerListSearchCommands, removePanelFromStack, resolveCssVars, resolveGrid, resolveLeafPath, resolveTracks, serializeLayout, setActive, setIconFont, svgToDataUri, swapLeaves, tickledItemStyles, tickledStyles, timelineStyles, toSnapshot, walk, wrapRoot };
|
|
42378
|
+
export { AcTextElement, AcTokenElement, BottomDrawerElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, DataGridElement, DataTableElement, DetailListElement, DockHostElement, DockPanelElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GridListElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, KeyedElementIndex, LIST_ITEM_MOTION_MS, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, ListDragSelectController, ListSearchController, ListSelectionController, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, SliderInputElement, SlidingNumberElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SplitPanelElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TextShimmerElement, TickledController, TimelineController, TimelineTrackTabElement, TitlebarElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeKeyboardNavController, TreeListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, animateListItemIn, animateListItemOut, applyAgeModification, applyHighlights, applySnapshot, attachTimelineInteractions, bottomDrawerCommandId, buildHighlightTargets, buildModel, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, computeColour, computeLeafGeoms, createAcCompletionProvider, createDataListSearchAdapter, createElementIncrSearch, createElementListSearchAdapter, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createTreeListSearchAdapter, createVerticalListAdapter, distribute, extractStack, findNode, findParentOf, findStackOf, findStackPathByName, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, iconBus, init, insertBeside, isDragging, isMultiMode, isSplit, isStack, keyForElement, listItemFadeKeyframes, listSearchStyles, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, normalise, normalize, panelGapIndex, parseColourScaleAttr, parseLayout, pointerOverAnyHost, prefersReducedMotion, readBaseColour, registerFontIcon, registerIcon, registerListSearchCommands, removePanelFromStack, resolveCssVars, resolveGrid, resolveLeafPath, resolveTracks, serializeLayout, setActive, setIconFont, svgToDataUri, swapLeaves, tickledItemStyles, tickledStyles, timelineStyles, toSnapshot, walk, wrapRoot };
|
|
40881
42379
|
|
|
40882
42380
|
//# sourceMappingURL=index.js.map
|