@vodafone_de/brix-components 3.0.1 → 3.0.2

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.
Files changed (139) hide show
  1. package/dist/BackgroundColor-JObp_2xA.js +14 -0
  2. package/dist/BorderColor-BummoQ1-.js +24 -0
  3. package/dist/BorderRadius-ClUShVLu.js +10 -0
  4. package/dist/BorderWidth-DfOlyKK7.js +16 -0
  5. package/dist/CornerStyle-JEbGNArR.js +6 -0
  6. package/dist/FontWeight-CR22KTex.js +8 -0
  7. package/dist/HeadingSize-CfCRn3Lh.js +12 -0
  8. package/dist/IconColor-CtC9WUgr.js +10 -0
  9. package/dist/ObjectColor-BZDBuV8H.js +22 -0
  10. package/dist/Opacity-smkGiwsf.js +6 -0
  11. package/dist/SizeTypes-Ck_RdzIf.js +8 -0
  12. package/dist/Spacing-D0HQH9YJ.js +16 -0
  13. package/dist/TextBodySize-BcZR9mh2.js +6 -0
  14. package/dist/TextColor-BXiR5Uq9.js +16 -0
  15. package/dist/colorUtils-uLZF5UIN.js +94 -0
  16. package/dist/components/Accordion/index.js +195 -0
  17. package/dist/components/AccordionGroup/index.js +59 -0
  18. package/dist/components/Badge/index.js +11 -0
  19. package/dist/components/Body/index.js +72 -6
  20. package/dist/components/BottomBar/index.js +79 -0
  21. package/dist/components/Button/index.js +24 -0
  22. package/dist/components/ButtonAsLink/index.js +7 -0
  23. package/dist/components/ButtonGroup/index.js +34 -0
  24. package/dist/components/Card/index.js +18 -0
  25. package/dist/components/Carousel/index.js +497 -0
  26. package/dist/components/Checkbox/index.js +218 -0
  27. package/dist/components/CheckboxGroup/index.js +58 -0
  28. package/dist/components/Collapsible/index.js +85 -0
  29. package/dist/components/ColorSwatch/index.js +87 -0
  30. package/dist/components/ColorSwatchGroup/index.js +43 -0
  31. package/dist/components/Container/index.js +76 -0
  32. package/dist/components/DateInput/index.js +86 -0
  33. package/dist/components/DemoBox/index.js +21 -0
  34. package/dist/components/Dialog/index.js +172 -0
  35. package/dist/components/DiscoveryCard/index.js +130 -0
  36. package/dist/components/DiscoveryCardGroup/index.js +53 -0
  37. package/dist/components/Divider/index.js +30 -0
  38. package/dist/components/Fieldset/index.js +41 -0
  39. package/dist/components/FilterGroup/index.js +148 -0
  40. package/dist/components/Flex/index.js +17 -0
  41. package/dist/components/FlexItem/index.js +41 -0
  42. package/dist/components/FootnoteContent/index.js +39 -0
  43. package/dist/components/FootnoteLink/index.js +46 -0
  44. package/dist/components/Form/index.js +20 -0
  45. package/dist/components/FormElement/index.js +31 -0
  46. package/dist/components/FormHelperLabel/index.js +21 -0
  47. package/dist/components/FormHelperMessage/index.js +47 -0
  48. package/dist/components/FormHelperStatusIcon/index.js +50 -0
  49. package/dist/components/GoogleMap/index.js +196 -0
  50. package/dist/components/Grid/index.js +39 -0
  51. package/dist/components/GridItem/index.js +12 -0
  52. package/dist/components/Heading/index.js +94 -0
  53. package/dist/components/HifiIcon/index.js +31 -0
  54. package/dist/components/Icon/index.js +38 -0
  55. package/dist/components/IconButton/index.js +85 -0
  56. package/dist/components/IconSnippet/index.js +112 -0
  57. package/dist/components/IconSnippet/styled.d.ts +1 -1
  58. package/dist/components/IconSnippetList/index.js +25 -0
  59. package/dist/components/Image/index.js +84 -0
  60. package/dist/components/ImageHeader/index.js +262 -0
  61. package/dist/components/ImageHeader/styled.d.ts +4 -4
  62. package/dist/components/InlineLink/index.js +43 -0
  63. package/dist/components/Input/index.js +55 -0
  64. package/dist/components/Label/index.js +22 -0
  65. package/dist/components/Legend/index.js +60 -0
  66. package/dist/components/Link/index.js +19 -0
  67. package/dist/components/LinkAsButton/index.js +7 -0
  68. package/dist/components/LinkList/index.js +64 -0
  69. package/dist/components/LinkListItem/index.js +316 -0
  70. package/dist/components/LoadingSpinner/index.js +70 -0
  71. package/dist/components/Notification/index.js +181 -0
  72. package/dist/components/Overlay/index.js +33 -0
  73. package/dist/components/PickerGroup/index.js +282 -0
  74. package/dist/components/Price/index.js +18 -0
  75. package/dist/components/ProductCard/index.js +81 -0
  76. package/dist/components/RadioGroup/index.js +197 -0
  77. package/dist/components/ResponsiveImage/index.js +89 -0
  78. package/dist/components/RichText/index.js +7 -0
  79. package/dist/components/ScreenreaderOnly/index.js +6 -0
  80. package/dist/components/SearchInput/index.js +140 -0
  81. package/dist/components/SelectInput/index.js +160 -0
  82. package/dist/components/Stepper/index.js +205 -0
  83. package/dist/components/SuggestInput/index.js +387 -0
  84. package/dist/components/Switch/index.js +169 -0
  85. package/dist/components/TabularPrice/index.js +8 -0
  86. package/dist/components/TextList/index.js +10 -0
  87. package/dist/components/Textarea/index.js +156 -0
  88. package/dist/components/Tray/index.js +218 -0
  89. package/dist/easing-Dm-pO8SY.js +6 -0
  90. package/dist/filterProps-Cewck8OH.js +13 -0
  91. package/dist/foundations/GlobalStyle/index.js +3 -292
  92. package/dist/foundations/PatternProps/index.js +1 -0
  93. package/dist/foundations/media-query/forcedColors/index.js +12 -0
  94. package/dist/foundations/media-query/reducedMotion/index.js +21 -0
  95. package/dist/foundations/media-query/viewport/index.js +6 -0
  96. package/dist/foundations/token/getBackgroundColor/index.js +5 -0
  97. package/dist/foundations/token/getBodySize/index.js +13 -2
  98. package/dist/foundations/token/getBorderColor/index.js +5 -0
  99. package/dist/foundations/token/getBorderRadius/index.js +15 -0
  100. package/dist/foundations/token/getBorderWidth/index.js +19 -0
  101. package/dist/foundations/token/getBottomSpacing/index.js +14 -0
  102. package/dist/foundations/token/getFontWeight/index.js +13 -0
  103. package/dist/foundations/token/getHeadingSize/index.js +27 -0
  104. package/dist/foundations/token/getHoverColor/index.js +7 -0
  105. package/dist/foundations/token/getIconColor/index.js +5 -0
  106. package/dist/foundations/token/getObjectColor/index.js +5 -0
  107. package/dist/foundations/token/getOpacity/index.js +11 -0
  108. package/dist/foundations/token/getPressColor/index.js +7 -0
  109. package/dist/foundations/token/getSpacing/index.js +5 -0
  110. package/dist/foundations/token/getTextColor/index.js +5 -0
  111. package/dist/foundations/token/getTextDecoration/index.js +13 -0
  112. package/dist/getCssVar-BP6T9pFM.js +6 -0
  113. package/dist/hooks/useFocusWithin/index.js +36 -0
  114. package/dist/hooks/useForcedColors/index.js +9 -0
  115. package/dist/hooks/useMediaQuery/index.js +19 -0
  116. package/dist/hooks/useReducedMotion/index.js +9 -0
  117. package/dist/hooks/useThirdPartyConsent/index.js +54 -0
  118. package/dist/hooks/useViewport/index.js +24 -0
  119. package/dist/index-BXLT6ke-.js +79 -0
  120. package/dist/index-C4XnzWFL.js +61 -0
  121. package/dist/index-CeJsIf3Z.js +208 -0
  122. package/dist/index-Ck2bCrhT.js +32 -0
  123. package/dist/index-CzTqNQTT.js +79 -0
  124. package/dist/index-D6hvbziL.js +167 -0
  125. package/dist/index-DQhtQZ85.js +24 -0
  126. package/dist/props-Czq9XX2J.js +6 -0
  127. package/dist/{index-BaPlSfS3.js → renderInlineRichTextFromOpenText-CA52y1-B.js} +3 -105
  128. package/dist/shadow-u158mzuN.js +4 -0
  129. package/dist/styled-BpvuD699.js +45 -0
  130. package/dist/styled-CDWclYAa.js +124 -0
  131. package/dist/styled-CXSdomF5.js +34 -0
  132. package/dist/styled-CpoX5USb.js +71 -0
  133. package/dist/styled-DZo6MwrF.js +245 -0
  134. package/dist/styled-FNJyDkPV.js +165 -0
  135. package/dist/styled-Wlt68LfQ.js +133 -0
  136. package/dist/styled-ZpQohvyx.js +29 -0
  137. package/dist/tags-DI6H1biK.js +29 -0
  138. package/package.json +2 -1
  139. package/dist/index-BoPDwZgt.js +0 -18
@@ -0,0 +1,205 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useState, useRef, useEffect } from "react";
4
+ import { useViewport } from "../../hooks/useViewport/index.js";
5
+ import { r as renderInlineRichTextFromOpenText } from "../../renderInlineRichTextFromOpenText-CA52y1-B.js";
6
+ import styled from "styled-components";
7
+ import forcedColors from "../../foundations/media-query/forcedColors/index.js";
8
+ import { v as viewport, b as breakpoint_medium_number } from "../../index-Ck2bCrhT.js";
9
+ import { getBodySize } from "../../foundations/token/getBodySize/index.js";
10
+ import { getBorderColor } from "../../foundations/token/getBorderColor/index.js";
11
+ import { getBottomSpacing } from "../../foundations/token/getBottomSpacing/index.js";
12
+ import { getFontWeight } from "../../foundations/token/getFontWeight/index.js";
13
+ import { getObjectColor } from "../../foundations/token/getObjectColor/index.js";
14
+ import { g as colorBorderBrand, a as colorBorderNeutral, h as colorBorderInverse } from "../../BorderColor-BummoQ1-.js";
15
+ import { f as fontWeightBold } from "../../FontWeight-CR22KTex.js";
16
+ import { c as colorObjectBrand, a as colorObjectInverse } from "../../ObjectColor-BZDBuV8H.js";
17
+ import { s as spacingMd } from "../../Spacing-D0HQH9YJ.js";
18
+ import { t as textBodyMd } from "../../TextBodySize-BcZR9mh2.js";
19
+ import { f as filterProps } from "../../filterProps-Cewck8OH.js";
20
+ const StepperItemStyled = styled.li.withConfig({
21
+ shouldForwardProp: filterProps(),
22
+ displayName: "StepperItemStyled",
23
+ componentId: "sc-6fjel6-0"
24
+ })(({
25
+ isActive = false
26
+ }) => {
27
+ return {
28
+ fontWeight: isActive ? getFontWeight(fontWeightBold) : void 0,
29
+ position: "relative",
30
+ flex: 1,
31
+ textAlign: "center",
32
+ textIndent: isActive ? "0px" : "-9999px",
33
+ ...viewport.md({
34
+ textIndent: "0px"
35
+ })
36
+ };
37
+ }, ({
38
+ next
39
+ }) => ({
40
+ // using :before to create the track between the dots
41
+ "&::before": {
42
+ ...forcedColors({
43
+ background: "CanvasText"
44
+ }),
45
+ position: "absolute",
46
+ display: "block",
47
+ background: getBorderColor(next ? colorBorderBrand : colorBorderNeutral),
48
+ content: "''",
49
+ width: "100%",
50
+ height: next ? "2px" : "1px",
51
+ top: "-17px",
52
+ ...viewport.md({
53
+ top: "-20px"
54
+ }),
55
+ left: "-50%",
56
+ //move track behind dots
57
+ zIndex: 1
58
+ },
59
+ /* hide the first one, because there is always one less gap in the fence than slats */
60
+ "&:first-child::before": {
61
+ display: "none"
62
+ }
63
+ }), ({
64
+ isActive,
65
+ next
66
+ }) => {
67
+ const boxShadow = {};
68
+ if (isActive) {
69
+ boxShadow.boxShadow = `0px 0px 0px 2px ${getBorderColor(colorBorderInverse)}, 0px 0px 0px 4px ${getBorderColor(colorBorderBrand)}`;
70
+ }
71
+ return {
72
+ // using :after to create the dots on the track
73
+ "&::after": {
74
+ ...forcedColors({
75
+ background: next ? "CanvasText" : "Canvas",
76
+ borderWidth: isActive ? "2px" : "1px",
77
+ borderColor: isActive ? "Canvas" : getBorderColor(next ? colorBorderBrand : colorBorderNeutral),
78
+ outline: isActive ? "2px solid CanvasText" : "none"
79
+ }),
80
+ position: "absolute",
81
+ display: "block",
82
+ background: getObjectColor(next ? colorObjectBrand : colorObjectInverse),
83
+ content: "''",
84
+ width: "14px",
85
+ height: "14px",
86
+ ...viewport.md({
87
+ width: "18px",
88
+ height: "18px"
89
+ }),
90
+ borderRadius: "20px",
91
+ borderWidth: "1px",
92
+ borderStyle: "solid",
93
+ borderColor: getBorderColor(next ? colorBorderBrand : colorBorderNeutral),
94
+ top: "-24px",
95
+ ...viewport.md({
96
+ top: "-28px"
97
+ }),
98
+ left: "0",
99
+ right: 0,
100
+ margin: "auto",
101
+ ...boxShadow,
102
+ //move dots before track
103
+ zIndex: 2
104
+ }
105
+ };
106
+ });
107
+ const mobileOnly = (stylesInViewport) => {
108
+ return {
109
+ [`@media screen and (max-width: ${breakpoint_medium_number - 1}px)`]: {
110
+ ...stylesInViewport
111
+ }
112
+ };
113
+ };
114
+ const StepperActiveItemStyled = styled.strong.withConfig({
115
+ shouldForwardProp: filterProps(),
116
+ displayName: "StepperActiveItemStyled",
117
+ componentId: "sc-6fjel6-1"
118
+ })(({
119
+ offset = 0
120
+ }) => mobileOnly({
121
+ position: "absolute",
122
+ width: "max-content",
123
+ left: `50%`,
124
+ transform: "translateX(-50%)",
125
+ textAlign: "center",
126
+ zIndex: 3,
127
+ marginLeft: offset ? `${offset}px` : void 0
128
+ }));
129
+ const StepperStyled = styled.ol.withConfig({
130
+ shouldForwardProp: filterProps(),
131
+ displayName: "StepperStyled",
132
+ componentId: "sc-6fjel6-2"
133
+ })({
134
+ flexGrow: 1,
135
+ display: "flex",
136
+ paddingTop: "28px",
137
+ ...viewport.md({
138
+ paddingTop: "32px"
139
+ }),
140
+ ...getBodySize(textBodyMd)
141
+ }, mobileOnly({
142
+ position: "relative"
143
+ }), ({
144
+ bottomSpacing = spacingMd
145
+ }) => getBottomSpacing({
146
+ bottomSpacing
147
+ }));
148
+ const getAriaLabel = ({
149
+ activeStep = 1,
150
+ steps,
151
+ ariaLabelTemplate
152
+ }) => {
153
+ return ariaLabelTemplate.replace("%current%", activeStep.toString()).replace("%total%", steps.length.toString());
154
+ };
155
+ const Stepper = ({
156
+ activeStep = 1,
157
+ steps,
158
+ ariaLabelTemplate,
159
+ ...props
160
+ }) => {
161
+ activeStep = Math.min(Math.max(activeStep, 1), steps.length);
162
+ const [offset, setOffset] = useState(0);
163
+ const stepperRef = useRef(null);
164
+ const viewport2 = useViewport();
165
+ const check = () => {
166
+ if (null === stepperRef.current || "sm" !== viewport2) {
167
+ return;
168
+ }
169
+ const listItemWidth = stepperRef.current.getElementsByTagName("li")[0].offsetWidth;
170
+ const activeWidth = stepperRef.current.getElementsByTagName("strong")[0].offsetWidth;
171
+ if (listItemWidth >= activeWidth) {
172
+ setOffset(0);
173
+ return;
174
+ }
175
+ const neededSpace = activeWidth / 2;
176
+ const availableSpaceRight = listItemWidth * (activeStep - 0.5);
177
+ const wholeSpace = listItemWidth * steps.length;
178
+ if (neededSpace + availableSpaceRight > wholeSpace) {
179
+ setOffset(wholeSpace - availableSpaceRight - neededSpace);
180
+ return;
181
+ }
182
+ const availableSpaceLeft = (activeStep - 0.5) * listItemWidth;
183
+ if (availableSpaceLeft > neededSpace) {
184
+ setOffset(0);
185
+ return;
186
+ }
187
+ setOffset(neededSpace - availableSpaceLeft);
188
+ };
189
+ useEffect(() => {
190
+ if (!stepperRef.current) {
191
+ return;
192
+ }
193
+ const resizeObserver = new ResizeObserver(check);
194
+ resizeObserver.observe(stepperRef.current.getElementsByTagName("strong")[0]);
195
+ return () => resizeObserver.disconnect();
196
+ }, [activeStep]);
197
+ return /* @__PURE__ */ jsx("div", { role: "region", "aria-label": getAriaLabel({
198
+ activeStep,
199
+ steps,
200
+ ariaLabelTemplate
201
+ }), children: /* @__PURE__ */ jsx(StepperStyled, { ref: stepperRef, ...props, children: steps.map((step, index) => /* @__PURE__ */ jsx(StepperItemStyled, { isActive: index + 1 === activeStep, next: index < activeStep, children: index + 1 === activeStep ? /* @__PURE__ */ jsx(StepperActiveItemStyled, { offset, "aria-current": "step", children: renderInlineRichTextFromOpenText(step) }) : renderInlineRichTextFromOpenText(step) }, `${step}`)) }) });
202
+ };
203
+ export {
204
+ Stepper as default
205
+ };
@@ -0,0 +1,387 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { IconLoader, iconSizeSm } from "@vfde-react/inline-icon-library";
4
+ import { useState, useEffect, forwardRef, useRef, useImperativeHandle } from "react";
5
+ import FlexItem from "../FlexItem/index.js";
6
+ import FormHelperLabel from "../FormHelperLabel/index.js";
7
+ import FormHelperMessage from "../FormHelperMessage/index.js";
8
+ import FormHelperStatusIcon from "../FormHelperStatusIcon/index.js";
9
+ import { i as inputStateError } from "../../props-Czq9XX2J.js";
10
+ import { I as InputWrapperStyled, a as InputStyled } from "../../styled-CDWclYAa.js";
11
+ import { c as spacingSm, a as spacingXs, s as spacingMd } from "../../Spacing-D0HQH9YJ.js";
12
+ import { r as renderInlineRichTextFromOpenText } from "../../renderInlineRichTextFromOpenText-CA52y1-B.js";
13
+ import Body from "../Body/index.js";
14
+ import { g as strongTagName } from "../../tags-DI6H1biK.js";
15
+ import styled from "styled-components";
16
+ import Card from "../Card/index.js";
17
+ import forcedColors from "../../foundations/media-query/forcedColors/index.js";
18
+ import { getBodySize } from "../../foundations/token/getBodySize/index.js";
19
+ import { getBorderColor } from "../../foundations/token/getBorderColor/index.js";
20
+ import { getHoverColor } from "../../foundations/token/getHoverColor/index.js";
21
+ import { getSpacing } from "../../foundations/token/getSpacing/index.js";
22
+ import { c as colorBackgroundNeutral } from "../../BackgroundColor-JObp_2xA.js";
23
+ import { c as colorBorderFocus } from "../../BorderColor-BummoQ1-.js";
24
+ import { t as textBodyMd } from "../../TextBodySize-BcZR9mh2.js";
25
+ import Flex from "../Flex/index.js";
26
+ import LoadingSpinner from "../LoadingSpinner/index.js";
27
+ import { getBottomSpacing } from "../../foundations/token/getBottomSpacing/index.js";
28
+ import { getOpacity } from "../../foundations/token/getOpacity/index.js";
29
+ import { getTextColor } from "../../foundations/token/getTextColor/index.js";
30
+ import { a as opacityDisabled } from "../../Opacity-smkGiwsf.js";
31
+ import { a as colorTextNeutral } from "../../TextColor-BXiR5Uq9.js";
32
+ import { f as filterProps } from "../../filterProps-Cewck8OH.js";
33
+ const calculateListMaxHeight = (numberOfVisibleItems) => {
34
+ return `calc((${getSpacing(spacingSm)} * 2 + ${getBodySize(textBodyMd).fontSize} * ${getBodySize(textBodyMd).lineHeight}) * ${numberOfVisibleItems})`;
35
+ };
36
+ const SuggestInputListWrapperStyled = styled(Card).withConfig({
37
+ displayName: "SuggestInputListWrapperStyled",
38
+ componentId: "sc-5e6nao-0"
39
+ })({
40
+ ...forcedColors({
41
+ background: "Field",
42
+ color: "fieldtext",
43
+ border: "none"
44
+ }),
45
+ position: "absolute",
46
+ maxHeight: 0,
47
+ overflow: "hidden",
48
+ transition: "max-height .2s cubic-bezier(0.445, 0.05, 0.55, 0.95)",
49
+ zIndex: 1,
50
+ "&&": {
51
+ padding: 0,
52
+ height: "fit-content"
53
+ }
54
+ }, ({
55
+ showList
56
+ }) => {
57
+ if (showList) {
58
+ return {
59
+ maxHeight: calculateListMaxHeight(5)
60
+ };
61
+ }
62
+ });
63
+ const SuggestInputListStyled = styled.ul.withConfig({
64
+ displayName: "SuggestInputListStyled",
65
+ componentId: "sc-5e6nao-1"
66
+ })({
67
+ display: "flex",
68
+ flexDirection: "column",
69
+ overflowY: "auto",
70
+ maxHeight: calculateListMaxHeight(5)
71
+ });
72
+ const SuggestInputListItemStyled = styled.li.withConfig({
73
+ displayName: "SuggestInputListItemStyled",
74
+ componentId: "sc-5e6nao-2"
75
+ })({
76
+ padding: `${getSpacing(spacingSm)}`,
77
+ "&:hover": {
78
+ ...forcedColors({
79
+ background: "Field"
80
+ }),
81
+ background: getHoverColor(colorBackgroundNeutral),
82
+ cursor: "pointer"
83
+ },
84
+ "&:focus-visible": {
85
+ outline: "none"
86
+ }
87
+ }, ({
88
+ isSelected
89
+ }) => {
90
+ if (isSelected) {
91
+ return {
92
+ ...forcedColors({
93
+ background: "SelectedItem",
94
+ color: "SelectedItemText"
95
+ }),
96
+ boxShadow: `inset 0px 0px 0px 4px ${getBorderColor(colorBorderFocus)} `,
97
+ background: getHoverColor(colorBackgroundNeutral),
98
+ outline: "none"
99
+ };
100
+ }
101
+ }, getBodySize(textBodyMd));
102
+ const highlightQuery = (label, query) => {
103
+ const lowerLabel = label.toLowerCase();
104
+ const lowerQuery = query.toLowerCase();
105
+ const index = lowerLabel.indexOf(lowerQuery);
106
+ if (query.length > 0 && index !== -1) {
107
+ const beforeQuery = label.slice(0, index);
108
+ const afterQuery = label.slice(index + lowerQuery.length);
109
+ const boldQuery = /* @__PURE__ */ jsx(Body, { tag: strongTagName, children: label.slice(index, index + lowerQuery.length) });
110
+ return [beforeQuery, boldQuery, afterQuery];
111
+ }
112
+ return label;
113
+ };
114
+ const SuggestInputList = ({
115
+ listItems,
116
+ showList,
117
+ filterItems,
118
+ sortItems,
119
+ selectedOption,
120
+ listItemsRef,
121
+ pickOption,
122
+ uid,
123
+ query
124
+ }) => {
125
+ const [options, setOptions] = useState(listItems);
126
+ useEffect(() => {
127
+ setOptions(listItems);
128
+ }, [listItems]);
129
+ return /* @__PURE__ */ jsx(SuggestInputListWrapperStyled, { showList, children: /* @__PURE__ */ jsx(SuggestInputListStyled, { role: "listbox", id: "listbox", children: options == null ? void 0 : options.filter((listItem) => filterItems(listItem.label)).sort((a, b) => {
130
+ return sortItems(query, a.label, b.label);
131
+ }).map((listItem, index) => {
132
+ const isSelected = index === selectedOption;
133
+ return /* @__PURE__ */ jsx(SuggestInputListItemStyled, { ref: (el) => {
134
+ listItemsRef.current[index] = el;
135
+ }, onMouseDown: () => pickOption(listItem.label), "aria-selected": isSelected ? "true" : void 0, isSelected, role: "option", id: `${uid}-item-${index}`, children: highlightQuery(listItem.label, query) }, listItem.label);
136
+ }) }) });
137
+ };
138
+ const SuggestInputFormElementStyled = styled.div.withConfig({
139
+ shouldForwardProp: filterProps(),
140
+ displayName: "SuggestInputFormElementStyled",
141
+ componentId: "sc-tvkime-0"
142
+ })({
143
+ position: "relative"
144
+ }, getBodySize("md"), ({
145
+ disabled
146
+ }) => {
147
+ if (disabled) {
148
+ return {
149
+ pointerEvents: "none",
150
+ opacity: getOpacity(opacityDisabled)
151
+ };
152
+ }
153
+ return {};
154
+ }, getBottomSpacing);
155
+ const SuggestInputWrapperStyled = styled(InputWrapperStyled).withConfig({
156
+ shouldForwardProp: filterProps(),
157
+ displayName: "SuggestInputWrapperStyled",
158
+ componentId: "sc-tvkime-1"
159
+ })({
160
+ position: "relative",
161
+ ":focus, :focus-visible": {
162
+ outline: "none"
163
+ },
164
+ marginBottom: getSpacing(spacingXs)
165
+ });
166
+ const SuggestInputIconsBarStyled = styled(Flex).withConfig({
167
+ displayName: "SuggestInputIconsBarStyled",
168
+ componentId: "sc-tvkime-2"
169
+ })({
170
+ gap: `${getSpacing(spacingXs)}`,
171
+ flexWrap: "nowrap",
172
+ height: "auto"
173
+ });
174
+ const SuggestInputIconButtonStyled = styled.button.withConfig({
175
+ displayName: "SuggestInputIconButtonStyled",
176
+ componentId: "sc-tvkime-3"
177
+ })({
178
+ background: "none",
179
+ color: getTextColor(colorTextNeutral),
180
+ flexGrow: 1,
181
+ "&:focus-visible": {
182
+ boxShadow: `${getBorderColor(colorBorderFocus)} 0px 0px 0px 4px`
183
+ }
184
+ }, ({
185
+ disabled
186
+ }) => {
187
+ if (!disabled) {
188
+ return {
189
+ "&:hover": {
190
+ cursor: "pointer"
191
+ }
192
+ };
193
+ }
194
+ });
195
+ const SuggestInputLoadingSpinner = styled(LoadingSpinner).withConfig({
196
+ displayName: "SuggestInputLoadingSpinner",
197
+ componentId: "sc-tvkime-4"
198
+ })({
199
+ ...forcedColors({
200
+ stroke: "FieldText"
201
+ })
202
+ });
203
+ const SuggestInputFormElement = forwardRef(({
204
+ children,
205
+ ...props
206
+ }, ref) => {
207
+ return /* @__PURE__ */ jsx(SuggestInputFormElementStyled, { ...props, ref, children });
208
+ });
209
+ const SuggestInput = forwardRef(({
210
+ bottomSpacing = spacingMd,
211
+ isLoading = false,
212
+ label,
213
+ listItems,
214
+ errorMessage,
215
+ helperText,
216
+ onClose,
217
+ onPick,
218
+ onUpdate,
219
+ status,
220
+ uid,
221
+ disabled,
222
+ placeholder,
223
+ ...props
224
+ }, outerRef) => {
225
+ const initialValueState = !props.value ? "" : props.value;
226
+ const [buttonIcon, setButtonIcon] = useState("ChevronDown");
227
+ const [selectedOption, setSelectedOption] = useState(-1);
228
+ const [showList, setShowList] = useState(false);
229
+ const [confirmedValue, setConfirmedValue] = useState(initialValueState);
230
+ const [value, setValue] = useState(initialValueState);
231
+ const messageId = `text-${uid}`;
232
+ const inputProps = {
233
+ ...props,
234
+ type: "text",
235
+ id: uid,
236
+ "aria-describedby": inputStateError !== status && helperText || inputStateError === status && errorMessage ? messageId : void 0,
237
+ "aria-invalid": inputStateError === status ? true : void 0
238
+ };
239
+ const inputRef = useRef(null);
240
+ useImperativeHandle(outerRef, () => inputRef.current, []);
241
+ const formElementRef = useRef(null);
242
+ const listItemsRef = useRef([]);
243
+ useEffect(() => {
244
+ showList ? setButtonIcon("Close") : setButtonIcon("ChevronDown");
245
+ if (!showList) {
246
+ setSelectedOption(-1);
247
+ }
248
+ }, [showList]);
249
+ useEffect(() => {
250
+ if (!props.value) {
251
+ return;
252
+ }
253
+ setValue(props.value);
254
+ setConfirmedValue(props.value);
255
+ }, [props.value]);
256
+ useEffect(() => {
257
+ var _a;
258
+ document.addEventListener("click", onClick);
259
+ (_a = formElementRef.current) == null ? void 0 : _a.addEventListener("keydown", onKeyDown);
260
+ return () => {
261
+ var _a2;
262
+ document.removeEventListener("click", onClick);
263
+ (_a2 = formElementRef.current) == null ? void 0 : _a2.removeEventListener("keydown", onKeyDown);
264
+ };
265
+ });
266
+ const closeList = () => {
267
+ setValue(confirmedValue);
268
+ setShowList(false);
269
+ onClose && onClose();
270
+ };
271
+ const filterItems = (option) => {
272
+ if (props.filterItems) {
273
+ return props.filterItems(value, option);
274
+ }
275
+ const queryString = value.trim().toLowerCase();
276
+ const optionString = option.trim().toLowerCase();
277
+ return optionString.includes(queryString);
278
+ };
279
+ const sortItems = (value2, a, b) => {
280
+ if (props.sortItems) {
281
+ return props.sortItems(value2, a, b);
282
+ }
283
+ if (a === b) {
284
+ return 0;
285
+ }
286
+ if (a > b) {
287
+ return 1;
288
+ }
289
+ return -1;
290
+ };
291
+ const handleChange = (userInput) => {
292
+ if (!showList && !isLoading) setShowList(true);
293
+ setValue(userInput);
294
+ setSelectedOption(-1);
295
+ if (userInput === "") setConfirmedValue("");
296
+ onUpdate && onUpdate(userInput);
297
+ };
298
+ const pickOption = (value2) => {
299
+ var _a;
300
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
301
+ setShowList(false);
302
+ setValue(value2);
303
+ setConfirmedValue(value2);
304
+ onPick && onPick(value2);
305
+ onClose && onClose();
306
+ };
307
+ const onClick = (event) => {
308
+ if (formElementRef.current && !formElementRef.current.contains(event.target)) {
309
+ formElementRef.current.blur();
310
+ closeList();
311
+ }
312
+ };
313
+ const moveToOption = (option) => {
314
+ option.focus();
315
+ option.scrollIntoView({
316
+ block: "nearest",
317
+ inline: "nearest"
318
+ });
319
+ };
320
+ const onKeyDown = (event) => {
321
+ var _a;
322
+ switch (event.key) {
323
+ case "ArrowDown":
324
+ if (!showList) setShowList(true);
325
+ if (listItems && listItems.length > 0 && listItemsRef.current[selectedOption + 1]) {
326
+ moveToOption(listItemsRef.current[selectedOption + 1]);
327
+ setSelectedOption(selectedOption + 1);
328
+ } else {
329
+ moveToOption(listItemsRef.current[0]);
330
+ setSelectedOption(0);
331
+ }
332
+ break;
333
+ case "ArrowUp":
334
+ if (!showList) setShowList(true);
335
+ if (listItems && listItems.length > 0 && listItemsRef.current[selectedOption - 1]) {
336
+ moveToOption(listItemsRef.current[selectedOption - 1]);
337
+ setSelectedOption(selectedOption - 1);
338
+ } else if (listItems == null ? void 0 : listItems.length) {
339
+ moveToOption(listItemsRef.current[(listItems == null ? void 0 : listItems.length) - 1]);
340
+ setSelectedOption((listItems == null ? void 0 : listItems.length) - 1);
341
+ }
342
+ break;
343
+ case "Enter":
344
+ if (showList) {
345
+ pickOption(listItemsRef.current[selectedOption].innerText);
346
+ (_a = inputRef.current) == null ? void 0 : _a.setSelectionRange(value.length, value.length);
347
+ }
348
+ break;
349
+ case "Escape":
350
+ if (showList) {
351
+ closeList();
352
+ }
353
+ break;
354
+ }
355
+ };
356
+ return /* @__PURE__ */ jsxs(SuggestInputFormElement, { tabIndex: 0, ref: formElementRef, bottomSpacing, disabled, children: [
357
+ /* @__PURE__ */ jsx(FormHelperLabel, { label, uid }),
358
+ /* @__PURE__ */ jsxs(SuggestInputWrapperStyled, { status, bottomSpacing: inputStateError !== status && helperText || inputStateError === status && errorMessage ? spacingXs : void 0, children: [
359
+ /* @__PURE__ */ jsx(InputStyled, { ...inputProps, ref: inputRef, onChange: (e) => handleChange(e.target.value), onClick: () => {
360
+ if (disabled) return;
361
+ setShowList(true);
362
+ }, role: "combobox", value, ...{
363
+ "aria-expanded": showList,
364
+ "aria-controls": "listbox",
365
+ "aria-activedescendant": selectedOption > -1 ? `${uid}-item-${selectedOption}` : void 0,
366
+ "aria-live": isLoading !== void 0 ? "polite" : void 0,
367
+ "aria-busy": isLoading ? isLoading : void 0,
368
+ "aria-autocomplete": "list"
369
+ }, disabled, placeholder: renderInlineRichTextFromOpenText(placeholder) }),
370
+ /* @__PURE__ */ jsxs(SuggestInputIconsBarStyled, { children: [
371
+ /* @__PURE__ */ jsx(FlexItem, { grow: "full", children: /* @__PURE__ */ jsx(SuggestInputLoadingSpinner, { size: "xs", isActive: isLoading }) }),
372
+ status && /* @__PURE__ */ jsx(FlexItem, { grow: "full", children: /* @__PURE__ */ jsx(FormHelperStatusIcon, { status }) }),
373
+ listItems && listItems.length > 0 && /* @__PURE__ */ jsx(SuggestInputIconButtonStyled, { type: "button", onClick: () => {
374
+ if (disabled) return;
375
+ showList ? closeList() : setShowList(true);
376
+ }, tabIndex: -1, disabled, children: /* @__PURE__ */ jsx(IconLoader, { size: iconSizeSm, name: buttonIcon }) })
377
+ ] })
378
+ ] }),
379
+ /* @__PURE__ */ jsx(SuggestInputList, { listItems, listItemsRef, filterItems, sortItems, pickOption, query: value, showList, selectedOption, uid, ...{
380
+ "aria-label": label
381
+ } }),
382
+ /* @__PURE__ */ jsx(FormHelperMessage, { id: messageId, status, message: inputStateError === status ? errorMessage : helperText })
383
+ ] });
384
+ });
385
+ export {
386
+ SuggestInput as default
387
+ };