@xsolla/xui-b2b-collapsible 0.147.1

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.
@@ -0,0 +1,501 @@
1
+ // src/Collapsible.tsx
2
+ import { forwardRef, useState, useCallback, useRef } from "react";
3
+
4
+ // ../../foundation/primitives-native/src/Box.tsx
5
+ import {
6
+ View,
7
+ Pressable,
8
+ Image
9
+ } from "react-native";
10
+ import { jsx } from "react/jsx-runtime";
11
+ var Box = ({
12
+ children,
13
+ onPress,
14
+ onLayout,
15
+ onMoveShouldSetResponder,
16
+ onResponderGrant,
17
+ onResponderMove,
18
+ onResponderRelease,
19
+ onResponderTerminate,
20
+ backgroundColor,
21
+ borderColor,
22
+ borderWidth,
23
+ borderBottomWidth,
24
+ borderBottomColor,
25
+ borderTopWidth,
26
+ borderTopColor,
27
+ borderLeftWidth,
28
+ borderLeftColor,
29
+ borderRightWidth,
30
+ borderRightColor,
31
+ borderRadius,
32
+ borderStyle,
33
+ height,
34
+ padding,
35
+ paddingHorizontal,
36
+ paddingVertical,
37
+ margin,
38
+ marginTop,
39
+ marginBottom,
40
+ marginLeft,
41
+ marginRight,
42
+ flexDirection,
43
+ alignItems,
44
+ justifyContent,
45
+ position,
46
+ top,
47
+ bottom,
48
+ left,
49
+ right,
50
+ width,
51
+ minWidth,
52
+ minHeight,
53
+ maxWidth,
54
+ maxHeight,
55
+ flex,
56
+ overflow,
57
+ zIndex,
58
+ hoverStyle,
59
+ pressStyle,
60
+ style,
61
+ "data-testid": dataTestId,
62
+ testID,
63
+ as,
64
+ src,
65
+ alt,
66
+ ...rest
67
+ }) => {
68
+ const getContainerStyle = (pressed) => ({
69
+ backgroundColor: pressed && pressStyle?.backgroundColor ? pressStyle.backgroundColor : backgroundColor,
70
+ borderColor,
71
+ borderWidth,
72
+ borderBottomWidth,
73
+ borderBottomColor,
74
+ borderTopWidth,
75
+ borderTopColor,
76
+ borderLeftWidth,
77
+ borderLeftColor,
78
+ borderRightWidth,
79
+ borderRightColor,
80
+ borderRadius,
81
+ borderStyle,
82
+ overflow,
83
+ zIndex,
84
+ height,
85
+ width,
86
+ minWidth,
87
+ minHeight,
88
+ maxWidth,
89
+ maxHeight,
90
+ padding,
91
+ paddingHorizontal,
92
+ paddingVertical,
93
+ margin,
94
+ marginTop,
95
+ marginBottom,
96
+ marginLeft,
97
+ marginRight,
98
+ flexDirection,
99
+ alignItems,
100
+ justifyContent,
101
+ position,
102
+ top,
103
+ bottom,
104
+ left,
105
+ right,
106
+ flex,
107
+ ...style
108
+ });
109
+ const finalTestID = dataTestId || testID;
110
+ const {
111
+ role,
112
+ tabIndex,
113
+ onKeyDown,
114
+ onKeyUp,
115
+ "aria-label": _ariaLabel,
116
+ "aria-labelledby": _ariaLabelledBy,
117
+ "aria-current": _ariaCurrent,
118
+ "aria-disabled": _ariaDisabled,
119
+ "aria-live": _ariaLive,
120
+ className,
121
+ "data-testid": _dataTestId,
122
+ ...nativeRest
123
+ } = rest;
124
+ if (as === "img" && src) {
125
+ const imageStyle = {
126
+ width,
127
+ height,
128
+ borderRadius,
129
+ position,
130
+ top,
131
+ bottom,
132
+ left,
133
+ right,
134
+ ...style
135
+ };
136
+ return /* @__PURE__ */ jsx(
137
+ Image,
138
+ {
139
+ source: { uri: src },
140
+ style: imageStyle,
141
+ testID: finalTestID,
142
+ resizeMode: "cover",
143
+ ...nativeRest
144
+ }
145
+ );
146
+ }
147
+ if (onPress) {
148
+ return /* @__PURE__ */ jsx(
149
+ Pressable,
150
+ {
151
+ onPress,
152
+ onLayout,
153
+ onMoveShouldSetResponder,
154
+ onResponderGrant,
155
+ onResponderMove,
156
+ onResponderRelease,
157
+ onResponderTerminate,
158
+ style: ({ pressed }) => getContainerStyle(pressed),
159
+ testID: finalTestID,
160
+ ...nativeRest,
161
+ children
162
+ }
163
+ );
164
+ }
165
+ return /* @__PURE__ */ jsx(
166
+ View,
167
+ {
168
+ style: getContainerStyle(),
169
+ testID: finalTestID,
170
+ onLayout,
171
+ onMoveShouldSetResponder,
172
+ onResponderGrant,
173
+ onResponderMove,
174
+ onResponderRelease,
175
+ onResponderTerminate,
176
+ ...nativeRest,
177
+ children
178
+ }
179
+ );
180
+ };
181
+
182
+ // ../../foundation/primitives-native/src/Text.tsx
183
+ import {
184
+ Text as RNText,
185
+ StyleSheet
186
+ } from "react-native";
187
+ import { jsx as jsx2 } from "react/jsx-runtime";
188
+ var roleMap = {
189
+ alert: "alert",
190
+ heading: "header",
191
+ button: "button",
192
+ link: "link",
193
+ text: "text"
194
+ };
195
+ var parseNumericValue = (value) => {
196
+ if (value === void 0) return void 0;
197
+ if (typeof value === "number") return value;
198
+ const parsed = parseFloat(value);
199
+ return isNaN(parsed) ? void 0 : parsed;
200
+ };
201
+ var Text = ({
202
+ children,
203
+ color,
204
+ fontSize,
205
+ fontWeight,
206
+ fontFamily,
207
+ textAlign,
208
+ lineHeight,
209
+ numberOfLines,
210
+ id,
211
+ role,
212
+ style: styleProp,
213
+ ...props
214
+ }) => {
215
+ let resolvedFontFamily = fontFamily ? fontFamily.split(",")[0].replace(/['"]/g, "").trim() : void 0;
216
+ if (resolvedFontFamily === "Pilat Wide" || resolvedFontFamily === "Pilat Wide Bold" || resolvedFontFamily === "Aktiv Grotesk") {
217
+ resolvedFontFamily = void 0;
218
+ }
219
+ const incomingStyle = StyleSheet.flatten(styleProp);
220
+ const baseStyle = {
221
+ color: color ?? incomingStyle?.color,
222
+ fontSize: typeof fontSize === "number" ? fontSize : void 0,
223
+ fontWeight,
224
+ fontFamily: resolvedFontFamily,
225
+ textDecorationLine: props.textDecoration,
226
+ textAlign: textAlign ?? incomingStyle?.textAlign,
227
+ lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),
228
+ marginTop: parseNumericValue(
229
+ incomingStyle?.marginTop
230
+ ),
231
+ marginBottom: parseNumericValue(
232
+ incomingStyle?.marginBottom
233
+ )
234
+ };
235
+ const accessibilityRole = role ? roleMap[role] : void 0;
236
+ return /* @__PURE__ */ jsx2(
237
+ RNText,
238
+ {
239
+ style: baseStyle,
240
+ numberOfLines,
241
+ testID: id,
242
+ accessibilityRole,
243
+ children
244
+ }
245
+ );
246
+ };
247
+
248
+ // ../../foundation/primitives-native/src/Icon.tsx
249
+ import React from "react";
250
+ import { View as View2 } from "react-native";
251
+ import { jsx as jsx3 } from "react/jsx-runtime";
252
+ var Icon = ({ children, color, size }) => {
253
+ const style = {
254
+ width: typeof size === "number" ? size : void 0,
255
+ height: typeof size === "number" ? size : void 0,
256
+ alignItems: "center",
257
+ justifyContent: "center"
258
+ };
259
+ const childrenWithProps = React.Children.map(children, (child) => {
260
+ if (React.isValidElement(child)) {
261
+ return React.cloneElement(child, {
262
+ color: child.props.color || color,
263
+ // Also pass size if child seems to be an icon that needs it
264
+ size: child.props.size || size
265
+ });
266
+ }
267
+ return child;
268
+ });
269
+ return /* @__PURE__ */ jsx3(View2, { style, children: childrenWithProps });
270
+ };
271
+
272
+ // src/Collapsible.tsx
273
+ import { useResolvedTheme } from "@xsolla/xui-core";
274
+ import { ChevronDown } from "@xsolla/xui-icons-base";
275
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
276
+ var PANEL_TRANSITION = "grid-template-rows 280ms cubic-bezier(0.4, 0, 0.2, 1)";
277
+ var CHEVRON_TRANSITION = "transform 280ms cubic-bezier(0.4, 0, 0.2, 1)";
278
+ var Collapsible = forwardRef(
279
+ ({
280
+ title,
281
+ caption: captionProp,
282
+ icon,
283
+ trailing: trailingProp,
284
+ view = "without-surface",
285
+ open: openProp,
286
+ defaultOpen = false,
287
+ onOpenChange,
288
+ children,
289
+ className,
290
+ "aria-label": ariaLabel,
291
+ themeMode,
292
+ themeProductContext,
293
+ // deprecated aliases
294
+ onChange,
295
+ statusIcon,
296
+ description,
297
+ ...rest
298
+ }, ref) => {
299
+ const caption = captionProp ?? description;
300
+ const trailing = trailingProp ?? statusIcon;
301
+ const resolvedOnOpenChange = onOpenChange ?? onChange;
302
+ const panelIdRef = useRef();
303
+ if (!panelIdRef.current) {
304
+ panelIdRef.current = `collapsible-panel-${Math.random().toString(36).slice(2, 10)}`;
305
+ }
306
+ const panelId = panelIdRef.current;
307
+ const { theme } = useResolvedTheme({ themeMode, themeProductContext });
308
+ const sizing = theme.sizing.collapsibleB2b();
309
+ const isControlled = openProp !== void 0;
310
+ const [openState, setOpenState] = useState(defaultOpen);
311
+ const open = isControlled ? openProp : openState;
312
+ const handleToggle = useCallback(() => {
313
+ const next = !open;
314
+ if (!isControlled) setOpenState(next);
315
+ resolvedOnOpenChange?.(next);
316
+ }, [open, isControlled, resolvedOnOpenChange]);
317
+ const handleKeyDown = useCallback(
318
+ (e) => {
319
+ if (e.key === "Enter") {
320
+ e.preventDefault();
321
+ handleToggle();
322
+ } else if (e.key === " ") {
323
+ e.preventDefault();
324
+ }
325
+ },
326
+ [handleToggle]
327
+ );
328
+ const handleKeyUp = useCallback(
329
+ (e) => {
330
+ if (e.key === " ") {
331
+ e.preventDefault();
332
+ handleToggle();
333
+ }
334
+ },
335
+ [handleToggle]
336
+ );
337
+ const isWhite = view === "white-surface";
338
+ const isGrey = view === "grey-surface";
339
+ const isWithout = view === "without-surface";
340
+ const rootStyle = {
341
+ boxSizing: "border-box",
342
+ display: "flex",
343
+ flexDirection: "column",
344
+ overflow: "hidden",
345
+ backgroundColor: isWhite ? theme.colors.background.primary : isGrey ? theme.colors.overlay.mono : void 0,
346
+ borderRadius: !isWithout ? sizing.surfaceRadius : void 0,
347
+ borderBottom: isWithout ? `1px solid ${theme.colors.border.secondary}` : void 0
348
+ };
349
+ const cellStyle = {
350
+ boxSizing: "border-box",
351
+ display: "flex",
352
+ flexDirection: "row",
353
+ alignItems: "center",
354
+ gap: sizing.triggerGap,
355
+ width: "100%",
356
+ minHeight: isWithout ? sizing.triggerMinHeight : void 0,
357
+ padding: !isWithout ? sizing.triggerPadding : 0,
358
+ backgroundColor: isWhite ? theme.colors.background.primary : isGrey ? theme.colors.overlay.mono : void 0,
359
+ borderRadius: !isWithout ? open ? `${sizing.cellRadius}px ${sizing.cellRadius}px 0 0` : sizing.cellRadius : void 0,
360
+ borderBottom: open ? `1px solid ${theme.colors.border.secondary}` : void 0
361
+ };
362
+ const panelGridStyle = {
363
+ display: "grid",
364
+ gridTemplateRows: open ? "1fr" : "0fr",
365
+ transition: PANEL_TRANSITION,
366
+ width: "100%"
367
+ };
368
+ const panelInnerStyle = {
369
+ overflow: "hidden"
370
+ };
371
+ const panelContentStyle = {
372
+ boxSizing: "border-box",
373
+ width: "100%",
374
+ padding: sizing.panelPadding
375
+ };
376
+ return /* @__PURE__ */ jsxs(
377
+ Box,
378
+ {
379
+ ref,
380
+ "data-testid": "collapsible",
381
+ "data-open": open,
382
+ className,
383
+ width: "100%",
384
+ style: rootStyle,
385
+ ...rest,
386
+ children: [
387
+ /* @__PURE__ */ jsx4(
388
+ "div",
389
+ {
390
+ role: "button",
391
+ tabIndex: 0,
392
+ "aria-expanded": open,
393
+ "aria-controls": panelId,
394
+ "aria-label": ariaLabel ?? (typeof title === "string" ? title : void 0),
395
+ onClick: handleToggle,
396
+ onKeyDown: handleKeyDown,
397
+ onKeyUp: handleKeyUp,
398
+ style: { boxSizing: "border-box", width: "100%", cursor: "pointer" },
399
+ children: /* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
400
+ icon && /* @__PURE__ */ jsx4(
401
+ "div",
402
+ {
403
+ onClick: (e) => e.stopPropagation(),
404
+ onKeyDown: (e) => e.stopPropagation(),
405
+ onKeyUp: (e) => e.stopPropagation(),
406
+ style: { flexShrink: 0, display: "flex", alignItems: "center" },
407
+ children: icon
408
+ }
409
+ ),
410
+ /* @__PURE__ */ jsxs(
411
+ "div",
412
+ {
413
+ style: {
414
+ flex: 1,
415
+ display: "flex",
416
+ flexDirection: "column",
417
+ alignItems: "flex-start",
418
+ gap: sizing.textGap,
419
+ minWidth: 0
420
+ },
421
+ children: [
422
+ typeof title === "string" || typeof title === "number" ? /* @__PURE__ */ jsx4(
423
+ Text,
424
+ {
425
+ color: theme.colors.content.primary,
426
+ fontSize: sizing.titleFontSize,
427
+ lineHeight: sizing.titleLineHeight,
428
+ fontWeight: "500",
429
+ children: title
430
+ }
431
+ ) : title,
432
+ caption !== void 0 && (typeof caption === "string" || typeof caption === "number" ? /* @__PURE__ */ jsx4(
433
+ Text,
434
+ {
435
+ color: theme.colors.content.tertiary,
436
+ fontSize: sizing.captionFontSize,
437
+ lineHeight: sizing.captionLineHeight,
438
+ fontWeight: "400",
439
+ children: caption
440
+ }
441
+ ) : caption)
442
+ ]
443
+ }
444
+ ),
445
+ /* @__PURE__ */ jsxs(
446
+ "div",
447
+ {
448
+ style: {
449
+ display: "flex",
450
+ flexDirection: "row",
451
+ alignItems: "center",
452
+ gap: sizing.trailingGap,
453
+ flexShrink: 0
454
+ },
455
+ children: [
456
+ trailing && /* @__PURE__ */ jsx4(
457
+ "div",
458
+ {
459
+ onClick: (e) => e.stopPropagation(),
460
+ onKeyDown: (e) => e.stopPropagation(),
461
+ onKeyUp: (e) => e.stopPropagation(),
462
+ style: { display: "flex", alignItems: "center" },
463
+ children: trailing
464
+ }
465
+ ),
466
+ /* @__PURE__ */ jsx4(
467
+ "div",
468
+ {
469
+ style: {
470
+ transform: open ? "rotate(180deg)" : "rotate(0deg)",
471
+ transition: CHEVRON_TRANSITION,
472
+ display: "flex",
473
+ alignItems: "center"
474
+ },
475
+ children: /* @__PURE__ */ jsx4(
476
+ Icon,
477
+ {
478
+ color: theme.colors.content.primary,
479
+ size: sizing.chevronSize,
480
+ children: /* @__PURE__ */ jsx4(ChevronDown, {})
481
+ }
482
+ )
483
+ }
484
+ )
485
+ ]
486
+ }
487
+ )
488
+ ] })
489
+ }
490
+ ),
491
+ /* @__PURE__ */ jsx4("div", { id: panelId, style: panelGridStyle, children: /* @__PURE__ */ jsx4("div", { style: panelInnerStyle, children: /* @__PURE__ */ jsx4("div", { style: panelContentStyle, children }) }) })
492
+ ]
493
+ }
494
+ );
495
+ }
496
+ );
497
+ Collapsible.displayName = "Collapsible";
498
+ export {
499
+ Collapsible
500
+ };
501
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/Collapsible.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx"],"sourcesContent":["import { forwardRef, useState, useCallback, useRef } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport { ChevronDown, ChevronUp } from \"@xsolla/xui-icons-base\";\nimport type { CollapsibleProps } from \"./types\";\n\nconst PANEL_TRANSITION =\n \"grid-template-rows 280ms cubic-bezier(0.4, 0, 0.2, 1)\";\nconst CHEVRON_TRANSITION = \"transform 280ms cubic-bezier(0.4, 0, 0.2, 1)\";\n\nexport const Collapsible = forwardRef<HTMLDivElement, CollapsibleProps>(\n (\n {\n title,\n caption: captionProp,\n icon,\n trailing: trailingProp,\n view = \"without-surface\",\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n children,\n className,\n \"aria-label\": ariaLabel,\n themeMode,\n themeProductContext,\n // deprecated aliases\n onChange,\n statusIcon,\n description,\n ...rest\n },\n ref\n ) => {\n const caption = captionProp ?? description;\n const trailing = trailingProp ?? statusIcon;\n const resolvedOnOpenChange = onOpenChange ?? onChange;\n\n // Stable panel ID — React 16 compatible (no useId)\n const panelIdRef = useRef<string>();\n if (!panelIdRef.current) {\n panelIdRef.current = `collapsible-panel-${Math.random().toString(36).slice(2, 10)}`;\n }\n const panelId = panelIdRef.current;\n\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.collapsibleB2b();\n\n const isControlled = openProp !== undefined;\n const [openState, setOpenState] = useState(defaultOpen);\n const open = isControlled ? openProp! : openState;\n\n const handleToggle = useCallback(() => {\n const next = !open;\n if (!isControlled) setOpenState(next);\n resolvedOnOpenChange?.(next);\n }, [open, isControlled, resolvedOnOpenChange]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleToggle();\n } else if (e.key === \" \") {\n e.preventDefault();\n }\n },\n [handleToggle]\n );\n\n const handleKeyUp = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \" \") {\n e.preventDefault();\n handleToggle();\n }\n },\n [handleToggle]\n );\n\n const isWhite = view === \"white-surface\";\n const isGrey = view === \"grey-surface\";\n const isWithout = view === \"without-surface\";\n\n // Root is always column — avoids flex-direction flip that breaks width\n const rootStyle: React.CSSProperties = {\n boxSizing: \"border-box\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n backgroundColor: isWhite\n ? theme.colors.background.primary\n : isGrey\n ? theme.colors.overlay.mono\n : undefined,\n borderRadius: !isWithout ? sizing.surfaceRadius : undefined,\n borderBottom: isWithout\n ? `1px solid ${theme.colors.border.secondary}`\n : undefined,\n };\n\n const cellStyle: React.CSSProperties = {\n boxSizing: \"border-box\",\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: sizing.triggerGap,\n width: \"100%\",\n minHeight: isWithout ? sizing.triggerMinHeight : undefined,\n padding: !isWithout ? sizing.triggerPadding : 0,\n backgroundColor: isWhite\n ? theme.colors.background.primary\n : isGrey\n ? theme.colors.overlay.mono\n : undefined,\n borderRadius: !isWithout\n ? open\n ? `${sizing.cellRadius}px ${sizing.cellRadius}px 0 0`\n : sizing.cellRadius\n : undefined,\n borderBottom: open\n ? `1px solid ${theme.colors.border.secondary}`\n : undefined,\n };\n\n // grid-template-rows trick: 0fr (collapsed) ↔ 1fr (expanded)\n // The inner div has overflow:hidden so content is clipped during transition\n const panelGridStyle: React.CSSProperties = {\n display: \"grid\",\n gridTemplateRows: open ? \"1fr\" : \"0fr\",\n transition: PANEL_TRANSITION,\n width: \"100%\",\n };\n\n const panelInnerStyle: React.CSSProperties = {\n overflow: \"hidden\",\n };\n\n const panelContentStyle: React.CSSProperties = {\n boxSizing: \"border-box\",\n width: \"100%\",\n padding: sizing.panelPadding,\n };\n\n return (\n <Box\n ref={ref}\n data-testid=\"collapsible\"\n data-open={open}\n className={className}\n width=\"100%\"\n style={rootStyle}\n {...rest}\n >\n {/* Trigger */}\n <div\n role=\"button\"\n tabIndex={0}\n aria-expanded={open}\n aria-controls={panelId}\n aria-label={\n ariaLabel ?? (typeof title === \"string\" ? title : undefined)\n }\n onClick={handleToggle}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n style={{ boxSizing: \"border-box\", width: \"100%\", cursor: \"pointer\" }}\n >\n <div style={cellStyle}>\n {/* Left icon slot — consumer is responsible for icon/checkbox styling */}\n {icon && (\n <div\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n onKeyUp={(e) => e.stopPropagation()}\n style={{ flexShrink: 0, display: \"flex\", alignItems: \"center\" }}\n >\n {icon}\n </div>\n )}\n\n {/* Title + caption */}\n <div\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n gap: sizing.textGap,\n minWidth: 0,\n }}\n >\n {typeof title === \"string\" || typeof title === \"number\" ? (\n <Text\n color={theme.colors.content.primary}\n fontSize={sizing.titleFontSize}\n lineHeight={sizing.titleLineHeight}\n fontWeight=\"500\"\n >\n {title}\n </Text>\n ) : (\n title\n )}\n {caption !== undefined &&\n (typeof caption === \"string\" || typeof caption === \"number\" ? (\n <Text\n color={theme.colors.content.tertiary}\n fontSize={sizing.captionFontSize}\n lineHeight={sizing.captionLineHeight}\n fontWeight=\"400\"\n >\n {caption}\n </Text>\n ) : (\n caption\n ))}\n </div>\n\n {/* Trailing slot + animated chevron */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: sizing.trailingGap,\n flexShrink: 0,\n }}\n >\n {trailing && (\n <div\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n onKeyUp={(e) => e.stopPropagation()}\n style={{ display: \"flex\", alignItems: \"center\" }}\n >\n {trailing}\n </div>\n )}\n <div\n style={{\n transform: open ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: CHEVRON_TRANSITION,\n display: \"flex\",\n alignItems: \"center\",\n }}\n >\n <Icon\n color={theme.colors.content.primary}\n size={sizing.chevronSize}\n >\n <ChevronDown />\n </Icon>\n </div>\n </div>\n </div>\n </div>\n\n {/* Animated panel using grid-template-rows trick */}\n <div id={panelId} style={panelGridStyle}>\n <div style={panelInnerStyle}>\n <div style={panelContentStyle}>{children}</div>\n </div>\n </div>\n </Box>\n );\n }\n);\n\nCollapsible.displayName = \"Collapsible\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({ children, color, size }) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return <View style={style}>{childrenWithProps}</View>;\n};\n"],"mappings":"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","names":["jsx","View","jsx","jsx"]}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@xsolla/xui-b2b-collapsible",
3
+ "version": "0.147.1",
4
+ "main": "./web/index.js",
5
+ "module": "./web/index.mjs",
6
+ "types": "./web/index.d.ts",
7
+ "scripts": {
8
+ "build": "yarn build:web && yarn build:native",
9
+ "build:web": "PLATFORM=web tsup",
10
+ "build:native": "PLATFORM=native tsup",
11
+ "test": "vitest",
12
+ "test:run": "vitest run",
13
+ "test:coverage": "vitest run --coverage"
14
+ },
15
+ "dependencies": {
16
+ "@xsolla/xui-core": "0.147.1",
17
+ "@xsolla/xui-icons-base": "0.147.1",
18
+ "@xsolla/xui-primitives-core": "0.147.1"
19
+ },
20
+ "peerDependencies": {
21
+ "react": ">=16.8.0",
22
+ "styled-components": ">=4"
23
+ },
24
+ "devDependencies": {
25
+ "@testing-library/jest-dom": "^6.9.1",
26
+ "@testing-library/react": "^14.1.2",
27
+ "@vitest/coverage-v8": "^4.0.18",
28
+ "jsdom": "^24.0.0",
29
+ "react": "^18.0.0",
30
+ "react-dom": "^18.0.0",
31
+ "tsup": "^8.0.0",
32
+ "vitest": "^4.0.18"
33
+ },
34
+ "license": "MIT",
35
+ "sideEffects": false,
36
+ "react-native": "./native/index.js",
37
+ "exports": {
38
+ ".": {
39
+ "react-native": {
40
+ "types": "./native/index.d.ts",
41
+ "import": "./native/index.mjs",
42
+ "require": "./native/index.js"
43
+ },
44
+ "import": {
45
+ "types": "./web/index.d.ts",
46
+ "default": "./web/index.mjs"
47
+ },
48
+ "require": {
49
+ "types": "./web/index.d.ts",
50
+ "default": "./web/index.js"
51
+ },
52
+ "default": {
53
+ "types": "./web/index.d.ts",
54
+ "default": "./web/index.js"
55
+ }
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,32 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { ThemeOverrideProps } from '@xsolla/xui-core';
4
+
5
+ type CollapsibleView = "without-surface" | "white-surface" | "grey-surface";
6
+ interface CollapsibleProps extends ThemeOverrideProps {
7
+ title: ReactNode;
8
+ caption?: ReactNode;
9
+ /** Optional icon shown in a 32×32 slot at the left of the trigger. */
10
+ icon?: ReactNode;
11
+ /** Optional content shown to the right of the text, before the chevron. */
12
+ trailing?: ReactNode;
13
+ view?: CollapsibleView;
14
+ /** Controlled open state. */
15
+ open?: boolean;
16
+ /** Initial open state for uncontrolled usage. */
17
+ defaultOpen?: boolean;
18
+ onOpenChange?: (open: boolean) => void;
19
+ children: ReactNode;
20
+ className?: string;
21
+ "aria-label"?: string;
22
+ /** @deprecated Use `onOpenChange` instead. */
23
+ onChange?: (isOpen: boolean) => void;
24
+ /** @deprecated Use `trailing` instead. */
25
+ statusIcon?: ReactNode;
26
+ /** @deprecated Use `caption` instead. */
27
+ description?: string;
28
+ }
29
+
30
+ declare const Collapsible: react.ForwardRefExoticComponent<CollapsibleProps & react.RefAttributes<HTMLDivElement>>;
31
+
32
+ export { Collapsible, type CollapsibleProps, type CollapsibleView };
package/web/index.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { ThemeOverrideProps } from '@xsolla/xui-core';
4
+
5
+ type CollapsibleView = "without-surface" | "white-surface" | "grey-surface";
6
+ interface CollapsibleProps extends ThemeOverrideProps {
7
+ title: ReactNode;
8
+ caption?: ReactNode;
9
+ /** Optional icon shown in a 32×32 slot at the left of the trigger. */
10
+ icon?: ReactNode;
11
+ /** Optional content shown to the right of the text, before the chevron. */
12
+ trailing?: ReactNode;
13
+ view?: CollapsibleView;
14
+ /** Controlled open state. */
15
+ open?: boolean;
16
+ /** Initial open state for uncontrolled usage. */
17
+ defaultOpen?: boolean;
18
+ onOpenChange?: (open: boolean) => void;
19
+ children: ReactNode;
20
+ className?: string;
21
+ "aria-label"?: string;
22
+ /** @deprecated Use `onOpenChange` instead. */
23
+ onChange?: (isOpen: boolean) => void;
24
+ /** @deprecated Use `trailing` instead. */
25
+ statusIcon?: ReactNode;
26
+ /** @deprecated Use `caption` instead. */
27
+ description?: string;
28
+ }
29
+
30
+ declare const Collapsible: react.ForwardRefExoticComponent<CollapsibleProps & react.RefAttributes<HTMLDivElement>>;
31
+
32
+ export { Collapsible, type CollapsibleProps, type CollapsibleView };