@keenmate/web-multiselect 2.0.0-rc02 → 2.0.0-rc03
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 +57 -41
- package/custom-elements.json +627 -6
- package/dist/index.d.ts +244 -7
- package/dist/multiselect.js +2201 -1525
- package/dist/multiselect.umd.js +23 -23
- 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 +400 -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 +101 -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,102 @@
|
|
|
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": "fullscreenNav",
|
|
493
|
+
"type": {
|
|
494
|
+
"text": "HTMLDivElement | null"
|
|
495
|
+
},
|
|
496
|
+
"privacy": "private",
|
|
497
|
+
"default": "null"
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
"kind": "field",
|
|
501
|
+
"name": "fullscreenNavCount",
|
|
502
|
+
"type": {
|
|
503
|
+
"text": "HTMLElement | null"
|
|
504
|
+
},
|
|
505
|
+
"privacy": "private",
|
|
506
|
+
"default": "null"
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
"kind": "field",
|
|
510
|
+
"name": "fullscreenNavPrev",
|
|
511
|
+
"type": {
|
|
512
|
+
"text": "HTMLButtonElement | null"
|
|
513
|
+
},
|
|
514
|
+
"privacy": "private",
|
|
515
|
+
"default": "null"
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
"kind": "field",
|
|
519
|
+
"name": "fullscreenNavNext",
|
|
520
|
+
"type": {
|
|
521
|
+
"text": "HTMLButtonElement | null"
|
|
522
|
+
},
|
|
523
|
+
"privacy": "private",
|
|
524
|
+
"default": "null"
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
"kind": "field",
|
|
528
|
+
"name": "bodyScrollUnlock",
|
|
529
|
+
"type": {
|
|
530
|
+
"text": "(() => void) | null"
|
|
531
|
+
},
|
|
532
|
+
"privacy": "private",
|
|
533
|
+
"default": "null"
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
"kind": "field",
|
|
537
|
+
"name": "keyboardInsetCleanup",
|
|
538
|
+
"type": {
|
|
539
|
+
"text": "(() => void) | null"
|
|
540
|
+
},
|
|
541
|
+
"privacy": "private",
|
|
542
|
+
"default": "null"
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
"kind": "field",
|
|
546
|
+
"name": "overlayHistoryActive",
|
|
547
|
+
"type": {
|
|
548
|
+
"text": "boolean"
|
|
549
|
+
},
|
|
550
|
+
"privacy": "private",
|
|
551
|
+
"default": "false"
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
"kind": "field",
|
|
555
|
+
"name": "onOverlayPopstate",
|
|
556
|
+
"privacy": "private",
|
|
557
|
+
"readonly": true
|
|
558
|
+
},
|
|
454
559
|
{
|
|
455
560
|
"kind": "field",
|
|
456
561
|
"name": "dropdownCleanup",
|
|
@@ -484,6 +589,60 @@
|
|
|
484
589
|
"privacy": "private",
|
|
485
590
|
"default": "new Map<string, TooltipHandle>()"
|
|
486
591
|
},
|
|
592
|
+
{
|
|
593
|
+
"kind": "field",
|
|
594
|
+
"name": "labelRevealTrigger",
|
|
595
|
+
"type": {
|
|
596
|
+
"text": "HTMLElement | null"
|
|
597
|
+
},
|
|
598
|
+
"privacy": "private",
|
|
599
|
+
"default": "null"
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
"kind": "field",
|
|
603
|
+
"name": "labelRevealPanel",
|
|
604
|
+
"type": {
|
|
605
|
+
"text": "HTMLDivElement | null"
|
|
606
|
+
},
|
|
607
|
+
"privacy": "private",
|
|
608
|
+
"default": "null"
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
"kind": "field",
|
|
612
|
+
"name": "labelRevealPopover",
|
|
613
|
+
"type": {
|
|
614
|
+
"text": "PopoverHandle | null"
|
|
615
|
+
},
|
|
616
|
+
"privacy": "private",
|
|
617
|
+
"default": "null"
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
"kind": "field",
|
|
621
|
+
"name": "messageEl",
|
|
622
|
+
"type": {
|
|
623
|
+
"text": "HTMLDivElement | null"
|
|
624
|
+
},
|
|
625
|
+
"privacy": "private",
|
|
626
|
+
"default": "null"
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
"kind": "field",
|
|
630
|
+
"name": "messageCleanup",
|
|
631
|
+
"type": {
|
|
632
|
+
"text": "(() => void) | null"
|
|
633
|
+
},
|
|
634
|
+
"privacy": "private",
|
|
635
|
+
"default": "null"
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
"kind": "field",
|
|
639
|
+
"name": "messageTimer",
|
|
640
|
+
"type": {
|
|
641
|
+
"text": "ReturnType<typeof setTimeout> | null"
|
|
642
|
+
},
|
|
643
|
+
"privacy": "private",
|
|
644
|
+
"default": "null"
|
|
645
|
+
},
|
|
487
646
|
{
|
|
488
647
|
"kind": "field",
|
|
489
648
|
"name": "onDropdownScroll",
|
|
@@ -1010,6 +1169,28 @@
|
|
|
1010
1169
|
],
|
|
1011
1170
|
"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
1171
|
},
|
|
1172
|
+
{
|
|
1173
|
+
"kind": "method",
|
|
1174
|
+
"name": "detectRTL",
|
|
1175
|
+
"privacy": "private",
|
|
1176
|
+
"return": {
|
|
1177
|
+
"type": {
|
|
1178
|
+
"text": "void"
|
|
1179
|
+
}
|
|
1180
|
+
},
|
|
1181
|
+
"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."
|
|
1182
|
+
},
|
|
1183
|
+
{
|
|
1184
|
+
"kind": "method",
|
|
1185
|
+
"name": "refreshDirection",
|
|
1186
|
+
"privacy": "public",
|
|
1187
|
+
"return": {
|
|
1188
|
+
"type": {
|
|
1189
|
+
"text": "void"
|
|
1190
|
+
}
|
|
1191
|
+
},
|
|
1192
|
+
"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)."
|
|
1193
|
+
},
|
|
1013
1194
|
{
|
|
1014
1195
|
"kind": "method",
|
|
1015
1196
|
"name": "buildHTML",
|
|
@@ -1050,7 +1231,16 @@
|
|
|
1050
1231
|
"type": {
|
|
1051
1232
|
"text": "void"
|
|
1052
1233
|
}
|
|
1053
|
-
}
|
|
1234
|
+
},
|
|
1235
|
+
"parameters": [
|
|
1236
|
+
{
|
|
1237
|
+
"name": "opts",
|
|
1238
|
+
"optional": true,
|
|
1239
|
+
"type": {
|
|
1240
|
+
"text": "{ preserveScroll?: boolean }"
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
]
|
|
1054
1244
|
},
|
|
1055
1245
|
{
|
|
1056
1246
|
"kind": "method",
|
|
@@ -1116,6 +1306,17 @@
|
|
|
1116
1306
|
}
|
|
1117
1307
|
]
|
|
1118
1308
|
},
|
|
1309
|
+
{
|
|
1310
|
+
"kind": "method",
|
|
1311
|
+
"name": "renderOptionInfoButton",
|
|
1312
|
+
"privacy": "private",
|
|
1313
|
+
"return": {
|
|
1314
|
+
"type": {
|
|
1315
|
+
"text": "string"
|
|
1316
|
+
}
|
|
1317
|
+
},
|
|
1318
|
+
"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."
|
|
1319
|
+
},
|
|
1119
1320
|
{
|
|
1120
1321
|
"kind": "method",
|
|
1121
1322
|
"name": "renderTreeNode",
|
|
@@ -1720,6 +1921,217 @@
|
|
|
1720
1921
|
}
|
|
1721
1922
|
}
|
|
1722
1923
|
},
|
|
1924
|
+
{
|
|
1925
|
+
"kind": "method",
|
|
1926
|
+
"name": "setPresentation",
|
|
1927
|
+
"privacy": "public",
|
|
1928
|
+
"return": {
|
|
1929
|
+
"type": {
|
|
1930
|
+
"text": "void"
|
|
1931
|
+
}
|
|
1932
|
+
},
|
|
1933
|
+
"parameters": [
|
|
1934
|
+
{
|
|
1935
|
+
"name": "mode",
|
|
1936
|
+
"type": {
|
|
1937
|
+
"text": "'floating' | 'fullscreen'"
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
],
|
|
1941
|
+
"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."
|
|
1942
|
+
},
|
|
1943
|
+
{
|
|
1944
|
+
"kind": "method",
|
|
1945
|
+
"name": "lockBodyScroll",
|
|
1946
|
+
"privacy": "private",
|
|
1947
|
+
"return": {
|
|
1948
|
+
"type": {
|
|
1949
|
+
"text": "void"
|
|
1950
|
+
}
|
|
1951
|
+
},
|
|
1952
|
+
"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."
|
|
1953
|
+
},
|
|
1954
|
+
{
|
|
1955
|
+
"kind": "method",
|
|
1956
|
+
"name": "unlockBodyScroll",
|
|
1957
|
+
"privacy": "private",
|
|
1958
|
+
"return": {
|
|
1959
|
+
"type": {
|
|
1960
|
+
"text": "void"
|
|
1961
|
+
}
|
|
1962
|
+
},
|
|
1963
|
+
"description": "Restore page scroll (no-op if it wasn't locked)."
|
|
1964
|
+
},
|
|
1965
|
+
{
|
|
1966
|
+
"kind": "method",
|
|
1967
|
+
"name": "observeKeyboardInset",
|
|
1968
|
+
"privacy": "private",
|
|
1969
|
+
"return": {
|
|
1970
|
+
"type": {
|
|
1971
|
+
"text": "void"
|
|
1972
|
+
}
|
|
1973
|
+
},
|
|
1974
|
+
"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."
|
|
1975
|
+
},
|
|
1976
|
+
{
|
|
1977
|
+
"kind": "method",
|
|
1978
|
+
"name": "unobserveKeyboardInset",
|
|
1979
|
+
"privacy": "private",
|
|
1980
|
+
"return": {
|
|
1981
|
+
"type": {
|
|
1982
|
+
"text": "void"
|
|
1983
|
+
}
|
|
1984
|
+
},
|
|
1985
|
+
"description": "Detach keyboard-inset tracking and restore the panel's CSS-driven geometry."
|
|
1986
|
+
},
|
|
1987
|
+
{
|
|
1988
|
+
"kind": "method",
|
|
1989
|
+
"name": "fullscreenScale",
|
|
1990
|
+
"privacy": "private",
|
|
1991
|
+
"return": {
|
|
1992
|
+
"type": {
|
|
1993
|
+
"text": "number"
|
|
1994
|
+
}
|
|
1995
|
+
},
|
|
1996
|
+
"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)."
|
|
1997
|
+
},
|
|
1998
|
+
{
|
|
1999
|
+
"kind": "method",
|
|
2000
|
+
"name": "scaledOptionHeight",
|
|
2001
|
+
"privacy": "private",
|
|
2002
|
+
"return": {
|
|
2003
|
+
"type": {
|
|
2004
|
+
"text": "number"
|
|
2005
|
+
}
|
|
2006
|
+
},
|
|
2007
|
+
"description": "Virtual/fixed row height (px), scaled up in the fullscreen phone view."
|
|
2008
|
+
},
|
|
2009
|
+
{
|
|
2010
|
+
"kind": "method",
|
|
2011
|
+
"name": "applyVirtualOptionsSizing",
|
|
2012
|
+
"privacy": "private",
|
|
2013
|
+
"return": {
|
|
2014
|
+
"type": {
|
|
2015
|
+
"text": "void"
|
|
2016
|
+
}
|
|
2017
|
+
},
|
|
2018
|
+
"parameters": [
|
|
2019
|
+
{
|
|
2020
|
+
"name": "container",
|
|
2021
|
+
"type": {
|
|
2022
|
+
"text": "HTMLElement"
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
],
|
|
2026
|
+
"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."
|
|
2027
|
+
},
|
|
2028
|
+
{
|
|
2029
|
+
"kind": "method",
|
|
2030
|
+
"name": "scaledBadgeHeight",
|
|
2031
|
+
"privacy": "private",
|
|
2032
|
+
"return": {
|
|
2033
|
+
"type": {
|
|
2034
|
+
"text": "number"
|
|
2035
|
+
}
|
|
2036
|
+
},
|
|
2037
|
+
"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."
|
|
2038
|
+
},
|
|
2039
|
+
{
|
|
2040
|
+
"kind": "method",
|
|
2041
|
+
"name": "clearFloatingInlineGeometry",
|
|
2042
|
+
"privacy": "private",
|
|
2043
|
+
"return": {
|
|
2044
|
+
"type": {
|
|
2045
|
+
"text": "void"
|
|
2046
|
+
}
|
|
2047
|
+
},
|
|
2048
|
+
"parameters": [
|
|
2049
|
+
{
|
|
2050
|
+
"name": "panel",
|
|
2051
|
+
"type": {
|
|
2052
|
+
"text": "HTMLElement"
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
],
|
|
2056
|
+
"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."
|
|
2057
|
+
},
|
|
2058
|
+
{
|
|
2059
|
+
"kind": "method",
|
|
2060
|
+
"name": "enterFullscreen",
|
|
2061
|
+
"privacy": "private",
|
|
2062
|
+
"return": {
|
|
2063
|
+
"type": {
|
|
2064
|
+
"text": "void"
|
|
2065
|
+
}
|
|
2066
|
+
},
|
|
2067
|
+
"description": "Stand up the fullscreen dropdown overlay: modifier class, header, scroll lock, focus."
|
|
2068
|
+
},
|
|
2069
|
+
{
|
|
2070
|
+
"kind": "method",
|
|
2071
|
+
"name": "exitFullscreen",
|
|
2072
|
+
"privacy": "private",
|
|
2073
|
+
"return": {
|
|
2074
|
+
"type": {
|
|
2075
|
+
"text": "void"
|
|
2076
|
+
}
|
|
2077
|
+
},
|
|
2078
|
+
"description": "Tear down the fullscreen dropdown chrome and restore page scroll (no-op if floating)."
|
|
2079
|
+
},
|
|
2080
|
+
{
|
|
2081
|
+
"kind": "method",
|
|
2082
|
+
"name": "pushOverlayHistory",
|
|
2083
|
+
"privacy": "private",
|
|
2084
|
+
"return": {
|
|
2085
|
+
"type": {
|
|
2086
|
+
"text": "void"
|
|
2087
|
+
}
|
|
2088
|
+
},
|
|
2089
|
+
"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."
|
|
2090
|
+
},
|
|
2091
|
+
{
|
|
2092
|
+
"kind": "method",
|
|
2093
|
+
"name": "handleOverlayPopstate",
|
|
2094
|
+
"privacy": "private",
|
|
2095
|
+
"return": {
|
|
2096
|
+
"type": {
|
|
2097
|
+
"text": "void"
|
|
2098
|
+
}
|
|
2099
|
+
},
|
|
2100
|
+
"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)."
|
|
2101
|
+
},
|
|
2102
|
+
{
|
|
2103
|
+
"kind": "method",
|
|
2104
|
+
"name": "popOverlayHistory",
|
|
2105
|
+
"privacy": "private",
|
|
2106
|
+
"return": {
|
|
2107
|
+
"type": {
|
|
2108
|
+
"text": "void"
|
|
2109
|
+
}
|
|
2110
|
+
},
|
|
2111
|
+
"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)."
|
|
2112
|
+
},
|
|
2113
|
+
{
|
|
2114
|
+
"kind": "method",
|
|
2115
|
+
"name": "buildFullscreenHeader",
|
|
2116
|
+
"privacy": "private",
|
|
2117
|
+
"return": {
|
|
2118
|
+
"type": {
|
|
2119
|
+
"text": "void"
|
|
2120
|
+
}
|
|
2121
|
+
},
|
|
2122
|
+
"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."
|
|
2123
|
+
},
|
|
2124
|
+
{
|
|
2125
|
+
"kind": "method",
|
|
2126
|
+
"name": "updateFullscreenNav",
|
|
2127
|
+
"privacy": "private",
|
|
2128
|
+
"return": {
|
|
2129
|
+
"type": {
|
|
2130
|
+
"text": "void"
|
|
2131
|
+
}
|
|
2132
|
+
},
|
|
2133
|
+
"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)."
|
|
2134
|
+
},
|
|
1723
2135
|
{
|
|
1724
2136
|
"kind": "method",
|
|
1725
2137
|
"name": "positionHint",
|
|
@@ -2094,6 +2506,84 @@
|
|
|
2094
2506
|
},
|
|
2095
2507
|
"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
2508
|
},
|
|
2509
|
+
{
|
|
2510
|
+
"kind": "method",
|
|
2511
|
+
"name": "markTruncatedOptions",
|
|
2512
|
+
"privacy": "private",
|
|
2513
|
+
"return": {
|
|
2514
|
+
"type": {
|
|
2515
|
+
"text": "void"
|
|
2516
|
+
}
|
|
2517
|
+
},
|
|
2518
|
+
"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."
|
|
2519
|
+
},
|
|
2520
|
+
{
|
|
2521
|
+
"kind": "method",
|
|
2522
|
+
"name": "toggleLabelReveal",
|
|
2523
|
+
"privacy": "private",
|
|
2524
|
+
"return": {
|
|
2525
|
+
"type": {
|
|
2526
|
+
"text": "void"
|
|
2527
|
+
}
|
|
2528
|
+
},
|
|
2529
|
+
"parameters": [
|
|
2530
|
+
{
|
|
2531
|
+
"name": "infoBtn",
|
|
2532
|
+
"type": {
|
|
2533
|
+
"text": "HTMLElement"
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2536
|
+
],
|
|
2537
|
+
"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."
|
|
2538
|
+
},
|
|
2539
|
+
{
|
|
2540
|
+
"kind": "method",
|
|
2541
|
+
"name": "hideLabelReveal",
|
|
2542
|
+
"privacy": "private",
|
|
2543
|
+
"return": {
|
|
2544
|
+
"type": {
|
|
2545
|
+
"text": "void"
|
|
2546
|
+
}
|
|
2547
|
+
},
|
|
2548
|
+
"description": "Dismiss the full-label reveal popover, if shown. Idempotent."
|
|
2549
|
+
},
|
|
2550
|
+
{
|
|
2551
|
+
"kind": "method",
|
|
2552
|
+
"name": "showMessage",
|
|
2553
|
+
"privacy": "public",
|
|
2554
|
+
"return": {
|
|
2555
|
+
"type": {
|
|
2556
|
+
"text": "void"
|
|
2557
|
+
}
|
|
2558
|
+
},
|
|
2559
|
+
"parameters": [
|
|
2560
|
+
{
|
|
2561
|
+
"name": "content",
|
|
2562
|
+
"type": {
|
|
2563
|
+
"text": "string | HTMLElement"
|
|
2564
|
+
}
|
|
2565
|
+
},
|
|
2566
|
+
{
|
|
2567
|
+
"name": "opts",
|
|
2568
|
+
"optional": true,
|
|
2569
|
+
"type": {
|
|
2570
|
+
"text": "MessageOptions"
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
],
|
|
2574
|
+
"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."
|
|
2575
|
+
},
|
|
2576
|
+
{
|
|
2577
|
+
"kind": "method",
|
|
2578
|
+
"name": "hideMessage",
|
|
2579
|
+
"privacy": "public",
|
|
2580
|
+
"return": {
|
|
2581
|
+
"type": {
|
|
2582
|
+
"text": "void"
|
|
2583
|
+
}
|
|
2584
|
+
},
|
|
2585
|
+
"description": "Dismiss the transient message, if shown. Idempotent."
|
|
2586
|
+
},
|
|
2097
2587
|
{
|
|
2098
2588
|
"kind": "method",
|
|
2099
2589
|
"name": "hideOptionTooltips",
|
|
@@ -2636,7 +3126,7 @@
|
|
|
2636
3126
|
"name": "inputs",
|
|
2637
3127
|
"privacy": "protected",
|
|
2638
3128
|
"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.' }, ]",
|
|
3129
|
+
"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
3130
|
"type": {
|
|
2641
3131
|
"text": "readonly InputDef[]"
|
|
2642
3132
|
}
|
|
@@ -2755,6 +3245,25 @@
|
|
|
2755
3245
|
},
|
|
2756
3246
|
"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
3247
|
},
|
|
3248
|
+
{
|
|
3249
|
+
"kind": "method",
|
|
3250
|
+
"name": "directionChanged",
|
|
3251
|
+
"privacy": "protected",
|
|
3252
|
+
"return": {
|
|
3253
|
+
"type": {
|
|
3254
|
+
"text": "void"
|
|
3255
|
+
}
|
|
3256
|
+
},
|
|
3257
|
+
"parameters": [
|
|
3258
|
+
{
|
|
3259
|
+
"name": "_isRTL",
|
|
3260
|
+
"type": {
|
|
3261
|
+
"text": "boolean"
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
],
|
|
3265
|
+
"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."
|
|
3266
|
+
},
|
|
2758
3267
|
{
|
|
2759
3268
|
"kind": "method",
|
|
2760
3269
|
"name": "reinit",
|
|
@@ -2807,6 +3316,44 @@
|
|
|
2807
3316
|
},
|
|
2808
3317
|
"description": "Deactivate: tear the picker down (rebuilt on the next connect)."
|
|
2809
3318
|
},
|
|
3319
|
+
{
|
|
3320
|
+
"kind": "method",
|
|
3321
|
+
"name": "environmentChanged",
|
|
3322
|
+
"privacy": "protected",
|
|
3323
|
+
"return": {
|
|
3324
|
+
"type": {
|
|
3325
|
+
"text": "void"
|
|
3326
|
+
}
|
|
3327
|
+
},
|
|
3328
|
+
"parameters": [
|
|
3329
|
+
{
|
|
3330
|
+
"name": "env",
|
|
3331
|
+
"type": {
|
|
3332
|
+
"text": "EnvironmentSnapshot"
|
|
3333
|
+
}
|
|
3334
|
+
}
|
|
3335
|
+
],
|
|
3336
|
+
"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."
|
|
3337
|
+
},
|
|
3338
|
+
{
|
|
3339
|
+
"kind": "method",
|
|
3340
|
+
"name": "#applyPresentation",
|
|
3341
|
+
"privacy": "private",
|
|
3342
|
+
"return": {
|
|
3343
|
+
"type": {
|
|
3344
|
+
"text": "void"
|
|
3345
|
+
}
|
|
3346
|
+
},
|
|
3347
|
+
"parameters": [
|
|
3348
|
+
{
|
|
3349
|
+
"name": "env",
|
|
3350
|
+
"type": {
|
|
3351
|
+
"text": "EnvironmentSnapshot"
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
],
|
|
3355
|
+
"description": "Resolve `mobile-presentation` against `env` and relay it to the live picker."
|
|
3356
|
+
},
|
|
2810
3357
|
{
|
|
2811
3358
|
"kind": "method",
|
|
2812
3359
|
"name": "#rebuildPicker",
|
|
@@ -3055,6 +3602,41 @@
|
|
|
3055
3602
|
}
|
|
3056
3603
|
}
|
|
3057
3604
|
},
|
|
3605
|
+
{
|
|
3606
|
+
"kind": "method",
|
|
3607
|
+
"name": "showMessage",
|
|
3608
|
+
"return": {
|
|
3609
|
+
"type": {
|
|
3610
|
+
"text": "void"
|
|
3611
|
+
}
|
|
3612
|
+
},
|
|
3613
|
+
"parameters": [
|
|
3614
|
+
{
|
|
3615
|
+
"name": "content",
|
|
3616
|
+
"type": {
|
|
3617
|
+
"text": "string | HTMLElement"
|
|
3618
|
+
}
|
|
3619
|
+
},
|
|
3620
|
+
{
|
|
3621
|
+
"name": "opts",
|
|
3622
|
+
"optional": true,
|
|
3623
|
+
"type": {
|
|
3624
|
+
"text": "MessageOptions"
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3627
|
+
],
|
|
3628
|
+
"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."
|
|
3629
|
+
},
|
|
3630
|
+
{
|
|
3631
|
+
"kind": "method",
|
|
3632
|
+
"name": "hideMessage",
|
|
3633
|
+
"return": {
|
|
3634
|
+
"type": {
|
|
3635
|
+
"text": "void"
|
|
3636
|
+
}
|
|
3637
|
+
},
|
|
3638
|
+
"description": "Dismiss the transient message shown by showMessage, if any."
|
|
3639
|
+
},
|
|
3058
3640
|
{
|
|
3059
3641
|
"kind": "method",
|
|
3060
3642
|
"name": "destroy",
|
|
@@ -3519,6 +4101,28 @@
|
|
|
3519
4101
|
"attribute": "option-tooltip-placement",
|
|
3520
4102
|
"description": "Preferred placement of an option tooltip (floating-ui placement)."
|
|
3521
4103
|
},
|
|
4104
|
+
{
|
|
4105
|
+
"kind": "field",
|
|
4106
|
+
"name": "mobilePresentation",
|
|
4107
|
+
"privacy": "public",
|
|
4108
|
+
"type": {
|
|
4109
|
+
"text": "'auto' | 'floating' | 'fullscreen'"
|
|
4110
|
+
},
|
|
4111
|
+
"default": "'auto'",
|
|
4112
|
+
"attribute": "mobile-presentation",
|
|
4113
|
+
"reflects": true,
|
|
4114
|
+
"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."
|
|
4115
|
+
},
|
|
4116
|
+
{
|
|
4117
|
+
"kind": "field",
|
|
4118
|
+
"name": "fullscreenAutofocus",
|
|
4119
|
+
"privacy": "public",
|
|
4120
|
+
"type": {
|
|
4121
|
+
"text": "boolean"
|
|
4122
|
+
},
|
|
4123
|
+
"attribute": "fullscreen-autofocus",
|
|
4124
|
+
"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."
|
|
4125
|
+
},
|
|
3522
4126
|
{
|
|
3523
4127
|
"kind": "field",
|
|
3524
4128
|
"name": "badgesThreshold",
|
|
@@ -4129,18 +4733,18 @@
|
|
|
4129
4733
|
"name": "beforeSelectCallback",
|
|
4130
4734
|
"privacy": "public",
|
|
4131
4735
|
"type": {
|
|
4132
|
-
"text": "(option: unknown, selectedOptions: unknown[]) => boolean | void"
|
|
4736
|
+
"text": "(option: unknown, selectedOptions: unknown[]) => boolean | string | void"
|
|
4133
4737
|
},
|
|
4134
|
-
"description": "Runs before selecting; return false to veto."
|
|
4738
|
+
"description": "Runs before selecting; return false to veto, or a string to veto and show it as a message."
|
|
4135
4739
|
},
|
|
4136
4740
|
{
|
|
4137
4741
|
"kind": "field",
|
|
4138
4742
|
"name": "beforeDeselectCallback",
|
|
4139
4743
|
"privacy": "public",
|
|
4140
4744
|
"type": {
|
|
4141
|
-
"text": "(option: unknown, selectedOptions: unknown[]) => boolean | void"
|
|
4745
|
+
"text": "(option: unknown, selectedOptions: unknown[]) => boolean | string | void"
|
|
4142
4746
|
},
|
|
4143
|
-
"description": "Runs before deselecting; return false to veto."
|
|
4747
|
+
"description": "Runs before deselecting; return false to veto, or a string to veto and show it as a message."
|
|
4144
4748
|
},
|
|
4145
4749
|
{
|
|
4146
4750
|
"kind": "field",
|
|
@@ -4505,6 +5109,23 @@
|
|
|
4505
5109
|
"default": "'top-start'",
|
|
4506
5110
|
"description": "Preferred placement of an option tooltip (floating-ui placement)."
|
|
4507
5111
|
},
|
|
5112
|
+
{
|
|
5113
|
+
"name": "mobile-presentation",
|
|
5114
|
+
"fieldName": "mobilePresentation",
|
|
5115
|
+
"type": {
|
|
5116
|
+
"text": "'auto' | 'floating' | 'fullscreen'"
|
|
5117
|
+
},
|
|
5118
|
+
"default": "'auto'",
|
|
5119
|
+
"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."
|
|
5120
|
+
},
|
|
5121
|
+
{
|
|
5122
|
+
"name": "fullscreen-autofocus",
|
|
5123
|
+
"fieldName": "fullscreenAutofocus",
|
|
5124
|
+
"type": {
|
|
5125
|
+
"text": "boolean"
|
|
5126
|
+
},
|
|
5127
|
+
"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."
|
|
5128
|
+
},
|
|
4508
5129
|
{
|
|
4509
5130
|
"name": "badges-threshold",
|
|
4510
5131
|
"fieldName": "badgesThreshold",
|