@stokr/components-library 3.0.17 → 3.0.18

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.
@@ -1,4 +1,4 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { Text } from "../Text/Text.styles.js";
3
3
  import { createRoot } from "react-dom/client";
4
4
  import { Button } from "../Button/Button.styles.js";
@@ -28,8 +28,9 @@ const ConfirmModalComponent = ({
28
28
  buttonProps,
29
29
  cancelButtonProps,
30
30
  barStyle,
31
- style,
32
- maxWidth
31
+ maxWidth,
32
+ modalStyles,
33
+ innerModalStyles
33
34
  }) => {
34
35
  const [titleHeight, setTitleHeight] = useState(0);
35
36
  const observerRef = useRef(null);
@@ -72,11 +73,11 @@ const ConfirmModalComponent = ({
72
73
  isOpen,
73
74
  onClose: handleCancel,
74
75
  maxHeight: "90vh",
75
- boxStyles: { minHeight: "unset", ...style || {} },
76
+ boxStyles: { minHeight: "unset", ...modalStyles || {} },
76
77
  maxWidth,
77
78
  ...modalProps,
78
79
  children: [
79
- /* @__PURE__ */ jsx(ModalInner, { children: /* @__PURE__ */ jsxs(ContainerWithLine, { height: titleHeight, lineColor, children: [
80
+ /* @__PURE__ */ jsx(ModalInner, { style: innerModalStyles, children: /* @__PURE__ */ jsxs(ContainerWithLine, { height: titleHeight, lineColor, children: [
80
81
  /* @__PURE__ */ jsxs(Text, { children: [
81
82
  /* @__PURE__ */ jsxs("div", { children: [
82
83
  title && /* @__PURE__ */ jsx("h3", { ref: titleRef, style: { margin: 0 }, children: title }),
@@ -84,6 +85,15 @@ const ConfirmModalComponent = ({
84
85
  ] }),
85
86
  content && /* @__PURE__ */ jsx("div", { style: { marginTop: "16px" }, children: content })
86
87
  ] }),
88
+ renderFooter ? /* @__PURE__ */ jsx(Fragment, { children: renderFooter({
89
+ onConfirm: handleConfirm,
90
+ onCancel: handleCancel
91
+ }) }) : /* @__PURE__ */ jsxs(ComponentWrapper, { noPaddingHorizontal: true, flex: true, style: { gap: 16 }, children: [
92
+ showCancel && /* @__PURE__ */ jsx(Button, { outlineBlack: true, minWidth: "120px", onClick: handleCancel, ...cancelButtonProps, children: cancelText }),
93
+ /* @__PURE__ */ jsx(Button, { minWidth: "120px", onClick: () => handleConfirm(true), ...buttonProps, children: confirmText })
94
+ ] }),
95
+ message && /* @__PURE__ */ jsx("p", { children: message }),
96
+ content && /* @__PURE__ */ jsx("div", { style: { marginTop: "16px" }, children: content }),
87
97
  renderFooter ? /* @__PURE__ */ jsx(ComponentWrapper, { children: renderFooter({
88
98
  onConfirm: handleConfirm,
89
99
  onCancel: handleCancel
@@ -112,7 +122,8 @@ const confirm = (options = {}) => {
112
122
  modalProps = {},
113
123
  buttonProps = {},
114
124
  cancelButtonProps = {},
115
- style
125
+ modalStyles,
126
+ innerModalStyles
116
127
  } = options;
117
128
  return new Promise((resolve) => {
118
129
  if (!confirmContainer) {
@@ -173,7 +184,8 @@ const confirm = (options = {}) => {
173
184
  modalProps,
174
185
  buttonProps,
175
186
  cancelButtonProps,
176
- style
187
+ modalStyles,
188
+ innerModalStyles
177
189
  }
178
190
  )
179
191
  );
@@ -0,0 +1,93 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import "react";
3
+ import styled from "styled-components";
4
+ import { colors } from "../../styles/colors.js";
5
+ const VARIANTS = {
6
+ warning: {
7
+ background: "#FFFBEB",
8
+ border: colors.warningOrange,
9
+ iconColor: "black"
10
+ },
11
+ info: {
12
+ background: "#F8FAFC",
13
+ border: colors.blueDark,
14
+ iconColor: "black"
15
+ },
16
+ error: {
17
+ background: "#FDEDEC",
18
+ border: colors.darkRed,
19
+ iconColor: "black"
20
+ }
21
+ };
22
+ const Container = styled.div`
23
+ position: relative;
24
+ display: flex;
25
+ overflow: hidden;
26
+ align-items: flex-start;
27
+ align-items: center;
28
+ gap: 12px;
29
+ padding: 12px 20px 12px 16px;
30
+ background: ${(props) => props.$bg};
31
+ border: 1px solid ${(props) => props.$border};
32
+ border-radius: 8px;
33
+ font-size: 12px;
34
+ line-height: 18px;
35
+ letter-spacing: 0.6px;
36
+ font-weight: 400;
37
+ color: ${colors.black};
38
+
39
+ ${(props) => !props.$noLeftBorder && `
40
+ &:before {
41
+ content: '';
42
+ display: block;
43
+ width: 4px;
44
+ position: absolute;
45
+ height: 100%;
46
+ left: 0px;
47
+ background: ${props.$border};
48
+ }
49
+ `}
50
+ `;
51
+ const DefaultIcon = styled.i.attrs({
52
+ className: "ion ion-md-information-circle-outline"
53
+ })`
54
+ flex-shrink: 0;
55
+ font-size: 18px;
56
+ line-height: 18px;
57
+ color: ${(props) => props.$color};
58
+ margin-top: 1px;
59
+ `;
60
+ const CustomIconWrapper = styled.span`
61
+ flex-shrink: 0;
62
+ display: flex;
63
+ align-items: center;
64
+ justify-content: center;
65
+ margin-top: 1px;
66
+ `;
67
+ const Content = styled.div`
68
+ flex: 1;
69
+ min-width: 0;
70
+ `;
71
+ const InfoBox = ({
72
+ variant = "warning",
73
+ children,
74
+ icon,
75
+ style,
76
+ className,
77
+ noLeftBorder
78
+ }) => {
79
+ const theme = VARIANTS[variant] || VARIANTS.warning;
80
+ const renderIcon = () => {
81
+ if (icon) {
82
+ return /* @__PURE__ */ jsx(CustomIconWrapper, { children: icon });
83
+ }
84
+ return /* @__PURE__ */ jsx(DefaultIcon, { $color: theme.iconColor });
85
+ };
86
+ return /* @__PURE__ */ jsxs(Container, { $bg: theme.background, $noLeftBorder: noLeftBorder, $border: theme.border, style, className, children: [
87
+ renderIcon(),
88
+ /* @__PURE__ */ jsx(Content, { children })
89
+ ] });
90
+ };
91
+ export {
92
+ InfoBox
93
+ };
@@ -1,9 +1,43 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
- import { useState, useEffect } from "react";
2
+ import { useState, useRef, useEffect } from "react";
3
3
  import { createPortal } from "react-dom";
4
4
  import { SideModalRoot, Dimmer, SideModalBox } from "./SideModal.styles.js";
5
5
  import { ModalClose } from "./Modal.styles.js";
6
6
  import { IoniconsStyles } from "../../styles/ioniconsStyles.js";
7
+ function findScrolledElement() {
8
+ let best = null;
9
+ function walk(el) {
10
+ if (!el || el.nodeType !== 1) return;
11
+ const s = getComputedStyle(el);
12
+ const scrollable = (s.overflowY === "auto" || s.overflowY === "scroll" || s.overflow === "auto" || s.overflow === "scroll") && el.scrollHeight > el.clientHeight && el.scrollTop > 0;
13
+ if (scrollable && (!best || el.scrollTop > best.scrollTop)) best = { el, scrollTop: el.scrollTop };
14
+ for (let i = 0; i < el.children.length; i++) walk(el.children[i]);
15
+ }
16
+ walk(document.body);
17
+ return best;
18
+ }
19
+ function restoreScroll(saved) {
20
+ if (!saved) return;
21
+ if (saved.type === "window") {
22
+ window.scrollTo(0, saved.y);
23
+ } else if (saved.el && document.contains(saved.el)) {
24
+ saved.el.scrollTop = saved.scrollTop;
25
+ }
26
+ }
27
+ function clearBodyLock() {
28
+ const { style } = document.body;
29
+ const docEl = document.documentElement;
30
+ style.position = "";
31
+ style.top = "";
32
+ style.left = "";
33
+ style.right = "";
34
+ style.width = "";
35
+ style.height = "";
36
+ style.overflow = "";
37
+ style.paddingRight = "";
38
+ docEl.style.overflow = "";
39
+ docEl.style.setProperty("--scrollbar-compensation", "0px");
40
+ }
7
41
  const SideModal = ({
8
42
  children,
9
43
  isOpen,
@@ -17,44 +51,55 @@ const SideModal = ({
17
51
  ...props
18
52
  }) => {
19
53
  const [isVisible, setIsVisible] = useState(false);
54
+ const savedScroll = useRef(null);
20
55
  useEffect(() => {
21
- let timeoutId;
22
56
  if (isOpen) {
57
+ const found = findScrolledElement();
58
+ if (found) savedScroll.current = found;
59
+ else if (window.scrollY > 0) savedScroll.current = { type: "window", y: window.scrollY };
60
+ else savedScroll.current = null;
61
+ const saved = savedScroll.current;
23
62
  const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
24
- const scrollY = window.scrollY;
25
- document.body.style.position = "fixed";
26
- document.body.style.top = `-${scrollY}px`;
27
- document.body.style.left = "0";
28
- document.body.style.right = "0";
29
- document.body.style.overflow = "hidden";
30
- document.body.style.paddingRight = `${scrollbarWidth}px`;
31
- document.documentElement.style.setProperty("--scrollbar-compensation", `${scrollbarWidth}px`);
32
- document.body.dataset.scrollY = scrollY;
33
- timeoutId = setTimeout(() => setIsVisible(true), 10);
63
+ const isWindowScroll = saved && saved.type === "window";
64
+ if (isWindowScroll) {
65
+ const y = saved.y;
66
+ const docHeight = document.documentElement.scrollHeight;
67
+ document.documentElement.style.overflow = "hidden";
68
+ document.documentElement.style.setProperty("--scrollbar-compensation", `${scrollbarWidth}px`);
69
+ document.body.style.position = "fixed";
70
+ document.body.style.top = `-${y}px`;
71
+ document.body.style.left = "0";
72
+ document.body.style.right = "0";
73
+ document.body.style.width = "100%";
74
+ document.body.style.height = `${docHeight}px`;
75
+ document.body.style.paddingRight = `${scrollbarWidth}px`;
76
+ } else {
77
+ document.documentElement.style.overflow = "hidden";
78
+ document.body.style.overflow = "hidden";
79
+ document.body.style.paddingRight = `${scrollbarWidth}px`;
80
+ document.documentElement.style.setProperty("--scrollbar-compensation", `${scrollbarWidth}px`);
81
+ if (saved) {
82
+ requestAnimationFrame(() => {
83
+ restoreScroll(saved);
84
+ requestAnimationFrame(() => restoreScroll(saved));
85
+ });
86
+ }
87
+ }
88
+ const timerId = setTimeout(() => setIsVisible(true), 10);
89
+ return () => {
90
+ clearTimeout(timerId);
91
+ const scrollState = savedScroll.current;
92
+ savedScroll.current = null;
93
+ clearBodyLock();
94
+ if (scrollState) requestAnimationFrame(() => restoreScroll(scrollState));
95
+ };
34
96
  } else {
35
- const scrollY = document.body.dataset.scrollY || "0";
36
- document.body.style.position = "";
37
- document.body.style.top = "";
38
- document.body.style.left = "";
39
- document.body.style.right = "";
40
- document.body.style.overflow = "";
41
- document.body.style.paddingRight = "";
42
- document.documentElement.style.setProperty("--scrollbar-compensation", "0px");
43
- window.scrollTo(0, parseInt(scrollY));
97
+ const saved = savedScroll.current;
98
+ savedScroll.current = null;
99
+ clearBodyLock();
44
100
  setIsVisible(false);
101
+ if (saved) requestAnimationFrame(() => restoreScroll(saved));
45
102
  }
46
- return () => {
47
- if (timeoutId != null) clearTimeout(timeoutId);
48
- const scrollY = document.body.dataset.scrollY || "0";
49
- document.body.style.position = "";
50
- document.body.style.top = "";
51
- document.body.style.left = "";
52
- document.body.style.right = "";
53
- document.body.style.overflow = "";
54
- document.body.style.paddingRight = "";
55
- document.documentElement.style.setProperty("--scrollbar-compensation", "0px");
56
- window.scrollTo(0, parseInt(scrollY));
57
- };
58
103
  }, [isOpen]);
59
104
  useEffect(() => {
60
105
  const handleEscape = (e) => {
@@ -3,7 +3,9 @@ import React__default from "react";
3
3
  import styled from "styled-components";
4
4
  import { colors } from "../../styles/colors.js";
5
5
  import { InfoIcon } from "../InfoIcon/InfoIcon.js";
6
+ import { ArrowSimple } from "../icons/ArrowSimple.js";
6
7
  import { formatCurrencyValue, getCurrencyIcon } from "../../utils/formatCurrencyValue.js";
8
+ import externalLinkIcon from "../../static/images/external-link-icon.svg.js";
7
9
  const CardContainer = styled.div`
8
10
  background: ${colors.white};
9
11
  border-radius: 10px;
@@ -11,16 +13,17 @@ const CardContainer = styled.div`
11
13
  padding: 20px 32px;
12
14
  `;
13
15
  const CardTitle = styled.div`
14
- font-size: 12px;
15
- letter-spacing: 0.6px;
16
- font-weight: 600;
17
- color: ${colors.futureBlack};
18
- background: #f1f5f9;
16
+ font-size: 10px;
17
+ letter-spacing: 1.12px;
18
+ font-weight: 500;
19
+ color: ${colors.white};
20
+ background: ${colors.futureBlack};
19
21
  padding: 12px 24px;
20
22
  margin: -20px -32px 20px -32px;
21
23
  border-radius: 9px 9px 0 0;
22
- border-bottom: 1px solid ${colors.lightGrey};
24
+ // border-bottom: 1px solid ${colors.lightGrey};
23
25
  text-align: start;
26
+ text-transform: uppercase;
24
27
  `;
25
28
  const AmountSection = styled.div``;
26
29
  const AmountLabel = styled.div`
@@ -29,8 +32,17 @@ const AmountLabel = styled.div`
29
32
  line-height: 20px;
30
33
  text-transform: uppercase;
31
34
  letter-spacing: 2px;
32
- margin-bottom: 12px;
33
- color: ${colors.futureBlack};
35
+ margin-bottom: 8px;
36
+ color: ${colors.grayBlue};
37
+ text-align: start;
38
+ `;
39
+ const AmountSubtitle = styled.div`
40
+ font-size: 12px;
41
+ font-weight: 400;
42
+ line-height: 18px;
43
+ letter-spacing: 0.6px;
44
+ color: #90a1b9;
45
+ margin-top: 8px;
34
46
  text-align: start;
35
47
  `;
36
48
  const AmountDisplay = styled.div`
@@ -38,11 +50,27 @@ const AmountDisplay = styled.div`
38
50
  align-items: center;
39
51
  gap: 16px;
40
52
  `;
53
+ const AmountLeft = styled.div`
54
+ display: flex;
55
+ align-items: center;
56
+ gap: 12px;
57
+ flex: 1;
58
+ min-width: 0;
59
+ `;
60
+ const CurrencyTicker = styled.div`
61
+ font-size: 22px;
62
+ font-weight: 300;
63
+ color: #90a1b9;
64
+ letter-spacing: 0.8px;
65
+ line-height: 28px;
66
+ flex-shrink: 0;
67
+ margin-left: auto;
68
+ `;
41
69
  const CurrencyLogo = styled.div.withConfig({
42
70
  shouldForwardProp: (props) => !["color"].includes(props)
43
71
  })`
44
- width: 32px;
45
- height: 32px;
72
+ width: 24px;
73
+ height: 24px;
46
74
  border-radius: 50%;
47
75
  background-color: ${(props) => props.color || colors.black};
48
76
  display: flex;
@@ -57,12 +85,11 @@ const CurrencyLogo = styled.div.withConfig({
57
85
  const CurrencyIcon = styled.img`
58
86
  width: 100%;
59
87
  height: 100%;
60
-
61
88
  object-fit: contain;
62
89
  `;
63
90
  const AmountValue = styled.div`
64
91
  font-size: 34px;
65
- font-weight: 600;
92
+ font-weight: 300;
66
93
  text-transform: uppercase;
67
94
  line-height: 40px;
68
95
  letter-spacing: 1.5px;
@@ -71,8 +98,40 @@ const AmountValue = styled.div`
71
98
  `;
72
99
  const Separator = styled.hr`
73
100
  border: none;
74
- border-top: 1px solid ${colors.lightGrey};
75
- margin: 20px -32px;
101
+ border-top: 1px solid #e2e8f0;
102
+ margin: 20px 0px;
103
+ `;
104
+ const ArrowSeparatorWrapper = styled.div`
105
+ position: relative;
106
+ display: flex;
107
+ align-items: center;
108
+ margin: 20px 0;
109
+
110
+ &::before,
111
+ &::after {
112
+ content: '';
113
+ flex: 1;
114
+ height: 1px;
115
+ background: #e2e8f0;
116
+ }
117
+ `;
118
+ const ArrowCircle = styled.div`
119
+ display: flex;
120
+ align-items: center;
121
+ justify-content: center;
122
+ margin: 0 16px;
123
+ height: 0;
124
+ color: #cbd5e1;
125
+ `;
126
+ const SectionHeader = styled.div`
127
+ font-size: 11px;
128
+ font-weight: 400;
129
+ line-height: 20px;
130
+ text-transform: uppercase;
131
+ letter-spacing: 2px;
132
+ color: ${colors.grayBlue};
133
+ text-align: start;
134
+ margin-bottom: 4px;
76
135
  `;
77
136
  const DetailsSection = styled.div.withConfig({
78
137
  shouldForwardProp: (props) => !["noMargin"].includes(props)
@@ -83,16 +142,14 @@ const DetailRow = styled.div`
83
142
  display: flex;
84
143
  justify-content: space-between;
85
144
  align-items: flex-start;
86
- padding: 10px 0;
87
- border-bottom: 1px solid #f1f5f9;
145
+ padding: 6px 0;
88
146
 
89
147
  &:first-child {
90
148
  padding-top: 0;
91
149
  }
92
150
 
93
151
  &:last-child {
94
- padding: 10px 0 0 0;
95
- border-bottom: none;
152
+ padding: 6px 0 0 0;
96
153
  }
97
154
  `;
98
155
  const DetailLabel = styled.div`
@@ -100,7 +157,7 @@ const DetailLabel = styled.div`
100
157
  align-items: center;
101
158
  gap: 10px;
102
159
  font-size: 14px;
103
- font-weight: 600;
160
+ font-weight: 400;
104
161
  line-height: 20px;
105
162
  letter-spacing: 0.5px;
106
163
  color: #56606f;
@@ -117,29 +174,63 @@ const DetailValue = styled.div`
117
174
  word-wrap: break-word;
118
175
  text-align: right;
119
176
  max-width: 60%;
120
- color: ${colors.black};
177
+ color: ${colors.futureBlack};
121
178
  `;
122
179
  const PlaceholderValue = styled.span`
123
- color: #62748e;
180
+ color: ${colors.grayBlue};
124
181
  font-weight: 300;
125
182
  font-size: 14px;
126
183
  letter-spacing: 0.5px;
127
184
  `;
185
+ const ExternalLink = styled.a`
186
+ color: ${colors.futureBlack};
187
+ text-decoration: underline;
188
+ font-size: 14px;
189
+ font-weight: 600;
190
+ letter-spacing: 0.5px;
191
+ display: inline-flex;
192
+ align-items: center;
193
+ gap: 6px;
194
+
195
+ &:hover {
196
+ text-decoration: underline;
197
+ }
198
+
199
+ svg {
200
+ width: 12px;
201
+ height: 12px;
202
+ flex-shrink: 0;
203
+ }
204
+ `;
128
205
  const InfoSectionContainer = styled.div`
129
206
  margin-top: 24px;
130
207
  `;
131
- const DetailItem = ({ label, value, tooltip, placeholder, isCustom }) => {
208
+ const BannerSlot = styled.div`
209
+ margin-top: 8px;
210
+ `;
211
+ const ExternalLinkIconImg = styled.img`
212
+ width: 12px;
213
+ height: 12px;
214
+ flex-shrink: 0;
215
+ `;
216
+ const DetailItem = ({ label, value, tooltip, placeholder, isCustom, href, target }) => {
132
217
  const renderValue = () => {
133
218
  if (isCustom && value) {
134
219
  return value;
135
220
  }
221
+ if (href) {
222
+ return /* @__PURE__ */ jsxs(ExternalLink, { href, target: target || "_blank", rel: "noopener noreferrer", children: [
223
+ /* @__PURE__ */ jsx(ExternalLinkIconImg, { src: externalLinkIcon, alt: "" }),
224
+ value || placeholder || "-"
225
+ ] });
226
+ }
136
227
  if (value !== void 0 && value !== null && value !== "") {
137
228
  return value;
138
229
  }
139
230
  if (placeholder) {
140
231
  return /* @__PURE__ */ jsx(PlaceholderValue, { children: placeholder });
141
232
  }
142
- return /* @__PURE__ */ jsx(PlaceholderValue, { children: "-" });
233
+ return "-";
143
234
  };
144
235
  return /* @__PURE__ */ jsxs(DetailRow, { children: [
145
236
  /* @__PURE__ */ jsxs(DetailLabel, { children: [
@@ -149,58 +240,102 @@ const DetailItem = ({ label, value, tooltip, placeholder, isCustom }) => {
149
240
  /* @__PURE__ */ jsx(DetailValue, { children: renderValue() })
150
241
  ] });
151
242
  };
152
- const PaymentDetailsCard = ({
153
- title,
154
- amountSection,
155
- details,
156
- infoSection,
157
- showSeparators = true,
158
- containerStyle
159
- }) => {
160
- const renderAmountSection = () => {
161
- if (!amountSection) return null;
162
- if (React__default.isValidElement(amountSection)) {
163
- return /* @__PURE__ */ jsxs(Fragment, { children: [
164
- amountSection,
165
- showSeparators && /* @__PURE__ */ jsx(Separator, {})
166
- ] });
243
+ const AmountBlock = ({ config }) => {
244
+ if (!config) return null;
245
+ if (React__default.isValidElement(config)) {
246
+ return config;
247
+ }
248
+ const { label = "Amount", subtitle, amount, currency, currencyColor, icon, showTicker = true, banner } = config;
249
+ const formattedAmount = amount !== void 0 && amount !== null && amount !== "" ? formatCurrencyValue(currency, amount, 2, { valueFirst: true }) : null;
250
+ const currencyIcon = getCurrencyIcon(currency, icon);
251
+ const logoColor = currencyColor || colors.black;
252
+ const ticker = showTicker ? (currency || "").toUpperCase() : null;
253
+ const displayValue = formattedAmount ? formattedAmount.replace(/\s*\S+$/, "") : null;
254
+ const renderCurrencyLogo = () => {
255
+ if (currencyIcon) {
256
+ return /* @__PURE__ */ jsx(CurrencyLogo, { color: "transparent", children: /* @__PURE__ */ jsx(CurrencyIcon, { src: currencyIcon, alt: currency || "currency" }) });
167
257
  }
168
- const { label = "Amount", amount, currency, currencyColor, icon } = amountSection;
169
- const displayAmount = formatCurrencyValue(currency, amount, 2, {
170
- valueFirst: true
171
- });
172
- const currencyIcon = getCurrencyIcon(currency, icon);
173
- const logoColor = currencyColor || colors.black;
174
- const renderCurrencyLogo = () => {
175
- if (currencyIcon) {
176
- return /* @__PURE__ */ jsx(CurrencyLogo, { color: "transparent", children: /* @__PURE__ */ jsx(CurrencyIcon, { src: currencyIcon, alt: currency || "currency" }) });
177
- }
178
- return /* @__PURE__ */ jsx(CurrencyLogo, { color: logoColor, children: currency ? currency.charAt(0).toUpperCase() : "" });
179
- };
180
- return /* @__PURE__ */ jsxs(Fragment, { children: [
181
- /* @__PURE__ */ jsxs(AmountSection, { children: [
182
- /* @__PURE__ */ jsx(AmountLabel, { children: label }),
183
- /* @__PURE__ */ jsxs(AmountDisplay, { children: [
184
- renderCurrencyLogo(),
185
- /* @__PURE__ */ jsx(AmountValue, { children: displayAmount })
186
- ] })
187
- ] }),
188
- showSeparators && /* @__PURE__ */ jsx(Separator, {})
189
- ] });
258
+ return /* @__PURE__ */ jsx(CurrencyLogo, { color: logoColor });
190
259
  };
191
- const renderDetailsSection = () => {
192
- if (!details || details.length === 0) return null;
193
- return /* @__PURE__ */ jsx(DetailsSection, { noMargin: !infoSection, children: details.map((detail, index) => /* @__PURE__ */ jsx(
260
+ return /* @__PURE__ */ jsxs(AmountSection, { children: [
261
+ /* @__PURE__ */ jsx(AmountLabel, { hasSubtitle: !!subtitle, children: label }),
262
+ /* @__PURE__ */ jsxs(AmountDisplay, { children: [
263
+ /* @__PURE__ */ jsxs(AmountLeft, { children: [
264
+ renderCurrencyLogo(),
265
+ /* @__PURE__ */ jsx(AmountValue, { children: displayValue !== null ? displayValue : "-" })
266
+ ] }),
267
+ ticker && /* @__PURE__ */ jsx(CurrencyTicker, { children: ticker })
268
+ ] }),
269
+ subtitle && /* @__PURE__ */ jsx(AmountSubtitle, { children: subtitle }),
270
+ banner && /* @__PURE__ */ jsx(BannerSlot, { children: banner })
271
+ ] });
272
+ };
273
+ const DetailGroup = ({ group, isLast }) => {
274
+ const { sectionTitle, items } = group;
275
+ return /* @__PURE__ */ jsxs(DetailsSection, { noMargin: isLast, children: [
276
+ sectionTitle && /* @__PURE__ */ jsx(SectionHeader, { children: sectionTitle }),
277
+ items.map((detail, index) => /* @__PURE__ */ jsx(
194
278
  DetailItem,
195
279
  {
196
280
  label: detail.label,
197
281
  value: detail.value,
198
282
  tooltip: detail.tooltip,
199
283
  placeholder: detail.placeholder,
200
- isCustom: detail.isCustom
284
+ isCustom: detail.isCustom,
285
+ href: detail.href,
286
+ target: detail.target
201
287
  },
202
288
  detail.key || index
203
- )) });
289
+ ))
290
+ ] });
291
+ };
292
+ const PaymentDetailsCard = ({
293
+ title,
294
+ amountSection,
295
+ amountSections,
296
+ details,
297
+ detailGroups,
298
+ infoSection,
299
+ showSeparators = true,
300
+ showArrowSeparator = false,
301
+ containerStyle
302
+ }) => {
303
+ const allAmountSections = amountSections || (amountSection ? [amountSection] : []);
304
+ const renderAmountSections = () => {
305
+ if (allAmountSections.length === 0) return null;
306
+ return allAmountSections.map((section, index) => {
307
+ const isLast = index === allAmountSections.length - 1;
308
+ const useArrow = showArrowSeparator && !isLast && allAmountSections.length > 1;
309
+ return /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
310
+ /* @__PURE__ */ jsx(AmountBlock, { config: section }),
311
+ showSeparators && !isLast && (useArrow ? /* @__PURE__ */ jsx(ArrowSeparatorWrapper, { children: /* @__PURE__ */ jsx(ArrowCircle, { children: /* @__PURE__ */ jsx(ArrowSimple, { direction: "bottom" }) }) }) : /* @__PURE__ */ jsx(Separator, {})),
312
+ showSeparators && isLast && (detailGroups || details) && /* @__PURE__ */ jsx(Separator, {})
313
+ ] }, index.toString() + section.label);
314
+ });
315
+ };
316
+ const renderDetails = () => {
317
+ if (detailGroups && detailGroups.length > 0) {
318
+ return detailGroups.map((group, index) => {
319
+ const isLast = index === detailGroups.length - 1 && !infoSection;
320
+ return /* @__PURE__ */ jsx(React__default.Fragment, { children: /* @__PURE__ */ jsx(DetailGroup, { group, isLast }) }, group.key || index);
321
+ });
322
+ }
323
+ if (details && details.length > 0) {
324
+ return /* @__PURE__ */ jsx(DetailsSection, { noMargin: !infoSection, children: details.map((detail, index) => /* @__PURE__ */ jsx(
325
+ DetailItem,
326
+ {
327
+ label: detail.label,
328
+ value: detail.value,
329
+ tooltip: detail.tooltip,
330
+ placeholder: detail.placeholder,
331
+ isCustom: detail.isCustom,
332
+ href: detail.href,
333
+ target: detail.target
334
+ },
335
+ detail.key || index
336
+ )) });
337
+ }
338
+ return null;
204
339
  };
205
340
  const renderInfoSection = () => {
206
341
  if (!infoSection) return null;
@@ -211,8 +346,8 @@ const PaymentDetailsCard = ({
211
346
  };
212
347
  return /* @__PURE__ */ jsxs(CardContainer, { style: containerStyle, children: [
213
348
  title && /* @__PURE__ */ jsx(CardTitle, { children: title }),
214
- renderAmountSection(),
215
- renderDetailsSection(),
349
+ renderAmountSections(),
350
+ renderDetails(),
216
351
  renderInfoSection()
217
352
  ] });
218
353
  };
@@ -0,0 +1,100 @@
1
+ import { useState, useRef, useCallback, useEffect } from "react";
2
+ const useTransactionPolling = (options = {}) => {
3
+ const {
4
+ fetcher,
5
+ payload,
6
+ enabled = true,
7
+ isSuccess = (response) => Boolean(response),
8
+ pollingInterval = 5e3,
9
+ maxAttempts = 360,
10
+ delayBeforeStart = 2e3,
11
+ onSuccess,
12
+ onError,
13
+ onMaxAttemptsReached
14
+ } = options;
15
+ if (typeof fetcher !== "function") {
16
+ throw new Error("useTransactionPolling: options.fetcher is required and must be a function");
17
+ }
18
+ const [isLoading, setIsLoading] = useState(false);
19
+ const [error, setError] = useState(null);
20
+ const [attempts, setAttempts] = useState(0);
21
+ const [isPolling, setIsPolling] = useState(false);
22
+ const intervalRef = useRef(null);
23
+ const timeoutRef = useRef(null);
24
+ const completedRef = useRef(false);
25
+ const pollRef = useRef(null);
26
+ const poll = useCallback(async () => {
27
+ if (!enabled || attempts >= maxAttempts || completedRef.current) {
28
+ return;
29
+ }
30
+ setIsLoading(true);
31
+ setError(null);
32
+ try {
33
+ const response = await fetcher(payload);
34
+ if (isSuccess(response)) {
35
+ completedRef.current = true;
36
+ setIsPolling(false);
37
+ setIsLoading(false);
38
+ onSuccess?.(response);
39
+ return;
40
+ }
41
+ } catch (err) {
42
+ console.error("Transaction polling error:", err);
43
+ setError(err);
44
+ onError?.(err);
45
+ } finally {
46
+ setIsLoading(false);
47
+ setAttempts((prev) => prev + 1);
48
+ }
49
+ }, [
50
+ enabled,
51
+ attempts,
52
+ maxAttempts,
53
+ fetcher,
54
+ payload,
55
+ isSuccess,
56
+ onSuccess,
57
+ onError
58
+ ]);
59
+ pollRef.current = poll;
60
+ useEffect(() => {
61
+ if (!enabled) return;
62
+ setIsPolling(true);
63
+ setAttempts(0);
64
+ completedRef.current = false;
65
+ setError(null);
66
+ const runPoll = () => pollRef.current?.();
67
+ timeoutRef.current = setTimeout(() => {
68
+ intervalRef.current = setInterval(runPoll, pollingInterval);
69
+ runPoll();
70
+ }, delayBeforeStart);
71
+ return () => {
72
+ if (intervalRef.current) {
73
+ clearInterval(intervalRef.current);
74
+ }
75
+ if (timeoutRef.current) {
76
+ clearTimeout(timeoutRef.current);
77
+ }
78
+ setIsPolling(false);
79
+ };
80
+ }, [enabled, payload, pollingInterval, delayBeforeStart, maxAttempts]);
81
+ useEffect(() => {
82
+ if (attempts >= maxAttempts && isPolling) {
83
+ if (intervalRef.current) {
84
+ clearInterval(intervalRef.current);
85
+ }
86
+ setIsPolling(false);
87
+ onMaxAttemptsReached?.();
88
+ }
89
+ }, [attempts, maxAttempts, isPolling, onMaxAttemptsReached]);
90
+ return {
91
+ isLoading,
92
+ error,
93
+ attempts,
94
+ isPolling,
95
+ maxAttempts
96
+ };
97
+ };
98
+ export {
99
+ useTransactionPolling
100
+ };
package/dist/index.js CHANGED
@@ -125,6 +125,7 @@ import { SnackbarContext, SnackbarProvider } from "./components/Snackbar/Snackba
125
125
  import { useSnackbar } from "./components/Snackbar/useSnackbar.js";
126
126
  import { Layout } from "./components/Layout/Layout.js";
127
127
  import { AnimatedSpan, LoadingDots, StokrLoader, StokrLoaderBox, loaderGif } from "./components/StokrLoader/StokrLoader.js";
128
+ import { InfoBox } from "./components/InfoBox/InfoBox.js";
128
129
  import { HeaderHo } from "./components/headerHo/HeaderHo.js";
129
130
  import { LoginModal } from "./components/LoginModal/LoginModal.js";
130
131
  import { CheckboxContext, CheckboxProvider, useCheckboxActions, useCheckboxes } from "./context/Checkbox/CheckboxContext.js";
@@ -189,6 +190,7 @@ import { momentUtils } from "./utils/moment.js";
189
190
  import { openFile, saveAs } from "./utils/saveAs.js";
190
191
  import { ScrollToTop, scrollToElement, useScrollActions } from "./utils/scrollUtils.js";
191
192
  import { useTimer } from "./hooks/useTimer.js";
193
+ import { useTransactionPolling } from "./hooks/useTransactionPolling.js";
192
194
  import { configure, getConfig } from "./config.js";
193
195
  import { default as default40 } from "./components/2FA/Connect2FA.js";
194
196
  import { default as default41 } from "./components/2FA/enable-2fa-flow.js";
@@ -352,6 +354,7 @@ export {
352
354
  ImageSlide,
353
355
  ImageSlideWrapper,
354
356
  Info,
357
+ InfoBox,
355
358
  InfoIcon,
356
359
  Container2 as InfoIconContainer,
357
360
  Icon3 as InfoIconWrapper,
@@ -625,6 +628,7 @@ export {
625
628
  useScrollActions,
626
629
  useSnackbar,
627
630
  useTimer,
631
+ useTransactionPolling,
628
632
  walletTypes,
629
633
  withCopyToClipboard
630
634
  };
@@ -0,0 +1,3 @@
1
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M4.33347 1.66667H3.13347C2.38673 1.66667 2.01308 1.66667 1.72787 1.81199C1.47698 1.93982 1.27315 2.14365 1.14533 2.39453C1 2.67975 1 3.05339 1 3.80013V8.8668C1 9.61353 1 9.98673 1.14533 10.2719C1.27315 10.5228 1.47698 10.727 1.72787 10.8548C2.0128 11 2.38599 11 3.13127 11H8.20207C8.94733 11 9.32 11 9.60493 10.8548C9.8558 10.727 10.0603 10.5226 10.1881 10.2717C10.3333 9.9868 10.3333 9.614 10.3333 8.86873V7.66667M11 4.33333V1M11 1H7.66667M11 1L6.33333 5.66667" stroke="#BCBCBC" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>
@@ -0,0 +1,4 @@
1
+ const externalLinkIcon = "data:image/svg+xml,%3csvg%20width='12'%20height='12'%20viewBox='0%200%2012%2012'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M4.33347%201.66667H3.13347C2.38673%201.66667%202.01308%201.66667%201.72787%201.81199C1.47698%201.93982%201.27315%202.14365%201.14533%202.39453C1%202.67975%201%203.05339%201%203.80013V8.8668C1%209.61353%201%209.98673%201.14533%2010.2719C1.27315%2010.5228%201.47698%2010.727%201.72787%2010.8548C2.0128%2011%202.38599%2011%203.13127%2011H8.20207C8.94733%2011%209.32%2011%209.60493%2010.8548C9.8558%2010.727%2010.0603%2010.5226%2010.1881%2010.2717C10.3333%209.9868%2010.3333%209.614%2010.3333%208.86873V7.66667M11%204.33333V1M11%201H7.66667M11%201L6.33333%205.66667'%20stroke='%23BCBCBC'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e";
2
+ export {
3
+ externalLinkIcon as default
4
+ };
@@ -48,7 +48,8 @@ const colors = {
48
48
  warningYellow: "#facc33",
49
49
  darkRed: "#D2200D",
50
50
  warningOrange: "#EB8003",
51
- futureBlack: "#021128"
51
+ futureBlack: "#021128",
52
+ grayBlue: "#56606F"
52
53
  };
53
54
  export {
54
55
  colors,
package/package.json CHANGED
@@ -1,146 +1,146 @@
1
- {
2
- "name": "@stokr/components-library",
3
- "version": "3.0.17",
4
- "description": "STOKR - Components Library",
5
- "author": "Bilal Hodzic <bilal@stokr.io>",
6
- "license": "MIT",
7
- "type": "module",
8
- "main": "./dist/index.js",
9
- "module": "./dist/index.js",
10
- "files": [
11
- "dist",
12
- "README.md"
13
- ],
14
- "exports": {
15
- ".": {
16
- "import": "./dist/index.js",
17
- "default": "./dist/index.js"
18
- },
19
- "./auth": {
20
- "import": "./dist/auth/index.js",
21
- "default": "./dist/auth/index.js"
22
- },
23
- "./auth/index.js": "./dist/auth/index.js",
24
- "./ionicons.css": "./dist/static/fonts/Ionicons/ionicons.min.css",
25
- "./dist/*": "./dist/static/*"
26
- },
27
- "repository": {
28
- "type": "git",
29
- "url": "http://46.101.229.186:3000/stokr/components-library"
30
- },
31
- "scripts": {
32
- "build": "vite build",
33
- "build-storybook": "storybook build",
34
- "build-storybook-docs": "storybook build -s public --docs",
35
- "copy:static": "node -e \"require('fs').cpSync('src/static', 'dist/static', {recursive: true})\"",
36
- "build:dist": "vite build && npm run copy:static",
37
- "prepare": "npm run build:dist",
38
- "storybook": "storybook dev -p 6006",
39
- "start": "npm run storybook",
40
- "format": "prettier --write ./src",
41
- "lint": "eslint .",
42
- "chromatic": "CHROMATIC_APP_CODE=7kzdke5umep chromatic",
43
- "release": "auto shipit",
44
- "pub": "npm run publish:build && npm publish --access public",
45
- "publish:build": "npm run build:dist",
46
- "dev": "vite dev",
47
- "serve": "npx http-server ./storybook-static -p 9009"
48
- },
49
- "dependencies": {
50
- "@lottiefiles/dotlottie-react": "^0.17.13",
51
- "ajv": "^8.18.0",
52
- "axios": "^1.13.5",
53
- "bignumber.js": "^9.1.1",
54
- "d3": "^7.8.3",
55
- "date-fns": "^4.1.0",
56
- "date-fns-tz": "^3.2.0",
57
- "dompurify": "^3.2.4",
58
- "firebase": "^12.4.0",
59
- "formik": "^2.2.9",
60
- "formik-persist": "^1.1.0",
61
- "html-react-parser": "^5.0.6",
62
- "js-cookie": "^3.0.5",
63
- "mixpanel-browser": "^2.74.0",
64
- "mobile-detect": "^1.4.5",
65
- "moment": "^2.30.1",
66
- "moment-timezone": "^0.6.0",
67
- "prop-types": "^15.8.1",
68
- "qrcode.react": "^4.2.0",
69
- "react-collapse": "^5.1.1",
70
- "react-copy-to-clipboard": "^5.1.0",
71
- "react-countup": "^6.4.1",
72
- "react-custom-scrollbars-2": "^4.5.0",
73
- "react-day-picker": "^9.11.1",
74
- "react-device-detect": "^2.2.3",
75
- "react-ga4": "^2.1.0",
76
- "react-helmet": "^6.1.0",
77
- "react-intersection-observer": "^10.0.2",
78
- "react-otp-input": "^3.1.0",
79
- "react-portal": "^4.2.2",
80
- "react-qr-code": "^2.0.12",
81
- "react-range": "^1.8.14",
82
- "react-select": "^5.7.0",
83
- "react-slick": "^0.31.0",
84
- "react-table": "^7.8.0",
85
- "react-tippy": "^1.4.0",
86
- "scroll-to-element": "^2.0.3",
87
- "semantic-ui-react": "^2.1.4",
88
- "slick-carousel": "^1.8.1",
89
- "yup": "^1.0.0"
90
- },
91
- "peerDependencies": {
92
- "react": "^18.0.0 || ^19.0.0",
93
- "react-dom": "^18.0.0 || ^19.0.0",
94
- "react-router-dom": "^6.0.0",
95
- "styled-components": "^6.0.0"
96
- },
97
- "devDependencies": {
98
- "@chromatic-com/storybook": "^5.0.0",
99
- "cross-env": "^10.1.0",
100
- "depcheck": "^1.4.7",
101
- "@eslint-react/eslint-plugin": "^1.53.1",
102
- "@eslint/js": "^9.39.2",
103
- "@storybook/addon-docs": "^10.2.0",
104
- "@storybook/addon-links": "^10.2.0",
105
- "@storybook/builder-vite": "^10.2.0",
106
- "@storybook/react-vite": "^10.2.0",
107
- "@types/node": "^25.0.10",
108
- "@types/react": "^19.2.9",
109
- "@types/react-dom": "^19.2.3",
110
- "@typescript-eslint/eslint-plugin": "^8.53.1",
111
- "@typescript-eslint/parser": "^8.53.1",
112
- "@vitejs/plugin-react": "^5.1.2",
113
- "eslint": "^9.39.2",
114
- "eslint-config-prettier": "^10.1.8",
115
- "eslint-plugin-prettier": "^5.5.5",
116
- "eslint-plugin-react": "^7.37.2",
117
- "eslint-plugin-react-hooks": "^7.0.1",
118
- "eslint-plugin-react-refresh": "^0.4.26",
119
- "eslint-plugin-storybook": "10.2.0",
120
- "http-server": "^14.1.1",
121
- "prettier": "^3.8.1",
122
- "react": "^19.2.3",
123
- "react-dom": "^19.2.3",
124
- "react-router-dom": "^6.30.3",
125
- "storybook": "^10.2.0",
126
- "styled-components": "^6.0.7",
127
- "typescript": "^5.9.3",
128
- "typescript-eslint": "^8.54.0",
129
- "vite": "^7.3.1",
130
- "vite-plugin-dts": "^4.5.4",
131
- "vite-plugin-lottie": "^1.0.1",
132
- "vite-plugin-svgr": "4.5.0"
133
- },
134
- "overrides": {
135
- "minimatch": "^10.2.1"
136
- },
137
- "bugs": {
138
- "url": "https://github.com/stokr-io/components-library/issues"
139
- },
140
- "homepage": "https://github.com/stokr-io/components-library#readme",
141
- "keywords": [
142
- "stokr",
143
- "components-library",
144
- "story-book"
145
- ]
146
- }
1
+ {
2
+ "name": "@stokr/components-library",
3
+ "version": "3.0.18",
4
+ "description": "STOKR - Components Library",
5
+ "author": "Bilal Hodzic <bilal@stokr.io>",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "module": "./dist/index.js",
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "exports": {
15
+ ".": {
16
+ "import": "./dist/index.js",
17
+ "default": "./dist/index.js"
18
+ },
19
+ "./auth": {
20
+ "import": "./dist/auth/index.js",
21
+ "default": "./dist/auth/index.js"
22
+ },
23
+ "./auth/index.js": "./dist/auth/index.js",
24
+ "./ionicons.css": "./dist/static/fonts/Ionicons/ionicons.min.css",
25
+ "./dist/*": "./dist/static/*"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "http://46.101.229.186:3000/stokr/components-library"
30
+ },
31
+ "scripts": {
32
+ "build": "vite build",
33
+ "build-storybook": "storybook build",
34
+ "build-storybook-docs": "storybook build -s public --docs",
35
+ "copy:static": "node -e \"require('fs').cpSync('src/static', 'dist/static', {recursive: true})\"",
36
+ "build:dist": "vite build && npm run copy:static",
37
+ "prepare": "npm run build:dist",
38
+ "storybook": "storybook dev -p 6006",
39
+ "start": "npm run storybook",
40
+ "format": "prettier --write ./src",
41
+ "lint": "eslint .",
42
+ "chromatic": "CHROMATIC_APP_CODE=7kzdke5umep chromatic",
43
+ "release": "auto shipit",
44
+ "pub": "npm run publish:build && npm publish --access public",
45
+ "publish:build": "npm run build:dist",
46
+ "dev": "vite dev",
47
+ "serve": "npx http-server ./storybook-static -p 9009"
48
+ },
49
+ "dependencies": {
50
+ "@lottiefiles/dotlottie-react": "^0.17.13",
51
+ "ajv": "^8.18.0",
52
+ "axios": "^1.13.5",
53
+ "bignumber.js": "^9.1.1",
54
+ "d3": "^7.8.3",
55
+ "date-fns": "^4.1.0",
56
+ "date-fns-tz": "^3.2.0",
57
+ "dompurify": "^3.2.4",
58
+ "firebase": "^12.4.0",
59
+ "formik": "^2.2.9",
60
+ "formik-persist": "^1.1.0",
61
+ "html-react-parser": "^5.0.6",
62
+ "js-cookie": "^3.0.5",
63
+ "mixpanel-browser": "^2.74.0",
64
+ "mobile-detect": "^1.4.5",
65
+ "moment": "^2.30.1",
66
+ "moment-timezone": "^0.6.0",
67
+ "prop-types": "^15.8.1",
68
+ "qrcode.react": "^4.2.0",
69
+ "react-collapse": "^5.1.1",
70
+ "react-copy-to-clipboard": "^5.1.0",
71
+ "react-countup": "^6.4.1",
72
+ "react-custom-scrollbars-2": "^4.5.0",
73
+ "react-day-picker": "^9.11.1",
74
+ "react-device-detect": "^2.2.3",
75
+ "react-ga4": "^2.1.0",
76
+ "react-helmet": "^6.1.0",
77
+ "react-intersection-observer": "^10.0.2",
78
+ "react-otp-input": "^3.1.0",
79
+ "react-portal": "^4.2.2",
80
+ "react-qr-code": "^2.0.12",
81
+ "react-range": "^1.8.14",
82
+ "react-select": "^5.7.0",
83
+ "react-slick": "^0.31.0",
84
+ "react-table": "^7.8.0",
85
+ "react-tippy": "^1.4.0",
86
+ "scroll-to-element": "^2.0.3",
87
+ "semantic-ui-react": "^2.1.4",
88
+ "slick-carousel": "^1.8.1",
89
+ "yup": "^1.0.0"
90
+ },
91
+ "peerDependencies": {
92
+ "react": "^18.0.0 || ^19.0.0",
93
+ "react-dom": "^18.0.0 || ^19.0.0",
94
+ "react-router-dom": "^6.0.0",
95
+ "styled-components": "^6.0.0"
96
+ },
97
+ "devDependencies": {
98
+ "@chromatic-com/storybook": "^5.0.0",
99
+ "cross-env": "^10.1.0",
100
+ "depcheck": "^1.4.7",
101
+ "@eslint-react/eslint-plugin": "^1.53.1",
102
+ "@eslint/js": "^9.39.2",
103
+ "@storybook/addon-docs": "^10.2.0",
104
+ "@storybook/addon-links": "^10.2.0",
105
+ "@storybook/builder-vite": "^10.2.0",
106
+ "@storybook/react-vite": "^10.2.0",
107
+ "@types/node": "^25.0.10",
108
+ "@types/react": "^19.2.9",
109
+ "@types/react-dom": "^19.2.3",
110
+ "@typescript-eslint/eslint-plugin": "^8.53.1",
111
+ "@typescript-eslint/parser": "^8.53.1",
112
+ "@vitejs/plugin-react": "^5.1.2",
113
+ "eslint": "^9.39.2",
114
+ "eslint-config-prettier": "^10.1.8",
115
+ "eslint-plugin-prettier": "^5.5.5",
116
+ "eslint-plugin-react": "^7.37.2",
117
+ "eslint-plugin-react-hooks": "^7.0.1",
118
+ "eslint-plugin-react-refresh": "^0.4.26",
119
+ "eslint-plugin-storybook": "10.2.0",
120
+ "http-server": "^14.1.1",
121
+ "prettier": "^3.8.1",
122
+ "react": "^19.2.3",
123
+ "react-dom": "^19.2.3",
124
+ "react-router-dom": "^6.30.3",
125
+ "storybook": "^10.2.0",
126
+ "styled-components": "^6.0.7",
127
+ "typescript": "^5.9.3",
128
+ "typescript-eslint": "^8.54.0",
129
+ "vite": "^7.3.1",
130
+ "vite-plugin-dts": "^4.5.4",
131
+ "vite-plugin-lottie": "^1.0.1",
132
+ "vite-plugin-svgr": "4.5.0"
133
+ },
134
+ "overrides": {
135
+ "minimatch": "^10.2.1"
136
+ },
137
+ "bugs": {
138
+ "url": "https://github.com/stokr-io/components-library/issues"
139
+ },
140
+ "homepage": "https://github.com/stokr-io/components-library#readme",
141
+ "keywords": [
142
+ "stokr",
143
+ "components-library",
144
+ "story-book"
145
+ ]
146
+ }