@threadlabs/looma 0.10.10 → 0.10.12

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.
@@ -2945,6 +2945,146 @@ svg[data-v-bcedd63e-s] {
2945
2945
  display: none;
2946
2946
  }
2947
2947
 
2948
+ /* A list of items (ui-list-item). It owns the spacing between them, so a view never sets it. The
2949
+ explicit list role keeps the list announced as one: some browsers drop it from a list with no
2950
+ markers. */
2951
+ [data-component~="ui-list"][data-v-935b1197] {
2952
+ display: flex;
2953
+ flex-direction: column;
2954
+ gap: var(--ui-list-gap, var(--ui-space-1));
2955
+ min-inline-size: 0;
2956
+ margin: 0;
2957
+ padding: 0;
2958
+ list-style: none;
2959
+ }
2960
+ [data-component~="ui-list"][data-ui-list-state~="layout=grid"][data-v-935b1197] {
2961
+ display: grid;
2962
+ grid-template-columns:
2963
+ repeat(auto-fill, minmax(min(100%, var(--ui-list-min-item-width, 14rem)), 1fr));
2964
+ gap: var(--ui-list-gap, var(--ui-space-3));
2965
+ }
2966
+
2967
+ /* A component that sets its display still honours the hidden attribute on its root. */
2968
+ [data-component~="ui-list"][hidden][data-v-935b1197] {
2969
+ display: none;
2970
+ }
2971
+
2972
+ /* One entry in a list: something to recognise (leading, usually an icon), its name (the default
2973
+ slot), one line about it (description), and what it offers (trailing, such as a button or a
2974
+ badge). The title and description are one line each and end in an ellipsis, so every item in a
2975
+ list has the same height.
2976
+
2977
+ A link in the title is the whole item: its hit area stretches over the item, so the icon and the
2978
+ padding follow it too, and the item takes the link's focus ring. The link stays a real link, so
2979
+ a router, a modified click, and "open in new tab" all work. Trailing controls sit above it and
2980
+ stay their own. */
2981
+ [data-component~="ui-list-item"][data-v-d61daf46] {
2982
+ position: relative;
2983
+ box-sizing: border-box;
2984
+ display: flex;
2985
+ align-items: center;
2986
+ gap: var(--ui-list-item-gap, var(--ui-space-3));
2987
+ min-inline-size: 0;
2988
+ min-block-size: var(--ui-control-size, 2.5rem);
2989
+ padding-block: var(--ui-list-item-padding-block, var(--ui-space-2));
2990
+ padding-inline: var(--ui-list-item-padding-inline, var(--ui-space-3));
2991
+ border-radius: var(--ui-radius-md);
2992
+ color: var(--ui-text-primary);
2993
+ transition:
2994
+ background-color var(--ui-motion-fast) var(--ui-motion-ease),
2995
+ border-color var(--ui-motion-fast) var(--ui-motion-ease);
2996
+ }
2997
+ [data-component~="ui-list-item"][data-ui-list-item-state~="variant=card"][data-v-d61daf46] {
2998
+ padding-block: var(--ui-list-item-padding-block, var(--ui-space-3));
2999
+ padding-inline: var(--ui-list-item-padding-inline, var(--ui-space-4));
3000
+ border: 1px solid var(--ui-border-default);
3001
+ border-radius: var(--ui-radius-lg);
3002
+ background: var(--ui-surface-raised);
3003
+ }
3004
+ [data-component~="ui-list-item"][data-v-d61daf46]:has(.title a[href]:hover) {
3005
+ background: var(--ui-surface-hover);
3006
+ }
3007
+ [data-component~="ui-list-item"][data-ui-list-item-state~="variant=card"][data-v-d61daf46]:has(.title
3008
+ a[href]:hover) {
3009
+ border-color: var(--ui-border-strong);
3010
+ }
3011
+ [data-component~="ui-list-item"][data-ui-list-item-state~="current"][data-v-d61daf46] {
3012
+ background: var(--ui-surface-hover);
3013
+ }
3014
+ [data-component~="ui-list-item"][data-v-d61daf46]:has(.title a[href]:focus-visible) {
3015
+ box-shadow: 0 0 0 2px var(--ui-focus-ring);
3016
+ }
3017
+ .leading[data-v-d61daf46],
3018
+ .trailing[data-v-d61daf46] {
3019
+ display: inline-flex;
3020
+ flex: none;
3021
+ align-items: center;
3022
+ gap: var(--ui-space-2);
3023
+ }
3024
+ .leading[data-v-d61daf46] {
3025
+ color: var(--ui-text-muted);
3026
+ font-size: var(--ui-list-item-icon-size, var(--ui-font-size-lg));
3027
+ }
3028
+
3029
+ /* Trailing controls take their own clicks, above the title link's stretched hit area. */
3030
+ .trailing[data-v-d61daf46] {
3031
+ position: relative;
3032
+ z-index: 1;
3033
+ color: var(--ui-text-muted);
3034
+ font-size: var(--ui-font-size-sm);
3035
+ }
3036
+ .content[data-v-d61daf46] {
3037
+ display: flex;
3038
+ flex: 1;
3039
+ flex-direction: column;
3040
+ gap: var(--ui-space-0-5, 2px);
3041
+ min-inline-size: 0;
3042
+ }
3043
+ .title[data-v-d61daf46],
3044
+ .description[data-v-d61daf46] {
3045
+ display: block;
3046
+ min-inline-size: 0;
3047
+ overflow: hidden;
3048
+ text-overflow: ellipsis;
3049
+ white-space: nowrap;
3050
+ }
3051
+ .title[data-v-d61daf46] {
3052
+ font-size: var(--ui-font-size-md);
3053
+ font-weight: var(--ui-font-medium);
3054
+ line-height: var(--ui-line-height-tight);
3055
+ }
3056
+ .description[data-v-d61daf46] {
3057
+ color: var(--ui-text-muted);
3058
+ font-size: var(--ui-font-size-sm);
3059
+ line-height: var(--ui-line-height-tight);
3060
+ }
3061
+ .title > a[data-v-d61daf46-s] {
3062
+ color: inherit;
3063
+ text-decoration: none;
3064
+ }
3065
+ .title > a[data-v-d61daf46-s]:focus-visible {
3066
+ outline: none;
3067
+ box-shadow: none;
3068
+ }
3069
+ .title > a[href][data-v-d61daf46-s]::after {
3070
+ position: absolute;
3071
+ inset: 0;
3072
+ border-radius: inherit;
3073
+ content: "";
3074
+ }
3075
+
3076
+ /* An unused region takes no space. */
3077
+ .leading[data-v-d61daf46]:empty,
3078
+ .description[data-v-d61daf46]:empty,
3079
+ .trailing[data-v-d61daf46]:empty {
3080
+ display: none;
3081
+ }
3082
+
3083
+ /* A component that sets its display still honours the hidden attribute on its root. */
3084
+ [data-component~="ui-list-item"][hidden][data-v-d61daf46] {
3085
+ display: none;
3086
+ }
3087
+
2948
3088
  /* Compact sets the part tokens its items read, so nothing has to rescale a global. */
2949
3089
  [data-component~="ui-menu"][data-ui-menu-state~="density=compact"][data-v-ad1dce95] {
2950
3090
  --ui-menu-item-padding-block: var(--ui-space-1);
@@ -4304,7 +4444,7 @@ to {
4304
4444
  display: none;
4305
4445
  }
4306
4446
 
4307
- [data-component~="ui-tree-item"][data-v-a950b4d2] {
4447
+ [data-component~="ui-tree-item"][data-v-3778b642] {
4308
4448
  --_tree-row-min-height: 32px;
4309
4449
  --_tree-disclosure-size: 16px;
4310
4450
 
@@ -4313,7 +4453,7 @@ to {
4313
4453
  min-inline-size: 0;
4314
4454
  margin-inline-start: calc(var(--ui-tree-item-depth, 0) * var(--ui-tree-indent, 16px));
4315
4455
  }
4316
- .row[data-v-a950b4d2] {
4456
+ .row[data-v-3778b642] {
4317
4457
  position: relative;
4318
4458
  display: grid;
4319
4459
  grid-template-columns: var(--_tree-disclosure-size) auto minmax(0, 1fr);
@@ -4330,38 +4470,38 @@ to {
4330
4470
  box-shadow var(--ui-motion-fast) var(--ui-motion-ease),
4331
4471
  min-block-size var(--ui-motion-base) var(--ui-motion-ease);
4332
4472
  }
4333
- .row[data-v-a950b4d2]:hover,
4334
- [data-component~="ui-tree-item"][data-ui-tree-item-state~="selected"] .row[data-v-a950b4d2],
4335
- .row[data-v-a950b4d2]:focus-within {
4473
+ .row[data-v-3778b642]:hover,
4474
+ [data-component~="ui-tree-item"][data-ui-tree-item-state~="selected"] .row[data-v-3778b642],
4475
+ .row[data-v-3778b642]:focus-within {
4336
4476
  color: var(--ui-text-primary);
4337
4477
  background: var(--ui-surface-muted);
4338
4478
  }
4339
- [data-component~="ui-tree-item"][data-ui-tree-item-state~="disabled"] .row[data-v-a950b4d2] {
4479
+ [data-component~="ui-tree-item"][data-ui-tree-item-state~="disabled"] .row[data-v-3778b642] {
4340
4480
  opacity: 0.55;
4341
4481
  }
4342
- [data-component~="ui-tree-item"][data-dragging] .row[data-v-a950b4d2] {
4482
+ [data-component~="ui-tree-item"][data-dragging] .row[data-v-3778b642] {
4343
4483
  opacity: 0.42;
4344
4484
  }
4345
- [data-component~="ui-tree-item"][data-v-a950b4d2]:focus {
4485
+ [data-component~="ui-tree-item"][data-v-3778b642]:focus {
4346
4486
  outline: none;
4347
4487
  }
4348
- [data-component~="ui-tree-item"]:focus-visible .row[data-v-a950b4d2] {
4488
+ [data-component~="ui-tree-item"]:focus-visible .row[data-v-3778b642] {
4349
4489
  box-shadow: 0 0 0 2px var(--ui-focus-ring);
4350
4490
  }
4351
4491
 
4352
4492
  /* Child combinators: drop feedback belongs to this item's own row, not the rows nested in it. */
4353
- [data-component~="ui-tree-item"][data-drop-position="inside"] > .row[data-v-a950b4d2] {
4493
+ [data-component~="ui-tree-item"][data-drop-position="inside"] > .row[data-v-3778b642] {
4354
4494
  background: var(--ui-accent-subtle);
4355
4495
  box-shadow: inset 0 0 0 1px var(--ui-tree-drop-color, var(--ui-accent-solid));
4356
4496
  }
4357
- .disclosure[data-v-a950b4d2],
4358
- .disclosure-spacer[data-v-a950b4d2] {
4497
+ .disclosure[data-v-3778b642],
4498
+ .disclosure-spacer[data-v-3778b642] {
4359
4499
  grid-column: 1;
4360
4500
  grid-row: 1;
4361
4501
  inline-size: var(--_tree-disclosure-size);
4362
4502
  block-size: 28px;
4363
4503
  }
4364
- .disclosure[data-v-a950b4d2] {
4504
+ .disclosure[data-v-3778b642] {
4365
4505
  display: grid;
4366
4506
  /* Start-aligned: the chevron's ink, not its hit area, aligns with the content above it. */
4367
4507
  place-items: center start;
@@ -4372,14 +4512,14 @@ to {
4372
4512
  border-radius: var(--ui-radius-sm);
4373
4513
  cursor: pointer;
4374
4514
  }
4375
- .disclosure[hidden][data-v-a950b4d2] {
4515
+ .disclosure[hidden][data-v-3778b642] {
4376
4516
  display: none;
4377
4517
  }
4378
- .disclosure[data-v-a950b4d2]:hover {
4518
+ .disclosure[data-v-3778b642]:hover {
4379
4519
  color: var(--ui-text-primary);
4380
4520
  background: var(--ui-surface-elevated);
4381
4521
  }
4382
- .disclosure-icon[data-v-a950b4d2] {
4522
+ .disclosure-icon[data-v-3778b642] {
4383
4523
  display: grid;
4384
4524
  place-items: center;
4385
4525
  inline-size: 12px;
@@ -4387,7 +4527,7 @@ to {
4387
4527
  transform: rotate(-90deg);
4388
4528
  transition: transform var(--ui-motion-fast) var(--ui-motion-ease);
4389
4529
  }
4390
- .disclosure-icon[data-v-a950b4d2]::before {
4530
+ .disclosure-icon[data-v-3778b642]::before {
4391
4531
  display: block;
4392
4532
  inline-size: 0.375rem;
4393
4533
  block-size: 0.375rem;
@@ -4397,19 +4537,19 @@ to {
4397
4537
  /* A chevron's ink sits below its box centre; lift it so it centres optically (in either rotation). */
4398
4538
  transform: translateY(-20%) rotate(45deg);
4399
4539
  }
4400
- [data-component~="ui-tree-item"][aria-expanded="true"] .disclosure-icon[data-v-a950b4d2] {
4540
+ [data-component~="ui-tree-item"][aria-expanded="true"] .disclosure-icon[data-v-3778b642] {
4401
4541
  transform: rotate(0deg);
4402
4542
  }
4403
4543
 
4404
4544
  /* Lucide grip-vertical, filling the handle as in Looma 0.2. */
4405
- .drag-handle svg[data-v-a950b4d2] {
4545
+ .drag-handle svg[data-v-3778b642] {
4406
4546
  display: block;
4407
4547
  inline-size: 100%;
4408
4548
  block-size: 100%;
4409
4549
  }
4410
4550
 
4411
4551
  /* Slotted content is outside this scope, so :has() cannot see it; hide only a truly empty slot. */
4412
- .leading[data-v-a950b4d2] {
4552
+ .leading[data-v-3778b642] {
4413
4553
  display: inline-grid;
4414
4554
  place-items: center;
4415
4555
  grid-column: 2;
@@ -4418,13 +4558,16 @@ to {
4418
4558
  block-size: 1em;
4419
4559
  margin-inline-start: var(--ui-space-1);
4420
4560
  color: var(--ui-text-muted);
4561
+ /* Above the label, so a sliding name passes under the icon. */
4562
+ position: relative;
4563
+ z-index: 1;
4421
4564
  }
4422
- .leading[data-v-a950b4d2]:empty {
4565
+ .leading[data-v-3778b642]:empty {
4423
4566
  display: none;
4424
4567
  }
4425
4568
 
4426
4569
  /* Icons match the label's size (as in Knit's tree): an unsized SVG would otherwise render 300×150. */
4427
- svg[data-v-a950b4d2-s],img[data-v-a950b4d2-s] {
4570
+ svg[data-v-3778b642-s],img[data-v-3778b642-s] {
4428
4571
  display: block;
4429
4572
  inline-size: 1em;
4430
4573
  block-size: 1em;
@@ -4433,7 +4576,7 @@ svg[data-v-a950b4d2-s],img[data-v-a950b4d2-s] {
4433
4576
 
4434
4577
  /* The label spans the row's height and centres its content, so slotted content (a link) can
4435
4578
  stretch to fill the row as its own hit area; the padding tokens remove the inset. */
4436
- .label[data-v-a950b4d2] {
4579
+ .label[data-v-3778b642] {
4437
4580
  grid-column: 3;
4438
4581
  grid-row: 1;
4439
4582
  align-self: stretch;
@@ -4444,11 +4587,14 @@ svg[data-v-a950b4d2-s],img[data-v-a950b4d2-s] {
4444
4587
  overflow: hidden;
4445
4588
  padding: var(--ui-tree-item-label-padding-block, var(--ui-space-1))
4446
4589
  var(--ui-tree-item-label-padding-inline, var(--ui-space-2));
4590
+ /* The length of the fade before the controls. The label's one flex child lays out no gap; this
4591
+ is where the controller reads the length in pixels to stop a sliding name before the fade. */
4592
+ column-gap: var(--ui-space-3);
4447
4593
  }
4448
4594
 
4449
4595
  /* Slotted label content fills the cell, so a link is the row's hit area rather than sizing to
4450
4596
  its own text and reading as overflow. */
4451
- .label-text[data-v-a950b4d2] {
4597
+ .label-text[data-v-3778b642] {
4452
4598
  display: flex;
4453
4599
  align-items: center;
4454
4600
  /* Stretches, so slotted content can still be the row's full-height hit area. */
@@ -4458,43 +4604,73 @@ svg[data-v-a950b4d2-s],img[data-v-a950b4d2-s] {
4458
4604
  inline-size: 100%;
4459
4605
  white-space: nowrap;
4460
4606
  }
4461
- .label-text > [data-v-a950b4d2-s] {
4607
+ .label-text > [data-v-3778b642-s] {
4462
4608
  flex: 1 1 auto;
4463
4609
  min-inline-size: 0;
4464
4610
  }
4465
4611
 
4612
+ /* The controls sit over the label's end, so the text fades out where they begin. The fade is
4613
+ the truncation mark while it shows: an ellipsis under it would read as a second one. */
4614
+ .row:hover > .label[data-v-3778b642],
4615
+ .row:focus-within > .label[data-v-3778b642] {
4616
+ text-overflow: clip;
4617
+ mask-image: linear-gradient(
4618
+ to right,
4619
+ #000 calc(100% - var(--_tree-actions-width, 1.75rem) - var(--ui-space-3)),
4620
+ transparent calc(100% - var(--_tree-actions-width, 1.75rem))
4621
+ );
4622
+ }
4623
+ .row:hover > .label[data-v-3778b642]:dir(rtl),
4624
+ .row:focus-within > .label[data-v-3778b642]:dir(rtl) {
4625
+ mask-image: linear-gradient(
4626
+ to left,
4627
+ #000 calc(100% - var(--_tree-actions-width, 1.75rem) - var(--ui-space-3)),
4628
+ transparent calc(100% - var(--_tree-actions-width, 1.75rem))
4629
+ );
4630
+ }
4631
+
4466
4632
  /* A hovered row reads its whole name: the label slides far enough to show the end, waits
4467
4633
  there, and comes back. Only when it actually overflows — the controller measures by how
4468
4634
  much — after the controls have taken their place over its end — and hands over the distance
4469
4635
  and a duration from it, so a longer name travels no faster. */
4470
- .row[data-ui-marquee] > .label > .label-text[data-v-a950b4d2] {
4636
+ .row[data-ui-marquee] > .label > .label-text[data-v-3778b642] {
4471
4637
  /* Once, and it stays at the end while the pointer is there: a name that keeps sliding back
4472
4638
  and forth under the pointer is harder to read than one that arrives and holds. */
4473
- animation: ui-tree-item-marquee-a950b4d2 var(--_marquee-duration) linear 0.5s 1 normal forwards;
4639
+ animation: ui-tree-item-marquee-3778b642 var(--_marquee-duration) linear 0.5s 1 normal forwards;
4474
4640
  will-change: transform;
4475
4641
  }
4476
4642
 
4477
- /* While it slides, the start fades too: the name is leaving the cell at both ends, and a hard
4478
- edge beside the icon reads as a collision rather than as more text. */
4479
- .row[data-ui-marquee] > .label[data-v-a950b4d2] {
4643
+ /* This comes after the hover fade, which it replaces at the same specificity. While the name
4644
+ slides, the label reaches back under the icon (the controller measures how far) with its text
4645
+ where it was, and fades out across that stretch, gone by the icon's middle: the name slips
4646
+ under the icon rather than stopping at a hard edge beside it. */
4647
+ .row[data-ui-marquee] > .label[data-v-3778b642] {
4648
+ margin-inline-start: calc(-1 * var(--_marquee-lead, 0px));
4649
+ padding-inline-start: calc(
4650
+ var(--_marquee-lead, 0px) + var(--ui-tree-item-label-padding-inline, var(--ui-space-2))
4651
+ );
4480
4652
  mask-image: linear-gradient(
4481
4653
  to right,
4482
- transparent 0,
4483
- #000 var(--ui-space-2),
4654
+ transparent calc(var(--_marquee-lead, 0px) / 2),
4655
+ #000 calc(
4656
+ var(--_marquee-lead, 0px) + var(--ui-tree-item-label-padding-inline, var(--ui-space-2))
4657
+ ),
4484
4658
  #000 calc(100% - var(--_tree-actions-width, 1.75rem) - var(--ui-space-3)),
4485
4659
  transparent calc(100% - var(--_tree-actions-width, 1.75rem))
4486
4660
  );
4487
4661
  }
4488
- .row[data-ui-marquee] > .label[data-v-a950b4d2]:dir(rtl) {
4662
+ .row[data-ui-marquee] > .label[data-v-3778b642]:dir(rtl) {
4489
4663
  mask-image: linear-gradient(
4490
4664
  to left,
4491
- transparent 0,
4492
- #000 var(--ui-space-2),
4665
+ transparent calc(var(--_marquee-lead, 0px) / 2),
4666
+ #000 calc(
4667
+ var(--_marquee-lead, 0px) + var(--ui-tree-item-label-padding-inline, var(--ui-space-2))
4668
+ ),
4493
4669
  #000 calc(100% - var(--_tree-actions-width, 1.75rem) - var(--ui-space-3)),
4494
4670
  transparent calc(100% - var(--_tree-actions-width, 1.75rem))
4495
4671
  );
4496
4672
  }
4497
- @keyframes ui-tree-item-marquee-a950b4d2 {
4673
+ @keyframes ui-tree-item-marquee-3778b642 {
4498
4674
  from {
4499
4675
  transform: translateX(0);
4500
4676
  }
@@ -4505,35 +4681,15 @@ to {
4505
4681
 
4506
4682
  /* Reduced motion keeps the fade, which already says the name continues. */
4507
4683
  @media (prefers-reduced-motion: reduce) {
4508
- .row[data-ui-marquee] > .label > .label-text[data-v-a950b4d2] {
4684
+ .row[data-ui-marquee] > .label > .label-text[data-v-3778b642] {
4509
4685
  animation: none;
4510
4686
  }
4511
4687
  }
4512
-
4513
- /* The controls sit over the label's end, so the text fades out where they begin. The fade is
4514
- the truncation mark while it shows: an ellipsis under it would read as a second one. */
4515
- .row:hover > .label[data-v-a950b4d2],
4516
- .row:focus-within > .label[data-v-a950b4d2] {
4517
- text-overflow: clip;
4518
- mask-image: linear-gradient(
4519
- to right,
4520
- #000 calc(100% - var(--_tree-actions-width, 1.75rem) - var(--ui-space-3)),
4521
- transparent calc(100% - var(--_tree-actions-width, 1.75rem))
4522
- );
4523
- }
4524
- .row:hover > .label[data-v-a950b4d2]:dir(rtl),
4525
- .row:focus-within > .label[data-v-a950b4d2]:dir(rtl) {
4526
- mask-image: linear-gradient(
4527
- to left,
4528
- #000 calc(100% - var(--_tree-actions-width, 1.75rem) - var(--ui-space-3)),
4529
- transparent calc(100% - var(--_tree-actions-width, 1.75rem))
4530
- );
4531
- }
4532
- .row:hover > .label > [data-v-a950b4d2-s],
4533
- .row:focus-within > .label > [data-v-a950b4d2-s] {
4688
+ .row:hover > .label > [data-v-3778b642-s],
4689
+ .row:focus-within > .label > [data-v-3778b642-s] {
4534
4690
  text-overflow: clip;
4535
4691
  }
4536
- .actions[data-v-a950b4d2] {
4692
+ .actions[data-v-3778b642] {
4537
4693
  position: absolute;
4538
4694
  z-index: 1;
4539
4695
  inset-block: 0;
@@ -4545,18 +4701,18 @@ to {
4545
4701
  pointer-events: none;
4546
4702
  transition: opacity var(--ui-motion-fast) var(--ui-motion-ease);
4547
4703
  }
4548
- .row:hover > .actions[data-v-a950b4d2],
4549
- .row:focus-within > .actions[data-v-a950b4d2] {
4704
+ .row:hover > .actions[data-v-3778b642],
4705
+ .row:focus-within > .actions[data-v-3778b642] {
4550
4706
  opacity: 1;
4551
4707
  pointer-events: auto;
4552
4708
  }
4553
4709
 
4554
4710
  /* Without hover there is no reveal, so the controls keep their own column. */
4555
4711
  @media (hover: none) {
4556
- .row[data-v-a950b4d2] {
4712
+ .row[data-v-3778b642] {
4557
4713
  grid-template-columns: var(--_tree-disclosure-size) auto minmax(0, 1fr) auto;
4558
4714
  }
4559
- .actions[data-v-a950b4d2] {
4715
+ .actions[data-v-3778b642] {
4560
4716
  position: static;
4561
4717
  grid-column: 4;
4562
4718
  grid-row: 1;
@@ -4571,7 +4727,7 @@ to {
4571
4727
  empty column, right before the icon; a branch's disclosure is there, so its handle sits just
4572
4728
  outside the row. It is bare until pointed at: a resting surface behind it read as a faint
4573
4729
  patch rather than as a control. */
4574
- .drag-handle[data-v-a950b4d2] {
4730
+ .drag-handle[data-v-3778b642] {
4575
4731
  position: absolute;
4576
4732
  z-index: 2;
4577
4733
  inset-block-start: 50%;
@@ -4592,24 +4748,24 @@ to {
4592
4748
  transform: translateY(-50%);
4593
4749
  transition: opacity var(--ui-motion-fast) var(--ui-motion-ease);
4594
4750
  }
4595
- .row:hover .drag-handle[data-v-a950b4d2],
4596
- .drag-handle[data-v-a950b4d2]:hover,
4597
- .drag-handle[data-v-a950b4d2]:focus-visible,
4598
- [data-component~="ui-tree-item"][data-dragging] > .row > .drag-handle[data-v-a950b4d2] {
4751
+ .row:hover .drag-handle[data-v-3778b642],
4752
+ .drag-handle[data-v-3778b642]:hover,
4753
+ .drag-handle[data-v-3778b642]:focus-visible,
4754
+ [data-component~="ui-tree-item"][data-dragging] > .row > .drag-handle[data-v-3778b642] {
4599
4755
  opacity: 1;
4600
4756
  }
4601
- [data-component~="ui-tree-item"][data-ui-tree-item-state~="isContainer"] > .row > .drag-handle[data-v-a950b4d2] {
4757
+ [data-component~="ui-tree-item"][data-ui-tree-item-state~="isContainer"] > .row > .drag-handle[data-v-3778b642] {
4602
4758
  inset-inline-start: calc(-1 * var(--_tree-disclosure-size) - 2px);
4603
4759
  }
4604
- .drag-handle[data-v-a950b4d2]:hover,
4605
- .drag-handle[data-v-a950b4d2]:focus-visible {
4760
+ .drag-handle[data-v-3778b642]:hover,
4761
+ .drag-handle[data-v-3778b642]:focus-visible {
4606
4762
  color: var(--ui-text-primary);
4607
4763
  background: var(--ui-surface-hover);
4608
4764
  }
4609
- .drag-handle[data-v-a950b4d2]:active {
4765
+ .drag-handle[data-v-3778b642]:active {
4610
4766
  cursor: grabbing;
4611
4767
  }
4612
- .drop-indicator[data-v-a950b4d2] {
4768
+ .drop-indicator[data-v-3778b642] {
4613
4769
  position: absolute;
4614
4770
  z-index: 3;
4615
4771
  inset-inline: 1px;
@@ -4619,8 +4775,8 @@ to {
4619
4775
  background: var(--ui-tree-drop-color, var(--ui-accent-solid));
4620
4776
  pointer-events: none;
4621
4777
  }
4622
- .drop-indicator[data-v-a950b4d2]::before,
4623
- .drop-indicator[data-v-a950b4d2]::after {
4778
+ .drop-indicator[data-v-3778b642]::before,
4779
+ .drop-indicator[data-v-3778b642]::after {
4624
4780
  content: "";
4625
4781
  position: absolute;
4626
4782
  inset-block-start: 50%;
@@ -4631,39 +4787,39 @@ to {
4631
4787
  background: var(--ui-surface-elevated);
4632
4788
  transform: translateY(-50%);
4633
4789
  }
4634
- .drop-indicator[data-v-a950b4d2]::before {
4790
+ .drop-indicator[data-v-3778b642]::before {
4635
4791
  inset-inline-start: -1px;
4636
4792
  }
4637
- .drop-indicator[data-v-a950b4d2]::after {
4793
+ .drop-indicator[data-v-3778b642]::after {
4638
4794
  inset-inline-end: -1px;
4639
4795
  }
4640
- [data-component~="ui-tree-item"][data-drop-position="before"] > .row > .row-drop-indicator[data-v-a950b4d2] {
4796
+ [data-component~="ui-tree-item"][data-drop-position="before"] > .row > .row-drop-indicator[data-v-3778b642] {
4641
4797
  display: block;
4642
4798
  inset-block-start: -1px;
4643
4799
  }
4644
- [data-component~="ui-tree-item"][data-drop-position="after"] > .subtree-drop-indicator[data-v-a950b4d2] {
4800
+ [data-component~="ui-tree-item"][data-drop-position="after"] > .subtree-drop-indicator[data-v-3778b642] {
4645
4801
  display: block;
4646
4802
  inset-block-end: -1px;
4647
4803
  }
4648
- .children[hidden][data-v-a950b4d2] {
4804
+ .children[hidden][data-v-3778b642] {
4649
4805
  display: none;
4650
4806
  }
4651
- html[data-ui-input-modality="touch"] [data-component~="ui-tree-item"][data-v-a950b4d2] {
4807
+ html[data-ui-input-modality="touch"] [data-component~="ui-tree-item"][data-v-3778b642] {
4652
4808
  --_tree-row-min-height: 44px;
4653
4809
  }
4654
- html[data-ui-input-modality="touch"] [data-component~="ui-tree-item"] .drag-handle[data-v-a950b4d2] {
4810
+ html[data-ui-input-modality="touch"] [data-component~="ui-tree-item"] .drag-handle[data-v-3778b642] {
4655
4811
  display: none;
4656
4812
  }
4657
4813
  @media (prefers-reduced-motion: reduce) {
4658
- .row[data-v-a950b4d2],
4659
- .disclosure-icon[data-v-a950b4d2],
4660
- .drag-handle[data-v-a950b4d2] {
4814
+ .row[data-v-3778b642],
4815
+ .disclosure-icon[data-v-3778b642],
4816
+ .drag-handle[data-v-3778b642] {
4661
4817
  transition: none;
4662
4818
  }
4663
4819
  }
4664
4820
 
4665
4821
  /* A component that sets its display still honours the hidden attribute on its root. */
4666
- [data-component~="ui-tree-item"][hidden][data-v-a950b4d2] {
4822
+ [data-component~="ui-tree-item"][hidden][data-v-3778b642] {
4667
4823
  display: none;
4668
4824
  }
4669
4825
  /**
package/vue/index.d.ts CHANGED
@@ -25,6 +25,8 @@ export { default as Grid } from "./UiGrid.js";
25
25
  export { default as Icon } from "./UiIcon.js";
26
26
  export { default as IconButton } from "./UiIconButton.js";
27
27
  export { default as Input } from "./UiInput.js";
28
+ export { default as List } from "./UiList.js";
29
+ export { default as ListItem } from "./UiListItem.js";
28
30
  export { default as Menu } from "./UiMenu.js";
29
31
  export { default as MenuItem } from "./UiMenuItem.js";
30
32
  export { default as Popover } from "./UiPopover.js";
package/vue/index.js CHANGED
@@ -26,6 +26,8 @@ import { t as UiFormField_default } from "./chunks/UiFormField.js";
26
26
  import { t as UiGrid_default } from "./chunks/UiGrid.js";
27
27
  import { t as UiIconButton_default } from "./chunks/UiIconButton.js";
28
28
  import { t as UiInput_default } from "./chunks/UiInput.js";
29
+ import { t as UiList_default } from "./chunks/UiList.js";
30
+ import { t as UiListItem_default } from "./chunks/UiListItem.js";
29
31
  import { t as UiMenu_default } from "./chunks/UiMenu.js";
30
32
  import { t as UiMenuItem_default } from "./chunks/UiMenuItem.js";
31
33
  import { t as UiPopover_default } from "./chunks/UiPopover.js";
@@ -48,4 +50,4 @@ import { t as UiTopBar_default } from "./chunks/UiTopBar.js";
48
50
  import { t as UiTree_default } from "./chunks/UiTree.js";
49
51
  import { t as UiTreeItem_default } from "./chunks/UiTreeItem.js";
50
52
  import { trackInputModality } from "@threadlabs/looma/components/shared/input-modality.js";
51
- export { UiAffordanceScope_default as AffordanceScope, UiAvatar_default as Avatar, UiAvatarGroup_default as AvatarGroup, UiBadge_default as Badge, UiButton_default as Button, UiCallout_default as Callout, UiCheckbox_default as Checkbox, UiCluster_default as Cluster, UiCombobox_default as Combobox, UiContainer_default as Container, UiContextMenu_default as ContextMenu, UiDialog_default as Dialog, UiDisclosure_default as Disclosure, UiEditable_default as Editable, UiEditorInsertTableGrid_default as EditorInsertTableGrid, UiEditorMentionMenu_default as EditorMentionMenu, UiEditorSlashMenu_default as EditorSlashMenu, UiEditorTableContextMenu_default as EditorTableContextMenu, UiEditorTableOverlay_default as EditorTableOverlay, UiEditorTableToolbar_default as EditorTableToolbar, UiEditorToolbar_default as EditorToolbar, UiFloatingActionButton_default as FloatingActionButton, UiFormField_default as FormField, UiGrid_default as Grid, UiIcon_default as Icon, UiIconButton_default as IconButton, UiInput_default as Input, UiMenu_default as Menu, UiMenuItem_default as MenuItem, UiPopover_default as Popover, UiRadio_default as Radio, UiRadioGroup_default as RadioGroup, UiReel_default as Reel, UiScrollArea_default as ScrollArea, UiSearchResultRow_default as SearchResultRow, UiSearchShell_default as SearchShell, UiSelect_default as Select, UiSeparator_default as Separator, UiSidebar_default as Sidebar, UiStack_default as Stack, UiSwitch_default as Switch, UiSwitcher_default as Switcher, UiTabs_default as Tabs, UiTextarea_default as Textarea, UiToastRegion_default as ToastRegion, UiTooltip_default as Tooltip, UiTopBar_default as TopBar, UiTree_default as Tree, UiTreeItem_default as TreeItem, trackInputModality };
53
+ export { UiAffordanceScope_default as AffordanceScope, UiAvatar_default as Avatar, UiAvatarGroup_default as AvatarGroup, UiBadge_default as Badge, UiButton_default as Button, UiCallout_default as Callout, UiCheckbox_default as Checkbox, UiCluster_default as Cluster, UiCombobox_default as Combobox, UiContainer_default as Container, UiContextMenu_default as ContextMenu, UiDialog_default as Dialog, UiDisclosure_default as Disclosure, UiEditable_default as Editable, UiEditorInsertTableGrid_default as EditorInsertTableGrid, UiEditorMentionMenu_default as EditorMentionMenu, UiEditorSlashMenu_default as EditorSlashMenu, UiEditorTableContextMenu_default as EditorTableContextMenu, UiEditorTableOverlay_default as EditorTableOverlay, UiEditorTableToolbar_default as EditorTableToolbar, UiEditorToolbar_default as EditorToolbar, UiFloatingActionButton_default as FloatingActionButton, UiFormField_default as FormField, UiGrid_default as Grid, UiIcon_default as Icon, UiIconButton_default as IconButton, UiInput_default as Input, UiList_default as List, UiListItem_default as ListItem, UiMenu_default as Menu, UiMenuItem_default as MenuItem, UiPopover_default as Popover, UiRadio_default as Radio, UiRadioGroup_default as RadioGroup, UiReel_default as Reel, UiScrollArea_default as ScrollArea, UiSearchResultRow_default as SearchResultRow, UiSearchShell_default as SearchShell, UiSelect_default as Select, UiSeparator_default as Separator, UiSidebar_default as Sidebar, UiStack_default as Stack, UiSwitch_default as Switch, UiSwitcher_default as Switcher, UiTabs_default as Tabs, UiTextarea_default as Textarea, UiToastRegion_default as ToastRegion, UiTooltip_default as Tooltip, UiTopBar_default as TopBar, UiTree_default as Tree, UiTreeItem_default as TreeItem, trackInputModality };