@keenmate/web-multiselect 2.0.0-rc02 → 2.0.0-rc04
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/README.md +76 -47
- package/custom-elements.json +736 -84
- package/dist/index.d.ts +256 -7
- package/dist/multiselect.js +2397 -1684
- package/dist/multiselect.umd.js +19 -19
- package/dist/style.css +1 -1
- package/package.json +2 -2
- package/src/css/badges.css +14 -6
- package/src/css/base.css +13 -0
- package/src/css/controls.css +11 -6
- package/src/css/debug.css +1 -1
- package/src/css/floating.css +471 -0
- package/src/css/options.css +40 -20
- package/src/css/rtl.css +27 -140
- package/src/css/states.css +2 -2
- package/src/css/variables.css +137 -0
- package/vscode.html-custom-data.json +15 -1
- package/web-types.json +29 -6
package/custom-elements.json
CHANGED
|
@@ -442,6 +442,15 @@
|
|
|
442
442
|
"privacy": "private",
|
|
443
443
|
"default": "false"
|
|
444
444
|
},
|
|
445
|
+
{
|
|
446
|
+
"kind": "field",
|
|
447
|
+
"name": "justOpenedViaClick",
|
|
448
|
+
"type": {
|
|
449
|
+
"text": "boolean"
|
|
450
|
+
},
|
|
451
|
+
"privacy": "private",
|
|
452
|
+
"default": "false"
|
|
453
|
+
},
|
|
445
454
|
{
|
|
446
455
|
"kind": "field",
|
|
447
456
|
"name": "positioningDriftWarned",
|
|
@@ -451,6 +460,111 @@
|
|
|
451
460
|
"privacy": "private",
|
|
452
461
|
"default": "false"
|
|
453
462
|
},
|
|
463
|
+
{
|
|
464
|
+
"kind": "field",
|
|
465
|
+
"name": "presentationMode",
|
|
466
|
+
"type": {
|
|
467
|
+
"text": "'floating' | 'fullscreen'"
|
|
468
|
+
},
|
|
469
|
+
"privacy": "private",
|
|
470
|
+
"default": "'floating'"
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
"kind": "field",
|
|
474
|
+
"name": "fullscreenHeader",
|
|
475
|
+
"type": {
|
|
476
|
+
"text": "HTMLDivElement | null"
|
|
477
|
+
},
|
|
478
|
+
"privacy": "private",
|
|
479
|
+
"default": "null"
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
"kind": "field",
|
|
483
|
+
"name": "fullscreenSearchInput",
|
|
484
|
+
"type": {
|
|
485
|
+
"text": "HTMLInputElement | null"
|
|
486
|
+
},
|
|
487
|
+
"privacy": "private",
|
|
488
|
+
"default": "null"
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
"kind": "field",
|
|
492
|
+
"name": "fullscreenSearchClear",
|
|
493
|
+
"type": {
|
|
494
|
+
"text": "HTMLButtonElement | null"
|
|
495
|
+
},
|
|
496
|
+
"privacy": "private",
|
|
497
|
+
"default": "null"
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
"kind": "field",
|
|
501
|
+
"name": "fullscreenNav",
|
|
502
|
+
"type": {
|
|
503
|
+
"text": "HTMLDivElement | null"
|
|
504
|
+
},
|
|
505
|
+
"privacy": "private",
|
|
506
|
+
"default": "null"
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
"kind": "field",
|
|
510
|
+
"name": "fullscreenNavCount",
|
|
511
|
+
"type": {
|
|
512
|
+
"text": "HTMLElement | null"
|
|
513
|
+
},
|
|
514
|
+
"privacy": "private",
|
|
515
|
+
"default": "null"
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
"kind": "field",
|
|
519
|
+
"name": "fullscreenNavPrev",
|
|
520
|
+
"type": {
|
|
521
|
+
"text": "HTMLButtonElement | null"
|
|
522
|
+
},
|
|
523
|
+
"privacy": "private",
|
|
524
|
+
"default": "null"
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
"kind": "field",
|
|
528
|
+
"name": "fullscreenNavNext",
|
|
529
|
+
"type": {
|
|
530
|
+
"text": "HTMLButtonElement | null"
|
|
531
|
+
},
|
|
532
|
+
"privacy": "private",
|
|
533
|
+
"default": "null"
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
"kind": "field",
|
|
537
|
+
"name": "bodyScrollUnlock",
|
|
538
|
+
"type": {
|
|
539
|
+
"text": "(() => void) | null"
|
|
540
|
+
},
|
|
541
|
+
"privacy": "private",
|
|
542
|
+
"default": "null"
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
"kind": "field",
|
|
546
|
+
"name": "keyboardInsetCleanup",
|
|
547
|
+
"type": {
|
|
548
|
+
"text": "(() => void) | null"
|
|
549
|
+
},
|
|
550
|
+
"privacy": "private",
|
|
551
|
+
"default": "null"
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
"kind": "field",
|
|
555
|
+
"name": "overlayHistoryActive",
|
|
556
|
+
"type": {
|
|
557
|
+
"text": "boolean"
|
|
558
|
+
},
|
|
559
|
+
"privacy": "private",
|
|
560
|
+
"default": "false"
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
"kind": "field",
|
|
564
|
+
"name": "onOverlayPopstate",
|
|
565
|
+
"privacy": "private",
|
|
566
|
+
"readonly": true
|
|
567
|
+
},
|
|
454
568
|
{
|
|
455
569
|
"kind": "field",
|
|
456
570
|
"name": "dropdownCleanup",
|
|
@@ -484,6 +598,60 @@
|
|
|
484
598
|
"privacy": "private",
|
|
485
599
|
"default": "new Map<string, TooltipHandle>()"
|
|
486
600
|
},
|
|
601
|
+
{
|
|
602
|
+
"kind": "field",
|
|
603
|
+
"name": "labelRevealTrigger",
|
|
604
|
+
"type": {
|
|
605
|
+
"text": "HTMLElement | null"
|
|
606
|
+
},
|
|
607
|
+
"privacy": "private",
|
|
608
|
+
"default": "null"
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
"kind": "field",
|
|
612
|
+
"name": "labelRevealPanel",
|
|
613
|
+
"type": {
|
|
614
|
+
"text": "HTMLDivElement | null"
|
|
615
|
+
},
|
|
616
|
+
"privacy": "private",
|
|
617
|
+
"default": "null"
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
"kind": "field",
|
|
621
|
+
"name": "labelRevealPopover",
|
|
622
|
+
"type": {
|
|
623
|
+
"text": "PopoverHandle | null"
|
|
624
|
+
},
|
|
625
|
+
"privacy": "private",
|
|
626
|
+
"default": "null"
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
"kind": "field",
|
|
630
|
+
"name": "messageEl",
|
|
631
|
+
"type": {
|
|
632
|
+
"text": "HTMLDivElement | null"
|
|
633
|
+
},
|
|
634
|
+
"privacy": "private",
|
|
635
|
+
"default": "null"
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
"kind": "field",
|
|
639
|
+
"name": "messageCleanup",
|
|
640
|
+
"type": {
|
|
641
|
+
"text": "(() => void) | null"
|
|
642
|
+
},
|
|
643
|
+
"privacy": "private",
|
|
644
|
+
"default": "null"
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
"kind": "field",
|
|
648
|
+
"name": "messageTimer",
|
|
649
|
+
"type": {
|
|
650
|
+
"text": "ReturnType<typeof setTimeout> | null"
|
|
651
|
+
},
|
|
652
|
+
"privacy": "private",
|
|
653
|
+
"default": "null"
|
|
654
|
+
},
|
|
487
655
|
{
|
|
488
656
|
"kind": "field",
|
|
489
657
|
"name": "onDropdownScroll",
|
|
@@ -1010,6 +1178,28 @@
|
|
|
1010
1178
|
],
|
|
1011
1179
|
"description": "Tree mode: derive the visible list from an **external** set of matched\r\noptions — e.g. the results returned by `searchCallback` — keeping each\r\nmatch's ancestors so indentation stays coherent. This is the async-search\r\nanalogue of `rebuildTreeVisible`: the matching is done by the caller (their\r\nown index/engine) instead of a local substring test, but ancestor\r\npreservation and `treeNodes`/`filteredOptions` index-alignment still happen\r\nhere. Pass all options to show the whole tree."
|
|
1012
1180
|
},
|
|
1181
|
+
{
|
|
1182
|
+
"kind": "method",
|
|
1183
|
+
"name": "detectRTL",
|
|
1184
|
+
"privacy": "private",
|
|
1185
|
+
"return": {
|
|
1186
|
+
"type": {
|
|
1187
|
+
"text": "void"
|
|
1188
|
+
}
|
|
1189
|
+
},
|
|
1190
|
+
"description": "(Re)compute `isRTL` from the host's `dir` (or an RTL ancestor) and derive the\r\ndirection-mirrored badges position. Pure state — callers apply the DOM effects\r\n(class toggle, panel `dir`, badge re-render). In Shadow DOM the `dir` lives on\r\nthe host element, not the shadow content, so we resolve the host first."
|
|
1191
|
+
},
|
|
1192
|
+
{
|
|
1193
|
+
"kind": "method",
|
|
1194
|
+
"name": "refreshDirection",
|
|
1195
|
+
"privacy": "public",
|
|
1196
|
+
"return": {
|
|
1197
|
+
"type": {
|
|
1198
|
+
"text": "void"
|
|
1199
|
+
}
|
|
1200
|
+
},
|
|
1201
|
+
"description": "Re-read `dir` and re-apply RTL mirroring live. The web-component calls this when\r\nits `dir` attribute changes at runtime (e.g. an app-wide language/direction\r\nswitch). Most layout follows the inherited CSS `direction` automatically (the\r\ncomponent is authored with logical properties); this fixes the parts pinned at\r\nbuild time — the `.ms--rtl` class (badges/count-display placement) and the\r\nexplicit `dir` on the shadow-root-appended panels (which don't sit under the\r\n`.ms--rtl` element, so they'd otherwise keep a stale build-time direction)."
|
|
1202
|
+
},
|
|
1013
1203
|
{
|
|
1014
1204
|
"kind": "method",
|
|
1015
1205
|
"name": "buildHTML",
|
|
@@ -1050,7 +1240,16 @@
|
|
|
1050
1240
|
"type": {
|
|
1051
1241
|
"text": "void"
|
|
1052
1242
|
}
|
|
1053
|
-
}
|
|
1243
|
+
},
|
|
1244
|
+
"parameters": [
|
|
1245
|
+
{
|
|
1246
|
+
"name": "opts",
|
|
1247
|
+
"optional": true,
|
|
1248
|
+
"type": {
|
|
1249
|
+
"text": "{ preserveScroll?: boolean }"
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
]
|
|
1054
1253
|
},
|
|
1055
1254
|
{
|
|
1056
1255
|
"kind": "method",
|
|
@@ -1116,6 +1315,17 @@
|
|
|
1116
1315
|
}
|
|
1117
1316
|
]
|
|
1118
1317
|
},
|
|
1318
|
+
{
|
|
1319
|
+
"kind": "method",
|
|
1320
|
+
"name": "renderOptionInfoButton",
|
|
1321
|
+
"privacy": "private",
|
|
1322
|
+
"return": {
|
|
1323
|
+
"type": {
|
|
1324
|
+
"text": "string"
|
|
1325
|
+
}
|
|
1326
|
+
},
|
|
1327
|
+
"description": "Trailing info affordance for an option row, emitted only for the fullscreen\r\noverlay. CSS keeps it hidden until `markTruncatedOptions()` tags the row\r\n`.ms__option--truncated`, so it appears only when the label is actually clipped.\r\nTapping it reveals the full label — the touch substitute for the hover option\r\ntooltip, which never fires on touch (the very devices that get fullscreen).\r\n`tabindex=\"-1\"` keeps it out of the tab order; the search input owns keyboarding."
|
|
1328
|
+
},
|
|
1119
1329
|
{
|
|
1120
1330
|
"kind": "method",
|
|
1121
1331
|
"name": "renderTreeNode",
|
|
@@ -1531,49 +1741,313 @@
|
|
|
1531
1741
|
"text": "T"
|
|
1532
1742
|
}
|
|
1533
1743
|
}
|
|
1534
|
-
],
|
|
1535
|
-
"description": "The single funnel for an interactive (user-initiated) selection. Consults\r\n`beforeSelectCallback` and only mutates state if allowed, so the veto can\r\nnever be bypassed by a new UI entry point. Programmatic `setSelected` and\r\nthe Select-All button deliberately do not route through here.\r\nReturns true if the option was selected, false if the veto blocked it."
|
|
1744
|
+
],
|
|
1745
|
+
"description": "The single funnel for an interactive (user-initiated) selection. Consults\r\n`beforeSelectCallback` and only mutates state if allowed, so the veto can\r\nnever be bypassed by a new UI entry point. Programmatic `setSelected` and\r\nthe Select-All button deliberately do not route through here.\r\nReturns true if the option was selected, false if the veto blocked it."
|
|
1746
|
+
},
|
|
1747
|
+
{
|
|
1748
|
+
"kind": "method",
|
|
1749
|
+
"name": "interactiveDeselect",
|
|
1750
|
+
"privacy": "private",
|
|
1751
|
+
"return": {
|
|
1752
|
+
"type": {
|
|
1753
|
+
"text": "boolean"
|
|
1754
|
+
}
|
|
1755
|
+
},
|
|
1756
|
+
"parameters": [
|
|
1757
|
+
{
|
|
1758
|
+
"name": "option",
|
|
1759
|
+
"type": {
|
|
1760
|
+
"text": "T"
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
],
|
|
1764
|
+
"description": "The single funnel for an interactive (user-initiated) deselection. Every\r\nremoval affordance — dropdown toggle, badge × button, selected-items\r\npopover × button, and the \"remove hidden\" badge — routes through here so\r\nthe `beforeDeselectCallback` veto applies uniformly. Programmatic\r\n`setSelected` and the Clear-All button deliberately bypass it.\r\nReturns true if the option was deselected, false if the veto blocked it."
|
|
1765
|
+
},
|
|
1766
|
+
{
|
|
1767
|
+
"kind": "method",
|
|
1768
|
+
"name": "handleAddNew",
|
|
1769
|
+
"privacy": "private",
|
|
1770
|
+
"return": {
|
|
1771
|
+
"type": {
|
|
1772
|
+
"text": "Promise<void>"
|
|
1773
|
+
}
|
|
1774
|
+
},
|
|
1775
|
+
"parameters": [
|
|
1776
|
+
{
|
|
1777
|
+
"name": "value",
|
|
1778
|
+
"type": {
|
|
1779
|
+
"text": "string"
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
]
|
|
1783
|
+
},
|
|
1784
|
+
{
|
|
1785
|
+
"kind": "method",
|
|
1786
|
+
"name": "selectOption",
|
|
1787
|
+
"privacy": "private",
|
|
1788
|
+
"return": {
|
|
1789
|
+
"type": {
|
|
1790
|
+
"text": "void"
|
|
1791
|
+
}
|
|
1792
|
+
},
|
|
1793
|
+
"parameters": [
|
|
1794
|
+
{
|
|
1795
|
+
"name": "option",
|
|
1796
|
+
"type": {
|
|
1797
|
+
"text": "T"
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
]
|
|
1801
|
+
},
|
|
1802
|
+
{
|
|
1803
|
+
"kind": "method",
|
|
1804
|
+
"name": "deselectOption",
|
|
1805
|
+
"privacy": "private",
|
|
1806
|
+
"return": {
|
|
1807
|
+
"type": {
|
|
1808
|
+
"text": "void"
|
|
1809
|
+
}
|
|
1810
|
+
},
|
|
1811
|
+
"parameters": [
|
|
1812
|
+
{
|
|
1813
|
+
"name": "option",
|
|
1814
|
+
"type": {
|
|
1815
|
+
"text": "T"
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
]
|
|
1819
|
+
},
|
|
1820
|
+
{
|
|
1821
|
+
"kind": "method",
|
|
1822
|
+
"name": "selectAll",
|
|
1823
|
+
"privacy": "private",
|
|
1824
|
+
"return": {
|
|
1825
|
+
"type": {
|
|
1826
|
+
"text": "void"
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
},
|
|
1830
|
+
{
|
|
1831
|
+
"kind": "method",
|
|
1832
|
+
"name": "clearAll",
|
|
1833
|
+
"privacy": "public",
|
|
1834
|
+
"return": {
|
|
1835
|
+
"type": {
|
|
1836
|
+
"text": "void"
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
},
|
|
1840
|
+
{
|
|
1841
|
+
"kind": "method",
|
|
1842
|
+
"name": "commit",
|
|
1843
|
+
"privacy": "private",
|
|
1844
|
+
"return": {
|
|
1845
|
+
"type": {
|
|
1846
|
+
"text": "void"
|
|
1847
|
+
}
|
|
1848
|
+
},
|
|
1849
|
+
"parameters": [
|
|
1850
|
+
{
|
|
1851
|
+
"name": "delta",
|
|
1852
|
+
"type": {
|
|
1853
|
+
"text": "{ added?: T[]; removed?: T[] }"
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
],
|
|
1857
|
+
"description": "Re-render and fire callbacks after a selection state change.\r\n`added` / `removed` drive per-item select/deselect callbacks.\r\n`onChange` fires once if anything actually changed."
|
|
1858
|
+
},
|
|
1859
|
+
{
|
|
1860
|
+
"kind": "method",
|
|
1861
|
+
"name": "open",
|
|
1862
|
+
"privacy": "private",
|
|
1863
|
+
"return": {
|
|
1864
|
+
"type": {
|
|
1865
|
+
"text": "void"
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
},
|
|
1869
|
+
{
|
|
1870
|
+
"kind": "method",
|
|
1871
|
+
"name": "close",
|
|
1872
|
+
"privacy": "private",
|
|
1873
|
+
"return": {
|
|
1874
|
+
"type": {
|
|
1875
|
+
"text": "void"
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
},
|
|
1879
|
+
{
|
|
1880
|
+
"kind": "method",
|
|
1881
|
+
"name": "anchorFloatingPanel",
|
|
1882
|
+
"privacy": "private",
|
|
1883
|
+
"return": {
|
|
1884
|
+
"type": {
|
|
1885
|
+
"text": "() => void"
|
|
1886
|
+
}
|
|
1887
|
+
},
|
|
1888
|
+
"parameters": [
|
|
1889
|
+
{
|
|
1890
|
+
"name": "panel",
|
|
1891
|
+
"type": {
|
|
1892
|
+
"text": "HTMLElement"
|
|
1893
|
+
}
|
|
1894
|
+
},
|
|
1895
|
+
{
|
|
1896
|
+
"name": "opts",
|
|
1897
|
+
"type": {
|
|
1898
|
+
"text": "{\r\n getPlacement: () => Placement | null;\r\n setPlacement: (p: Placement) => void;\r\n /** When false, never locks (re-flips on every update). Defaults to true. */\r\n isLocked?: () => boolean;\r\n applyMaxWidth?: boolean;\r\n afterPosition?: () => void;\r\n }"
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
],
|
|
1902
|
+
"description": "Anchor a floating panel (dropdown or selected-items popover) below/above the input with\r\nplacement-locking and width-syncing. Returns the `autoUpdate` cleanup.\r\n\r\nBoth panels share: anchor on input, sync width, default to 'bottom-start', flip on first\r\ncompute then lock the resulting placement, optionally clamp by dropdownMin/MaxWidth."
|
|
1903
|
+
},
|
|
1904
|
+
{
|
|
1905
|
+
"kind": "method",
|
|
1906
|
+
"name": "warnDrift",
|
|
1907
|
+
"privacy": "private",
|
|
1908
|
+
"return": {
|
|
1909
|
+
"type": {
|
|
1910
|
+
"text": "void"
|
|
1911
|
+
}
|
|
1912
|
+
},
|
|
1913
|
+
"parameters": [
|
|
1914
|
+
{
|
|
1915
|
+
"name": "drift",
|
|
1916
|
+
"type": {
|
|
1917
|
+
"text": "DriftReport"
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
],
|
|
1921
|
+
"description": "Surface a multiselect-branded, once-per-instance warning when core's drift check\r\n(`anchor`'s `onDrift`) reports the panel didn't land where it was positioned. The\r\nconsumer has an ancestor that establishes a fixed containing block but isn't on the\r\nreliable-anchors list (likely `contain: paint|layout|strict` or `container-type`).\r\nWe can't fix it from inside the library, but we point at the likely culprit. Core\r\nowns the measurement + culprit-finding + CB-CSS diagnostic (`detectFixedDrift`)."
|
|
1922
|
+
},
|
|
1923
|
+
{
|
|
1924
|
+
"kind": "method",
|
|
1925
|
+
"name": "positionDropdown",
|
|
1926
|
+
"privacy": "private",
|
|
1927
|
+
"return": {
|
|
1928
|
+
"type": {
|
|
1929
|
+
"text": "void"
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
},
|
|
1933
|
+
{
|
|
1934
|
+
"kind": "method",
|
|
1935
|
+
"name": "setPresentation",
|
|
1936
|
+
"privacy": "public",
|
|
1937
|
+
"return": {
|
|
1938
|
+
"type": {
|
|
1939
|
+
"text": "void"
|
|
1940
|
+
}
|
|
1941
|
+
},
|
|
1942
|
+
"parameters": [
|
|
1943
|
+
{
|
|
1944
|
+
"name": "mode",
|
|
1945
|
+
"type": {
|
|
1946
|
+
"text": "'floating' | 'fullscreen'"
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
],
|
|
1950
|
+
"description": "Switch how the open panels are presented. 'floating' anchors them to the input\r\n(the default); 'fullscreen' renders them as full-viewport overlays (the phone\r\npattern) — the dropdown with its own search header + close, the selected-items\r\npopover with its existing header + close. Driven by the element's\r\n`environmentChanged` hook (auto → fullscreen on phones). A no-op when unchanged;\r\nwhen a panel is already open it re-applies live so an orientation flip / viewport\r\nresize can swap presentation without a reopen."
|
|
1951
|
+
},
|
|
1952
|
+
{
|
|
1953
|
+
"kind": "method",
|
|
1954
|
+
"name": "lockBodyScroll",
|
|
1955
|
+
"privacy": "private",
|
|
1956
|
+
"return": {
|
|
1957
|
+
"type": {
|
|
1958
|
+
"text": "void"
|
|
1959
|
+
}
|
|
1960
|
+
},
|
|
1961
|
+
"description": "Lock page scroll behind a fullscreen overlay via the core ref-counted helper.\r\nIdempotent per instance: the dropdown and the selected-items popover are mutually\r\nexclusive (opening one closes the other), so we hold at most one lock at a time,\r\nand a redundant call is a no-op rather than acquiring a second."
|
|
1962
|
+
},
|
|
1963
|
+
{
|
|
1964
|
+
"kind": "method",
|
|
1965
|
+
"name": "unlockBodyScroll",
|
|
1966
|
+
"privacy": "private",
|
|
1967
|
+
"return": {
|
|
1968
|
+
"type": {
|
|
1969
|
+
"text": "void"
|
|
1970
|
+
}
|
|
1971
|
+
},
|
|
1972
|
+
"description": "Restore page scroll (no-op if it wasn't locked)."
|
|
1973
|
+
},
|
|
1974
|
+
{
|
|
1975
|
+
"kind": "method",
|
|
1976
|
+
"name": "observeKeyboardInset",
|
|
1977
|
+
"privacy": "private",
|
|
1978
|
+
"return": {
|
|
1979
|
+
"type": {
|
|
1980
|
+
"text": "void"
|
|
1981
|
+
}
|
|
1982
|
+
},
|
|
1983
|
+
"description": "While the fullscreen dropdown is open, keep it sitting above the soft keyboard.\r\nDelegates to core's `observeKeyboardInset` (which tracks `window.visualViewport`\r\nand pins the panel's height/top so its flex column reflows above the keyboard);\r\nwe just hold the returned cleanup. No-op where `visualViewport` is unavailable."
|
|
1984
|
+
},
|
|
1985
|
+
{
|
|
1986
|
+
"kind": "method",
|
|
1987
|
+
"name": "unobserveKeyboardInset",
|
|
1988
|
+
"privacy": "private",
|
|
1989
|
+
"return": {
|
|
1990
|
+
"type": {
|
|
1991
|
+
"text": "void"
|
|
1992
|
+
}
|
|
1993
|
+
},
|
|
1994
|
+
"description": "Detach keyboard-inset tracking and restore the panel's CSS-driven geometry."
|
|
1995
|
+
},
|
|
1996
|
+
{
|
|
1997
|
+
"kind": "method",
|
|
1998
|
+
"name": "fullscreenScale",
|
|
1999
|
+
"privacy": "private",
|
|
2000
|
+
"return": {
|
|
2001
|
+
"type": {
|
|
2002
|
+
"text": "number"
|
|
2003
|
+
}
|
|
2004
|
+
},
|
|
2005
|
+
"description": "The fullscreen size multiplier = `--ms-fullscreen-rem ÷ --ms-rem` (both read off\r\nthe host). CSS scales itself — every size is `calc(N × --ms-rem)` and the panel\r\noverrides `--ms-rem` — so this exists only for the JS-driven pixel heights that\r\nCSS can't reach: the virtual/fixed option rows and the popover's virtual badges.\r\nReturns 1 when floating (or when computed styles aren't readable, e.g. jsdom)."
|
|
2006
|
+
},
|
|
2007
|
+
{
|
|
2008
|
+
"kind": "method",
|
|
2009
|
+
"name": "scaledOptionHeight",
|
|
2010
|
+
"privacy": "private",
|
|
2011
|
+
"return": {
|
|
2012
|
+
"type": {
|
|
2013
|
+
"text": "number"
|
|
2014
|
+
}
|
|
2015
|
+
},
|
|
2016
|
+
"description": "Virtual/fixed row height (px), scaled up in the fullscreen phone view."
|
|
1536
2017
|
},
|
|
1537
2018
|
{
|
|
1538
2019
|
"kind": "method",
|
|
1539
|
-
"name": "
|
|
2020
|
+
"name": "applyVirtualOptionsSizing",
|
|
1540
2021
|
"privacy": "private",
|
|
1541
2022
|
"return": {
|
|
1542
2023
|
"type": {
|
|
1543
|
-
"text": "
|
|
2024
|
+
"text": "void"
|
|
1544
2025
|
}
|
|
1545
2026
|
},
|
|
1546
2027
|
"parameters": [
|
|
1547
2028
|
{
|
|
1548
|
-
"name": "
|
|
2029
|
+
"name": "container",
|
|
1549
2030
|
"type": {
|
|
1550
|
-
"text": "
|
|
2031
|
+
"text": "HTMLElement"
|
|
1551
2032
|
}
|
|
1552
2033
|
}
|
|
1553
2034
|
],
|
|
1554
|
-
"description": "
|
|
2035
|
+
"description": "Size the virtual options scroll container for the current presentation. Applied on\r\nevery render (the container itself is built once), so a floating⇄fullscreen switch\r\nre-sizes it: floating = a fixed maxHeight scroll box; fullscreen = flex-fill the\r\npanel's flex column (no fixed height). Also refreshes --ms-option-height to the\r\nscaled row height so the CSS row height matches the virtual scroller's itemHeight."
|
|
1555
2036
|
},
|
|
1556
2037
|
{
|
|
1557
2038
|
"kind": "method",
|
|
1558
|
-
"name": "
|
|
2039
|
+
"name": "scaledBadgeHeight",
|
|
1559
2040
|
"privacy": "private",
|
|
1560
2041
|
"return": {
|
|
1561
2042
|
"type": {
|
|
1562
|
-
"text": "
|
|
2043
|
+
"text": "number"
|
|
1563
2044
|
}
|
|
1564
2045
|
},
|
|
1565
|
-
"
|
|
1566
|
-
{
|
|
1567
|
-
"name": "value",
|
|
1568
|
-
"type": {
|
|
1569
|
-
"text": "string"
|
|
1570
|
-
}
|
|
1571
|
-
}
|
|
1572
|
-
]
|
|
2046
|
+
"description": "Virtual popover badge row height (px). In the fullscreen phone view the rows are\r\nscaled up AND given extra height so a selected item is a comfortable, dropdown-like\r\ntouch target (the default 36px pill is short for touch). Mirrors the CSS\r\n`--ms-badge-height` override for the fullscreen popover (floating.css) so the\r\nvirtual list's fixed height agrees with the non-virtual pills."
|
|
1573
2047
|
},
|
|
1574
2048
|
{
|
|
1575
2049
|
"kind": "method",
|
|
1576
|
-
"name": "
|
|
2050
|
+
"name": "clearFloatingInlineGeometry",
|
|
1577
2051
|
"privacy": "private",
|
|
1578
2052
|
"return": {
|
|
1579
2053
|
"type": {
|
|
@@ -1582,143 +2056,112 @@
|
|
|
1582
2056
|
},
|
|
1583
2057
|
"parameters": [
|
|
1584
2058
|
{
|
|
1585
|
-
"name": "
|
|
2059
|
+
"name": "panel",
|
|
1586
2060
|
"type": {
|
|
1587
|
-
"text": "
|
|
2061
|
+
"text": "HTMLElement"
|
|
1588
2062
|
}
|
|
1589
2063
|
}
|
|
1590
|
-
]
|
|
2064
|
+
],
|
|
2065
|
+
"description": "Clear the inline geometry that floating-ui's `anchor` writes on a panel\r\n(position/left/top plus our composed max-width/min-width). Inline styles beat\r\nthe stylesheet, so a panel left over from a floating cycle would otherwise pin\r\nitself where it last anchored and ignore the fullscreen CSS (position: fixed;\r\ninset: 0; width: 100vw). Must run when switching a panel floating → fullscreen."
|
|
1591
2066
|
},
|
|
1592
2067
|
{
|
|
1593
2068
|
"kind": "method",
|
|
1594
|
-
"name": "
|
|
2069
|
+
"name": "enterFullscreen",
|
|
1595
2070
|
"privacy": "private",
|
|
1596
2071
|
"return": {
|
|
1597
2072
|
"type": {
|
|
1598
2073
|
"text": "void"
|
|
1599
2074
|
}
|
|
1600
2075
|
},
|
|
1601
|
-
"
|
|
1602
|
-
{
|
|
1603
|
-
"name": "option",
|
|
1604
|
-
"type": {
|
|
1605
|
-
"text": "T"
|
|
1606
|
-
}
|
|
1607
|
-
}
|
|
1608
|
-
]
|
|
2076
|
+
"description": "Stand up the fullscreen dropdown overlay: modifier class, header, scroll lock, focus."
|
|
1609
2077
|
},
|
|
1610
2078
|
{
|
|
1611
2079
|
"kind": "method",
|
|
1612
|
-
"name": "
|
|
2080
|
+
"name": "exitFullscreen",
|
|
1613
2081
|
"privacy": "private",
|
|
1614
2082
|
"return": {
|
|
1615
2083
|
"type": {
|
|
1616
2084
|
"text": "void"
|
|
1617
2085
|
}
|
|
1618
|
-
}
|
|
2086
|
+
},
|
|
2087
|
+
"description": "Tear down the fullscreen dropdown chrome and restore page scroll (no-op if floating)."
|
|
1619
2088
|
},
|
|
1620
2089
|
{
|
|
1621
2090
|
"kind": "method",
|
|
1622
|
-
"name": "
|
|
1623
|
-
"privacy": "
|
|
2091
|
+
"name": "pushOverlayHistory",
|
|
2092
|
+
"privacy": "private",
|
|
1624
2093
|
"return": {
|
|
1625
2094
|
"type": {
|
|
1626
2095
|
"text": "void"
|
|
1627
2096
|
}
|
|
1628
|
-
}
|
|
2097
|
+
},
|
|
2098
|
+
"description": "Back-gesture handling for the fullscreen sheet. On open we push a history entry\r\n(same URL) and listen for `popstate`; the phone Back gesture/button then pops that\r\nentry — which we treat as \"close the sheet\" — instead of navigating away from the\r\npage. A programmatic close (✕, selection, Escape) consumes the entry via\r\n`history.back()` so the stack is left as it was found."
|
|
1629
2099
|
},
|
|
1630
2100
|
{
|
|
1631
2101
|
"kind": "method",
|
|
1632
|
-
"name": "
|
|
2102
|
+
"name": "handleOverlayPopstate",
|
|
1633
2103
|
"privacy": "private",
|
|
1634
2104
|
"return": {
|
|
1635
2105
|
"type": {
|
|
1636
2106
|
"text": "void"
|
|
1637
2107
|
}
|
|
1638
2108
|
},
|
|
1639
|
-
"
|
|
1640
|
-
{
|
|
1641
|
-
"name": "delta",
|
|
1642
|
-
"type": {
|
|
1643
|
-
"text": "{ added?: T[]; removed?: T[] }"
|
|
1644
|
-
}
|
|
1645
|
-
}
|
|
1646
|
-
],
|
|
1647
|
-
"description": "Re-render and fire callbacks after a selection state change.\r\n`added` / `removed` drive per-item select/deselect callbacks.\r\n`onChange` fires once if anything actually changed."
|
|
2109
|
+
"description": "Back gesture/button fired: our pushed entry is already gone, so just close the\r\nsheet — WITHOUT popping history again (popOverlayHistory becomes a no-op)."
|
|
1648
2110
|
},
|
|
1649
2111
|
{
|
|
1650
2112
|
"kind": "method",
|
|
1651
|
-
"name": "
|
|
2113
|
+
"name": "popOverlayHistory",
|
|
1652
2114
|
"privacy": "private",
|
|
1653
2115
|
"return": {
|
|
1654
2116
|
"type": {
|
|
1655
2117
|
"text": "void"
|
|
1656
2118
|
}
|
|
1657
|
-
}
|
|
2119
|
+
},
|
|
2120
|
+
"description": "Programmatic close: remove the listener and pop the entry we pushed (so the\r\nhistory stack returns to its pre-open state). No-op if a Back gesture already\r\nconsumed it (overlayHistoryActive is false by then)."
|
|
1658
2121
|
},
|
|
1659
2122
|
{
|
|
1660
2123
|
"kind": "method",
|
|
1661
|
-
"name": "
|
|
2124
|
+
"name": "buildFullscreenHeader",
|
|
1662
2125
|
"privacy": "private",
|
|
1663
2126
|
"return": {
|
|
1664
2127
|
"type": {
|
|
1665
2128
|
"text": "void"
|
|
1666
2129
|
}
|
|
1667
|
-
}
|
|
2130
|
+
},
|
|
2131
|
+
"description": "Build the fullscreen overlay header: a search field (proxying to the same\r\n`handleSearch`/`handleKeydown` path as the main input, since the overlay covers\r\nit) plus a close button. Inserted before the scrolling list so it pins to the\r\ntop of the fixed panel. `renderDropdown()` only rewrites `dropdownInner`, so the\r\nheader survives re-renders."
|
|
1668
2132
|
},
|
|
1669
2133
|
{
|
|
1670
2134
|
"kind": "method",
|
|
1671
|
-
"name": "
|
|
2135
|
+
"name": "updateFullscreenNav",
|
|
1672
2136
|
"privacy": "private",
|
|
1673
2137
|
"return": {
|
|
1674
2138
|
"type": {
|
|
1675
|
-
"text": "
|
|
2139
|
+
"text": "void"
|
|
1676
2140
|
}
|
|
1677
2141
|
},
|
|
1678
|
-
"
|
|
1679
|
-
{
|
|
1680
|
-
"name": "panel",
|
|
1681
|
-
"type": {
|
|
1682
|
-
"text": "HTMLElement"
|
|
1683
|
-
}
|
|
1684
|
-
},
|
|
1685
|
-
{
|
|
1686
|
-
"name": "opts",
|
|
1687
|
-
"type": {
|
|
1688
|
-
"text": "{\r\n getPlacement: () => Placement | null;\r\n setPlacement: (p: Placement) => void;\r\n /** When false, never locks (re-flips on every update). Defaults to true. */\r\n isLocked?: () => boolean;\r\n applyMaxWidth?: boolean;\r\n afterPosition?: () => void;\r\n }"
|
|
1689
|
-
}
|
|
1690
|
-
}
|
|
1691
|
-
],
|
|
1692
|
-
"description": "Anchor a floating panel (dropdown or selected-items popover) below/above the input with\r\nplacement-locking and width-syncing. Returns the `autoUpdate` cleanup.\r\n\r\nBoth panels share: anchor on input, sync width, default to 'bottom-start', flip on first\r\ncompute then lock the resulting placement, optionally clamp by dropdownMin/MaxWidth."
|
|
2142
|
+
"description": "Sync the fullscreen match navigator (navigate mode only) with the current search\r\nstate: hide it until there's a term, then show \"N of M\" while a match is focused\r\n(or \"M matches\" / \"No matches\"), and disable the prev/next buttons when there's\r\nnothing to step through. No-op when the navigator isn't built (floating panel,\r\nfilter mode, or search disabled)."
|
|
1693
2143
|
},
|
|
1694
2144
|
{
|
|
1695
2145
|
"kind": "method",
|
|
1696
|
-
"name": "
|
|
2146
|
+
"name": "updateFullscreenSearchClear",
|
|
1697
2147
|
"privacy": "private",
|
|
1698
2148
|
"return": {
|
|
1699
2149
|
"type": {
|
|
1700
2150
|
"text": "void"
|
|
1701
2151
|
}
|
|
1702
2152
|
},
|
|
1703
|
-
"
|
|
1704
|
-
{
|
|
1705
|
-
"name": "drift",
|
|
1706
|
-
"type": {
|
|
1707
|
-
"text": "DriftReport"
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
],
|
|
1711
|
-
"description": "Surface a multiselect-branded, once-per-instance warning when core's drift check\r\n(`anchor`'s `onDrift`) reports the panel didn't land where it was positioned. The\r\nconsumer has an ancestor that establishes a fixed containing block but isn't on the\r\nreliable-anchors list (likely `contain: paint|layout|strict` or `container-type`).\r\nWe can't fix it from inside the library, but we point at the likely culprit. Core\r\nowns the measurement + culprit-finding + CB-CSS diagnostic (`detectFixedDrift`)."
|
|
2153
|
+
"description": "Show the fullscreen search's inline clear (✕) only while the field has text.\r\nNo-op when the button isn't built (floating panel, readonly/hidden search)."
|
|
1712
2154
|
},
|
|
1713
2155
|
{
|
|
1714
2156
|
"kind": "method",
|
|
1715
|
-
"name": "
|
|
2157
|
+
"name": "clearFullscreenSearch",
|
|
1716
2158
|
"privacy": "private",
|
|
1717
2159
|
"return": {
|
|
1718
2160
|
"type": {
|
|
1719
2161
|
"text": "void"
|
|
1720
2162
|
}
|
|
1721
|
-
}
|
|
2163
|
+
},
|
|
2164
|
+
"description": "Clear the fullscreen search term via the same path a keystroke takes, then\r\nrefocus the field so the user can keep typing. Touch has no keyboard Escape,\r\nso this button is the on-screen way to reset a search."
|
|
1722
2165
|
},
|
|
1723
2166
|
{
|
|
1724
2167
|
"kind": "method",
|
|
@@ -2094,6 +2537,84 @@
|
|
|
2094
2537
|
},
|
|
2095
2538
|
"description": "Attach hover tooltips to the currently rendered dropdown options. Prunes existing option\r\ntooltips first, so it's safe to call on every render and on every virtual-scroll range change\r\n(where option DOM is recycled). Each option resolves its source object via `data-index` into\r\n`filteredOptions`, the same global index `renderOption` was given."
|
|
2096
2539
|
},
|
|
2540
|
+
{
|
|
2541
|
+
"kind": "method",
|
|
2542
|
+
"name": "markTruncatedOptions",
|
|
2543
|
+
"privacy": "private",
|
|
2544
|
+
"return": {
|
|
2545
|
+
"type": {
|
|
2546
|
+
"text": "void"
|
|
2547
|
+
}
|
|
2548
|
+
},
|
|
2549
|
+
"description": "Tag each currently-rendered fullscreen option row whose title is horizontally\r\nclipped with `.ms__option--truncated`, so CSS reveals its info affordance.\r\nRuns per virtual-scroll render (rows recycle) and on the non-virtual render.\r\nHorizontal (ellipsis) overflow only — the truncation mode this pairs with;\r\na wrapping title isn't \"cut\", it grows vertically. No-op unless fullscreen."
|
|
2550
|
+
},
|
|
2551
|
+
{
|
|
2552
|
+
"kind": "method",
|
|
2553
|
+
"name": "toggleLabelReveal",
|
|
2554
|
+
"privacy": "private",
|
|
2555
|
+
"return": {
|
|
2556
|
+
"type": {
|
|
2557
|
+
"text": "void"
|
|
2558
|
+
}
|
|
2559
|
+
},
|
|
2560
|
+
"parameters": [
|
|
2561
|
+
{
|
|
2562
|
+
"name": "infoBtn",
|
|
2563
|
+
"type": {
|
|
2564
|
+
"text": "HTMLElement"
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
],
|
|
2568
|
+
"description": "Reveal (or dismiss) the full label of a clipped fullscreen row when its info\r\naffordance is tapped — hover tooltips don't fire on touch, and a hover tooltip's\r\nsynthetic mouseleave (from the tap itself, under devtools touch emulation) would\r\nflash it away. So this is a manually-controlled `createPopover` panel, mounted in\r\nthe shadow root for component styling, that stays until explicitly dismissed:\r\na second tap on the same button, a list scroll, a re-render, an outside tap, or\r\nclosing the panel (see hideLabelReveal + its call sites). Tapping the same button\r\nwhile it's shown toggles it off."
|
|
2569
|
+
},
|
|
2570
|
+
{
|
|
2571
|
+
"kind": "method",
|
|
2572
|
+
"name": "hideLabelReveal",
|
|
2573
|
+
"privacy": "private",
|
|
2574
|
+
"return": {
|
|
2575
|
+
"type": {
|
|
2576
|
+
"text": "void"
|
|
2577
|
+
}
|
|
2578
|
+
},
|
|
2579
|
+
"description": "Dismiss the full-label reveal popover, if shown. Idempotent."
|
|
2580
|
+
},
|
|
2581
|
+
{
|
|
2582
|
+
"kind": "method",
|
|
2583
|
+
"name": "showMessage",
|
|
2584
|
+
"privacy": "public",
|
|
2585
|
+
"return": {
|
|
2586
|
+
"type": {
|
|
2587
|
+
"text": "void"
|
|
2588
|
+
}
|
|
2589
|
+
},
|
|
2590
|
+
"parameters": [
|
|
2591
|
+
{
|
|
2592
|
+
"name": "content",
|
|
2593
|
+
"type": {
|
|
2594
|
+
"text": "string | HTMLElement"
|
|
2595
|
+
}
|
|
2596
|
+
},
|
|
2597
|
+
{
|
|
2598
|
+
"name": "opts",
|
|
2599
|
+
"optional": true,
|
|
2600
|
+
"type": {
|
|
2601
|
+
"text": "MessageOptions"
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
],
|
|
2605
|
+
"description": "Show a transient message (\"toast\") on top of the component. Its reason for existing:\r\nin the fullscreen overlay the sheet covers the whole page, so a consumer can't surface\r\nfeedback (a blocked veto, a hint) where the user can see it. This renders above the\r\npanel in BOTH presentations — anchored under the control when floating, pinned to the\r\nbottom of the viewport (over the overlay) when fullscreen.\r\n\r\nContent is a string (plain text) or an HTMLElement (rich markup). `opts.variant`\r\n(info | warning | error | success) picks the tone; `opts.duration` sets auto-dismiss\r\n(0 = sticky). Tapping the message dismisses it. Only one shows at a time — a new call\r\nreplaces the previous. Also reached automatically when a veto callback returns a string."
|
|
2606
|
+
},
|
|
2607
|
+
{
|
|
2608
|
+
"kind": "method",
|
|
2609
|
+
"name": "hideMessage",
|
|
2610
|
+
"privacy": "public",
|
|
2611
|
+
"return": {
|
|
2612
|
+
"type": {
|
|
2613
|
+
"text": "void"
|
|
2614
|
+
}
|
|
2615
|
+
},
|
|
2616
|
+
"description": "Dismiss the transient message, if shown. Idempotent."
|
|
2617
|
+
},
|
|
2097
2618
|
{
|
|
2098
2619
|
"kind": "method",
|
|
2099
2620
|
"name": "hideOptionTooltips",
|
|
@@ -2636,7 +3157,7 @@
|
|
|
2636
3157
|
"name": "inputs",
|
|
2637
3158
|
"privacy": "protected",
|
|
2638
3159
|
"static": true,
|
|
2639
|
-
"default": "[ // ── Strings (cosmetic → update). Optional ones are nullable: absent → null ─ { configKey: 'searchHint', attribute: 'search-hint', converter: toText({ isNullable: true }), on: 'update', description: 'Small hint text shown beneath the search input.' }, { configKey: 'searchPlaceholder', attribute: 'search-placeholder', converter: toText({ default: 'Search...' }), on: 'update', description: 'Placeholder text for the search input.' }, { configKey: 'selectPlaceholder', attribute: 'select-placeholder', converter: toText({ default: 'Pick an option...' }), on: 'update', description: 'Placeholder shown on the control when nothing is selected.' }, { configKey: 'noDataPlaceholder', attribute: 'no-data-placeholder', converter: toText({ isNullable: true }), on: 'update', description: 'Text shown when there are no options at all.' }, { configKey: 'dropdownMinWidth', attribute: 'dropdown-min-width', converter: toText({ isNullable: true }), on: 'update', description: 'Minimum width of the dropdown panel (any CSS length).' }, { configKey: 'dropdownMaxWidth', attribute: 'dropdown-max-width', converter: toText({ isNullable: true }), on: 'update', description: 'Maximum width of the dropdown panel (any CSS length).' }, { configKey: 'maxHeight', attribute: 'max-height', converter: toText({ default: '20rem' }), on: 'update', description: 'Maximum height of the dropdown list before it scrolls.' }, { configKey: 'emptyMessage', attribute: 'empty-message', converter: toText({ default: 'No results found' }), on: 'update', description: 'Message shown when a search yields no matches.' }, { configKey: 'loadingMessage', attribute: 'loading-message', converter: toText({ default: 'Loading...' }), on: 'update', description: 'Message shown while options are loading.' }, { configKey: 'removeButtonTooltipText', attribute: 'remove-button-tooltip-text', converter: toText({ isNullable: true }), on: 'update', description: 'Tooltip text for a badge remove (×) button.' }, { configKey: 'formFieldId', attribute: 'name', converter: toText({ isNullable: true }), on: 'reinit', description: 'HTML form field name/id used for the hidden input(s).' }, // ── CSS-var sugar (mirrored to a host style prop in reinit()/update()) ──── { configKey: 'dropdownWidth', attribute: 'dropdown-width', converter: toText({ isNullable: true }), on: 'update', description: 'Fixed dropdown width; mirrored to the `--ms-dropdown-width` CSS variable.' }, { configKey: 'selectedPopoverWidth', attribute: 'selected-popover-width', converter: toText({ isNullable: true }), on: 'update', description: 'Selected-items popover width; mirrored to `--ms-selected-popover-width`.' }, // ── Member properties (structural → reinit; optional → nullable) ───────── { configKey: 'valueMember', attribute: 'value-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name on an option object that holds its value.' }, { configKey: 'displayValueMember', attribute: 'display-value-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that holds an option display label.' }, { configKey: 'searchValueMember', attribute: 'search-value-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name searched against (falls back to the display value).' }, { configKey: 'iconMember', attribute: 'icon-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that holds an option icon.' }, { configKey: 'subtitleMember', attribute: 'subtitle-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that holds an option subtitle.' }, { configKey: 'fullTitleMember', attribute: 'full-title-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that holds an option full/long title.' }, { configKey: 'groupMember', attribute: 'group-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name used to group options under headers.' }, { configKey: 'disabledMember', attribute: 'disabled-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that marks an option disabled.' }, // ── Tree of options (structural → reinit; optional → nullable) ─────────── { configKey: 'pathMember', attribute: 'path-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name holding a node materialized tree path.' }, { configKey: 'parentPathMember', attribute: 'parent-path-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name holding a node parent path.' }, { configKey: 'levelMember', attribute: 'level-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name holding a node depth level.' }, { configKey: 'hasChildrenMember', attribute: 'has-children-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name flagging that a node has children.' }, { configKey: 'isSelectableMember', attribute: 'is-selectable-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name marking whether a node can be selected.' }, { configKey: 'treePathSeparator', attribute: 'tree-path-separator', converter: toText({ default: '.' }), reflect: true, on: 'reinit', description: 'Separator between segments in a materialized tree path.' }, { configKey: 'isTreeEnabled', converter: toBool('tristate'), on: 'reinit', type: 'boolean', description: 'Force tree mode on/off. Property-only; when unset (null) tree mode auto-enables if a path source (path-member / getPathCallback) is present.' }, { configKey: 'checkboxMode', attribute: 'checkbox-mode', converter: toEnum(['independent', 'cascade'] as const, { default: 'independent' }), reflect: true, on: 'update', description: `Tree checkbox interaction. - \\`independent\\` (default) — toggles only the clicked node. - \\`cascade\\` — checks a node whole subtree and shows a tristate (checked / indeterminate / unchecked) box on branches. Tree + multiple only.` }, { configKey: 'cascadeSelectPolicy', attribute: 'cascade-select-policy', converter: toEnum(['rolled-up', 'leaves', 'all'] as const, { default: 'rolled-up' }), reflect: true, on: 'update', description: `In \\`cascade\\` mode, which values a selection emits (badges / form / change): - \\`rolled-up\\` (default) — minimal cover: a fully-selected subtree collapses to its root; partially-selected branches emit their individually-checked descendants. - \\`leaves\\` — only the checked leaf-level nodes. - \\`all\\` — every fully-checked node (branches and leaves).` }, // ── Enums ──────────────────────────────────────────────────────────────── { configKey: 'badgesDisplayMode', attribute: 'badges-display-mode', converter: toEnum(['badges', 'count', 'compact', 'partial', 'none'] as const, { default: 'badges' }), on: 'reinit', description: 'How the current selection is shown in the control.' }, { configKey: 'badgesPosition', attribute: 'badges-position', converter: toEnum(['top', 'bottom', 'left', 'right'] as const, { default: 'bottom' }), on: 'reinit', description: 'Where the badges/selection appear relative to the input.' }, { configKey: 'badgesThresholdMode', attribute: 'badges-threshold-mode', converter: toEnum(['count', 'partial'] as const, { default: 'count' }), on: 'update', description: 'How `badgesThreshold` is interpreted: collapse to a count badge, or keep partial badges + a \"more\" badge.' }, { configKey: 'searchInputMode', attribute: 'search-input-mode', converter: toEnum(['normal', 'readonly', 'hidden'] as const, { default: 'normal' }), on: 'reinit', description: 'Search field mode: editable, read-only, or hidden.' }, { configKey: 'searchMode', attribute: 'search-mode', converter: toEnum(['filter', 'navigate'] as const, { default: 'filter' }), on: 'reinit', description: 'Whether typing filters the list or navigates it.' }, { configKey: 'actionsLayout', attribute: 'actions-layout', converter: toEnum(['nowrap', 'wrap'] as const, { default: 'nowrap' }), on: 'reinit', description: 'Whether the action bar wraps or stays on one line.' }, { configKey: 'actionsPosition', attribute: 'actions-position', converter: toEnum(['top', 'bottom'] as const, { default: 'top' }), on: 'reinit', description: 'Whether the action bar sits above or below the list.' }, { configKey: 'actionsAlign', attribute: 'actions-align', converter: toEnum(['stretch', 'left', 'right', 'center', 'space-between'] as const, { default: 'stretch' }), on: 'update', description: 'Horizontal alignment of the action buttons.' }, { configKey: 'checkboxAlign', attribute: 'checkbox-align', converter: toEnum(['top', 'center', 'bottom'] as const, { default: 'center' }), on: 'update', description: 'Vertical alignment of an option checkbox.' }, { configKey: 'valueFormat', attribute: 'value-format', converter: toEnum(['json', 'csv', 'array'] as const, { default: 'json' }), on: 'reinit', description: 'Serialization format the control emits its value in.' }, { configKey: 'badgeTooltipPlacement', attribute: 'badge-tooltip-placement', converter: toEnum(PLACEMENTS, { default: 'top' }), on: 'update', description: 'Preferred placement of a badge tooltip relative to its badge (floating-ui placement).' }, { configKey: 'optionTooltipPlacement', attribute: 'option-tooltip-placement', converter: toEnum(PLACEMENTS, { default: 'top-start' }), on: 'update', description: 'Preferred placement of an option tooltip (floating-ui placement).' }, // ── Numbers ────────────────────────────────────────────────────────────── { configKey: 'badgesThreshold', attribute: 'badges-threshold', converter: toInt(), on: 'update', description: 'Threshold at which badges collapse to a count/compact view.' }, { configKey: 'badgesMaxVisible', attribute: 'badges-max-visible', converter: toInt(), on: 'update', description: 'Maximum number of badges rendered before overflow.' }, { configKey: 'minSearchLength', attribute: 'min-search-length', converter: toInt({ default: 0 }), on: 'update', description: 'Minimum characters before searching/filtering starts.' }, { configKey: 'searchDebounce', attribute: 'search-debounce', converter: toInt({ default: 0 }), on: 'update', description: 'Debounce delay in ms applied to the search input.' }, { configKey: 'virtualScrollThreshold', attribute: 'virtual-scroll-threshold', converter: toInt({ default: 100 }), on: 'reinit', description: 'Option count above which virtual scrolling turns on.' }, { configKey: 'optionHeight', attribute: 'option-height', converter: toInt({ default: 50 }), on: 'update', description: 'Fixed row height in px used by virtual scrolling.' }, { configKey: 'badgeHeight', attribute: 'badge-height', converter: toInt({ default: 36 }), on: 'update', description: 'Fixed badge height in px used for layout/virtualization.' }, { configKey: 'virtualScrollBuffer', attribute: 'virtual-scroll-buffer', converter: toInt({ default: 10 }), on: 'update', description: 'Extra rows rendered above/below the viewport when virtualizing.' }, { configKey: 'badgeTooltipDelay', attribute: 'badge-tooltip-delay', converter: toInt({ default: 100 }), on: 'update', description: 'Delay in ms before a badge tooltip appears.' }, { configKey: 'badgeTooltipOffset', attribute: 'badge-tooltip-offset', converter: toInt({ default: 8 }), on: 'update', description: 'Gap in px between a badge and its tooltip.' }, { configKey: 'optionTooltipDelay', attribute: 'option-tooltip-delay', converter: toInt(), on: 'update', description: 'Delay in ms before an option tooltip appears (falls back to badgeTooltipDelay).' }, { configKey: 'optionTooltipOffset', attribute: 'option-tooltip-offset', converter: toInt(), on: 'update', description: 'Gap in px between an option and its tooltip.' }, // ── Booleans (default true) ────────────────────────────────────────────── { configKey: 'isMultipleEnabled', attribute: 'multiple', converter: toBool('default-true'), on: 'reinit', description: 'Allow selecting multiple options. When off, selecting one replaces the previous.' }, { configKey: 'isGroupsAllowed', attribute: 'allow-groups', converter: toBool('default-true'), on: 'reinit', description: 'Allow grouping options under group headers.' }, { configKey: 'isCheckboxesShown', attribute: 'show-checkboxes', converter: toBool('default-true'), on: 'reinit', description: 'Show a checkbox on each option.' }, { configKey: 'isActionsSticky', attribute: 'sticky-actions', converter: toBool('default-true'), on: 'update', description: 'Keep the action bar pinned while the list scrolls.' }, { configKey: 'isPlacementLocked', attribute: 'lock-placement', converter: toBool('default-true'), on: 'update', description: 'Keep the dropdown initial placement instead of flipping when it fits.' }, { configKey: 'isSearchEnabled', attribute: 'enable-search', converter: toBool('default-true'), on: 'reinit', description: 'Show the search input.' }, { configKey: 'isKeepOptionsOnSearch', attribute: 'keep-options-on-search', converter: toBool('default-true'), on: 'update', description: 'Keep already-selected options visible while filtering.' }, { configKey: 'shouldKeepSearchOnClose', attribute: 'should-keep-search-on-close', converter: toBool('default-true'), on: 'update', description: 'Preserve the search text after the dropdown closes.' }, // ── Booleans (default false) ───────────────────────────────────────────── { configKey: 'isCloseOnSelect', attribute: 'close-on-select', converter: toBool('default-false'), on: 'update', description: 'Close the dropdown immediately after a selection.' }, { configKey: 'isAddNewAllowed', attribute: 'allow-add-new', converter: toBool('default-false'), on: 'reinit', description: 'Allow adding a new option from the search text.' }, { configKey: 'isCounterShown', attribute: 'show-counter', converter: toBool('default-false'), on: 'update', description: 'Show a selected-count indicator.' }, { configKey: 'isBadgeFullTitleShown', attribute: 'show-badge-full-title', converter: toBool('default-false'), on: 'update', description: 'Show the full title on badges instead of the short label.' }, { configKey: 'isVirtualScrollEnabled', attribute: 'enable-virtual-scroll', converter: toBool('default-false'), on: 'reinit', description: 'Force virtual scrolling on regardless of the threshold.' }, { configKey: 'isBadgeTooltipsEnabled', attribute: 'enable-badge-tooltips', converter: toBool('default-false'), on: 'update', description: 'Enable tooltips on badges.' }, { configKey: 'isOptionTooltipsEnabled', attribute: 'enable-option-tooltips', converter: toBool('default-false'), on: 'update', description: 'Enable tooltips on options.' }, { configKey: 'isOptionTooltipFollowCursor', attribute: 'option-tooltip-follow-cursor', converter: toBool('default-false'), on: 'update', description: 'Make option tooltips follow the pointer.' }, // ── Special attributes ─────────────────────────────────────────────────── { configKey: 'initialValues', attribute: 'initial-values', converter: toInitialValues(), default: [], on: 'reinit', type: 'Array<string | number>', description: 'Values selected on first render. Accepts a JSON array (`[\"a\",\"b\"]`) or a bare CSV (`a,b,c`).' }, { configKey: 'showDebugInfo', attribute: 'show-debug-info', converter: toBool('default-false'), on: 'update', description: 'Render an in-component debug panel.', deprecated: 'Use per-instance logging (el.enableLogging()) instead.' }, // ── Complex property (data) ────────────────────────────────────────────── { configKey: 'options', converter: toObjectArray(), on: 'reinit', type: 'ReadonlyArray<Record<string, unknown>>', description: 'The array of option objects to render. The JS API — assign `el.options` directly. For HTML authoring use the `data-options` attribute (parsed per `data-options-format`) or declarative <option> children; both feed the same list and take precedence over this property in the order: <option> children > property > data-options.' }, { configKey: 'optionsSource', attribute: 'data-options', converter: toText({ isNullable: true }), on: 'reinit', type: 'string', description: 'HTML-authoring source for the option list, parsed per `data-options-format`. Reactive: changing either attribute re-renders. Prefer the `options` property in JS; a set `options` property and declarative <option> children both win over this.' }, { configKey: 'optionsFormat', attribute: 'data-options-format', converter: toEnum(OPTIONS_FORMATS, { default: 'json' }), on: 'reinit', type: \"'json' | 'csv' | 'plain'\", description: 'How to parse the `data-options` attribute: `json` (a JSON array of objects or [value, label] tuples), `csv` (rows split on `data-options-row-splitter`, cells on `data-options-splitter`; the first row is a header — map columns via *-member), or `plain` (bare values split on both splitters -> [value, label] tuples, value === label). Default `json`.' }, { configKey: 'optionsSplitter', attribute: 'data-options-splitter', converter: toText({ default: ',' }), on: 'reinit', type: 'string', description: 'Field/cell delimiter for the `csv` and `plain` `data-options` formats. Default `,`. Escapes `\\\\t` `\\\\n` `\\\\r` are honoured (e.g. `data-options-splitter=\"\\\\t\"` for TSV). Ignored for `json`.' }, { configKey: 'optionsRowSplitter', attribute: 'data-options-row-splitter', converter: toText({ default: '\\n' }), on: 'reinit', type: 'string', description: 'Row/record delimiter for the `csv` and `plain` `data-options` formats. Default newline. Escapes honoured (e.g. `data-options-row-splitter=\";\"` for single-line data). Ignored for `json`.' }, { configKey: 'actionButtons', converter: toValue({ validate: (v): v is unknown[] => Array.isArray(v) }), on: 'reinit', type: 'Array<Record<string, unknown>>', description: 'Custom action buttons for the dropdown footer/header. Property-only; when unset the default Select-All / Clear buttons apply.' }, // ── Callbacks: data shape (structural → reinit) ────────────────────────── { configKey: 'getValueCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => string | number', description: 'Extract an option value (overrides valueMember).' }, { configKey: 'getPathCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => string', description: 'Extract a node tree path (enables tree mode; overrides pathMember).' }, { configKey: 'getGroupCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => string', description: 'Extract the group name from an option (overrides groupMember).' }, { configKey: 'getDisabledCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => boolean', description: 'Whether an option is disabled (overrides disabledMember).' }, { configKey: 'getIsSelectableCallback', converter: cb(), on: 'reinit', type: '(node: unknown) => boolean', description: 'Whether a tree node can be selected (overrides is-selectable-member).' }, { configKey: 'getSearchValueCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => string', description: 'Text an option is searched against (overrides searchValueMember).' }, { configKey: 'searchCallback', converter: cb(), on: 'reinit', type: '(searchTerm: string, signal?: AbortSignal) => Promise<unknown[]>', description: 'Custom / async search; return the filtered options.' }, // ── Callbacks: display / render (cosmetic → update) ────────────────────── { configKey: 'getDisplayValueCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Compute the display label for an option (overrides displayValueMember).' }, { configKey: 'getBadgeDisplayCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Compute the text shown on an option badge.' }, { configKey: 'getBadgeClassCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | string[]', description: 'Extra CSS class(es) for an option badge.' }, { configKey: 'getIconCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Icon for an option (overrides iconMember).' }, { configKey: 'getSubtitleCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Subtitle for an option (overrides subtitleMember).' }, { configKey: 'getFullTitleCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Full title for an option (used by badges when show-badge-full-title is on).' }, { configKey: 'getCounterCallback', converter: cb(), on: 'update', type: '(count: number, moreCount?: number) => string', description: 'Render the selected-count label.' }, { configKey: 'getValueFormatCallback', converter: cb(), on: 'update', type: '(selectedValues: (string | number)[]) => string', description: 'Serialize the selected values for form submission.' }, { configKey: 'getBadgeTooltipCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | HTMLElement', description: 'Tooltip content for an option badge.' }, { configKey: 'getOptionTooltipCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | HTMLElement', description: 'Tooltip content for an option row.' }, { configKey: 'getRemoveButtonTooltipCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Tooltip text for a badge remove button.' }, { configKey: 'getSelectedItemClassCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | string[]', description: 'Extra CSS class(es) for a selected item.' }, { configKey: 'renderOptionContentCallback', converter: cb(), on: 'update', type: '(item: unknown, context: OptionContentRenderContext) => string | HTMLElement', description: 'Custom render for an option row; may return HTML or an element.' }, { configKey: 'renderBadgeContentCallback', converter: cb(), on: 'update', type: '(item: unknown, context: BadgeContentRenderContext) => string | HTMLElement', description: 'Custom render for a badge; may return HTML or an element.' }, { configKey: 'renderGroupLabelContentCallback', converter: cb(), on: 'update', type: '(groupName: string) => string | HTMLElement', description: 'Customize a group label; may return an HTML string or element.' }, { configKey: 'renderSelectedContentCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Custom render for the whole selected area.' }, { configKey: 'renderSelectedItemContentCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | HTMLElement', description: 'Custom render for one selected item.' }, { configKey: 'customStylesCallback', converter: cb(), on: 'update', type: '() => string', description: 'Returns a CSS string injected into the component via a replaceable style slot (§12.8).' }, // ── Callbacks: before-hooks (behavior-shaping) ─────────────────────────── { configKey: 'beforeSearchCallback', converter: cb(), on: 'update', type: '(searchTerm: string) => string | null', description: 'Runs before a search; return a rewritten term or null to veto.' }, { configKey: 'beforeSelectCallback', converter: cb(), on: 'update', type: '(option: unknown, selectedOptions: unknown[]) => boolean | void', description: 'Runs before selecting; return false to veto.' }, { configKey: 'beforeDeselectCallback', converter: cb(), on: 'update', type: '(option: unknown, selectedOptions: unknown[]) => boolean | void', description: 'Runs before deselecting; return false to veto.' }, { configKey: 'addNewCallback', converter: cb(), on: 'update', type: '(value: string) => unknown | Promise<unknown>', description: 'Create a new option from the typed text.' }, ]",
|
|
3160
|
+
"default": "[ // ── Strings (cosmetic → update). Optional ones are nullable: absent → null ─ { configKey: 'searchHint', attribute: 'search-hint', converter: toText({ isNullable: true }), on: 'update', description: 'Small hint text shown beneath the search input.' }, { configKey: 'searchPlaceholder', attribute: 'search-placeholder', converter: toText({ default: 'Search...' }), on: 'update', description: 'Placeholder text for the search input.' }, { configKey: 'selectPlaceholder', attribute: 'select-placeholder', converter: toText({ default: 'Pick an option...' }), on: 'update', description: 'Placeholder shown on the control when nothing is selected.' }, { configKey: 'noDataPlaceholder', attribute: 'no-data-placeholder', converter: toText({ isNullable: true }), on: 'update', description: 'Text shown when there are no options at all.' }, { configKey: 'dropdownMinWidth', attribute: 'dropdown-min-width', converter: toText({ isNullable: true }), on: 'update', description: 'Minimum width of the dropdown panel (any CSS length).' }, { configKey: 'dropdownMaxWidth', attribute: 'dropdown-max-width', converter: toText({ isNullable: true }), on: 'update', description: 'Maximum width of the dropdown panel (any CSS length).' }, { configKey: 'maxHeight', attribute: 'max-height', converter: toText({ default: '20rem' }), on: 'update', description: 'Maximum height of the dropdown list before it scrolls.' }, { configKey: 'emptyMessage', attribute: 'empty-message', converter: toText({ default: 'No results found' }), on: 'update', description: 'Message shown when a search yields no matches.' }, { configKey: 'loadingMessage', attribute: 'loading-message', converter: toText({ default: 'Loading...' }), on: 'update', description: 'Message shown while options are loading.' }, { configKey: 'removeButtonTooltipText', attribute: 'remove-button-tooltip-text', converter: toText({ isNullable: true }), on: 'update', description: 'Tooltip text for a badge remove (×) button.' }, { configKey: 'formFieldId', attribute: 'name', converter: toText({ isNullable: true }), on: 'reinit', description: 'HTML form field name/id used for the hidden input(s).' }, // ── CSS-var sugar (mirrored to a host style prop in reinit()/update()) ──── { configKey: 'dropdownWidth', attribute: 'dropdown-width', converter: toText({ isNullable: true }), on: 'update', description: 'Fixed dropdown width; mirrored to the `--ms-dropdown-width` CSS variable.' }, { configKey: 'selectedPopoverWidth', attribute: 'selected-popover-width', converter: toText({ isNullable: true }), on: 'update', description: 'Selected-items popover width; mirrored to `--ms-selected-popover-width`.' }, // ── Member properties (structural → reinit; optional → nullable) ───────── { configKey: 'valueMember', attribute: 'value-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name on an option object that holds its value.' }, { configKey: 'displayValueMember', attribute: 'display-value-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that holds an option display label.' }, { configKey: 'searchValueMember', attribute: 'search-value-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name searched against (falls back to the display value).' }, { configKey: 'iconMember', attribute: 'icon-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that holds an option icon.' }, { configKey: 'subtitleMember', attribute: 'subtitle-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that holds an option subtitle.' }, { configKey: 'fullTitleMember', attribute: 'full-title-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that holds an option full/long title.' }, { configKey: 'groupMember', attribute: 'group-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name used to group options under headers.' }, { configKey: 'disabledMember', attribute: 'disabled-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name that marks an option disabled.' }, // ── Tree of options (structural → reinit; optional → nullable) ─────────── { configKey: 'pathMember', attribute: 'path-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name holding a node materialized tree path.' }, { configKey: 'parentPathMember', attribute: 'parent-path-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name holding a node parent path.' }, { configKey: 'levelMember', attribute: 'level-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name holding a node depth level.' }, { configKey: 'hasChildrenMember', attribute: 'has-children-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name flagging that a node has children.' }, { configKey: 'isSelectableMember', attribute: 'is-selectable-member', converter: toText({ isNullable: true }), reflect: true, on: 'reinit', description: 'Property name marking whether a node can be selected.' }, { configKey: 'treePathSeparator', attribute: 'tree-path-separator', converter: toText({ default: '.' }), reflect: true, on: 'reinit', description: 'Separator between segments in a materialized tree path.' }, { configKey: 'isTreeEnabled', converter: toBool('tristate'), on: 'reinit', type: 'boolean', description: 'Force tree mode on/off. Property-only; when unset (null) tree mode auto-enables if a path source (path-member / getPathCallback) is present.' }, { configKey: 'checkboxMode', attribute: 'checkbox-mode', converter: toEnum(['independent', 'cascade'] as const, { default: 'independent' }), reflect: true, on: 'update', description: `Tree checkbox interaction. - \\`independent\\` (default) — toggles only the clicked node. - \\`cascade\\` — checks a node whole subtree and shows a tristate (checked / indeterminate / unchecked) box on branches. Tree + multiple only.` }, { configKey: 'cascadeSelectPolicy', attribute: 'cascade-select-policy', converter: toEnum(['rolled-up', 'leaves', 'all'] as const, { default: 'rolled-up' }), reflect: true, on: 'update', description: `In \\`cascade\\` mode, which values a selection emits (badges / form / change): - \\`rolled-up\\` (default) — minimal cover: a fully-selected subtree collapses to its root; partially-selected branches emit their individually-checked descendants. - \\`leaves\\` — only the checked leaf-level nodes. - \\`all\\` — every fully-checked node (branches and leaves).` }, // ── Enums ──────────────────────────────────────────────────────────────── { configKey: 'badgesDisplayMode', attribute: 'badges-display-mode', converter: toEnum(['badges', 'count', 'compact', 'partial', 'none'] as const, { default: 'badges' }), on: 'reinit', description: 'How the current selection is shown in the control.' }, { configKey: 'badgesPosition', attribute: 'badges-position', converter: toEnum(['top', 'bottom', 'left', 'right'] as const, { default: 'bottom' }), on: 'reinit', description: 'Where the badges/selection appear relative to the input.' }, { configKey: 'badgesThresholdMode', attribute: 'badges-threshold-mode', converter: toEnum(['count', 'partial'] as const, { default: 'count' }), on: 'update', description: 'How `badgesThreshold` is interpreted: collapse to a count badge, or keep partial badges + a \"more\" badge.' }, { configKey: 'searchInputMode', attribute: 'search-input-mode', converter: toEnum(['normal', 'readonly', 'hidden'] as const, { default: 'normal' }), on: 'reinit', description: 'Search field mode: editable, read-only, or hidden.' }, { configKey: 'searchMode', attribute: 'search-mode', converter: toEnum(['filter', 'navigate'] as const, { default: 'filter' }), on: 'reinit', description: 'Whether typing filters the list or navigates it.' }, { configKey: 'actionsLayout', attribute: 'actions-layout', converter: toEnum(['nowrap', 'wrap'] as const, { default: 'nowrap' }), on: 'reinit', description: 'Whether the action bar wraps or stays on one line.' }, { configKey: 'actionsPosition', attribute: 'actions-position', converter: toEnum(['top', 'bottom'] as const, { default: 'top' }), on: 'reinit', description: 'Whether the action bar sits above or below the list.' }, { configKey: 'actionsAlign', attribute: 'actions-align', converter: toEnum(['stretch', 'left', 'right', 'center', 'space-between'] as const, { default: 'stretch' }), on: 'update', description: 'Horizontal alignment of the action buttons.' }, { configKey: 'checkboxAlign', attribute: 'checkbox-align', converter: toEnum(['top', 'center', 'bottom'] as const, { default: 'center' }), on: 'update', description: 'Vertical alignment of an option checkbox.' }, { configKey: 'valueFormat', attribute: 'value-format', converter: toEnum(['json', 'csv', 'array'] as const, { default: 'json' }), on: 'reinit', description: 'Serialization format the control emits its value in.' }, { configKey: 'badgeTooltipPlacement', attribute: 'badge-tooltip-placement', converter: toEnum(PLACEMENTS, { default: 'top' }), on: 'update', description: 'Preferred placement of a badge tooltip relative to its badge (floating-ui placement).' }, { configKey: 'optionTooltipPlacement', attribute: 'option-tooltip-placement', converter: toEnum(PLACEMENTS, { default: 'top-start' }), on: 'update', description: 'Preferred placement of an option tooltip (floating-ui placement).' }, { configKey: 'mobilePresentation', attribute: 'mobile-presentation', converter: toEnum(['auto', 'floating', 'fullscreen'] as const, { default: 'auto' }), reflect: true, on: 'update', description: 'How the open dropdown is presented on phones. `auto` (default) keeps the floating panel on desktop/tablet and switches to a full-screen overlay on phone-sized touch devices (touch primary + shorter viewport side < 600px, orientation-robust); `floating` forces the anchored panel everywhere; `fullscreen` forces the full-screen overlay on any device (handy for previews/testing). Resolved reactively from the device/viewport environment.' }, { configKey: 'fullscreenAutofocus', attribute: 'fullscreen-autofocus', converter: toBool('default-false'), on: 'update', description: 'In the phone fullscreen overlay, auto-focus the search field on open (pops the soft keyboard immediately). Default `false`: the sheet opens with the list visible and the keyboard closed, appearing only when the user taps the search. Set `true` to type-to-filter right away. No effect in the floating presentation.' }, // ── Numbers ────────────────────────────────────────────────────────────── { configKey: 'badgesThreshold', attribute: 'badges-threshold', converter: toInt(), on: 'update', description: 'Threshold at which badges collapse to a count/compact view.' }, { configKey: 'badgesMaxVisible', attribute: 'badges-max-visible', converter: toInt(), on: 'update', description: 'Maximum number of badges rendered before overflow.' }, { configKey: 'minSearchLength', attribute: 'min-search-length', converter: toInt({ default: 0 }), on: 'update', description: 'Minimum characters before searching/filtering starts.' }, { configKey: 'searchDebounce', attribute: 'search-debounce', converter: toInt({ default: 0 }), on: 'update', description: 'Debounce delay in ms applied to the search input.' }, { configKey: 'virtualScrollThreshold', attribute: 'virtual-scroll-threshold', converter: toInt({ default: 100 }), on: 'reinit', description: 'Option count above which virtual scrolling turns on.' }, { configKey: 'optionHeight', attribute: 'option-height', converter: toInt({ default: 50 }), on: 'update', description: 'Fixed row height in px used by virtual scrolling.' }, { configKey: 'badgeHeight', attribute: 'badge-height', converter: toInt({ default: 36 }), on: 'update', description: 'Fixed badge height in px used for layout/virtualization.' }, { configKey: 'virtualScrollBuffer', attribute: 'virtual-scroll-buffer', converter: toInt({ default: 10 }), on: 'update', description: 'Extra rows rendered above/below the viewport when virtualizing.' }, { configKey: 'badgeTooltipDelay', attribute: 'badge-tooltip-delay', converter: toInt({ default: 100 }), on: 'update', description: 'Delay in ms before a badge tooltip appears.' }, { configKey: 'badgeTooltipOffset', attribute: 'badge-tooltip-offset', converter: toInt({ default: 8 }), on: 'update', description: 'Gap in px between a badge and its tooltip.' }, { configKey: 'optionTooltipDelay', attribute: 'option-tooltip-delay', converter: toInt(), on: 'update', description: 'Delay in ms before an option tooltip appears (falls back to badgeTooltipDelay).' }, { configKey: 'optionTooltipOffset', attribute: 'option-tooltip-offset', converter: toInt(), on: 'update', description: 'Gap in px between an option and its tooltip.' }, // ── Booleans (default true) ────────────────────────────────────────────── { configKey: 'isMultipleEnabled', attribute: 'multiple', converter: toBool('default-true'), on: 'reinit', description: 'Allow selecting multiple options. When off, selecting one replaces the previous.' }, { configKey: 'isGroupsAllowed', attribute: 'allow-groups', converter: toBool('default-true'), on: 'reinit', description: 'Allow grouping options under group headers.' }, { configKey: 'isCheckboxesShown', attribute: 'show-checkboxes', converter: toBool('default-true'), on: 'reinit', description: 'Show a checkbox on each option.' }, { configKey: 'isActionsSticky', attribute: 'sticky-actions', converter: toBool('default-true'), on: 'update', description: 'Keep the action bar pinned while the list scrolls.' }, { configKey: 'isPlacementLocked', attribute: 'lock-placement', converter: toBool('default-true'), on: 'update', description: 'Keep the dropdown initial placement instead of flipping when it fits.' }, { configKey: 'isSearchEnabled', attribute: 'enable-search', converter: toBool('default-true'), on: 'reinit', description: 'Show the search input.' }, { configKey: 'isKeepOptionsOnSearch', attribute: 'keep-options-on-search', converter: toBool('default-true'), on: 'update', description: 'Keep already-selected options visible while filtering.' }, { configKey: 'shouldKeepSearchOnClose', attribute: 'should-keep-search-on-close', converter: toBool('default-true'), on: 'update', description: 'Preserve the search text after the dropdown closes.' }, // ── Booleans (default false) ───────────────────────────────────────────── { configKey: 'isCloseOnSelect', attribute: 'close-on-select', converter: toBool('default-false'), on: 'update', description: 'Close the dropdown immediately after a selection.' }, { configKey: 'isAddNewAllowed', attribute: 'allow-add-new', converter: toBool('default-false'), on: 'reinit', description: 'Allow adding a new option from the search text.' }, { configKey: 'isCounterShown', attribute: 'show-counter', converter: toBool('default-false'), on: 'update', description: 'Show a selected-count indicator.' }, { configKey: 'isBadgeFullTitleShown', attribute: 'show-badge-full-title', converter: toBool('default-false'), on: 'update', description: 'Show the full title on badges instead of the short label.' }, { configKey: 'isVirtualScrollEnabled', attribute: 'enable-virtual-scroll', converter: toBool('default-false'), on: 'reinit', description: 'Force virtual scrolling on regardless of the threshold.' }, { configKey: 'isBadgeTooltipsEnabled', attribute: 'enable-badge-tooltips', converter: toBool('default-false'), on: 'update', description: 'Enable tooltips on badges.' }, { configKey: 'isOptionTooltipsEnabled', attribute: 'enable-option-tooltips', converter: toBool('default-false'), on: 'update', description: 'Enable tooltips on options.' }, { configKey: 'isOptionTooltipFollowCursor', attribute: 'option-tooltip-follow-cursor', converter: toBool('default-false'), on: 'update', description: 'Make option tooltips follow the pointer.' }, // ── Special attributes ─────────────────────────────────────────────────── { configKey: 'initialValues', attribute: 'initial-values', converter: toInitialValues(), default: [], on: 'reinit', type: 'Array<string | number>', description: 'Values selected on first render. Accepts a JSON array (`[\"a\",\"b\"]`) or a bare CSV (`a,b,c`).' }, { configKey: 'showDebugInfo', attribute: 'show-debug-info', converter: toBool('default-false'), on: 'update', description: 'Render an in-component debug panel.', deprecated: 'Use per-instance logging (el.enableLogging()) instead.' }, // ── Complex property (data) ────────────────────────────────────────────── { configKey: 'options', converter: toObjectArray(), on: 'reinit', type: 'ReadonlyArray<Record<string, unknown>>', description: 'The array of option objects to render. The JS API — assign `el.options` directly. For HTML authoring use the `data-options` attribute (parsed per `data-options-format`) or declarative <option> children; both feed the same list and take precedence over this property in the order: <option> children > property > data-options.' }, { configKey: 'optionsSource', attribute: 'data-options', converter: toText({ isNullable: true }), on: 'reinit', type: 'string', description: 'HTML-authoring source for the option list, parsed per `data-options-format`. Reactive: changing either attribute re-renders. Prefer the `options` property in JS; a set `options` property and declarative <option> children both win over this.' }, { configKey: 'optionsFormat', attribute: 'data-options-format', converter: toEnum(OPTIONS_FORMATS, { default: 'json' }), on: 'reinit', type: \"'json' | 'csv' | 'plain'\", description: 'How to parse the `data-options` attribute: `json` (a JSON array of objects or [value, label] tuples), `csv` (rows split on `data-options-row-splitter`, cells on `data-options-splitter`; the first row is a header — map columns via *-member), or `plain` (bare values split on both splitters -> [value, label] tuples, value === label). Default `json`.' }, { configKey: 'optionsSplitter', attribute: 'data-options-splitter', converter: toText({ default: ',' }), on: 'reinit', type: 'string', description: 'Field/cell delimiter for the `csv` and `plain` `data-options` formats. Default `,`. Escapes `\\\\t` `\\\\n` `\\\\r` are honoured (e.g. `data-options-splitter=\"\\\\t\"` for TSV). Ignored for `json`.' }, { configKey: 'optionsRowSplitter', attribute: 'data-options-row-splitter', converter: toText({ default: '\\n' }), on: 'reinit', type: 'string', description: 'Row/record delimiter for the `csv` and `plain` `data-options` formats. Default newline. Escapes honoured (e.g. `data-options-row-splitter=\";\"` for single-line data). Ignored for `json`.' }, { configKey: 'actionButtons', converter: toValue({ validate: (v): v is unknown[] => Array.isArray(v) }), on: 'reinit', type: 'Array<Record<string, unknown>>', description: 'Custom action buttons for the dropdown footer/header. Property-only; when unset the default Select-All / Clear buttons apply.' }, // ── Callbacks: data shape (structural → reinit) ────────────────────────── { configKey: 'getValueCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => string | number', description: 'Extract an option value (overrides valueMember).' }, { configKey: 'getPathCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => string', description: 'Extract a node tree path (enables tree mode; overrides pathMember).' }, { configKey: 'getGroupCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => string', description: 'Extract the group name from an option (overrides groupMember).' }, { configKey: 'getDisabledCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => boolean', description: 'Whether an option is disabled (overrides disabledMember).' }, { configKey: 'getIsSelectableCallback', converter: cb(), on: 'reinit', type: '(node: unknown) => boolean', description: 'Whether a tree node can be selected (overrides is-selectable-member).' }, { configKey: 'getSearchValueCallback', converter: cb(), on: 'reinit', type: '(item: unknown) => string', description: 'Text an option is searched against (overrides searchValueMember).' }, { configKey: 'searchCallback', converter: cb(), on: 'reinit', type: '(searchTerm: string, signal?: AbortSignal) => Promise<unknown[]>', description: 'Custom / async search; return the filtered options.' }, // ── Callbacks: display / render (cosmetic → update) ────────────────────── { configKey: 'getDisplayValueCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Compute the display label for an option (overrides displayValueMember).' }, { configKey: 'getBadgeDisplayCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Compute the text shown on an option badge.' }, { configKey: 'getBadgeClassCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | string[]', description: 'Extra CSS class(es) for an option badge.' }, { configKey: 'getIconCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Icon for an option (overrides iconMember).' }, { configKey: 'getSubtitleCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Subtitle for an option (overrides subtitleMember).' }, { configKey: 'getFullTitleCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Full title for an option (used by badges when show-badge-full-title is on).' }, { configKey: 'getCounterCallback', converter: cb(), on: 'update', type: '(count: number, moreCount?: number) => string', description: 'Render the selected-count label.' }, { configKey: 'getValueFormatCallback', converter: cb(), on: 'update', type: '(selectedValues: (string | number)[]) => string', description: 'Serialize the selected values for form submission.' }, { configKey: 'getBadgeTooltipCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | HTMLElement', description: 'Tooltip content for an option badge.' }, { configKey: 'getOptionTooltipCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | HTMLElement', description: 'Tooltip content for an option row.' }, { configKey: 'getRemoveButtonTooltipCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Tooltip text for a badge remove button.' }, { configKey: 'getSelectedItemClassCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | string[]', description: 'Extra CSS class(es) for a selected item.' }, { configKey: 'renderOptionContentCallback', converter: cb(), on: 'update', type: '(item: unknown, context: OptionContentRenderContext) => string | HTMLElement', description: 'Custom render for an option row; may return HTML or an element.' }, { configKey: 'renderBadgeContentCallback', converter: cb(), on: 'update', type: '(item: unknown, context: BadgeContentRenderContext) => string | HTMLElement', description: 'Custom render for a badge; may return HTML or an element.' }, { configKey: 'renderGroupLabelContentCallback', converter: cb(), on: 'update', type: '(groupName: string) => string | HTMLElement', description: 'Customize a group label; may return an HTML string or element.' }, { configKey: 'renderSelectedContentCallback', converter: cb(), on: 'update', type: '(item: unknown) => string', description: 'Custom render for the whole selected area.' }, { configKey: 'renderSelectedItemContentCallback', converter: cb(), on: 'update', type: '(item: unknown) => string | HTMLElement', description: 'Custom render for one selected item.' }, { configKey: 'customStylesCallback', converter: cb(), on: 'update', type: '() => string', description: 'Returns a CSS string injected into the component via a replaceable style slot (§12.8).' }, // ── Callbacks: before-hooks (behavior-shaping) ─────────────────────────── { configKey: 'beforeSearchCallback', converter: cb(), on: 'update', type: '(searchTerm: string) => string | null', description: 'Runs before a search; return a rewritten term or null to veto.' }, { configKey: 'beforeSelectCallback', converter: cb(), on: 'update', type: '(option: unknown, selectedOptions: unknown[]) => boolean | string | void', description: 'Runs before selecting; return false to veto, or a string to veto and show it as a message.' }, { configKey: 'beforeDeselectCallback', converter: cb(), on: 'update', type: '(option: unknown, selectedOptions: unknown[]) => boolean | string | void', description: 'Runs before deselecting; return false to veto, or a string to veto and show it as a message.' }, { configKey: 'addNewCallback', converter: cb(), on: 'update', type: '(value: string) => unknown | Promise<unknown>', description: 'Create a new option from the typed text.' }, ]",
|
|
2640
3161
|
"type": {
|
|
2641
3162
|
"text": "readonly InputDef[]"
|
|
2642
3163
|
}
|
|
@@ -2755,6 +3276,25 @@
|
|
|
2755
3276
|
},
|
|
2756
3277
|
"description": "Called by the browser when the surrounding <form> is reset. Clears the\r\npicker's selection so the control participates in the standard reset."
|
|
2757
3278
|
},
|
|
3279
|
+
{
|
|
3280
|
+
"kind": "method",
|
|
3281
|
+
"name": "directionChanged",
|
|
3282
|
+
"privacy": "protected",
|
|
3283
|
+
"return": {
|
|
3284
|
+
"type": {
|
|
3285
|
+
"text": "void"
|
|
3286
|
+
}
|
|
3287
|
+
},
|
|
3288
|
+
"parameters": [
|
|
3289
|
+
{
|
|
3290
|
+
"name": "_isRTL",
|
|
3291
|
+
"type": {
|
|
3292
|
+
"text": "boolean"
|
|
3293
|
+
}
|
|
3294
|
+
}
|
|
3295
|
+
],
|
|
3296
|
+
"description": "Runtime writing-direction switch (core observes `dir`): re-mirror the live\r\npicker. Layout mostly follows the inherited `direction` (logical properties);\r\nrefreshDirection() fixes the parts pinned at build time (the `.ms--rtl` class\r\nand the panels' explicit `dir`). The initial direction is read by the build."
|
|
3297
|
+
},
|
|
2758
3298
|
{
|
|
2759
3299
|
"kind": "method",
|
|
2760
3300
|
"name": "reinit",
|
|
@@ -2807,6 +3347,44 @@
|
|
|
2807
3347
|
},
|
|
2808
3348
|
"description": "Deactivate: tear the picker down (rebuilt on the next connect)."
|
|
2809
3349
|
},
|
|
3350
|
+
{
|
|
3351
|
+
"kind": "method",
|
|
3352
|
+
"name": "environmentChanged",
|
|
3353
|
+
"privacy": "protected",
|
|
3354
|
+
"return": {
|
|
3355
|
+
"type": {
|
|
3356
|
+
"text": "void"
|
|
3357
|
+
}
|
|
3358
|
+
},
|
|
3359
|
+
"parameters": [
|
|
3360
|
+
{
|
|
3361
|
+
"name": "env",
|
|
3362
|
+
"type": {
|
|
3363
|
+
"text": "EnvironmentSnapshot"
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3366
|
+
],
|
|
3367
|
+
"description": "Device/viewport/orientation changed (core §12.9). Overriding this opts the\r\nelement into the shared environment observable — core subscribes on connect\r\n(firing immediately with the current snapshot) and unsubscribes on disconnect.\r\nWe map it to the picker's floating/fullscreen presentation; the immediate fire\r\nlands right after `connect()` builds the picker, so the initial presentation is\r\nset before the dropdown can open."
|
|
3368
|
+
},
|
|
3369
|
+
{
|
|
3370
|
+
"kind": "method",
|
|
3371
|
+
"name": "#applyPresentation",
|
|
3372
|
+
"privacy": "private",
|
|
3373
|
+
"return": {
|
|
3374
|
+
"type": {
|
|
3375
|
+
"text": "void"
|
|
3376
|
+
}
|
|
3377
|
+
},
|
|
3378
|
+
"parameters": [
|
|
3379
|
+
{
|
|
3380
|
+
"name": "env",
|
|
3381
|
+
"type": {
|
|
3382
|
+
"text": "EnvironmentSnapshot"
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
],
|
|
3386
|
+
"description": "Resolve `mobile-presentation` against `env` and relay it to the live picker."
|
|
3387
|
+
},
|
|
2810
3388
|
{
|
|
2811
3389
|
"kind": "method",
|
|
2812
3390
|
"name": "#rebuildPicker",
|
|
@@ -3055,6 +3633,41 @@
|
|
|
3055
3633
|
}
|
|
3056
3634
|
}
|
|
3057
3635
|
},
|
|
3636
|
+
{
|
|
3637
|
+
"kind": "method",
|
|
3638
|
+
"name": "showMessage",
|
|
3639
|
+
"return": {
|
|
3640
|
+
"type": {
|
|
3641
|
+
"text": "void"
|
|
3642
|
+
}
|
|
3643
|
+
},
|
|
3644
|
+
"parameters": [
|
|
3645
|
+
{
|
|
3646
|
+
"name": "content",
|
|
3647
|
+
"type": {
|
|
3648
|
+
"text": "string | HTMLElement"
|
|
3649
|
+
}
|
|
3650
|
+
},
|
|
3651
|
+
{
|
|
3652
|
+
"name": "opts",
|
|
3653
|
+
"optional": true,
|
|
3654
|
+
"type": {
|
|
3655
|
+
"text": "MessageOptions"
|
|
3656
|
+
}
|
|
3657
|
+
}
|
|
3658
|
+
],
|
|
3659
|
+
"description": "Surface a transient message (\"toast\") on top of the component — visible even in the\r\nfullscreen overlay, where page-level UI is hidden behind the sheet. Content is text or\r\nan element; `opts.variant` sets the tone and `opts.duration` the auto-dismiss (0 =\r\nsticky). Also reached automatically when a `beforeSelect`/`beforeDeselect` callback\r\nreturns a reason string."
|
|
3660
|
+
},
|
|
3661
|
+
{
|
|
3662
|
+
"kind": "method",
|
|
3663
|
+
"name": "hideMessage",
|
|
3664
|
+
"return": {
|
|
3665
|
+
"type": {
|
|
3666
|
+
"text": "void"
|
|
3667
|
+
}
|
|
3668
|
+
},
|
|
3669
|
+
"description": "Dismiss the transient message shown by showMessage, if any."
|
|
3670
|
+
},
|
|
3058
3671
|
{
|
|
3059
3672
|
"kind": "method",
|
|
3060
3673
|
"name": "destroy",
|
|
@@ -3519,6 +4132,28 @@
|
|
|
3519
4132
|
"attribute": "option-tooltip-placement",
|
|
3520
4133
|
"description": "Preferred placement of an option tooltip (floating-ui placement)."
|
|
3521
4134
|
},
|
|
4135
|
+
{
|
|
4136
|
+
"kind": "field",
|
|
4137
|
+
"name": "mobilePresentation",
|
|
4138
|
+
"privacy": "public",
|
|
4139
|
+
"type": {
|
|
4140
|
+
"text": "'auto' | 'floating' | 'fullscreen'"
|
|
4141
|
+
},
|
|
4142
|
+
"default": "'auto'",
|
|
4143
|
+
"attribute": "mobile-presentation",
|
|
4144
|
+
"reflects": true,
|
|
4145
|
+
"description": "How the open dropdown is presented on phones. `auto` (default) keeps the floating panel on desktop/tablet and switches to a full-screen overlay on phone-sized touch devices (touch primary + shorter viewport side < 600px, orientation-robust); `floating` forces the anchored panel everywhere; `fullscreen` forces the full-screen overlay on any device (handy for previews/testing). Resolved reactively from the device/viewport environment."
|
|
4146
|
+
},
|
|
4147
|
+
{
|
|
4148
|
+
"kind": "field",
|
|
4149
|
+
"name": "fullscreenAutofocus",
|
|
4150
|
+
"privacy": "public",
|
|
4151
|
+
"type": {
|
|
4152
|
+
"text": "boolean"
|
|
4153
|
+
},
|
|
4154
|
+
"attribute": "fullscreen-autofocus",
|
|
4155
|
+
"description": "In the phone fullscreen overlay, auto-focus the search field on open (pops the soft keyboard immediately). Default `false`: the sheet opens with the list visible and the keyboard closed, appearing only when the user taps the search. Set `true` to type-to-filter right away. No effect in the floating presentation."
|
|
4156
|
+
},
|
|
3522
4157
|
{
|
|
3523
4158
|
"kind": "field",
|
|
3524
4159
|
"name": "badgesThreshold",
|
|
@@ -4129,18 +4764,18 @@
|
|
|
4129
4764
|
"name": "beforeSelectCallback",
|
|
4130
4765
|
"privacy": "public",
|
|
4131
4766
|
"type": {
|
|
4132
|
-
"text": "(option: unknown, selectedOptions: unknown[]) => boolean | void"
|
|
4767
|
+
"text": "(option: unknown, selectedOptions: unknown[]) => boolean | string | void"
|
|
4133
4768
|
},
|
|
4134
|
-
"description": "Runs before selecting; return false to veto."
|
|
4769
|
+
"description": "Runs before selecting; return false to veto, or a string to veto and show it as a message."
|
|
4135
4770
|
},
|
|
4136
4771
|
{
|
|
4137
4772
|
"kind": "field",
|
|
4138
4773
|
"name": "beforeDeselectCallback",
|
|
4139
4774
|
"privacy": "public",
|
|
4140
4775
|
"type": {
|
|
4141
|
-
"text": "(option: unknown, selectedOptions: unknown[]) => boolean | void"
|
|
4776
|
+
"text": "(option: unknown, selectedOptions: unknown[]) => boolean | string | void"
|
|
4142
4777
|
},
|
|
4143
|
-
"description": "Runs before deselecting; return false to veto."
|
|
4778
|
+
"description": "Runs before deselecting; return false to veto, or a string to veto and show it as a message."
|
|
4144
4779
|
},
|
|
4145
4780
|
{
|
|
4146
4781
|
"kind": "field",
|
|
@@ -4505,6 +5140,23 @@
|
|
|
4505
5140
|
"default": "'top-start'",
|
|
4506
5141
|
"description": "Preferred placement of an option tooltip (floating-ui placement)."
|
|
4507
5142
|
},
|
|
5143
|
+
{
|
|
5144
|
+
"name": "mobile-presentation",
|
|
5145
|
+
"fieldName": "mobilePresentation",
|
|
5146
|
+
"type": {
|
|
5147
|
+
"text": "'auto' | 'floating' | 'fullscreen'"
|
|
5148
|
+
},
|
|
5149
|
+
"default": "'auto'",
|
|
5150
|
+
"description": "How the open dropdown is presented on phones. `auto` (default) keeps the floating panel on desktop/tablet and switches to a full-screen overlay on phone-sized touch devices (touch primary + shorter viewport side < 600px, orientation-robust); `floating` forces the anchored panel everywhere; `fullscreen` forces the full-screen overlay on any device (handy for previews/testing). Resolved reactively from the device/viewport environment."
|
|
5151
|
+
},
|
|
5152
|
+
{
|
|
5153
|
+
"name": "fullscreen-autofocus",
|
|
5154
|
+
"fieldName": "fullscreenAutofocus",
|
|
5155
|
+
"type": {
|
|
5156
|
+
"text": "boolean"
|
|
5157
|
+
},
|
|
5158
|
+
"description": "In the phone fullscreen overlay, auto-focus the search field on open (pops the soft keyboard immediately). Default `false`: the sheet opens with the list visible and the keyboard closed, appearing only when the user taps the search. Set `true` to type-to-filter right away. No effect in the floating presentation."
|
|
5159
|
+
},
|
|
4508
5160
|
{
|
|
4509
5161
|
"name": "badges-threshold",
|
|
4510
5162
|
"fieldName": "badgesThreshold",
|