@xsolla/xui-multi-select 0.216.0 → 0.217.0

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/web/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/MultiSelect.tsx
2
2
  import {
3
- forwardRef as forwardRef4,
3
+ forwardRef as forwardRef2,
4
4
  useRef as useRef4,
5
5
  useEffect as useEffect4,
6
6
  useState as useState4
@@ -373,15 +373,15 @@ var isWeb = true;
373
373
  // src/MultiSelect.tsx
374
374
  import {
375
375
  useModalId,
376
- useResolvedTheme as useResolvedTheme4,
376
+ useResolvedTheme as useResolvedTheme3,
377
377
  useOverlayLayer,
378
378
  LAYER_OFFSET
379
379
  } from "@xsolla/xui-core";
380
380
  import { Search as SearchIcon } from "@xsolla/xui-icons-base";
381
381
 
382
382
  // src/MultiSelectControl.tsx
383
- import { forwardRef as forwardRef3, useRef as useRef2 } from "react";
384
- import { useResolvedTheme as useResolvedTheme3 } from "@xsolla/xui-core";
383
+ import { forwardRef, useRef as useRef2 } from "react";
384
+ import { useResolvedTheme as useResolvedTheme2 } from "@xsolla/xui-core";
385
385
  import {
386
386
  ChevronDown,
387
387
  ChevronUp,
@@ -396,646 +396,9 @@ import {
396
396
  useRef,
397
397
  useState
398
398
  } from "react";
399
-
400
- // ../tag/dist/web/index.mjs
401
- import React22 from "react";
402
- import styled5 from "styled-components";
403
- import React4 from "react";
404
- import { jsx as jsx5 } from "react/jsx-runtime";
405
- import styled22 from "styled-components";
406
- import { jsx as jsx23 } from "react/jsx-runtime";
407
- import styled32 from "styled-components";
408
- import { jsx as jsx32 } from "react/jsx-runtime";
399
+ import { Tag } from "@xsolla/xui-tag";
409
400
  import { useResolvedTheme } from "@xsolla/xui-core";
410
-
411
- // ../../foundation/icons/dist/web/index.mjs
412
- import React3 from "react";
413
- import styled4 from "styled-components";
414
- import { jsx as jsx4 } from "react/jsx-runtime";
415
-
416
- // ../../../node_modules/lucide-react/dist/esm/createLucideIcon.js
417
- import { forwardRef as forwardRef2, createElement as createElement2 } from "react";
418
-
419
- // ../../../node_modules/lucide-react/dist/esm/shared/src/utils.js
420
- var toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
421
- var mergeClasses = (...classes) => classes.filter((className, index4, array) => {
422
- return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index4;
423
- }).join(" ").trim();
424
-
425
- // ../../../node_modules/lucide-react/dist/esm/Icon.js
426
- import { forwardRef, createElement } from "react";
427
-
428
- // ../../../node_modules/lucide-react/dist/esm/defaultAttributes.js
429
- var defaultAttributes = {
430
- xmlns: "http://www.w3.org/2000/svg",
431
- width: 24,
432
- height: 24,
433
- viewBox: "0 0 24 24",
434
- fill: "none",
435
- stroke: "currentColor",
436
- strokeWidth: 2,
437
- strokeLinecap: "round",
438
- strokeLinejoin: "round"
439
- };
440
-
441
- // ../../../node_modules/lucide-react/dist/esm/Icon.js
442
- var Icon2 = forwardRef(
443
- ({
444
- color = "currentColor",
445
- size = 24,
446
- strokeWidth = 2,
447
- absoluteStrokeWidth,
448
- className = "",
449
- children,
450
- iconNode,
451
- ...rest
452
- }, ref) => {
453
- return createElement(
454
- "svg",
455
- {
456
- ref,
457
- ...defaultAttributes,
458
- width: size,
459
- height: size,
460
- stroke: color,
461
- strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
462
- className: mergeClasses("lucide", className),
463
- ...rest
464
- },
465
- [
466
- ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),
467
- ...Array.isArray(children) ? children : [children]
468
- ]
469
- );
470
- }
471
- );
472
-
473
- // ../../../node_modules/lucide-react/dist/esm/createLucideIcon.js
474
- var createLucideIcon = (iconName, iconNode) => {
475
- const Component = forwardRef2(
476
- ({ className, ...props }, ref) => createElement2(Icon2, {
477
- ref,
478
- iconNode,
479
- className: mergeClasses(`lucide-${toKebabCase(iconName)}`, className),
480
- ...props
481
- })
482
- );
483
- Component.displayName = `${iconName}`;
484
- return Component;
485
- };
486
-
487
- // ../../../node_modules/lucide-react/dist/esm/icons/x.js
488
- var X = createLucideIcon("X", [
489
- ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
490
- ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
491
- ]);
492
-
493
- // ../../foundation/icons/dist/web/index.mjs
494
- import { jsx as jsx22 } from "react/jsx-runtime";
495
- function memoize2(fn) {
496
- var cache = {};
497
- return function(arg) {
498
- if (cache[arg] === void 0) cache[arg] = fn(arg);
499
- return cache[arg];
500
- };
501
- }
502
- var memoize_esm_default2 = memoize2;
503
- var reactPropsRegex2 = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|inert|itemProp|itemScope|itemType|itemID|itemRef|on|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/;
504
- var index2 = memoize_esm_default2(
505
- function(prop) {
506
- return reactPropsRegex2.test(prop) || prop.charCodeAt(0) === 111 && prop.charCodeAt(1) === 110 && prop.charCodeAt(2) < 91;
507
- }
508
- /* Z+1 */
509
- );
510
- var is_prop_valid_esm_default2 = index2;
511
- var ADDITIONAL_BLOCKED_PROPS2 = /* @__PURE__ */ new Set([
512
- // RN-only event handlers (pass isPropValid's on* pattern)
513
- "onPress",
514
- "onChangeText",
515
- "onLayout",
516
- "onMoveShouldSetResponder",
517
- "onResponderGrant",
518
- "onResponderMove",
519
- "onResponderRelease",
520
- "onResponderTerminate",
521
- // SVG attributes that pass isPropValid
522
- "strokeWidth",
523
- // CSS properties that pass isPropValid but are used as component props
524
- "overflow",
525
- "opacity",
526
- "cursor",
527
- "fontSize",
528
- "fontWeight",
529
- "fontFamily",
530
- "textDecoration",
531
- // Cross-platform layout prop that Text consumes as CSS, never as an
532
- // attribute. Pinned explicitly because it is now spread into the styled
533
- // component rather than destructured away before it can reach the DOM.
534
- "numberOfLines"
535
- ]);
536
- function shouldForwardProp2(key) {
537
- if (ADDITIONAL_BLOCKED_PROPS2.has(key)) return false;
538
- return is_prop_valid_esm_default2(key);
539
- }
540
- function createFilteredElement2(defaultTag) {
541
- const Component = React3.forwardRef(
542
- ({ children, elementType, ...props }, ref) => {
543
- const Tag2 = elementType || defaultTag;
544
- const htmlProps = {};
545
- for (const key of Object.keys(props)) {
546
- if (shouldForwardProp2(key)) {
547
- htmlProps[key] = props[key];
548
- }
549
- }
550
- return React3.createElement(
551
- Tag2,
552
- { ref, ...htmlProps },
553
- children
554
- );
555
- }
556
- );
557
- Component.displayName = `Filtered(${defaultTag})`;
558
- return Component;
559
- }
560
- var FilteredDiv3 = createFilteredElement2("div");
561
- var StyledIcon2 = styled4(FilteredDiv3)`
562
- display: flex;
563
- align-items: center;
564
- justify-content: center;
565
- width: ${(props) => typeof props.size === "number" ? `${props.size}px` : props.size || "24px"};
566
- height: ${(props) => typeof props.size === "number" ? `${props.size}px` : props.size || "24px"};
567
- color: ${(props) => props.color || "currentColor"};
568
-
569
- /* Icons paint themselves — each icon's own SVG sets its fill/stroke
570
- (icons-base via inline "fill: currentColor", Lucide via "fill"/"stroke"
571
- attributes). Do not add fill/stroke here: it re-strokes fill-based icons
572
- and thickens the glyph. See FEP-877. */
573
- svg {
574
- width: 100%;
575
- height: 100%;
576
- }
577
- `;
578
- var Icon3 = ({
579
- children,
580
- testID,
581
- "data-testid": dataTestId,
582
- ...props
583
- }) => {
584
- return /* @__PURE__ */ jsx4(StyledIcon2, { "data-testid": dataTestId || testID, ...props, children });
585
- };
586
- var X2 = (props) => /* @__PURE__ */ jsx22(Icon3, { ...props, children: /* @__PURE__ */ jsx22(X, { size: "100%" }) });
587
-
588
- // ../tag/dist/web/index.mjs
589
- import { jsx as jsx42, jsxs } from "react/jsx-runtime";
590
- function memoize3(fn) {
591
- var cache = {};
592
- return function(arg) {
593
- if (cache[arg] === void 0) cache[arg] = fn(arg);
594
- return cache[arg];
595
- };
596
- }
597
- var memoize_esm_default3 = memoize3;
598
- var reactPropsRegex3 = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|inert|itemProp|itemScope|itemType|itemID|itemRef|on|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/;
599
- var index3 = memoize_esm_default3(
600
- function(prop) {
601
- return reactPropsRegex3.test(prop) || prop.charCodeAt(0) === 111 && prop.charCodeAt(1) === 110 && prop.charCodeAt(2) < 91;
602
- }
603
- /* Z+1 */
604
- );
605
- var is_prop_valid_esm_default3 = index3;
606
- var ADDITIONAL_BLOCKED_PROPS3 = /* @__PURE__ */ new Set([
607
- // RN-only event handlers (pass isPropValid's on* pattern)
608
- "onPress",
609
- "onChangeText",
610
- "onLayout",
611
- "onMoveShouldSetResponder",
612
- "onResponderGrant",
613
- "onResponderMove",
614
- "onResponderRelease",
615
- "onResponderTerminate",
616
- // SVG attributes that pass isPropValid
617
- "strokeWidth",
618
- // CSS properties that pass isPropValid but are used as component props
619
- "overflow",
620
- "opacity",
621
- "cursor",
622
- "fontSize",
623
- "fontWeight",
624
- "fontFamily",
625
- "textDecoration",
626
- // Cross-platform layout prop that Text consumes as CSS, never as an
627
- // attribute. Pinned explicitly because it is now spread into the styled
628
- // component rather than destructured away before it can reach the DOM.
629
- "numberOfLines"
630
- ]);
631
- function shouldForwardProp3(key) {
632
- if (ADDITIONAL_BLOCKED_PROPS3.has(key)) return false;
633
- return is_prop_valid_esm_default3(key);
634
- }
635
- function createFilteredElement3(defaultTag) {
636
- const Component = React4.forwardRef(
637
- ({ children, elementType, ...props }, ref) => {
638
- const Tag2 = elementType || defaultTag;
639
- const htmlProps = {};
640
- for (const key of Object.keys(props)) {
641
- if (shouldForwardProp3(key)) {
642
- htmlProps[key] = props[key];
643
- }
644
- }
645
- return React4.createElement(
646
- Tag2,
647
- { ref, ...htmlProps },
648
- children
649
- );
650
- }
651
- );
652
- Component.displayName = `Filtered(${defaultTag})`;
653
- return Component;
654
- }
655
- var FilteredDiv4 = createFilteredElement3("div");
656
- var StyledBox2 = styled5(FilteredDiv4)`
657
- display: flex;
658
- box-sizing: border-box;
659
- background-color: ${(props) => props.backgroundColor || "transparent"};
660
- border-color: ${(props) => props.borderColor || "transparent"};
661
- border-width: ${(props) => typeof props.borderWidth === "number" ? `${props.borderWidth}px` : props.borderWidth || 0};
662
-
663
- ${(props) => props.borderBottomWidth !== void 0 && `
664
- border-bottom-width: ${typeof props.borderBottomWidth === "number" ? `${props.borderBottomWidth}px` : props.borderBottomWidth};
665
- border-bottom-color: ${props.borderBottomColor || props.borderColor || "transparent"};
666
- border-bottom-style: solid;
667
- `}
668
- ${(props) => props.borderTopWidth !== void 0 && `
669
- border-top-width: ${typeof props.borderTopWidth === "number" ? `${props.borderTopWidth}px` : props.borderTopWidth};
670
- border-top-color: ${props.borderTopColor || props.borderColor || "transparent"};
671
- border-top-style: solid;
672
- `}
673
- ${(props) => props.borderLeftWidth !== void 0 && `
674
- border-left-width: ${typeof props.borderLeftWidth === "number" ? `${props.borderLeftWidth}px` : props.borderLeftWidth};
675
- border-left-color: ${props.borderLeftColor || props.borderColor || "transparent"};
676
- border-left-style: solid;
677
- `}
678
- ${(props) => props.borderRightWidth !== void 0 && `
679
- border-right-width: ${typeof props.borderRightWidth === "number" ? `${props.borderRightWidth}px` : props.borderRightWidth};
680
- border-right-color: ${props.borderRightColor || props.borderColor || "transparent"};
681
- border-right-style: solid;
682
- `}
683
-
684
- border-style: ${(props) => props.borderStyle || (props.borderWidth || props.borderBottomWidth || props.borderTopWidth || props.borderLeftWidth || props.borderRightWidth ? "solid" : "none")};
685
- border-radius: ${(props) => typeof props.borderRadius === "number" ? `${props.borderRadius}px` : props.borderRadius || 0};
686
- height: ${(props) => typeof props.height === "number" ? `${props.height}px` : props.height || "auto"};
687
- width: ${(props) => typeof props.width === "number" ? `${props.width}px` : props.width || "auto"};
688
- min-width: ${(props) => typeof props.minWidth === "number" ? `${props.minWidth}px` : props.minWidth || "auto"};
689
- min-height: ${(props) => typeof props.minHeight === "number" ? `${props.minHeight}px` : props.minHeight || "auto"};
690
- max-width: ${(props) => typeof props.maxWidth === "number" ? `${props.maxWidth}px` : props.maxWidth || "none"};
691
- max-height: ${(props) => typeof props.maxHeight === "number" ? `${props.maxHeight}px` : props.maxHeight || "none"};
692
-
693
- padding: ${(props) => typeof props.padding === "number" ? `${props.padding}px` : props.padding || 0};
694
- ${(props) => props.paddingHorizontal && `
695
- padding-left: ${typeof props.paddingHorizontal === "number" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};
696
- padding-right: ${typeof props.paddingHorizontal === "number" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};
697
- `}
698
- ${(props) => props.paddingVertical && `
699
- padding-top: ${typeof props.paddingVertical === "number" ? `${props.paddingVertical}px` : props.paddingVertical};
700
- padding-bottom: ${typeof props.paddingVertical === "number" ? `${props.paddingVertical}px` : props.paddingVertical};
701
- `}
702
- ${(props) => props.paddingTop !== void 0 && `padding-top: ${typeof props.paddingTop === "number" ? `${props.paddingTop}px` : props.paddingTop};`}
703
- ${(props) => props.paddingBottom !== void 0 && `padding-bottom: ${typeof props.paddingBottom === "number" ? `${props.paddingBottom}px` : props.paddingBottom};`}
704
- ${(props) => props.paddingLeft !== void 0 && `padding-left: ${typeof props.paddingLeft === "number" ? `${props.paddingLeft}px` : props.paddingLeft};`}
705
- ${(props) => props.paddingRight !== void 0 && `padding-right: ${typeof props.paddingRight === "number" ? `${props.paddingRight}px` : props.paddingRight};`}
706
-
707
- margin: ${(props) => typeof props.margin === "number" ? `${props.margin}px` : props.margin || 0};
708
- ${(props) => props.marginTop !== void 0 && `margin-top: ${typeof props.marginTop === "number" ? `${props.marginTop}px` : props.marginTop};`}
709
- ${(props) => props.marginBottom !== void 0 && `margin-bottom: ${typeof props.marginBottom === "number" ? `${props.marginBottom}px` : props.marginBottom};`}
710
- ${(props) => props.marginLeft !== void 0 && `margin-left: ${typeof props.marginLeft === "number" ? `${props.marginLeft}px` : props.marginLeft};`}
711
- ${(props) => props.marginRight !== void 0 && `margin-right: ${typeof props.marginRight === "number" ? `${props.marginRight}px` : props.marginRight};`}
712
-
713
- flex-direction: ${(props) => props.flexDirection || "column"};
714
- flex-wrap: ${(props) => props.flexWrap || "nowrap"};
715
- align-items: ${(props) => props.alignItems || "stretch"};
716
- justify-content: ${(props) => props.justifyContent || "flex-start"};
717
- cursor: ${(props) => props.cursor ? props.cursor : props.onClick || props.onPress ? "pointer" : "inherit"};
718
- position: ${(props) => props.position || "static"};
719
- top: ${(props) => typeof props.top === "number" ? `${props.top}px` : props.top};
720
- bottom: ${(props) => typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom};
721
- left: ${(props) => typeof props.left === "number" ? `${props.left}px` : props.left};
722
- right: ${(props) => typeof props.right === "number" ? `${props.right}px` : props.right};
723
- flex: ${(props) => props.flex};
724
- flex-shrink: ${(props) => props.flexShrink ?? 1};
725
- gap: ${(props) => typeof props.gap === "number" ? `${props.gap}px` : props.gap || 0};
726
- align-self: ${(props) => props.alignSelf || "auto"};
727
- /* Only emit overflow-x/y when explicitly set. Defaulting them to
728
- visible after overflow would override the shorthand and break
729
- clipping (e.g. OtherCard bottom-right promo image). */
730
- overflow: ${(props) => props.overflow || "visible"};
731
- ${(props) => props.overflowX != null ? `overflow-x: ${props.overflowX};` : ""}
732
- ${(props) => props.overflowY != null ? `overflow-y: ${props.overflowY};` : ""}
733
- z-index: ${(props) => props.zIndex};
734
- opacity: ${(props) => props.opacity != null ? props.opacity : props.disabled ? 0.5 : 1};
735
- pointer-events: ${(props) => props.disabled ? "none" : "auto"};
736
-
737
- /* \`background\` is emitted before \`background-color\` so a caller passing
738
- both still gets backgroundColor as the winner. Use the shorthand for a
739
- layered fill (e.g. an overlay tint over a resting surface colour), which
740
- a single background-color cannot express. */
741
- &:hover {
742
- ${(props) => props.hoverStyle?.background && `background: ${props.hoverStyle.background};`}
743
- ${(props) => props.hoverStyle?.backgroundColor && `background-color: ${props.hoverStyle.backgroundColor};`}
744
- ${(props) => props.hoverStyle?.borderColor && `border-color: ${props.hoverStyle.borderColor};`}
745
- }
746
-
747
- &:active {
748
- ${(props) => props.pressStyle?.background && `background: ${props.pressStyle.background};`}
749
- ${(props) => props.pressStyle?.backgroundColor && `background-color: ${props.pressStyle.backgroundColor};`}
750
- }
751
- `;
752
- var Box2 = React22.forwardRef(
753
- ({
754
- children,
755
- onPress,
756
- onKeyDown,
757
- onKeyUp,
758
- role,
759
- "aria-label": ariaLabel,
760
- "aria-labelledby": ariaLabelledBy,
761
- "aria-current": ariaCurrent,
762
- "aria-disabled": ariaDisabled,
763
- "aria-live": ariaLive,
764
- "aria-busy": ariaBusy,
765
- "aria-describedby": ariaDescribedBy,
766
- "aria-expanded": ariaExpanded,
767
- "aria-haspopup": ariaHasPopup,
768
- "aria-pressed": ariaPressed,
769
- "aria-controls": ariaControls,
770
- tabIndex,
771
- as,
772
- src,
773
- alt,
774
- onError,
775
- onLoad,
776
- type,
777
- disabled,
778
- id,
779
- testID,
780
- "data-testid": dataTestId,
781
- ...props
782
- }, ref) => {
783
- if (as === "img" && src) {
784
- return /* @__PURE__ */ jsx5(
785
- "img",
786
- {
787
- src,
788
- alt: alt || "",
789
- onError,
790
- onLoad,
791
- "data-testid": dataTestId || testID,
792
- style: {
793
- display: "block",
794
- objectFit: "cover",
795
- width: typeof props.width === "number" ? `${props.width}px` : props.width,
796
- height: typeof props.height === "number" ? `${props.height}px` : props.height,
797
- borderRadius: typeof props.borderRadius === "number" ? `${props.borderRadius}px` : props.borderRadius,
798
- position: props.position,
799
- top: typeof props.top === "number" ? `${props.top}px` : props.top,
800
- left: typeof props.left === "number" ? `${props.left}px` : props.left,
801
- right: typeof props.right === "number" ? `${props.right}px` : props.right,
802
- bottom: typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom,
803
- ...props.style
804
- }
805
- }
806
- );
807
- }
808
- return /* @__PURE__ */ jsx5(
809
- StyledBox2,
810
- {
811
- ref,
812
- elementType: as,
813
- id,
814
- type: as === "button" ? type || "button" : void 0,
815
- disabled: as === "button" ? disabled : void 0,
816
- onClick: onPress,
817
- onKeyDown,
818
- onKeyUp,
819
- role,
820
- "aria-label": ariaLabel,
821
- "aria-labelledby": ariaLabelledBy,
822
- "aria-current": ariaCurrent,
823
- "aria-disabled": ariaDisabled,
824
- "aria-busy": ariaBusy,
825
- "aria-describedby": ariaDescribedBy,
826
- "aria-expanded": ariaExpanded,
827
- "aria-haspopup": ariaHasPopup,
828
- "aria-pressed": ariaPressed,
829
- "aria-controls": ariaControls,
830
- "aria-live": ariaLive,
831
- tabIndex: tabIndex !== void 0 ? tabIndex : void 0,
832
- "data-testid": dataTestId || testID,
833
- ...props,
834
- children
835
- }
836
- );
837
- }
838
- );
839
- Box2.displayName = "Box";
840
- var truncationStyles2 = (numberOfLines) => {
841
- if (!numberOfLines || numberOfLines < 1) return "";
842
- if (numberOfLines === 1) {
843
- return `
844
- display: block;
845
- max-width: 100%;
846
- min-width: 0;
847
- overflow: hidden;
848
- text-overflow: ellipsis;
849
- white-space: nowrap;
850
- `;
851
- }
852
- return `
853
- display: -webkit-box;
854
- -webkit-box-orient: vertical;
855
- -webkit-line-clamp: ${numberOfLines};
856
- line-clamp: ${numberOfLines};
857
- max-width: 100%;
858
- min-width: 0;
859
- overflow: hidden;
860
- `;
861
- };
862
- var FilteredSpan2 = createFilteredElement3("span");
863
- var StyledText2 = styled22(FilteredSpan2)`
864
- color: ${(props) => props.color || "inherit"};
865
- font-size: ${(props) => typeof props.fontSize === "number" ? `${props.fontSize}px` : props.fontSize || "inherit"};
866
- font-weight: ${(props) => props.fontWeight || "normal"};
867
- font-family: ${(props) => props.fontFamily || '"Aktiv Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif'};
868
- line-height: ${(props) => typeof props.lineHeight === "number" ? `${props.lineHeight}px` : props.lineHeight || "inherit"};
869
- white-space: ${(props) => props.whiteSpace || "normal"};
870
- text-align: ${(props) => props.textAlign || "inherit"};
871
- text-decoration: ${(props) => props.textDecoration || "none"};
872
-
873
- /* Keep last: single-line truncation has to win over white-space above. */
874
- ${(props) => truncationStyles2(props.numberOfLines)}
875
- `;
876
- var Text2 = ({
877
- style,
878
- className,
879
- id,
880
- role,
881
- testID,
882
- "data-testid": dataTestId,
883
- ...props
884
- }) => {
885
- return /* @__PURE__ */ jsx23(
886
- StyledText2,
887
- {
888
- ...props,
889
- style,
890
- className,
891
- id,
892
- role,
893
- "data-testid": dataTestId || testID
894
- }
895
- );
896
- };
897
- var FilteredDiv22 = createFilteredElement3("div");
898
- var StyledIcon3 = styled32(FilteredDiv22)`
899
- display: flex;
900
- align-items: center;
901
- justify-content: center;
902
- width: ${(props) => typeof props.size === "number" ? `${props.size}px` : props.size || "24px"};
903
- height: ${(props) => typeof props.size === "number" ? `${props.size}px` : props.size || "24px"};
904
- color: ${(props) => props.color || "currentColor"};
905
-
906
- /* Icons paint themselves — each icon's own SVG sets its fill/stroke
907
- (icons-base via inline "fill: currentColor", Lucide via "fill"/"stroke"
908
- attributes). Do not add fill/stroke here: it re-strokes fill-based icons
909
- and thickens the glyph. See FEP-877. */
910
- svg {
911
- width: 100%;
912
- height: 100%;
913
- }
914
- `;
915
- var Icon4 = ({
916
- children,
917
- testID,
918
- "data-testid": dataTestId,
919
- ...props
920
- }) => {
921
- return /* @__PURE__ */ jsx32(StyledIcon3, { "data-testid": dataTestId || testID, ...props, children });
922
- };
923
- var Tag = ({
924
- size = "md",
925
- tone = "primary",
926
- type = "solid",
927
- children,
928
- iconLeft,
929
- iconRight,
930
- onRemove,
931
- testID,
932
- themeMode,
933
- themeProductContext
934
- }) => {
935
- const { theme } = useResolvedTheme({ themeMode, themeProductContext });
936
- const sizeStyles = theme.sizing.tag(size);
937
- const resolveColors = () => {
938
- const isOutlined = type === "outlined";
939
- switch (tone) {
940
- case "primary":
941
- return {
942
- bg: isOutlined ? "transparent" : theme.colors.background.primary,
943
- text: theme.colors.content.primary,
944
- border: theme.colors.border.secondary
945
- };
946
- case "brand":
947
- return {
948
- bg: isOutlined ? "transparent" : theme.colors.background.brand.primary,
949
- text: isOutlined ? theme.colors.content.brand.primary : theme.colors.content.on.brand,
950
- border: theme.colors.border.brand
951
- };
952
- case "brandExtra":
953
- return {
954
- bg: isOutlined ? "transparent" : theme.colors.background.brandExtra.primary,
955
- text: isOutlined ? theme.colors.content.brandExtra.primary : theme.colors.content.on.brandExtra,
956
- border: theme.colors.border.brandExtra
957
- };
958
- case "success":
959
- return {
960
- bg: isOutlined ? "transparent" : theme.colors.background.success.primary,
961
- text: isOutlined ? theme.colors.content.success.primary : theme.colors.content.on.success,
962
- border: theme.colors.border.success
963
- };
964
- case "warning":
965
- return {
966
- bg: isOutlined ? "transparent" : theme.colors.background.warning.primary,
967
- text: isOutlined ? theme.colors.content.warning.primary : theme.colors.content.on.warning,
968
- border: theme.colors.border.warning
969
- };
970
- case "alert":
971
- return {
972
- bg: isOutlined ? "transparent" : theme.colors.background.alert.primary,
973
- text: isOutlined ? theme.colors.content.alert.primary : theme.colors.content.on.alert,
974
- border: theme.colors.border.alert
975
- };
976
- case "neutral":
977
- return {
978
- bg: isOutlined ? "transparent" : theme.colors.background.neutral.primary,
979
- text: isOutlined ? theme.colors.content.neutral.primary : theme.colors.content.on.neutral,
980
- border: theme.colors.border.neutral
981
- };
982
- default:
983
- return {
984
- bg: isOutlined ? "transparent" : theme.colors.background.primary,
985
- text: theme.colors.content.primary,
986
- border: theme.colors.border.secondary
987
- };
988
- }
989
- };
990
- const { bg, text, border } = resolveColors();
991
- const isIconOnly = !children && (!!iconLeft || !!iconRight);
992
- return /* @__PURE__ */ jsxs(
993
- Box2,
994
- {
995
- testID,
996
- backgroundColor: bg,
997
- borderRadius: sizeStyles.radius,
998
- height: sizeStyles.height,
999
- width: isIconOnly ? sizeStyles.height : void 0,
1000
- paddingHorizontal: isIconOnly ? 0 : sizeStyles.padding,
1001
- flexDirection: "row",
1002
- alignItems: "center",
1003
- justifyContent: "center",
1004
- gap: sizeStyles.gap,
1005
- borderWidth: sizeStyles.borderWidth,
1006
- borderColor: border,
1007
- borderStyle: "solid",
1008
- style: {
1009
- overflow: "hidden",
1010
- textOverflow: "ellipsis",
1011
- whiteSpace: "nowrap"
1012
- },
1013
- children: [
1014
- iconLeft && /* @__PURE__ */ jsx42(Icon4, { size: sizeStyles.iconSize, color: text, children: iconLeft }),
1015
- children && /* @__PURE__ */ jsx42(
1016
- Text2,
1017
- {
1018
- color: text,
1019
- fontSize: sizeStyles.fontSize,
1020
- fontWeight: "500",
1021
- whiteSpace: "nowrap",
1022
- style: {
1023
- overflow: "hidden",
1024
- textOverflow: "ellipsis"
1025
- },
1026
- children
1027
- }
1028
- ),
1029
- iconRight && /* @__PURE__ */ jsx42(Icon4, { size: sizeStyles.iconSize, color: text, children: iconRight }),
1030
- onRemove && /* @__PURE__ */ jsx42(Box2, { onPress: onRemove, children: /* @__PURE__ */ jsx42(X2, { size: sizeStyles.iconSize, color: text }) })
1031
- ]
1032
- }
1033
- );
1034
- };
1035
-
1036
- // src/useMultiSelectControl.tsx
1037
- import { useResolvedTheme as useResolvedTheme2 } from "@xsolla/xui-core";
1038
- import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
401
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
1039
402
  var COUNT_ITEM_VALUE = "count-item";
1040
403
  var useMultiSelectControl = ({
1041
404
  variant,
@@ -1051,7 +414,7 @@ var useMultiSelectControl = ({
1051
414
  themeMode,
1052
415
  themeProductContext
1053
416
  }) => {
1054
- const { theme } = useResolvedTheme2({ themeMode, themeProductContext });
417
+ const { theme } = useResolvedTheme({ themeMode, themeProductContext });
1055
418
  const displayStateRef = useRef(0 /* Placeholder */);
1056
419
  const savedWidthsRef = useRef(null);
1057
420
  const itemsRef = useRef(null);
@@ -1085,7 +448,8 @@ var useMultiSelectControl = ({
1085
448
  stateList: stateList.map((item) => item.value),
1086
449
  variant,
1087
450
  size,
1088
- removeTagsButtons
451
+ removeTagsButtons,
452
+ lockedList: stateList.filter((item) => item.removable === false).map((item) => item.value)
1089
453
  }),
1090
454
  [stateList, variant, size, removeTagsButtons]
1091
455
  );
@@ -1098,16 +462,23 @@ var useMultiSelectControl = ({
1098
462
  return true;
1099
463
  if (prev.stateList.length !== widthsDependencies.stateList.length)
1100
464
  return true;
465
+ if (prev.lockedList.length !== widthsDependencies.lockedList.length)
466
+ return true;
1101
467
  let i = 0;
1102
468
  for (const v of prev.stateList) {
1103
469
  if (v !== widthsDependencies.stateList[i]) return true;
1104
470
  i++;
1105
471
  }
472
+ let j = 0;
473
+ for (const v of prev.lockedList) {
474
+ if (v !== widthsDependencies.lockedList[j]) return true;
475
+ j++;
476
+ }
1106
477
  return false;
1107
478
  };
1108
479
  const setPlaceholder = () => {
1109
480
  setSelectedContent(
1110
- /* @__PURE__ */ jsx6(
481
+ /* @__PURE__ */ jsx4(
1111
482
  Text,
1112
483
  {
1113
484
  color: theme.colors.control.input.placeholder,
@@ -1154,28 +525,30 @@ var useMultiSelectControl = ({
1154
525
  const countText = displayStateRef.current === 1 /* PreRender */ ? `+${itemsList.length}` : `+${itemsList.length - displayedItems.length}`;
1155
526
  displayedItems.push({ value: COUNT_ITEM_VALUE, label: countText });
1156
527
  }
1157
- const content = displayedItems.map((item, index4) => {
528
+ const content = displayedItems.map((item, index2) => {
1158
529
  const isCount = item.value === COUNT_ITEM_VALUE;
1159
- const isReducable = index4 === 0 && displayStateRef.current === 3 /* Render */ && displayedItemsCount === 0 || flexible;
530
+ const isLocked = !isCount && item.removable === false;
531
+ const canRemove = !isCount && !isLocked;
532
+ const isReducable = index2 === 0 && displayStateRef.current === 3 /* Render */ && displayedItemsCount === 0 || flexible;
1160
533
  if (variant === "tag") {
1161
- return /* @__PURE__ */ jsx6(
534
+ return /* @__PURE__ */ jsx4(
1162
535
  Box,
1163
536
  {
1164
- onPress: !isCount ? (e) => {
537
+ onPress: canRemove ? (e) => {
1165
538
  e.stopPropagation();
1166
539
  if (!disabled) removeValue(item.value, e);
1167
540
  } : void 0,
1168
541
  style: {
1169
542
  minWidth: isReducable ? 0 : "fit-content",
1170
543
  opacity: disabled ? 0.5 : 1,
1171
- cursor: disabled || isCount ? "not-allowed" : "pointer"
544
+ cursor: isLocked ? "default" : disabled || isCount ? "not-allowed" : "pointer"
1172
545
  },
1173
- children: /* @__PURE__ */ jsx6(
546
+ children: /* @__PURE__ */ jsx4(
1174
547
  Tag,
1175
548
  {
1176
549
  size,
1177
550
  tone: "primary",
1178
- onRemove: removeTagsButtons && !isCount ? (e) => {
551
+ onRemove: removeTagsButtons && canRemove ? (e) => {
1179
552
  e?.stopPropagation();
1180
553
  if (!disabled) removeValue(item.value, e);
1181
554
  } : void 0,
@@ -1187,8 +560,8 @@ var useMultiSelectControl = ({
1187
560
  );
1188
561
  }
1189
562
  const isCountItem = hasHidden;
1190
- const needsComma = index4 < displayedItems.length - 2 || index4 < displayedItems.length - 1 && !isCountItem;
1191
- return /* @__PURE__ */ jsxs2(
563
+ const needsComma = index2 < displayedItems.length - 2 || index2 < displayedItems.length - 1 && !isCountItem;
564
+ return /* @__PURE__ */ jsxs(
1192
565
  Text,
1193
566
  {
1194
567
  color: theme.colors.content.primary,
@@ -1223,11 +596,11 @@ var useMultiSelectControl = ({
1223
596
  const countItemWidth = countEl.getBoundingClientRect().width;
1224
597
  const columnGap = parseInt(getComputedStyle(itemsRef.current).columnGap || "0", 10) || 0;
1225
598
  const tagsWidths = {};
1226
- let index4 = 0;
599
+ let index2 = 0;
1227
600
  for (const el of allItems) {
1228
- const key = index4 < allItems.length - 1 ? stateList[index4].value : COUNT_ITEM_VALUE;
601
+ const key = index2 < allItems.length - 1 ? stateList[index2].value : COUNT_ITEM_VALUE;
1229
602
  tagsWidths[key] = el.getBoundingClientRect().width;
1230
- index4++;
603
+ index2++;
1231
604
  }
1232
605
  savedWidthsRef.current = {
1233
606
  tagsWidths,
@@ -1290,8 +663,8 @@ var useMultiSelectControl = ({
1290
663
  };
1291
664
 
1292
665
  // src/MultiSelectControl.tsx
1293
- import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
1294
- var MultiSelectControl = forwardRef3(
666
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
667
+ var MultiSelectControl = forwardRef(
1295
668
  ({
1296
669
  variant = "tag",
1297
670
  flexible = true,
@@ -1315,7 +688,7 @@ var MultiSelectControl = forwardRef3(
1315
688
  themeMode,
1316
689
  themeProductContext
1317
690
  }, ref) => {
1318
- const { theme } = useResolvedTheme3({ themeMode, themeProductContext });
691
+ const { theme } = useResolvedTheme2({ themeMode, themeProductContext });
1319
692
  const sizeStyles = theme.sizing.input(size);
1320
693
  const inputColors = theme.colors.control.input;
1321
694
  const state = externalState || (disabled ? "disable" : "default");
@@ -1350,7 +723,7 @@ var MultiSelectControl = forwardRef3(
1350
723
  borderColor = inputColors.borderHover;
1351
724
  }
1352
725
  const iconColor = isDisable ? inputColors.textDisable : inputColors.placeholder;
1353
- return /* @__PURE__ */ jsxs3(
726
+ return /* @__PURE__ */ jsxs2(
1354
727
  Box,
1355
728
  {
1356
729
  ref,
@@ -1378,7 +751,7 @@ var MultiSelectControl = forwardRef3(
1378
751
  borderColor: inputColors.borderHover
1379
752
  } : void 0,
1380
753
  children: [
1381
- /* @__PURE__ */ jsxs3(
754
+ /* @__PURE__ */ jsxs2(
1382
755
  Box,
1383
756
  {
1384
757
  ref: containerRef,
@@ -1388,8 +761,8 @@ var MultiSelectControl = forwardRef3(
1388
761
  gap: 8,
1389
762
  style: { minWidth: 0 },
1390
763
  children: [
1391
- iconLeft && /* @__PURE__ */ jsx7(Icon, { size: sizeStyles.iconSize, color: iconColor, variant: "line", children: iconLeft }),
1392
- /* @__PURE__ */ jsx7(
764
+ iconLeft && /* @__PURE__ */ jsx5(Icon, { size: sizeStyles.iconSize, color: iconColor, variant: "line", children: iconLeft }),
765
+ /* @__PURE__ */ jsx5(
1393
766
  Box,
1394
767
  {
1395
768
  ref: itemsRef,
@@ -1405,8 +778,8 @@ var MultiSelectControl = forwardRef3(
1405
778
  ]
1406
779
  }
1407
780
  ),
1408
- /* @__PURE__ */ jsxs3(Box, { flexDirection: "row", alignItems: "center", gap: 4, children: [
1409
- extraClear && selectedItems.length > 0 && !isDisable && /* @__PURE__ */ jsx7(
781
+ /* @__PURE__ */ jsxs2(Box, { flexDirection: "row", alignItems: "center", gap: 4, children: [
782
+ extraClear && selectedItems.length > 0 && !isDisable && /* @__PURE__ */ jsx5(
1410
783
  Box,
1411
784
  {
1412
785
  onPress: (e) => {
@@ -1414,11 +787,11 @@ var MultiSelectControl = forwardRef3(
1414
787
  removeAllValues();
1415
788
  },
1416
789
  style: { cursor: "pointer" },
1417
- children: /* @__PURE__ */ jsx7(Remove, { size: 18, color: iconColor, variant: "line" })
790
+ children: /* @__PURE__ */ jsx5(Remove, { size: 18, color: iconColor, variant: "line" })
1418
791
  }
1419
792
  ),
1420
- isError && /* @__PURE__ */ jsx7(ExclamationMarkCr, { size: 18, color: theme.colors.content.alert.primary }),
1421
- iconRight ? iconRight : isOpen ? /* @__PURE__ */ jsx7(ChevronUp, { size: 18, color: iconColor, variant: "line" }) : /* @__PURE__ */ jsx7(ChevronDown, { size: 18, color: iconColor, variant: "line" })
793
+ isError && /* @__PURE__ */ jsx5(ExclamationMarkCr, { size: 18, color: theme.colors.content.alert.primary }),
794
+ iconRight ? iconRight : isOpen ? /* @__PURE__ */ jsx5(ChevronUp, { size: 18, color: iconColor, variant: "line" }) : /* @__PURE__ */ jsx5(ChevronDown, { size: 18, color: iconColor, variant: "line" })
1422
795
  ] })
1423
796
  ]
1424
797
  }
@@ -1434,6 +807,7 @@ var initialState = {
1434
807
  selectedItems: [],
1435
808
  isOpen: false
1436
809
  };
810
+ var isLockedOption = (option) => option.removable === false;
1437
811
  var useMultiSelect = ({
1438
812
  options,
1439
813
  value = [],
@@ -1441,9 +815,13 @@ var useMultiSelect = ({
1441
815
  }) => {
1442
816
  const [state, setState] = useState2(initialState);
1443
817
  const optionsRef = useRef3(options);
818
+ const valuesRef = useRef3(value);
1444
819
  useEffect2(() => {
1445
820
  optionsRef.current = options;
1446
821
  }, [options]);
822
+ useEffect2(() => {
823
+ valuesRef.current = state.values;
824
+ }, [state.values]);
1447
825
  useEffect2(() => {
1448
826
  const selectedItems = options.filter((opt) => value.includes(opt.value));
1449
827
  setState((prevState) => ({
@@ -1452,9 +830,15 @@ var useMultiSelect = ({
1452
830
  selectedItems
1453
831
  }));
1454
832
  }, [options, value]);
833
+ const getLockedSelectedValues = () => optionsRef.current.filter(
834
+ (opt) => isLockedOption(opt) && valuesRef.current.includes(opt.value)
835
+ ).map((opt) => opt.value);
1455
836
  const onChoose = useCallback(
1456
837
  (selectedIds) => {
1457
- const newValues = optionsRef.current.filter((opt) => selectedIds.includes(String(opt.value))).map((opt) => opt.value);
838
+ const lockedValues = getLockedSelectedValues();
839
+ const newValues = optionsRef.current.filter(
840
+ (opt) => selectedIds.includes(String(opt.value)) || lockedValues.includes(opt.value)
841
+ ).map((opt) => opt.value);
1458
842
  const newSelectedItems = optionsRef.current.filter(
1459
843
  (opt) => newValues.includes(opt.value)
1460
844
  );
@@ -1470,6 +854,8 @@ var useMultiSelect = ({
1470
854
  const onRemove = useCallback(
1471
855
  (value2, event) => {
1472
856
  event?.stopPropagation();
857
+ const option = optionsRef.current.find((opt) => opt.value === value2);
858
+ if (option && isLockedOption(option)) return;
1473
859
  setState((prev) => {
1474
860
  const newValues = prev.values.filter((v) => v !== value2);
1475
861
  const newSelectedItems = optionsRef.current.filter(
@@ -1486,12 +872,16 @@ var useMultiSelect = ({
1486
872
  [onChange]
1487
873
  );
1488
874
  const onRemoveAll = useCallback(() => {
875
+ const keptValues = getLockedSelectedValues();
876
+ const keptItems = optionsRef.current.filter(
877
+ (opt) => keptValues.includes(opt.value)
878
+ );
1489
879
  setState((prevState) => ({
1490
880
  ...prevState,
1491
- values: [],
1492
- selectedItems: []
881
+ values: keptValues,
882
+ selectedItems: keptItems
1493
883
  }));
1494
- onChange?.([]);
884
+ onChange?.(keptValues);
1495
885
  }, [onChange]);
1496
886
  const onSelectClick = useCallback(() => {
1497
887
  setState((prevState) => ({
@@ -1529,9 +919,11 @@ var Portal = ({ children }) => {
1529
919
  };
1530
920
 
1531
921
  // src/MultiSelect.tsx
1532
- import { Fragment, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
922
+ import { Fragment, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
1533
923
  var EXTERNAL_MENU_MIN_WIDTH_DEFAULT = 540;
1534
- var MultiSelect = forwardRef4(
924
+ var SEARCH_ROW_HEIGHT = 60;
925
+ var SELECT_ALL_ROW_HEIGHT = 37;
926
+ var MultiSelect = forwardRef2(
1535
927
  ({
1536
928
  options,
1537
929
  errorMessage,
@@ -1557,11 +949,14 @@ var MultiSelect = forwardRef4(
1557
949
  searchable = false,
1558
950
  searchPlaceholder = "Search",
1559
951
  noOptionsMessage = "No results",
952
+ selectAll = false,
953
+ selectAllLabel = "Select all",
954
+ deselectAllLabel = "Deselect all",
1560
955
  testID,
1561
956
  themeMode,
1562
957
  themeProductContext
1563
958
  }, ref) => {
1564
- const { theme } = useResolvedTheme4({ themeMode, themeProductContext });
959
+ const { theme } = useResolvedTheme3({ themeMode, themeProductContext });
1565
960
  const modalId = useModalId();
1566
961
  const overlayLayer = useOverlayLayer();
1567
962
  const controlRef = useRef4(null);
@@ -1608,22 +1003,33 @@ var MultiSelect = forwardRef4(
1608
1003
  const filteredOptions = searchable && searchValue ? options.filter(
1609
1004
  (opt) => getOptionText(opt).toLowerCase().includes(searchValue.toLowerCase())
1610
1005
  ) : options;
1006
+ const selectedIds = values.map(String);
1611
1007
  const menuItems = filteredOptions.map((opt) => {
1612
1008
  const id = String(opt.value);
1613
- const checked = values.map(String).includes(id);
1009
+ const checked = selectedIds.includes(id);
1614
1010
  return {
1615
1011
  id,
1616
1012
  children: opt.label,
1617
1013
  checked,
1618
- disabled: opt.disabled
1014
+ disabled: opt.disabled,
1015
+ locked: opt.removable === false
1619
1016
  };
1620
1017
  });
1621
1018
  const handleItemToggle = (id, checked) => {
1622
- const value2 = options.find((opt) => String(opt.value) === id)?.value;
1623
- if (value2 === void 0) return;
1624
- const newValues = checked ? [...values, value2] : values.filter((v) => v !== value2);
1019
+ const option = options.find((opt) => String(opt.value) === id);
1020
+ if (option === void 0) return;
1021
+ if (!checked && option.removable === false) return;
1022
+ const newValues = checked ? [...values, option.value] : values.filter((v) => v !== option.value);
1625
1023
  onChoose(newValues.map(String));
1626
1024
  };
1025
+ const selectAllTargets = filteredOptions.filter((opt) => !opt.disabled);
1026
+ const showSelectAll = selectAll && dropdownMenu && selectAllTargets.length > 0;
1027
+ const areAllTargetsSelected = showSelectAll && selectAllTargets.every((opt) => selectedIds.includes(String(opt.value)));
1028
+ const handleSelectAllToggle = () => {
1029
+ const targetIds = selectAllTargets.map((opt) => String(opt.value));
1030
+ const nextIds = areAllTargetsSelected ? selectedIds.filter((id) => !targetIds.includes(id)) : Array.from(/* @__PURE__ */ new Set([...selectedIds, ...targetIds]));
1031
+ onChoose(nextIds);
1032
+ };
1627
1033
  const controlMenuOpen = dropdownMenu ? isOpen : Boolean(menuOpen);
1628
1034
  const controlOnClick = dropdownMenu ? onSelectClick : onTriggerPress;
1629
1035
  const isScrollOverflow = optionOverflow === "scroll";
@@ -1642,6 +1048,7 @@ var MultiSelect = forwardRef4(
1642
1048
  overflow: "hidden",
1643
1049
  textOverflow: "ellipsis"
1644
1050
  };
1051
+ const optionsListMaxHeight = maxHeight - (searchable ? SEARCH_ROW_HEIGHT : 0) - (showSelectAll ? SELECT_ALL_ROW_HEIGHT : 0);
1645
1052
  useEffect4(() => {
1646
1053
  if (!isWeb || !controlMenuOpen || isDisable || !dropdownMenu) return;
1647
1054
  let rafId = null;
@@ -1685,8 +1092,8 @@ var MultiSelect = forwardRef4(
1685
1092
  minWidth: menuMinWidth ?? EXTERNAL_MENU_MIN_WIDTH_DEFAULT,
1686
1093
  boxSizing: "border-box"
1687
1094
  } : void 0;
1688
- const dropdown = dropdownMenu && isOpen && !isDisable && (!isWeb || menuPosition) && /* @__PURE__ */ jsxs4(Fragment, { children: [
1689
- !isWeb && /* @__PURE__ */ jsx8(
1095
+ const dropdown = dropdownMenu && isOpen && !isDisable && (!isWeb || menuPosition) && /* @__PURE__ */ jsxs3(Fragment, { children: [
1096
+ !isWeb && /* @__PURE__ */ jsx6(
1690
1097
  Box,
1691
1098
  {
1692
1099
  "data-modal-id": modalId,
@@ -1702,7 +1109,7 @@ var MultiSelect = forwardRef4(
1702
1109
  onPress: onClose
1703
1110
  }
1704
1111
  ),
1705
- /* @__PURE__ */ jsxs4(
1112
+ /* @__PURE__ */ jsxs3(
1706
1113
  Box,
1707
1114
  {
1708
1115
  ref: menuRef,
@@ -1725,14 +1132,14 @@ var MultiSelect = forwardRef4(
1725
1132
  boxShadow: theme.shadow.popover
1726
1133
  },
1727
1134
  children: [
1728
- searchable && isWeb && /* @__PURE__ */ jsx8(
1135
+ searchable && isWeb && /* @__PURE__ */ jsx6(
1729
1136
  Box,
1730
1137
  {
1731
1138
  paddingHorizontal: sizeStyles.paddingHorizontal,
1732
1139
  paddingVertical: sizeStyles.paddingVertical,
1733
1140
  borderBottomWidth: 1,
1734
1141
  borderColor: theme.colors.border.secondary,
1735
- children: /* @__PURE__ */ jsxs4(
1142
+ children: /* @__PURE__ */ jsxs3(
1736
1143
  Box,
1737
1144
  {
1738
1145
  flexDirection: "row",
@@ -1740,15 +1147,15 @@ var MultiSelect = forwardRef4(
1740
1147
  gap: sizeStyles.paddingHorizontal / 2,
1741
1148
  paddingHorizontal: 4,
1742
1149
  children: [
1743
- /* @__PURE__ */ jsx8(
1150
+ /* @__PURE__ */ jsx6(
1744
1151
  Icon,
1745
1152
  {
1746
1153
  size: sizeStyles.iconSize - 2,
1747
1154
  color: inputColors.placeholder,
1748
- children: /* @__PURE__ */ jsx8(SearchIcon, {})
1155
+ children: /* @__PURE__ */ jsx6(SearchIcon, {})
1749
1156
  }
1750
1157
  ),
1751
- /* @__PURE__ */ jsx8(
1158
+ /* @__PURE__ */ jsx6(
1752
1159
  Box,
1753
1160
  {
1754
1161
  as: "input",
@@ -1775,23 +1182,52 @@ var MultiSelect = forwardRef4(
1775
1182
  )
1776
1183
  }
1777
1184
  ),
1778
- /* @__PURE__ */ jsx8(
1185
+ showSelectAll && /* @__PURE__ */ jsx6(
1186
+ Box,
1187
+ {
1188
+ role: "button",
1189
+ "aria-label": areAllTargetsSelected ? deselectAllLabel : selectAllLabel,
1190
+ testID: testID ? `${testID}-select-all` : void 0,
1191
+ paddingHorizontal: sizeStyles.paddingHorizontal,
1192
+ paddingVertical: 8,
1193
+ borderBottomWidth: 1,
1194
+ borderColor: theme.colors.border.secondary,
1195
+ flexDirection: "row",
1196
+ alignItems: "center",
1197
+ onPress: handleSelectAllToggle,
1198
+ hoverStyle: {
1199
+ backgroundColor: theme.colors.control.input.bgHover
1200
+ },
1201
+ style: { cursor: "pointer" },
1202
+ children: /* @__PURE__ */ jsx6(
1203
+ Text,
1204
+ {
1205
+ color: theme.colors.content.brand.primary,
1206
+ fontSize: sizeStyles.fontSize,
1207
+ fontWeight: "500",
1208
+ numberOfLines: 1,
1209
+ children: areAllTargetsSelected ? deselectAllLabel : selectAllLabel
1210
+ }
1211
+ )
1212
+ }
1213
+ ),
1214
+ /* @__PURE__ */ jsx6(
1779
1215
  Box,
1780
1216
  {
1781
1217
  paddingVertical: 4,
1782
1218
  style: {
1783
- maxHeight: searchable ? maxHeight - 60 : maxHeight,
1219
+ maxHeight: optionsListMaxHeight,
1784
1220
  overflowY: "auto",
1785
1221
  overflowX: optionListOverflowX,
1786
1222
  scrollbarWidth: "none"
1787
1223
  },
1788
- children: menuItems.length === 0 ? /* @__PURE__ */ jsx8(
1224
+ children: menuItems.length === 0 ? /* @__PURE__ */ jsx6(
1789
1225
  Box,
1790
1226
  {
1791
1227
  paddingVertical: sizeStyles.paddingVertical * 2,
1792
1228
  paddingHorizontal: sizeStyles.paddingHorizontal,
1793
1229
  alignItems: "center",
1794
- children: /* @__PURE__ */ jsx8(
1230
+ children: /* @__PURE__ */ jsx6(
1795
1231
  Text,
1796
1232
  {
1797
1233
  color: theme.colors.content.tertiary,
@@ -1803,14 +1239,15 @@ var MultiSelect = forwardRef4(
1803
1239
  ) : menuItems.map((item, _index) => {
1804
1240
  const brandColors = theme.colors.control.brand.primary;
1805
1241
  const contentColors = theme.colors.content;
1806
- return /* @__PURE__ */ jsx8(
1242
+ const isInert = item.locked && item.checked;
1243
+ return /* @__PURE__ */ jsx6(
1807
1244
  Box,
1808
1245
  {
1809
1246
  testID,
1810
1247
  paddingHorizontal: sizeStyles.paddingHorizontal,
1811
1248
  paddingVertical: 8,
1812
1249
  onPress: () => {
1813
- if (!item.disabled) {
1250
+ if (!item.disabled && !isInert) {
1814
1251
  handleItemToggle(item.id, !item.checked);
1815
1252
  }
1816
1253
  },
@@ -1822,11 +1259,11 @@ var MultiSelect = forwardRef4(
1822
1259
  backgroundColor: theme.colors.control.input.bgHover
1823
1260
  } : void 0,
1824
1261
  style: {
1825
- cursor: item.disabled ? "not-allowed" : "pointer",
1262
+ cursor: item.disabled ? "not-allowed" : isInert ? "default" : "pointer",
1826
1263
  opacity: item.disabled ? 0.5 : 1,
1827
1264
  minWidth: optionRowMinWidth
1828
1265
  },
1829
- children: /* @__PURE__ */ jsx8(
1266
+ children: /* @__PURE__ */ jsx6(
1830
1267
  Text,
1831
1268
  {
1832
1269
  color: item.checked ? contentColors.on.brand : theme.colors.content.secondary,
@@ -1847,7 +1284,7 @@ var MultiSelect = forwardRef4(
1847
1284
  }
1848
1285
  )
1849
1286
  ] });
1850
- return /* @__PURE__ */ jsxs4(
1287
+ return /* @__PURE__ */ jsxs3(
1851
1288
  Box,
1852
1289
  {
1853
1290
  ref: containerRef,
@@ -1856,7 +1293,7 @@ var MultiSelect = forwardRef4(
1856
1293
  gap: sizeStyles.fieldGap,
1857
1294
  style: externalFieldLayout,
1858
1295
  children: [
1859
- label && /* @__PURE__ */ jsx8(
1296
+ label && /* @__PURE__ */ jsx6(
1860
1297
  Text,
1861
1298
  {
1862
1299
  color: theme.colors.content.secondary,
@@ -1865,7 +1302,7 @@ var MultiSelect = forwardRef4(
1865
1302
  children: label
1866
1303
  }
1867
1304
  ),
1868
- /* @__PURE__ */ jsxs4(
1305
+ /* @__PURE__ */ jsxs3(
1869
1306
  Box,
1870
1307
  {
1871
1308
  ref,
@@ -1874,7 +1311,7 @@ var MultiSelect = forwardRef4(
1874
1311
  ...externalFieldLayout ? { width: "100%" } : {}
1875
1312
  },
1876
1313
  children: [
1877
- /* @__PURE__ */ jsx8(
1314
+ /* @__PURE__ */ jsx6(
1878
1315
  MultiSelectControl,
1879
1316
  {
1880
1317
  ref: controlRef,
@@ -1899,11 +1336,11 @@ var MultiSelect = forwardRef4(
1899
1336
  extraClear
1900
1337
  }
1901
1338
  ),
1902
- isWeb ? /* @__PURE__ */ jsx8(Portal, { children: dropdown }) : dropdown
1339
+ isWeb ? /* @__PURE__ */ jsx6(Portal, { children: dropdown }) : dropdown
1903
1340
  ]
1904
1341
  }
1905
1342
  ),
1906
- errorMessage && /* @__PURE__ */ jsx8(
1343
+ errorMessage && /* @__PURE__ */ jsx6(
1907
1344
  Text,
1908
1345
  {
1909
1346
  color: theme.colors.content.alert.primary,
@@ -1921,19 +1358,4 @@ MultiSelect.displayName = "MultiSelect";
1921
1358
  export {
1922
1359
  MultiSelect
1923
1360
  };
1924
- /*! Bundled license information:
1925
-
1926
- lucide-react/dist/esm/shared/src/utils.js:
1927
- lucide-react/dist/esm/defaultAttributes.js:
1928
- lucide-react/dist/esm/Icon.js:
1929
- lucide-react/dist/esm/createLucideIcon.js:
1930
- lucide-react/dist/esm/icons/x.js:
1931
- lucide-react/dist/esm/lucide-react.js:
1932
- (**
1933
- * @license lucide-react v0.470.0 - ISC
1934
- *
1935
- * This source code is licensed under the ISC license.
1936
- * See the LICENSE file in the root directory of this source tree.
1937
- *)
1938
- */
1939
1361
  //# sourceMappingURL=index.mjs.map