@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/native/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 useEffect3,
6
6
  useState as useState3
@@ -351,15 +351,15 @@ var isWeb = false;
351
351
  // src/MultiSelect.tsx
352
352
  import {
353
353
  useModalId,
354
- useResolvedTheme as useResolvedTheme4,
354
+ useResolvedTheme as useResolvedTheme3,
355
355
  useOverlayLayer,
356
356
  LAYER_OFFSET
357
357
  } from "@xsolla/xui-core";
358
358
  import { Search as SearchIcon } from "@xsolla/xui-icons-base";
359
359
 
360
360
  // src/MultiSelectControl.tsx
361
- import { forwardRef as forwardRef3, useRef as useRef2 } from "react";
362
- import { useResolvedTheme as useResolvedTheme3 } from "@xsolla/xui-core";
361
+ import { forwardRef, useRef as useRef2 } from "react";
362
+ import { useResolvedTheme as useResolvedTheme2 } from "@xsolla/xui-core";
363
363
  import {
364
364
  ChevronDown,
365
365
  ChevronUp,
@@ -374,646 +374,9 @@ import {
374
374
  useRef,
375
375
  useState
376
376
  } from "react";
377
-
378
- // ../tag/dist/web/index.mjs
379
- import React22 from "react";
380
- import styled2 from "styled-components";
381
- import React3 from "react";
382
- import { jsx as jsx5 } from "react/jsx-runtime";
383
- import styled22 from "styled-components";
384
- import { jsx as jsx23 } from "react/jsx-runtime";
385
- import styled3 from "styled-components";
386
- import { jsx as jsx32 } from "react/jsx-runtime";
377
+ import { Tag } from "@xsolla/xui-tag";
387
378
  import { useResolvedTheme } from "@xsolla/xui-core";
388
-
389
- // ../../foundation/icons/dist/web/index.mjs
390
- import React2 from "react";
391
- import styled from "styled-components";
392
- import { jsx as jsx4 } from "react/jsx-runtime";
393
-
394
- // ../../../node_modules/lucide-react/dist/esm/createLucideIcon.js
395
- import { forwardRef as forwardRef2, createElement as createElement2 } from "react";
396
-
397
- // ../../../node_modules/lucide-react/dist/esm/shared/src/utils.js
398
- var toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
399
- var mergeClasses = (...classes) => classes.filter((className, index3, array) => {
400
- return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index3;
401
- }).join(" ").trim();
402
-
403
- // ../../../node_modules/lucide-react/dist/esm/Icon.js
404
- import { forwardRef, createElement } from "react";
405
-
406
- // ../../../node_modules/lucide-react/dist/esm/defaultAttributes.js
407
- var defaultAttributes = {
408
- xmlns: "http://www.w3.org/2000/svg",
409
- width: 24,
410
- height: 24,
411
- viewBox: "0 0 24 24",
412
- fill: "none",
413
- stroke: "currentColor",
414
- strokeWidth: 2,
415
- strokeLinecap: "round",
416
- strokeLinejoin: "round"
417
- };
418
-
419
- // ../../../node_modules/lucide-react/dist/esm/Icon.js
420
- var Icon2 = forwardRef(
421
- ({
422
- color = "currentColor",
423
- size = 24,
424
- strokeWidth = 2,
425
- absoluteStrokeWidth,
426
- className = "",
427
- children,
428
- iconNode,
429
- ...rest
430
- }, ref) => {
431
- return createElement(
432
- "svg",
433
- {
434
- ref,
435
- ...defaultAttributes,
436
- width: size,
437
- height: size,
438
- stroke: color,
439
- strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
440
- className: mergeClasses("lucide", className),
441
- ...rest
442
- },
443
- [
444
- ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),
445
- ...Array.isArray(children) ? children : [children]
446
- ]
447
- );
448
- }
449
- );
450
-
451
- // ../../../node_modules/lucide-react/dist/esm/createLucideIcon.js
452
- var createLucideIcon = (iconName, iconNode) => {
453
- const Component = forwardRef2(
454
- ({ className, ...props }, ref) => createElement2(Icon2, {
455
- ref,
456
- iconNode,
457
- className: mergeClasses(`lucide-${toKebabCase(iconName)}`, className),
458
- ...props
459
- })
460
- );
461
- Component.displayName = `${iconName}`;
462
- return Component;
463
- };
464
-
465
- // ../../../node_modules/lucide-react/dist/esm/icons/x.js
466
- var X = createLucideIcon("X", [
467
- ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
468
- ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
469
- ]);
470
-
471
- // ../../foundation/icons/dist/web/index.mjs
472
- import { jsx as jsx22 } from "react/jsx-runtime";
473
- function memoize(fn) {
474
- var cache = {};
475
- return function(arg) {
476
- if (cache[arg] === void 0) cache[arg] = fn(arg);
477
- return cache[arg];
478
- };
479
- }
480
- var memoize_esm_default = memoize;
481
- var reactPropsRegex = /^((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)-.*))$/;
482
- var index = memoize_esm_default(
483
- function(prop) {
484
- return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111 && prop.charCodeAt(1) === 110 && prop.charCodeAt(2) < 91;
485
- }
486
- /* Z+1 */
487
- );
488
- var is_prop_valid_esm_default = index;
489
- var ADDITIONAL_BLOCKED_PROPS = /* @__PURE__ */ new Set([
490
- // RN-only event handlers (pass isPropValid's on* pattern)
491
- "onPress",
492
- "onChangeText",
493
- "onLayout",
494
- "onMoveShouldSetResponder",
495
- "onResponderGrant",
496
- "onResponderMove",
497
- "onResponderRelease",
498
- "onResponderTerminate",
499
- // SVG attributes that pass isPropValid
500
- "strokeWidth",
501
- // CSS properties that pass isPropValid but are used as component props
502
- "overflow",
503
- "opacity",
504
- "cursor",
505
- "fontSize",
506
- "fontWeight",
507
- "fontFamily",
508
- "textDecoration",
509
- // Cross-platform layout prop that Text consumes as CSS, never as an
510
- // attribute. Pinned explicitly because it is now spread into the styled
511
- // component rather than destructured away before it can reach the DOM.
512
- "numberOfLines"
513
- ]);
514
- function shouldForwardProp(key) {
515
- if (ADDITIONAL_BLOCKED_PROPS.has(key)) return false;
516
- return is_prop_valid_esm_default(key);
517
- }
518
- function createFilteredElement(defaultTag) {
519
- const Component = React2.forwardRef(
520
- ({ children, elementType, ...props }, ref) => {
521
- const Tag2 = elementType || defaultTag;
522
- const htmlProps = {};
523
- for (const key of Object.keys(props)) {
524
- if (shouldForwardProp(key)) {
525
- htmlProps[key] = props[key];
526
- }
527
- }
528
- return React2.createElement(
529
- Tag2,
530
- { ref, ...htmlProps },
531
- children
532
- );
533
- }
534
- );
535
- Component.displayName = `Filtered(${defaultTag})`;
536
- return Component;
537
- }
538
- var FilteredDiv = createFilteredElement("div");
539
- var StyledIcon = styled(FilteredDiv)`
540
- display: flex;
541
- align-items: center;
542
- justify-content: center;
543
- width: ${(props) => typeof props.size === "number" ? `${props.size}px` : props.size || "24px"};
544
- height: ${(props) => typeof props.size === "number" ? `${props.size}px` : props.size || "24px"};
545
- color: ${(props) => props.color || "currentColor"};
546
-
547
- /* Icons paint themselves — each icon's own SVG sets its fill/stroke
548
- (icons-base via inline "fill: currentColor", Lucide via "fill"/"stroke"
549
- attributes). Do not add fill/stroke here: it re-strokes fill-based icons
550
- and thickens the glyph. See FEP-877. */
551
- svg {
552
- width: 100%;
553
- height: 100%;
554
- }
555
- `;
556
- var Icon3 = ({
557
- children,
558
- testID,
559
- "data-testid": dataTestId,
560
- ...props
561
- }) => {
562
- return /* @__PURE__ */ jsx4(StyledIcon, { "data-testid": dataTestId || testID, ...props, children });
563
- };
564
- var X2 = (props) => /* @__PURE__ */ jsx22(Icon3, { ...props, children: /* @__PURE__ */ jsx22(X, { size: "100%" }) });
565
-
566
- // ../tag/dist/web/index.mjs
567
- import { jsx as jsx42, jsxs } from "react/jsx-runtime";
568
- function memoize2(fn) {
569
- var cache = {};
570
- return function(arg) {
571
- if (cache[arg] === void 0) cache[arg] = fn(arg);
572
- return cache[arg];
573
- };
574
- }
575
- var memoize_esm_default2 = memoize2;
576
- 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)-.*))$/;
577
- var index2 = memoize_esm_default2(
578
- function(prop) {
579
- return reactPropsRegex2.test(prop) || prop.charCodeAt(0) === 111 && prop.charCodeAt(1) === 110 && prop.charCodeAt(2) < 91;
580
- }
581
- /* Z+1 */
582
- );
583
- var is_prop_valid_esm_default2 = index2;
584
- var ADDITIONAL_BLOCKED_PROPS2 = /* @__PURE__ */ new Set([
585
- // RN-only event handlers (pass isPropValid's on* pattern)
586
- "onPress",
587
- "onChangeText",
588
- "onLayout",
589
- "onMoveShouldSetResponder",
590
- "onResponderGrant",
591
- "onResponderMove",
592
- "onResponderRelease",
593
- "onResponderTerminate",
594
- // SVG attributes that pass isPropValid
595
- "strokeWidth",
596
- // CSS properties that pass isPropValid but are used as component props
597
- "overflow",
598
- "opacity",
599
- "cursor",
600
- "fontSize",
601
- "fontWeight",
602
- "fontFamily",
603
- "textDecoration",
604
- // Cross-platform layout prop that Text consumes as CSS, never as an
605
- // attribute. Pinned explicitly because it is now spread into the styled
606
- // component rather than destructured away before it can reach the DOM.
607
- "numberOfLines"
608
- ]);
609
- function shouldForwardProp2(key) {
610
- if (ADDITIONAL_BLOCKED_PROPS2.has(key)) return false;
611
- return is_prop_valid_esm_default2(key);
612
- }
613
- function createFilteredElement2(defaultTag) {
614
- const Component = React3.forwardRef(
615
- ({ children, elementType, ...props }, ref) => {
616
- const Tag2 = elementType || defaultTag;
617
- const htmlProps = {};
618
- for (const key of Object.keys(props)) {
619
- if (shouldForwardProp2(key)) {
620
- htmlProps[key] = props[key];
621
- }
622
- }
623
- return React3.createElement(
624
- Tag2,
625
- { ref, ...htmlProps },
626
- children
627
- );
628
- }
629
- );
630
- Component.displayName = `Filtered(${defaultTag})`;
631
- return Component;
632
- }
633
- var FilteredDiv2 = createFilteredElement2("div");
634
- var StyledBox = styled2(FilteredDiv2)`
635
- display: flex;
636
- box-sizing: border-box;
637
- background-color: ${(props) => props.backgroundColor || "transparent"};
638
- border-color: ${(props) => props.borderColor || "transparent"};
639
- border-width: ${(props) => typeof props.borderWidth === "number" ? `${props.borderWidth}px` : props.borderWidth || 0};
640
-
641
- ${(props) => props.borderBottomWidth !== void 0 && `
642
- border-bottom-width: ${typeof props.borderBottomWidth === "number" ? `${props.borderBottomWidth}px` : props.borderBottomWidth};
643
- border-bottom-color: ${props.borderBottomColor || props.borderColor || "transparent"};
644
- border-bottom-style: solid;
645
- `}
646
- ${(props) => props.borderTopWidth !== void 0 && `
647
- border-top-width: ${typeof props.borderTopWidth === "number" ? `${props.borderTopWidth}px` : props.borderTopWidth};
648
- border-top-color: ${props.borderTopColor || props.borderColor || "transparent"};
649
- border-top-style: solid;
650
- `}
651
- ${(props) => props.borderLeftWidth !== void 0 && `
652
- border-left-width: ${typeof props.borderLeftWidth === "number" ? `${props.borderLeftWidth}px` : props.borderLeftWidth};
653
- border-left-color: ${props.borderLeftColor || props.borderColor || "transparent"};
654
- border-left-style: solid;
655
- `}
656
- ${(props) => props.borderRightWidth !== void 0 && `
657
- border-right-width: ${typeof props.borderRightWidth === "number" ? `${props.borderRightWidth}px` : props.borderRightWidth};
658
- border-right-color: ${props.borderRightColor || props.borderColor || "transparent"};
659
- border-right-style: solid;
660
- `}
661
-
662
- border-style: ${(props) => props.borderStyle || (props.borderWidth || props.borderBottomWidth || props.borderTopWidth || props.borderLeftWidth || props.borderRightWidth ? "solid" : "none")};
663
- border-radius: ${(props) => typeof props.borderRadius === "number" ? `${props.borderRadius}px` : props.borderRadius || 0};
664
- height: ${(props) => typeof props.height === "number" ? `${props.height}px` : props.height || "auto"};
665
- width: ${(props) => typeof props.width === "number" ? `${props.width}px` : props.width || "auto"};
666
- min-width: ${(props) => typeof props.minWidth === "number" ? `${props.minWidth}px` : props.minWidth || "auto"};
667
- min-height: ${(props) => typeof props.minHeight === "number" ? `${props.minHeight}px` : props.minHeight || "auto"};
668
- max-width: ${(props) => typeof props.maxWidth === "number" ? `${props.maxWidth}px` : props.maxWidth || "none"};
669
- max-height: ${(props) => typeof props.maxHeight === "number" ? `${props.maxHeight}px` : props.maxHeight || "none"};
670
-
671
- padding: ${(props) => typeof props.padding === "number" ? `${props.padding}px` : props.padding || 0};
672
- ${(props) => props.paddingHorizontal && `
673
- padding-left: ${typeof props.paddingHorizontal === "number" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};
674
- padding-right: ${typeof props.paddingHorizontal === "number" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};
675
- `}
676
- ${(props) => props.paddingVertical && `
677
- padding-top: ${typeof props.paddingVertical === "number" ? `${props.paddingVertical}px` : props.paddingVertical};
678
- padding-bottom: ${typeof props.paddingVertical === "number" ? `${props.paddingVertical}px` : props.paddingVertical};
679
- `}
680
- ${(props) => props.paddingTop !== void 0 && `padding-top: ${typeof props.paddingTop === "number" ? `${props.paddingTop}px` : props.paddingTop};`}
681
- ${(props) => props.paddingBottom !== void 0 && `padding-bottom: ${typeof props.paddingBottom === "number" ? `${props.paddingBottom}px` : props.paddingBottom};`}
682
- ${(props) => props.paddingLeft !== void 0 && `padding-left: ${typeof props.paddingLeft === "number" ? `${props.paddingLeft}px` : props.paddingLeft};`}
683
- ${(props) => props.paddingRight !== void 0 && `padding-right: ${typeof props.paddingRight === "number" ? `${props.paddingRight}px` : props.paddingRight};`}
684
-
685
- margin: ${(props) => typeof props.margin === "number" ? `${props.margin}px` : props.margin || 0};
686
- ${(props) => props.marginTop !== void 0 && `margin-top: ${typeof props.marginTop === "number" ? `${props.marginTop}px` : props.marginTop};`}
687
- ${(props) => props.marginBottom !== void 0 && `margin-bottom: ${typeof props.marginBottom === "number" ? `${props.marginBottom}px` : props.marginBottom};`}
688
- ${(props) => props.marginLeft !== void 0 && `margin-left: ${typeof props.marginLeft === "number" ? `${props.marginLeft}px` : props.marginLeft};`}
689
- ${(props) => props.marginRight !== void 0 && `margin-right: ${typeof props.marginRight === "number" ? `${props.marginRight}px` : props.marginRight};`}
690
-
691
- flex-direction: ${(props) => props.flexDirection || "column"};
692
- flex-wrap: ${(props) => props.flexWrap || "nowrap"};
693
- align-items: ${(props) => props.alignItems || "stretch"};
694
- justify-content: ${(props) => props.justifyContent || "flex-start"};
695
- cursor: ${(props) => props.cursor ? props.cursor : props.onClick || props.onPress ? "pointer" : "inherit"};
696
- position: ${(props) => props.position || "static"};
697
- top: ${(props) => typeof props.top === "number" ? `${props.top}px` : props.top};
698
- bottom: ${(props) => typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom};
699
- left: ${(props) => typeof props.left === "number" ? `${props.left}px` : props.left};
700
- right: ${(props) => typeof props.right === "number" ? `${props.right}px` : props.right};
701
- flex: ${(props) => props.flex};
702
- flex-shrink: ${(props) => props.flexShrink ?? 1};
703
- gap: ${(props) => typeof props.gap === "number" ? `${props.gap}px` : props.gap || 0};
704
- align-self: ${(props) => props.alignSelf || "auto"};
705
- /* Only emit overflow-x/y when explicitly set. Defaulting them to
706
- visible after overflow would override the shorthand and break
707
- clipping (e.g. OtherCard bottom-right promo image). */
708
- overflow: ${(props) => props.overflow || "visible"};
709
- ${(props) => props.overflowX != null ? `overflow-x: ${props.overflowX};` : ""}
710
- ${(props) => props.overflowY != null ? `overflow-y: ${props.overflowY};` : ""}
711
- z-index: ${(props) => props.zIndex};
712
- opacity: ${(props) => props.opacity != null ? props.opacity : props.disabled ? 0.5 : 1};
713
- pointer-events: ${(props) => props.disabled ? "none" : "auto"};
714
-
715
- /* \`background\` is emitted before \`background-color\` so a caller passing
716
- both still gets backgroundColor as the winner. Use the shorthand for a
717
- layered fill (e.g. an overlay tint over a resting surface colour), which
718
- a single background-color cannot express. */
719
- &:hover {
720
- ${(props) => props.hoverStyle?.background && `background: ${props.hoverStyle.background};`}
721
- ${(props) => props.hoverStyle?.backgroundColor && `background-color: ${props.hoverStyle.backgroundColor};`}
722
- ${(props) => props.hoverStyle?.borderColor && `border-color: ${props.hoverStyle.borderColor};`}
723
- }
724
-
725
- &:active {
726
- ${(props) => props.pressStyle?.background && `background: ${props.pressStyle.background};`}
727
- ${(props) => props.pressStyle?.backgroundColor && `background-color: ${props.pressStyle.backgroundColor};`}
728
- }
729
- `;
730
- var Box2 = React22.forwardRef(
731
- ({
732
- children,
733
- onPress,
734
- onKeyDown,
735
- onKeyUp,
736
- role,
737
- "aria-label": ariaLabel,
738
- "aria-labelledby": ariaLabelledBy,
739
- "aria-current": ariaCurrent,
740
- "aria-disabled": ariaDisabled,
741
- "aria-live": ariaLive,
742
- "aria-busy": ariaBusy,
743
- "aria-describedby": ariaDescribedBy,
744
- "aria-expanded": ariaExpanded,
745
- "aria-haspopup": ariaHasPopup,
746
- "aria-pressed": ariaPressed,
747
- "aria-controls": ariaControls,
748
- tabIndex,
749
- as,
750
- src,
751
- alt,
752
- onError,
753
- onLoad,
754
- type,
755
- disabled,
756
- id,
757
- testID,
758
- "data-testid": dataTestId,
759
- ...props
760
- }, ref) => {
761
- if (as === "img" && src) {
762
- return /* @__PURE__ */ jsx5(
763
- "img",
764
- {
765
- src,
766
- alt: alt || "",
767
- onError,
768
- onLoad,
769
- "data-testid": dataTestId || testID,
770
- style: {
771
- display: "block",
772
- objectFit: "cover",
773
- width: typeof props.width === "number" ? `${props.width}px` : props.width,
774
- height: typeof props.height === "number" ? `${props.height}px` : props.height,
775
- borderRadius: typeof props.borderRadius === "number" ? `${props.borderRadius}px` : props.borderRadius,
776
- position: props.position,
777
- top: typeof props.top === "number" ? `${props.top}px` : props.top,
778
- left: typeof props.left === "number" ? `${props.left}px` : props.left,
779
- right: typeof props.right === "number" ? `${props.right}px` : props.right,
780
- bottom: typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom,
781
- ...props.style
782
- }
783
- }
784
- );
785
- }
786
- return /* @__PURE__ */ jsx5(
787
- StyledBox,
788
- {
789
- ref,
790
- elementType: as,
791
- id,
792
- type: as === "button" ? type || "button" : void 0,
793
- disabled: as === "button" ? disabled : void 0,
794
- onClick: onPress,
795
- onKeyDown,
796
- onKeyUp,
797
- role,
798
- "aria-label": ariaLabel,
799
- "aria-labelledby": ariaLabelledBy,
800
- "aria-current": ariaCurrent,
801
- "aria-disabled": ariaDisabled,
802
- "aria-busy": ariaBusy,
803
- "aria-describedby": ariaDescribedBy,
804
- "aria-expanded": ariaExpanded,
805
- "aria-haspopup": ariaHasPopup,
806
- "aria-pressed": ariaPressed,
807
- "aria-controls": ariaControls,
808
- "aria-live": ariaLive,
809
- tabIndex: tabIndex !== void 0 ? tabIndex : void 0,
810
- "data-testid": dataTestId || testID,
811
- ...props,
812
- children
813
- }
814
- );
815
- }
816
- );
817
- Box2.displayName = "Box";
818
- var truncationStyles = (numberOfLines) => {
819
- if (!numberOfLines || numberOfLines < 1) return "";
820
- if (numberOfLines === 1) {
821
- return `
822
- display: block;
823
- max-width: 100%;
824
- min-width: 0;
825
- overflow: hidden;
826
- text-overflow: ellipsis;
827
- white-space: nowrap;
828
- `;
829
- }
830
- return `
831
- display: -webkit-box;
832
- -webkit-box-orient: vertical;
833
- -webkit-line-clamp: ${numberOfLines};
834
- line-clamp: ${numberOfLines};
835
- max-width: 100%;
836
- min-width: 0;
837
- overflow: hidden;
838
- `;
839
- };
840
- var FilteredSpan = createFilteredElement2("span");
841
- var StyledText = styled22(FilteredSpan)`
842
- color: ${(props) => props.color || "inherit"};
843
- font-size: ${(props) => typeof props.fontSize === "number" ? `${props.fontSize}px` : props.fontSize || "inherit"};
844
- font-weight: ${(props) => props.fontWeight || "normal"};
845
- font-family: ${(props) => props.fontFamily || '"Aktiv Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif'};
846
- line-height: ${(props) => typeof props.lineHeight === "number" ? `${props.lineHeight}px` : props.lineHeight || "inherit"};
847
- white-space: ${(props) => props.whiteSpace || "normal"};
848
- text-align: ${(props) => props.textAlign || "inherit"};
849
- text-decoration: ${(props) => props.textDecoration || "none"};
850
-
851
- /* Keep last: single-line truncation has to win over white-space above. */
852
- ${(props) => truncationStyles(props.numberOfLines)}
853
- `;
854
- var Text2 = ({
855
- style,
856
- className,
857
- id,
858
- role,
859
- testID,
860
- "data-testid": dataTestId,
861
- ...props
862
- }) => {
863
- return /* @__PURE__ */ jsx23(
864
- StyledText,
865
- {
866
- ...props,
867
- style,
868
- className,
869
- id,
870
- role,
871
- "data-testid": dataTestId || testID
872
- }
873
- );
874
- };
875
- var FilteredDiv22 = createFilteredElement2("div");
876
- var StyledIcon2 = styled3(FilteredDiv22)`
877
- display: flex;
878
- align-items: center;
879
- justify-content: center;
880
- width: ${(props) => typeof props.size === "number" ? `${props.size}px` : props.size || "24px"};
881
- height: ${(props) => typeof props.size === "number" ? `${props.size}px` : props.size || "24px"};
882
- color: ${(props) => props.color || "currentColor"};
883
-
884
- /* Icons paint themselves — each icon's own SVG sets its fill/stroke
885
- (icons-base via inline "fill: currentColor", Lucide via "fill"/"stroke"
886
- attributes). Do not add fill/stroke here: it re-strokes fill-based icons
887
- and thickens the glyph. See FEP-877. */
888
- svg {
889
- width: 100%;
890
- height: 100%;
891
- }
892
- `;
893
- var Icon4 = ({
894
- children,
895
- testID,
896
- "data-testid": dataTestId,
897
- ...props
898
- }) => {
899
- return /* @__PURE__ */ jsx32(StyledIcon2, { "data-testid": dataTestId || testID, ...props, children });
900
- };
901
- var Tag = ({
902
- size = "md",
903
- tone = "primary",
904
- type = "solid",
905
- children,
906
- iconLeft,
907
- iconRight,
908
- onRemove,
909
- testID,
910
- themeMode,
911
- themeProductContext
912
- }) => {
913
- const { theme } = useResolvedTheme({ themeMode, themeProductContext });
914
- const sizeStyles = theme.sizing.tag(size);
915
- const resolveColors = () => {
916
- const isOutlined = type === "outlined";
917
- switch (tone) {
918
- case "primary":
919
- return {
920
- bg: isOutlined ? "transparent" : theme.colors.background.primary,
921
- text: theme.colors.content.primary,
922
- border: theme.colors.border.secondary
923
- };
924
- case "brand":
925
- return {
926
- bg: isOutlined ? "transparent" : theme.colors.background.brand.primary,
927
- text: isOutlined ? theme.colors.content.brand.primary : theme.colors.content.on.brand,
928
- border: theme.colors.border.brand
929
- };
930
- case "brandExtra":
931
- return {
932
- bg: isOutlined ? "transparent" : theme.colors.background.brandExtra.primary,
933
- text: isOutlined ? theme.colors.content.brandExtra.primary : theme.colors.content.on.brandExtra,
934
- border: theme.colors.border.brandExtra
935
- };
936
- case "success":
937
- return {
938
- bg: isOutlined ? "transparent" : theme.colors.background.success.primary,
939
- text: isOutlined ? theme.colors.content.success.primary : theme.colors.content.on.success,
940
- border: theme.colors.border.success
941
- };
942
- case "warning":
943
- return {
944
- bg: isOutlined ? "transparent" : theme.colors.background.warning.primary,
945
- text: isOutlined ? theme.colors.content.warning.primary : theme.colors.content.on.warning,
946
- border: theme.colors.border.warning
947
- };
948
- case "alert":
949
- return {
950
- bg: isOutlined ? "transparent" : theme.colors.background.alert.primary,
951
- text: isOutlined ? theme.colors.content.alert.primary : theme.colors.content.on.alert,
952
- border: theme.colors.border.alert
953
- };
954
- case "neutral":
955
- return {
956
- bg: isOutlined ? "transparent" : theme.colors.background.neutral.primary,
957
- text: isOutlined ? theme.colors.content.neutral.primary : theme.colors.content.on.neutral,
958
- border: theme.colors.border.neutral
959
- };
960
- default:
961
- return {
962
- bg: isOutlined ? "transparent" : theme.colors.background.primary,
963
- text: theme.colors.content.primary,
964
- border: theme.colors.border.secondary
965
- };
966
- }
967
- };
968
- const { bg, text, border } = resolveColors();
969
- const isIconOnly = !children && (!!iconLeft || !!iconRight);
970
- return /* @__PURE__ */ jsxs(
971
- Box2,
972
- {
973
- testID,
974
- backgroundColor: bg,
975
- borderRadius: sizeStyles.radius,
976
- height: sizeStyles.height,
977
- width: isIconOnly ? sizeStyles.height : void 0,
978
- paddingHorizontal: isIconOnly ? 0 : sizeStyles.padding,
979
- flexDirection: "row",
980
- alignItems: "center",
981
- justifyContent: "center",
982
- gap: sizeStyles.gap,
983
- borderWidth: sizeStyles.borderWidth,
984
- borderColor: border,
985
- borderStyle: "solid",
986
- style: {
987
- overflow: "hidden",
988
- textOverflow: "ellipsis",
989
- whiteSpace: "nowrap"
990
- },
991
- children: [
992
- iconLeft && /* @__PURE__ */ jsx42(Icon4, { size: sizeStyles.iconSize, color: text, children: iconLeft }),
993
- children && /* @__PURE__ */ jsx42(
994
- Text2,
995
- {
996
- color: text,
997
- fontSize: sizeStyles.fontSize,
998
- fontWeight: "500",
999
- whiteSpace: "nowrap",
1000
- style: {
1001
- overflow: "hidden",
1002
- textOverflow: "ellipsis"
1003
- },
1004
- children
1005
- }
1006
- ),
1007
- iconRight && /* @__PURE__ */ jsx42(Icon4, { size: sizeStyles.iconSize, color: text, children: iconRight }),
1008
- onRemove && /* @__PURE__ */ jsx42(Box2, { onPress: onRemove, children: /* @__PURE__ */ jsx42(X2, { size: sizeStyles.iconSize, color: text }) })
1009
- ]
1010
- }
1011
- );
1012
- };
1013
-
1014
- // src/useMultiSelectControl.tsx
1015
- import { useResolvedTheme as useResolvedTheme2 } from "@xsolla/xui-core";
1016
- import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
379
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
1017
380
  var COUNT_ITEM_VALUE = "count-item";
1018
381
  var useMultiSelectControl = ({
1019
382
  variant,
@@ -1029,7 +392,7 @@ var useMultiSelectControl = ({
1029
392
  themeMode,
1030
393
  themeProductContext
1031
394
  }) => {
1032
- const { theme } = useResolvedTheme2({ themeMode, themeProductContext });
395
+ const { theme } = useResolvedTheme({ themeMode, themeProductContext });
1033
396
  const displayStateRef = useRef(0 /* Placeholder */);
1034
397
  const savedWidthsRef = useRef(null);
1035
398
  const itemsRef = useRef(null);
@@ -1063,7 +426,8 @@ var useMultiSelectControl = ({
1063
426
  stateList: stateList.map((item) => item.value),
1064
427
  variant,
1065
428
  size,
1066
- removeTagsButtons
429
+ removeTagsButtons,
430
+ lockedList: stateList.filter((item) => item.removable === false).map((item) => item.value)
1067
431
  }),
1068
432
  [stateList, variant, size, removeTagsButtons]
1069
433
  );
@@ -1076,16 +440,23 @@ var useMultiSelectControl = ({
1076
440
  return true;
1077
441
  if (prev.stateList.length !== widthsDependencies.stateList.length)
1078
442
  return true;
443
+ if (prev.lockedList.length !== widthsDependencies.lockedList.length)
444
+ return true;
1079
445
  let i = 0;
1080
446
  for (const v of prev.stateList) {
1081
447
  if (v !== widthsDependencies.stateList[i]) return true;
1082
448
  i++;
1083
449
  }
450
+ let j = 0;
451
+ for (const v of prev.lockedList) {
452
+ if (v !== widthsDependencies.lockedList[j]) return true;
453
+ j++;
454
+ }
1084
455
  return false;
1085
456
  };
1086
457
  const setPlaceholder = () => {
1087
458
  setSelectedContent(
1088
- /* @__PURE__ */ jsx6(
459
+ /* @__PURE__ */ jsx4(
1089
460
  Text,
1090
461
  {
1091
462
  color: theme.colors.control.input.placeholder,
@@ -1132,28 +503,30 @@ var useMultiSelectControl = ({
1132
503
  const countText = displayStateRef.current === 1 /* PreRender */ ? `+${itemsList.length}` : `+${itemsList.length - displayedItems.length}`;
1133
504
  displayedItems.push({ value: COUNT_ITEM_VALUE, label: countText });
1134
505
  }
1135
- const content = displayedItems.map((item, index3) => {
506
+ const content = displayedItems.map((item, index) => {
1136
507
  const isCount = item.value === COUNT_ITEM_VALUE;
1137
- const isReducable = index3 === 0 && displayStateRef.current === 3 /* Render */ && displayedItemsCount === 0 || flexible;
508
+ const isLocked = !isCount && item.removable === false;
509
+ const canRemove = !isCount && !isLocked;
510
+ const isReducable = index === 0 && displayStateRef.current === 3 /* Render */ && displayedItemsCount === 0 || flexible;
1138
511
  if (variant === "tag") {
1139
- return /* @__PURE__ */ jsx6(
512
+ return /* @__PURE__ */ jsx4(
1140
513
  Box,
1141
514
  {
1142
- onPress: !isCount ? (e) => {
515
+ onPress: canRemove ? (e) => {
1143
516
  e.stopPropagation();
1144
517
  if (!disabled) removeValue(item.value, e);
1145
518
  } : void 0,
1146
519
  style: {
1147
520
  minWidth: isReducable ? 0 : "fit-content",
1148
521
  opacity: disabled ? 0.5 : 1,
1149
- cursor: disabled || isCount ? "not-allowed" : "pointer"
522
+ cursor: isLocked ? "default" : disabled || isCount ? "not-allowed" : "pointer"
1150
523
  },
1151
- children: /* @__PURE__ */ jsx6(
524
+ children: /* @__PURE__ */ jsx4(
1152
525
  Tag,
1153
526
  {
1154
527
  size,
1155
528
  tone: "primary",
1156
- onRemove: removeTagsButtons && !isCount ? (e) => {
529
+ onRemove: removeTagsButtons && canRemove ? (e) => {
1157
530
  e?.stopPropagation();
1158
531
  if (!disabled) removeValue(item.value, e);
1159
532
  } : void 0,
@@ -1165,8 +538,8 @@ var useMultiSelectControl = ({
1165
538
  );
1166
539
  }
1167
540
  const isCountItem = hasHidden;
1168
- const needsComma = index3 < displayedItems.length - 2 || index3 < displayedItems.length - 1 && !isCountItem;
1169
- return /* @__PURE__ */ jsxs2(
541
+ const needsComma = index < displayedItems.length - 2 || index < displayedItems.length - 1 && !isCountItem;
542
+ return /* @__PURE__ */ jsxs(
1170
543
  Text,
1171
544
  {
1172
545
  color: theme.colors.content.primary,
@@ -1201,11 +574,11 @@ var useMultiSelectControl = ({
1201
574
  const countItemWidth = countEl.getBoundingClientRect().width;
1202
575
  const columnGap = parseInt(getComputedStyle(itemsRef.current).columnGap || "0", 10) || 0;
1203
576
  const tagsWidths = {};
1204
- let index3 = 0;
577
+ let index = 0;
1205
578
  for (const el of allItems) {
1206
- const key = index3 < allItems.length - 1 ? stateList[index3].value : COUNT_ITEM_VALUE;
579
+ const key = index < allItems.length - 1 ? stateList[index].value : COUNT_ITEM_VALUE;
1207
580
  tagsWidths[key] = el.getBoundingClientRect().width;
1208
- index3++;
581
+ index++;
1209
582
  }
1210
583
  savedWidthsRef.current = {
1211
584
  tagsWidths,
@@ -1268,8 +641,8 @@ var useMultiSelectControl = ({
1268
641
  };
1269
642
 
1270
643
  // src/MultiSelectControl.tsx
1271
- import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
1272
- var MultiSelectControl = forwardRef3(
644
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
645
+ var MultiSelectControl = forwardRef(
1273
646
  ({
1274
647
  variant = "tag",
1275
648
  flexible = true,
@@ -1293,7 +666,7 @@ var MultiSelectControl = forwardRef3(
1293
666
  themeMode,
1294
667
  themeProductContext
1295
668
  }, ref) => {
1296
- const { theme } = useResolvedTheme3({ themeMode, themeProductContext });
669
+ const { theme } = useResolvedTheme2({ themeMode, themeProductContext });
1297
670
  const sizeStyles = theme.sizing.input(size);
1298
671
  const inputColors = theme.colors.control.input;
1299
672
  const state = externalState || (disabled ? "disable" : "default");
@@ -1328,7 +701,7 @@ var MultiSelectControl = forwardRef3(
1328
701
  borderColor = inputColors.borderHover;
1329
702
  }
1330
703
  const iconColor = isDisable ? inputColors.textDisable : inputColors.placeholder;
1331
- return /* @__PURE__ */ jsxs3(
704
+ return /* @__PURE__ */ jsxs2(
1332
705
  Box,
1333
706
  {
1334
707
  ref,
@@ -1356,7 +729,7 @@ var MultiSelectControl = forwardRef3(
1356
729
  borderColor: inputColors.borderHover
1357
730
  } : void 0,
1358
731
  children: [
1359
- /* @__PURE__ */ jsxs3(
732
+ /* @__PURE__ */ jsxs2(
1360
733
  Box,
1361
734
  {
1362
735
  ref: containerRef,
@@ -1366,8 +739,8 @@ var MultiSelectControl = forwardRef3(
1366
739
  gap: 8,
1367
740
  style: { minWidth: 0 },
1368
741
  children: [
1369
- iconLeft && /* @__PURE__ */ jsx7(Icon, { size: sizeStyles.iconSize, color: iconColor, variant: "line", children: iconLeft }),
1370
- /* @__PURE__ */ jsx7(
742
+ iconLeft && /* @__PURE__ */ jsx5(Icon, { size: sizeStyles.iconSize, color: iconColor, variant: "line", children: iconLeft }),
743
+ /* @__PURE__ */ jsx5(
1371
744
  Box,
1372
745
  {
1373
746
  ref: itemsRef,
@@ -1383,8 +756,8 @@ var MultiSelectControl = forwardRef3(
1383
756
  ]
1384
757
  }
1385
758
  ),
1386
- /* @__PURE__ */ jsxs3(Box, { flexDirection: "row", alignItems: "center", gap: 4, children: [
1387
- extraClear && selectedItems.length > 0 && !isDisable && /* @__PURE__ */ jsx7(
759
+ /* @__PURE__ */ jsxs2(Box, { flexDirection: "row", alignItems: "center", gap: 4, children: [
760
+ extraClear && selectedItems.length > 0 && !isDisable && /* @__PURE__ */ jsx5(
1388
761
  Box,
1389
762
  {
1390
763
  onPress: (e) => {
@@ -1392,11 +765,11 @@ var MultiSelectControl = forwardRef3(
1392
765
  removeAllValues();
1393
766
  },
1394
767
  style: { cursor: "pointer" },
1395
- children: /* @__PURE__ */ jsx7(Remove, { size: 18, color: iconColor, variant: "line" })
768
+ children: /* @__PURE__ */ jsx5(Remove, { size: 18, color: iconColor, variant: "line" })
1396
769
  }
1397
770
  ),
1398
- isError && /* @__PURE__ */ jsx7(ExclamationMarkCr, { size: 18, color: theme.colors.content.alert.primary }),
1399
- iconRight ? iconRight : isOpen ? /* @__PURE__ */ jsx7(ChevronUp, { size: 18, color: iconColor, variant: "line" }) : /* @__PURE__ */ jsx7(ChevronDown, { size: 18, color: iconColor, variant: "line" })
771
+ isError && /* @__PURE__ */ jsx5(ExclamationMarkCr, { size: 18, color: theme.colors.content.alert.primary }),
772
+ iconRight ? iconRight : isOpen ? /* @__PURE__ */ jsx5(ChevronUp, { size: 18, color: iconColor, variant: "line" }) : /* @__PURE__ */ jsx5(ChevronDown, { size: 18, color: iconColor, variant: "line" })
1400
773
  ] })
1401
774
  ]
1402
775
  }
@@ -1412,6 +785,7 @@ var initialState = {
1412
785
  selectedItems: [],
1413
786
  isOpen: false
1414
787
  };
788
+ var isLockedOption = (option) => option.removable === false;
1415
789
  var useMultiSelect = ({
1416
790
  options,
1417
791
  value = [],
@@ -1419,9 +793,13 @@ var useMultiSelect = ({
1419
793
  }) => {
1420
794
  const [state, setState] = useState2(initialState);
1421
795
  const optionsRef = useRef3(options);
796
+ const valuesRef = useRef3(value);
1422
797
  useEffect2(() => {
1423
798
  optionsRef.current = options;
1424
799
  }, [options]);
800
+ useEffect2(() => {
801
+ valuesRef.current = state.values;
802
+ }, [state.values]);
1425
803
  useEffect2(() => {
1426
804
  const selectedItems = options.filter((opt) => value.includes(opt.value));
1427
805
  setState((prevState) => ({
@@ -1430,9 +808,15 @@ var useMultiSelect = ({
1430
808
  selectedItems
1431
809
  }));
1432
810
  }, [options, value]);
811
+ const getLockedSelectedValues = () => optionsRef.current.filter(
812
+ (opt) => isLockedOption(opt) && valuesRef.current.includes(opt.value)
813
+ ).map((opt) => opt.value);
1433
814
  const onChoose = useCallback(
1434
815
  (selectedIds) => {
1435
- const newValues = optionsRef.current.filter((opt) => selectedIds.includes(String(opt.value))).map((opt) => opt.value);
816
+ const lockedValues = getLockedSelectedValues();
817
+ const newValues = optionsRef.current.filter(
818
+ (opt) => selectedIds.includes(String(opt.value)) || lockedValues.includes(opt.value)
819
+ ).map((opt) => opt.value);
1436
820
  const newSelectedItems = optionsRef.current.filter(
1437
821
  (opt) => newValues.includes(opt.value)
1438
822
  );
@@ -1448,6 +832,8 @@ var useMultiSelect = ({
1448
832
  const onRemove = useCallback(
1449
833
  (value2, event) => {
1450
834
  event?.stopPropagation();
835
+ const option = optionsRef.current.find((opt) => opt.value === value2);
836
+ if (option && isLockedOption(option)) return;
1451
837
  setState((prev) => {
1452
838
  const newValues = prev.values.filter((v) => v !== value2);
1453
839
  const newSelectedItems = optionsRef.current.filter(
@@ -1464,12 +850,16 @@ var useMultiSelect = ({
1464
850
  [onChange]
1465
851
  );
1466
852
  const onRemoveAll = useCallback(() => {
853
+ const keptValues = getLockedSelectedValues();
854
+ const keptItems = optionsRef.current.filter(
855
+ (opt) => keptValues.includes(opt.value)
856
+ );
1467
857
  setState((prevState) => ({
1468
858
  ...prevState,
1469
- values: [],
1470
- selectedItems: []
859
+ values: keptValues,
860
+ selectedItems: keptItems
1471
861
  }));
1472
- onChange?.([]);
862
+ onChange?.(keptValues);
1473
863
  }, [onChange]);
1474
864
  const onSelectClick = useCallback(() => {
1475
865
  setState((prevState) => ({
@@ -1497,13 +887,15 @@ var useMultiSelect = ({
1497
887
  };
1498
888
 
1499
889
  // src/Portal.native.tsx
1500
- import { Fragment, jsx as jsx8 } from "react/jsx-runtime";
1501
- var Portal = ({ children }) => /* @__PURE__ */ jsx8(Fragment, { children });
890
+ import { Fragment, jsx as jsx6 } from "react/jsx-runtime";
891
+ var Portal = ({ children }) => /* @__PURE__ */ jsx6(Fragment, { children });
1502
892
 
1503
893
  // src/MultiSelect.tsx
1504
- import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
894
+ import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
1505
895
  var EXTERNAL_MENU_MIN_WIDTH_DEFAULT = 540;
1506
- var MultiSelect = forwardRef4(
896
+ var SEARCH_ROW_HEIGHT = 60;
897
+ var SELECT_ALL_ROW_HEIGHT = 37;
898
+ var MultiSelect = forwardRef2(
1507
899
  ({
1508
900
  options,
1509
901
  errorMessage,
@@ -1529,11 +921,14 @@ var MultiSelect = forwardRef4(
1529
921
  searchable = false,
1530
922
  searchPlaceholder = "Search",
1531
923
  noOptionsMessage = "No results",
924
+ selectAll = false,
925
+ selectAllLabel = "Select all",
926
+ deselectAllLabel = "Deselect all",
1532
927
  testID,
1533
928
  themeMode,
1534
929
  themeProductContext
1535
930
  }, ref) => {
1536
- const { theme } = useResolvedTheme4({ themeMode, themeProductContext });
931
+ const { theme } = useResolvedTheme3({ themeMode, themeProductContext });
1537
932
  const modalId = useModalId();
1538
933
  const overlayLayer = useOverlayLayer();
1539
934
  const controlRef = useRef4(null);
@@ -1580,22 +975,33 @@ var MultiSelect = forwardRef4(
1580
975
  const filteredOptions = searchable && searchValue ? options.filter(
1581
976
  (opt) => getOptionText(opt).toLowerCase().includes(searchValue.toLowerCase())
1582
977
  ) : options;
978
+ const selectedIds = values.map(String);
1583
979
  const menuItems = filteredOptions.map((opt) => {
1584
980
  const id = String(opt.value);
1585
- const checked = values.map(String).includes(id);
981
+ const checked = selectedIds.includes(id);
1586
982
  return {
1587
983
  id,
1588
984
  children: opt.label,
1589
985
  checked,
1590
- disabled: opt.disabled
986
+ disabled: opt.disabled,
987
+ locked: opt.removable === false
1591
988
  };
1592
989
  });
1593
990
  const handleItemToggle = (id, checked) => {
1594
- const value2 = options.find((opt) => String(opt.value) === id)?.value;
1595
- if (value2 === void 0) return;
1596
- const newValues = checked ? [...values, value2] : values.filter((v) => v !== value2);
991
+ const option = options.find((opt) => String(opt.value) === id);
992
+ if (option === void 0) return;
993
+ if (!checked && option.removable === false) return;
994
+ const newValues = checked ? [...values, option.value] : values.filter((v) => v !== option.value);
1597
995
  onChoose(newValues.map(String));
1598
996
  };
997
+ const selectAllTargets = filteredOptions.filter((opt) => !opt.disabled);
998
+ const showSelectAll = selectAll && dropdownMenu && selectAllTargets.length > 0;
999
+ const areAllTargetsSelected = showSelectAll && selectAllTargets.every((opt) => selectedIds.includes(String(opt.value)));
1000
+ const handleSelectAllToggle = () => {
1001
+ const targetIds = selectAllTargets.map((opt) => String(opt.value));
1002
+ const nextIds = areAllTargetsSelected ? selectedIds.filter((id) => !targetIds.includes(id)) : Array.from(/* @__PURE__ */ new Set([...selectedIds, ...targetIds]));
1003
+ onChoose(nextIds);
1004
+ };
1599
1005
  const controlMenuOpen = dropdownMenu ? isOpen : Boolean(menuOpen);
1600
1006
  const controlOnClick = dropdownMenu ? onSelectClick : onTriggerPress;
1601
1007
  const isScrollOverflow = optionOverflow === "scroll";
@@ -1614,6 +1020,7 @@ var MultiSelect = forwardRef4(
1614
1020
  overflow: "hidden",
1615
1021
  textOverflow: "ellipsis"
1616
1022
  };
1023
+ const optionsListMaxHeight = maxHeight - (searchable ? SEARCH_ROW_HEIGHT : 0) - (showSelectAll ? SELECT_ALL_ROW_HEIGHT : 0);
1617
1024
  useEffect3(() => {
1618
1025
  if (!isWeb || !controlMenuOpen || isDisable || !dropdownMenu) return;
1619
1026
  let rafId = null;
@@ -1657,8 +1064,8 @@ var MultiSelect = forwardRef4(
1657
1064
  minWidth: menuMinWidth ?? EXTERNAL_MENU_MIN_WIDTH_DEFAULT,
1658
1065
  boxSizing: "border-box"
1659
1066
  } : void 0;
1660
- const dropdown = dropdownMenu && isOpen && !isDisable && (!isWeb || menuPosition) && /* @__PURE__ */ jsxs4(Fragment2, { children: [
1661
- !isWeb && /* @__PURE__ */ jsx9(
1067
+ const dropdown = dropdownMenu && isOpen && !isDisable && (!isWeb || menuPosition) && /* @__PURE__ */ jsxs3(Fragment2, { children: [
1068
+ !isWeb && /* @__PURE__ */ jsx7(
1662
1069
  Box,
1663
1070
  {
1664
1071
  "data-modal-id": modalId,
@@ -1674,7 +1081,7 @@ var MultiSelect = forwardRef4(
1674
1081
  onPress: onClose
1675
1082
  }
1676
1083
  ),
1677
- /* @__PURE__ */ jsxs4(
1084
+ /* @__PURE__ */ jsxs3(
1678
1085
  Box,
1679
1086
  {
1680
1087
  ref: menuRef,
@@ -1697,14 +1104,14 @@ var MultiSelect = forwardRef4(
1697
1104
  boxShadow: theme.shadow.popover
1698
1105
  },
1699
1106
  children: [
1700
- searchable && isWeb && /* @__PURE__ */ jsx9(
1107
+ searchable && isWeb && /* @__PURE__ */ jsx7(
1701
1108
  Box,
1702
1109
  {
1703
1110
  paddingHorizontal: sizeStyles.paddingHorizontal,
1704
1111
  paddingVertical: sizeStyles.paddingVertical,
1705
1112
  borderBottomWidth: 1,
1706
1113
  borderColor: theme.colors.border.secondary,
1707
- children: /* @__PURE__ */ jsxs4(
1114
+ children: /* @__PURE__ */ jsxs3(
1708
1115
  Box,
1709
1116
  {
1710
1117
  flexDirection: "row",
@@ -1712,15 +1119,15 @@ var MultiSelect = forwardRef4(
1712
1119
  gap: sizeStyles.paddingHorizontal / 2,
1713
1120
  paddingHorizontal: 4,
1714
1121
  children: [
1715
- /* @__PURE__ */ jsx9(
1122
+ /* @__PURE__ */ jsx7(
1716
1123
  Icon,
1717
1124
  {
1718
1125
  size: sizeStyles.iconSize - 2,
1719
1126
  color: inputColors.placeholder,
1720
- children: /* @__PURE__ */ jsx9(SearchIcon, {})
1127
+ children: /* @__PURE__ */ jsx7(SearchIcon, {})
1721
1128
  }
1722
1129
  ),
1723
- /* @__PURE__ */ jsx9(
1130
+ /* @__PURE__ */ jsx7(
1724
1131
  Box,
1725
1132
  {
1726
1133
  as: "input",
@@ -1747,23 +1154,52 @@ var MultiSelect = forwardRef4(
1747
1154
  )
1748
1155
  }
1749
1156
  ),
1750
- /* @__PURE__ */ jsx9(
1157
+ showSelectAll && /* @__PURE__ */ jsx7(
1158
+ Box,
1159
+ {
1160
+ role: "button",
1161
+ "aria-label": areAllTargetsSelected ? deselectAllLabel : selectAllLabel,
1162
+ testID: testID ? `${testID}-select-all` : void 0,
1163
+ paddingHorizontal: sizeStyles.paddingHorizontal,
1164
+ paddingVertical: 8,
1165
+ borderBottomWidth: 1,
1166
+ borderColor: theme.colors.border.secondary,
1167
+ flexDirection: "row",
1168
+ alignItems: "center",
1169
+ onPress: handleSelectAllToggle,
1170
+ hoverStyle: {
1171
+ backgroundColor: theme.colors.control.input.bgHover
1172
+ },
1173
+ style: { cursor: "pointer" },
1174
+ children: /* @__PURE__ */ jsx7(
1175
+ Text,
1176
+ {
1177
+ color: theme.colors.content.brand.primary,
1178
+ fontSize: sizeStyles.fontSize,
1179
+ fontWeight: "500",
1180
+ numberOfLines: 1,
1181
+ children: areAllTargetsSelected ? deselectAllLabel : selectAllLabel
1182
+ }
1183
+ )
1184
+ }
1185
+ ),
1186
+ /* @__PURE__ */ jsx7(
1751
1187
  Box,
1752
1188
  {
1753
1189
  paddingVertical: 4,
1754
1190
  style: {
1755
- maxHeight: searchable ? maxHeight - 60 : maxHeight,
1191
+ maxHeight: optionsListMaxHeight,
1756
1192
  overflowY: "auto",
1757
1193
  overflowX: optionListOverflowX,
1758
1194
  scrollbarWidth: "none"
1759
1195
  },
1760
- children: menuItems.length === 0 ? /* @__PURE__ */ jsx9(
1196
+ children: menuItems.length === 0 ? /* @__PURE__ */ jsx7(
1761
1197
  Box,
1762
1198
  {
1763
1199
  paddingVertical: sizeStyles.paddingVertical * 2,
1764
1200
  paddingHorizontal: sizeStyles.paddingHorizontal,
1765
1201
  alignItems: "center",
1766
- children: /* @__PURE__ */ jsx9(
1202
+ children: /* @__PURE__ */ jsx7(
1767
1203
  Text,
1768
1204
  {
1769
1205
  color: theme.colors.content.tertiary,
@@ -1775,14 +1211,15 @@ var MultiSelect = forwardRef4(
1775
1211
  ) : menuItems.map((item, _index) => {
1776
1212
  const brandColors = theme.colors.control.brand.primary;
1777
1213
  const contentColors = theme.colors.content;
1778
- return /* @__PURE__ */ jsx9(
1214
+ const isInert = item.locked && item.checked;
1215
+ return /* @__PURE__ */ jsx7(
1779
1216
  Box,
1780
1217
  {
1781
1218
  testID,
1782
1219
  paddingHorizontal: sizeStyles.paddingHorizontal,
1783
1220
  paddingVertical: 8,
1784
1221
  onPress: () => {
1785
- if (!item.disabled) {
1222
+ if (!item.disabled && !isInert) {
1786
1223
  handleItemToggle(item.id, !item.checked);
1787
1224
  }
1788
1225
  },
@@ -1794,11 +1231,11 @@ var MultiSelect = forwardRef4(
1794
1231
  backgroundColor: theme.colors.control.input.bgHover
1795
1232
  } : void 0,
1796
1233
  style: {
1797
- cursor: item.disabled ? "not-allowed" : "pointer",
1234
+ cursor: item.disabled ? "not-allowed" : isInert ? "default" : "pointer",
1798
1235
  opacity: item.disabled ? 0.5 : 1,
1799
1236
  minWidth: optionRowMinWidth
1800
1237
  },
1801
- children: /* @__PURE__ */ jsx9(
1238
+ children: /* @__PURE__ */ jsx7(
1802
1239
  Text,
1803
1240
  {
1804
1241
  color: item.checked ? contentColors.on.brand : theme.colors.content.secondary,
@@ -1819,7 +1256,7 @@ var MultiSelect = forwardRef4(
1819
1256
  }
1820
1257
  )
1821
1258
  ] });
1822
- return /* @__PURE__ */ jsxs4(
1259
+ return /* @__PURE__ */ jsxs3(
1823
1260
  Box,
1824
1261
  {
1825
1262
  ref: containerRef,
@@ -1828,7 +1265,7 @@ var MultiSelect = forwardRef4(
1828
1265
  gap: sizeStyles.fieldGap,
1829
1266
  style: externalFieldLayout,
1830
1267
  children: [
1831
- label && /* @__PURE__ */ jsx9(
1268
+ label && /* @__PURE__ */ jsx7(
1832
1269
  Text,
1833
1270
  {
1834
1271
  color: theme.colors.content.secondary,
@@ -1837,7 +1274,7 @@ var MultiSelect = forwardRef4(
1837
1274
  children: label
1838
1275
  }
1839
1276
  ),
1840
- /* @__PURE__ */ jsxs4(
1277
+ /* @__PURE__ */ jsxs3(
1841
1278
  Box,
1842
1279
  {
1843
1280
  ref,
@@ -1846,7 +1283,7 @@ var MultiSelect = forwardRef4(
1846
1283
  ...externalFieldLayout ? { width: "100%" } : {}
1847
1284
  },
1848
1285
  children: [
1849
- /* @__PURE__ */ jsx9(
1286
+ /* @__PURE__ */ jsx7(
1850
1287
  MultiSelectControl,
1851
1288
  {
1852
1289
  ref: controlRef,
@@ -1871,11 +1308,11 @@ var MultiSelect = forwardRef4(
1871
1308
  extraClear
1872
1309
  }
1873
1310
  ),
1874
- isWeb ? /* @__PURE__ */ jsx9(Portal, { children: dropdown }) : dropdown
1311
+ isWeb ? /* @__PURE__ */ jsx7(Portal, { children: dropdown }) : dropdown
1875
1312
  ]
1876
1313
  }
1877
1314
  ),
1878
- errorMessage && /* @__PURE__ */ jsx9(
1315
+ errorMessage && /* @__PURE__ */ jsx7(
1879
1316
  Text,
1880
1317
  {
1881
1318
  color: theme.colors.content.alert.primary,
@@ -1893,19 +1330,4 @@ MultiSelect.displayName = "MultiSelect";
1893
1330
  export {
1894
1331
  MultiSelect
1895
1332
  };
1896
- /*! Bundled license information:
1897
-
1898
- lucide-react/dist/esm/shared/src/utils.js:
1899
- lucide-react/dist/esm/defaultAttributes.js:
1900
- lucide-react/dist/esm/Icon.js:
1901
- lucide-react/dist/esm/createLucideIcon.js:
1902
- lucide-react/dist/esm/icons/x.js:
1903
- lucide-react/dist/esm/lucide-react.js:
1904
- (**
1905
- * @license lucide-react v0.470.0 - ISC
1906
- *
1907
- * This source code is licensed under the ISC license.
1908
- * See the LICENSE file in the root directory of this source tree.
1909
- *)
1910
- */
1911
1333
  //# sourceMappingURL=index.mjs.map