@xsolla/xui-b2b-collapsible 0.218.1 → 0.220.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -35,12 +35,12 @@ import { Collapsible } from "@xsolla/xui-b2b-collapsible";
35
35
  | Prop | Type | Default | Description |
36
36
  | -------------- | ------------------------------------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
37
37
  | `testID` | `string` | — | Test ID for testing frameworks. On web this renders as `data-testid`; on React Native it renders as `testID`. |
38
- | `title` | `ReactNode` | — | Required. Title text or node in the trigger row. |
38
+ | `title` | `ReactNode` | — | Required. Title text or node in the trigger row. In the `button` view this is the FlexButton label. |
39
39
  | `children` | `ReactNode` | — | Required. Body content shown when expanded. |
40
40
  | `view` | `CollapsibleView` | `"without-surface"` | Visual surface style. |
41
- | `caption` | `ReactNode` | — | Secondary text rendered below the title. |
42
- | `icon` | `ReactNode` | — | Optional 32×32 left slot. Consumer controls styling — wrap with `IconWrapper` or pass a `Checkbox`. Click events on this slot are stopped before they reach the trigger. |
43
- | `trailing` | `ReactNode` | — | Content to the right of the text, before the chevron (e.g. `Status`). |
41
+ | `caption` | `ReactNode` | — | Secondary text rendered below the title. Not rendered in the `button` view. |
42
+ | `icon` | `ReactNode` | — | Optional 32×32 left slot. Consumer controls styling — wrap with `IconWrapper` or pass a `Checkbox`. Click events on this slot are stopped before they reach the trigger. In the `button` view it maps to FlexButton's `iconLeft` and must be a decorative icon, not an interactive control. |
43
+ | `trailing` | `ReactNode` | — | Content to the right of the text, before the chevron (e.g. `Status`). Not rendered in the `button` view. |
44
44
  | `chevronIcon` | `ReactNode \| ((open: boolean) => ReactNode)` | — | Replaces the built-in chevron. Custom icons are rendered as-is — the 180° rotation is not applied. Use the function form to render a different icon per open state. |
45
45
  | `hideChevron` | `boolean` | `false` | Renders the trigger with no chevron at all. Takes precedence over `chevronIcon`. The row still toggles on click and keyboard. |
46
46
  | `defaultOpen` | `boolean` | `false` | Initial open state for uncontrolled usage. |
@@ -54,30 +54,61 @@ Inherits `ThemeOverrideProps` (`themeMode`, `themeProductContext`).
54
54
  ### `CollapsibleView`
55
55
 
56
56
  ```ts
57
- type CollapsibleView = "without-surface" | "white-surface" | "grey-surface";
57
+ type CollapsibleView =
58
+ | "without-surface"
59
+ | "white-surface"
60
+ | "grey-surface"
61
+ | "button";
58
62
  ```
59
63
 
60
- | Value | Appearance |
61
- | ----------------- | ---------------------------------------------- |
62
- | `without-surface` | No background; bottom border divider. |
63
- | `white-surface` | White card with rounded corners. |
64
- | `grey-surface` | Tinted overlay-mono card with rounded corners. |
64
+ | Value | Appearance |
65
+ | ----------------- | ---------------------------------------------------------------------------------- |
66
+ | `without-surface` | No background; bottom border divider. |
67
+ | `white-surface` | White card with rounded corners. |
68
+ | `grey-surface` | Tinted overlay-mono card with rounded corners. |
69
+ | `button` | Trigger is a real `FlexButton`: content-width, no background, no divider. |
65
70
 
66
- ### Deprecated props
71
+ ## The `button` view
67
72
 
68
- The following are still accepted for migration from `@xsolla/publisher-account-core` and trigger an IDE `@deprecated` warning:
73
+ `view="button"` renders the trigger as an actual
74
+ [`FlexButton`](./button.md) from `@xsolla/xui-button` — not a lookalike — so its
75
+ typography, colour, and hover / focus / active / disabled treatments come from
76
+ the button component itself and cannot drift from it.
69
77
 
70
- | Deprecated | Replacement | Notes |
71
- | ------------- | -------------- | ------------------------------------------- |
72
- | `onChange` | `onOpenChange` | Same `(isOpen: boolean) => void` signature. |
73
- | `statusIcon` | `trailing` | Same shape. |
74
- | `description` | `caption` | Covers the legacy `lg`-size `description`. |
78
+ The button is configured as `variant="brand" size="sm" background={false}`,
79
+ which is the design-system spec for this trigger (Figma: Palette=Brand, Size=S,
80
+ Background=False). The chevron rides FlexButton's `iconRight` slot, so it
81
+ inherits the button's icon size and text colour, and still rotates 180° on open.
75
82
 
76
- Props with no equivalent (intentional redesign): `backgroundColor`, `size`, `childContentPadding`, `label` (sm size), `openingState` (use `open` / `defaultOpen`).
83
+ Use it for "Show details" / "Show guide" style toggles where a bordered,
84
+ full-width title row is visually too heavy.
85
+
86
+ ```tsx
87
+ import { Collapsible } from "@xsolla/xui-b2b-collapsible";
88
+
89
+ <Collapsible title="Using additional parameters in the URL" view="button">
90
+ <p>Content</p>
91
+ </Collapsible>;
92
+ ```
93
+
94
+ Differences from the other views:
95
+
96
+ - The trigger is **content-width**, not full width — the root aligns it to the
97
+ start so it sits inline with surrounding copy.
98
+ - There is **no background and no divider** in any state.
99
+ - The trigger renders a native `<button>` rather than a `div[role="button"]`, so
100
+ keyboard activation and focus come from `FlexButton`.
101
+ - `caption` and `trailing` are **not rendered** — a FlexButton has no caption row
102
+ or trailing slot. Use `white-surface` / `grey-surface` when you need them.
103
+ - `icon` maps to FlexButton's `iconLeft`, so it must be a decorative icon. An
104
+ interactive control (e.g. a `Checkbox`) is not valid inside a `<button>`.
105
+ - The panel keeps its normal padding, matching `without-surface`.
106
+
107
+ `hideChevron` and `chevronIcon` behave exactly as they do in the other views.
77
108
 
78
109
  ## Examples
79
110
 
80
- ### Three view variants
111
+ ### Three surface variants
81
112
 
82
113
  ```tsx
83
114
  import { Collapsible } from "@xsolla/xui-b2b-collapsible";
@@ -95,6 +126,16 @@ import { Collapsible } from "@xsolla/xui-b2b-collapsible";
95
126
  </>;
96
127
  ```
97
128
 
129
+ ### Button trigger
130
+
131
+ ```tsx
132
+ import { Collapsible } from "@xsolla/xui-b2b-collapsible";
133
+
134
+ <Collapsible title="Show details" view="button">
135
+ <p>Content</p>
136
+ </Collapsible>;
137
+ ```
138
+
98
139
  ### Open by default
99
140
 
100
141
  ```tsx
@@ -206,8 +247,9 @@ function ControlledCollapsible() {
206
247
 
207
248
  ## Accessibility
208
249
 
209
- - Trigger has `role="button"`, `tabIndex={0}`, `aria-expanded`, and `aria-controls` linking to the panel.
210
- - Responds to Enter and Space; the `icon` and `trailing` slots stop click/keyboard events so embedded controls do not toggle the trigger.
250
+ - Trigger has `aria-expanded` and `aria-controls` linking to the panel in every view.
251
+ - In `without-surface` / `white-surface` / `grey-surface` the trigger is a `div` with `role="button"` and `tabIndex={0}`, and responds to Enter and Space; the `icon` and `trailing` slots stop click/keyboard events so embedded controls do not toggle the trigger.
252
+ - In the `button` view the trigger is a native `<button>` rendered by `FlexButton`, so focus and Enter/Space activation come from the platform and the component adds no handlers of its own. The root does not clip overflow in this view, so the browser's `:focus-visible` ring is not cut off.
211
253
  - Panel content is always in the DOM (hidden via `grid-template-rows: 0fr`) for screen-reader access.
212
254
  - `hideChevron` removes the visual affordance only — `aria-expanded` and keyboard toggling are unchanged. Prefer keeping some visible affordance where the row is the only expand control.
213
255
 
@@ -245,3 +287,15 @@ import { Collapsible } from "@xsolla/xui-b2b-collapsible";
245
287
  content
246
288
  </Collapsible>;
247
289
  ```
290
+
291
+ ### Deprecated props
292
+
293
+ The following are still accepted for migration from `@xsolla/publisher-account-core` and trigger an IDE `@deprecated` warning:
294
+
295
+ | Deprecated | Replacement | Notes |
296
+ | ------------- | -------------- | ------------------------------------------- |
297
+ | `onChange` | `onOpenChange` | Same `(isOpen: boolean) => void` signature. |
298
+ | `statusIcon` | `trailing` | Same shape. |
299
+ | `description` | `caption` | Covers the legacy `lg`-size `description`. |
300
+
301
+ Props with no equivalent (intentional redesign): `backgroundColor`, `size`, `childContentPadding`, `label` (sm size), `openingState` (use `open` / `defaultOpen`).
@@ -2,14 +2,32 @@ import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { ThemeOverrideProps } from '@xsolla/xui-core';
4
4
 
5
- type CollapsibleView = "without-surface" | "white-surface" | "grey-surface";
5
+ type CollapsibleView = "without-surface" | "white-surface" | "grey-surface" | "button";
6
6
  interface CollapsibleProps extends ThemeOverrideProps {
7
7
  title: ReactNode;
8
+ /** Not rendered in the `button` view — a FlexButton has no caption row. */
8
9
  caption?: ReactNode;
9
- /** Optional icon shown in a 32×32 slot at the left of the trigger. */
10
+ /**
11
+ * Optional icon shown in a 32×32 slot at the left of the trigger.
12
+ *
13
+ * In the `button` view this is passed through to FlexButton's `iconLeft`, so
14
+ * it must be a decorative icon — an interactive control (e.g. a `Checkbox`)
15
+ * is not valid inside the native `<button>` that view renders.
16
+ */
10
17
  icon?: ReactNode;
11
- /** Optional content shown to the right of the text, before the chevron. */
18
+ /**
19
+ * Optional content shown to the right of the text, before the chevron.
20
+ * Not rendered in the `button` view.
21
+ */
12
22
  trailing?: ReactNode;
23
+ /**
24
+ * Visual surface style.
25
+ *
26
+ * `button` renders the trigger as a real `FlexButton`
27
+ * (`variant="brand" size="sm" background={false}`) with the chevron in its
28
+ * `iconRight` slot — content-width, no background, no divider — while the
29
+ * panel, open state, and aria wiring stay unchanged.
30
+ */
13
31
  view?: CollapsibleView;
14
32
  /** Controlled open state. */
15
33
  open?: boolean;
package/native/index.d.ts CHANGED
@@ -2,14 +2,32 @@ import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { ThemeOverrideProps } from '@xsolla/xui-core';
4
4
 
5
- type CollapsibleView = "without-surface" | "white-surface" | "grey-surface";
5
+ type CollapsibleView = "without-surface" | "white-surface" | "grey-surface" | "button";
6
6
  interface CollapsibleProps extends ThemeOverrideProps {
7
7
  title: ReactNode;
8
+ /** Not rendered in the `button` view — a FlexButton has no caption row. */
8
9
  caption?: ReactNode;
9
- /** Optional icon shown in a 32×32 slot at the left of the trigger. */
10
+ /**
11
+ * Optional icon shown in a 32×32 slot at the left of the trigger.
12
+ *
13
+ * In the `button` view this is passed through to FlexButton's `iconLeft`, so
14
+ * it must be a decorative icon — an interactive control (e.g. a `Checkbox`)
15
+ * is not valid inside the native `<button>` that view renders.
16
+ */
10
17
  icon?: ReactNode;
11
- /** Optional content shown to the right of the text, before the chevron. */
18
+ /**
19
+ * Optional content shown to the right of the text, before the chevron.
20
+ * Not rendered in the `button` view.
21
+ */
12
22
  trailing?: ReactNode;
23
+ /**
24
+ * Visual surface style.
25
+ *
26
+ * `button` renders the trigger as a real `FlexButton`
27
+ * (`variant="brand" size="sm" background={false}`) with the chevron in its
28
+ * `iconRight` slot — content-width, no background, no divider — while the
29
+ * panel, open state, and aria wiring stay unchanged.
30
+ */
13
31
  view?: CollapsibleView;
14
32
  /** Controlled open state. */
15
33
  open?: boolean;
package/native/index.js CHANGED
@@ -72,6 +72,7 @@ var toGapValue = (gap) => {
72
72
  const asNumber = Number(gap);
73
73
  return Number.isFinite(asNumber) ? asNumber : void 0;
74
74
  };
75
+ var toNativeDisplay = (display) => display === "none" ? "none" : void 0;
75
76
  var Box = ({
76
77
  children,
77
78
  onPress,
@@ -103,6 +104,7 @@ var Box = ({
103
104
  marginBottom,
104
105
  marginLeft,
105
106
  marginRight,
107
+ display,
106
108
  flexDirection,
107
109
  flexWrap,
108
110
  alignItems,
@@ -166,6 +168,7 @@ var Box = ({
166
168
  marginBottom,
167
169
  marginLeft,
168
170
  marginRight,
171
+ display: toNativeDisplay(display),
169
172
  flexDirection,
170
173
  flexWrap,
171
174
  alignItems,
@@ -372,9 +375,17 @@ var Icon = ({
372
375
  // src/Collapsible.tsx
373
376
  var import_xui_core = require("@xsolla/xui-core");
374
377
  var import_xui_icons_base = require("@xsolla/xui-icons-base");
378
+ var import_xui_button = require("@xsolla/xui-button");
375
379
  var import_jsx_runtime4 = require("react/jsx-runtime");
376
380
  var PANEL_TRANSITION = "grid-template-rows 280ms cubic-bezier(0.4, 0, 0.2, 1)";
377
381
  var CHEVRON_TRANSITION = "transform 280ms cubic-bezier(0.4, 0, 0.2, 1)";
382
+ var BUTTON_CHEVRON_SLOT = {
383
+ display: "flex",
384
+ alignItems: "center",
385
+ justifyContent: "center",
386
+ width: "100%",
387
+ height: "100%"
388
+ };
378
389
  var Collapsible = (0, import_react2.forwardRef)(
379
390
  ({
380
391
  title,
@@ -440,13 +451,21 @@ var Collapsible = (0, import_react2.forwardRef)(
440
451
  const isWhite = view === "white-surface";
441
452
  const isGrey = view === "grey-surface";
442
453
  const isWithout = view === "without-surface";
454
+ const isButton = view === "button";
455
+ const hasSurface = isWhite || isGrey;
443
456
  const rootStyle = {
444
457
  boxSizing: "border-box",
445
458
  display: "flex",
446
459
  flexDirection: "column",
447
- overflow: "hidden",
460
+ // The `button` view's trigger is a real FlexButton, which is content-width
461
+ // by contract. Without this the column's default `stretch` would widen it
462
+ // to the root and it would stop looking like a standalone FlexButton.
463
+ alignItems: isButton ? "flex-start" : void 0,
464
+ // `button` has no surface to clip, and clipping would cut the browser's
465
+ // native :focus-visible ring off the trigger.
466
+ overflow: isButton ? "visible" : "hidden",
448
467
  backgroundColor: isWhite ? theme.colors.background.primary : isGrey ? theme.colors.overlay.mono : void 0,
449
- borderRadius: !isWithout ? sizing.surfaceRadius : void 0,
468
+ borderRadius: hasSurface ? sizing.surfaceRadius : void 0,
450
469
  borderBottom: isWithout ? `1px solid ${theme.colors.border.secondary}` : void 0
451
470
  };
452
471
  const cellStyle = {
@@ -457,9 +476,9 @@ var Collapsible = (0, import_react2.forwardRef)(
457
476
  gap: sizing.triggerGap,
458
477
  width: "100%",
459
478
  minHeight: isWithout ? sizing.triggerMinHeight : void 0,
460
- padding: !isWithout ? sizing.triggerPadding : 0,
479
+ padding: hasSurface ? sizing.triggerPadding : 0,
461
480
  backgroundColor: isWhite ? theme.colors.background.primary : isGrey ? theme.colors.overlay.mono : void 0,
462
- borderRadius: !isWithout ? open ? `${sizing.cellRadius}px ${sizing.cellRadius}px 0 0` : sizing.cellRadius : void 0,
481
+ borderRadius: hasSurface ? open ? `${sizing.cellRadius}px ${sizing.cellRadius}px 0 0` : sizing.cellRadius : void 0,
463
482
  borderBottom: open ? `1px solid ${theme.colors.border.secondary}` : void 0
464
483
  };
465
484
  const panelGridStyle = {
@@ -478,6 +497,19 @@ var Collapsible = (0, import_react2.forwardRef)(
478
497
  };
479
498
  const hasCustomChevron = chevronIcon !== void 0 && chevronIcon !== null;
480
499
  const resolvedChevron = hasCustomChevron ? typeof chevronIcon === "function" ? chevronIcon(open) : chevronIcon : null;
500
+ const resolvedAriaLabel = ariaLabel ?? (typeof title === "string" ? title : void 0);
501
+ const buttonChevron = hideChevron ? void 0 : hasCustomChevron ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "data-testid": "collapsible-chevron", style: BUTTON_CHEVRON_SLOT, children: resolvedChevron }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
502
+ "span",
503
+ {
504
+ "data-testid": "collapsible-chevron",
505
+ style: {
506
+ ...BUTTON_CHEVRON_SLOT,
507
+ transform: open ? "rotate(180deg)" : "rotate(0deg)",
508
+ transition: CHEVRON_TRANSITION
509
+ },
510
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_xui_icons_base.ChevronDown, {})
511
+ }
512
+ );
481
513
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
482
514
  Box,
483
515
  {
@@ -489,14 +521,42 @@ var Collapsible = (0, import_react2.forwardRef)(
489
521
  style: rootStyle,
490
522
  ...rest,
491
523
  children: [
492
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
524
+ isButton ? (
525
+ /*
526
+ * The real FlexButton, not a lookalike — typography, colour, and the
527
+ * hover/press/disabled palettes all come from the component itself,
528
+ * so this view cannot drift from `@xsolla/xui-button` (XUITSD-105).
529
+ * `variant="brand"` + `size="sm"` + `background={false}` is the
530
+ * Figma spec (Palette=Brand, Size=S, Background=False).
531
+ *
532
+ * It also renders a native <button>, so Enter/Space activation and
533
+ * focus come from FlexButton and the manual key handlers above are
534
+ * not wired here.
535
+ */
536
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
537
+ import_xui_button.FlexButton,
538
+ {
539
+ variant: "brand",
540
+ size: "sm",
541
+ background: false,
542
+ "aria-expanded": open,
543
+ "aria-controls": panelId,
544
+ "aria-label": resolvedAriaLabel,
545
+ iconLeft: icon,
546
+ iconRight: buttonChevron,
547
+ onPress: handleToggle,
548
+ testID: "collapsible-trigger",
549
+ children: title
550
+ }
551
+ )
552
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
493
553
  "div",
494
554
  {
495
555
  role: "button",
496
556
  tabIndex: 0,
497
557
  "aria-expanded": open,
498
558
  "aria-controls": panelId,
499
- "aria-label": ariaLabel ?? (typeof title === "string" ? title : void 0),
559
+ "aria-label": resolvedAriaLabel,
500
560
  onClick: handleToggle,
501
561
  onKeyDown: handleKeyDown,
502
562
  onKeyUp: handleKeyUp,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../src/Collapsible.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx"],"sourcesContent":["export { Collapsible } from \"./Collapsible\";\nexport type { CollapsibleProps, CollapsibleView } from \"./types\";\n","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 } 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 testID,\n themeMode,\n themeProductContext,\n chevronIcon,\n hideChevron = false,\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 // Chevron slot: hidden entirely via `hideChevron`, replaced via `chevronIcon`\n // (node or `(open) => node`). Custom icons are rendered as-is — the 180°\n // rotation is reserved for the built-in chevron so a replacement icon that\n // is not directionally symmetric (a minus, a plus/minus pair) is not flipped.\n const hasCustomChevron = chevronIcon !== undefined && chevronIcon !== null;\n const resolvedChevron = hasCustomChevron\n ? typeof chevronIcon === \"function\"\n ? chevronIcon(open)\n : chevronIcon\n : null;\n\n return (\n <Box\n ref={ref}\n testID={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 {!hideChevron &&\n (hasCustomChevron ? (\n <div\n data-testid=\"collapsible-chevron\"\n style={{ display: \"flex\", alignItems: \"center\" }}\n >\n {resolvedChevron}\n </div>\n ) : (\n <div\n data-testid=\"collapsible-chevron\"\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 ))}\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 AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\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 flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n opacity,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\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 opacity: opacity ?? (disabled ? 0.5 : undefined),\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 flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\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 flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\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 \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\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 accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\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 accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\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 accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\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 testID,\n \"data-testid\": dataTestId,\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={dataTestId || 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> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\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 (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../src/Collapsible.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx"],"sourcesContent":["export { Collapsible } from \"./Collapsible\";\nexport type { CollapsibleProps, CollapsibleView } from \"./types\";\n","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 } from \"@xsolla/xui-icons-base\";\nimport { FlexButton } from \"@xsolla/xui-button\";\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\n/**\n * Fill style for the `button` view's chevron wrapper.\n *\n * `FlexButton` renders `iconRight` inside its own `<Icon>` frame, which sizes\n * the glyph with `svg { width: 100%; height: 100% }`. The rotation wrapper sits\n * between the two, so it has to fill that frame — otherwise the svg would size\n * against a shrink-to-fit span and collapse.\n */\nconst BUTTON_CHEVRON_SLOT: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"100%\",\n height: \"100%\",\n};\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 testID,\n themeMode,\n themeProductContext,\n chevronIcon,\n hideChevron = false,\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 const isButton = view === \"button\";\n /**\n * Views that paint a card behind the trigger and panel. `without-surface`\n * and `button` both render flush, so neither takes the surface padding,\n * radius, or fill.\n */\n const hasSurface = isWhite || isGrey;\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 // The `button` view's trigger is a real FlexButton, which is content-width\n // by contract. Without this the column's default `stretch` would widen it\n // to the root and it would stop looking like a standalone FlexButton.\n alignItems: isButton ? \"flex-start\" : undefined,\n // `button` has no surface to clip, and clipping would cut the browser's\n // native :focus-visible ring off the trigger.\n overflow: isButton ? \"visible\" : \"hidden\",\n backgroundColor: isWhite\n ? theme.colors.background.primary\n : isGrey\n ? theme.colors.overlay.mono\n : undefined,\n borderRadius: hasSurface ? 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: hasSurface ? sizing.triggerPadding : 0,\n backgroundColor: isWhite\n ? theme.colors.background.primary\n : isGrey\n ? theme.colors.overlay.mono\n : undefined,\n borderRadius: hasSurface\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 // Chevron slot: hidden entirely via `hideChevron`, replaced via `chevronIcon`\n // (node or `(open) => node`). Custom icons are rendered as-is — the 180°\n // rotation is reserved for the built-in chevron so a replacement icon that\n // is not directionally symmetric (a minus, a plus/minus pair) is not flipped.\n const hasCustomChevron = chevronIcon !== undefined && chevronIcon !== null;\n const resolvedChevron = hasCustomChevron\n ? typeof chevronIcon === \"function\"\n ? chevronIcon(open)\n : chevronIcon\n : null;\n\n const resolvedAriaLabel =\n ariaLabel ?? (typeof title === \"string\" ? title : undefined);\n\n // `button` view: the chevron rides FlexButton's own `iconRight` slot, so it\n // inherits the button's icon size and text colour rather than re-deriving\n // them here. Same hideChevron / chevronIcon semantics as the other views.\n const buttonChevron = hideChevron ? undefined : hasCustomChevron ? (\n <span data-testid=\"collapsible-chevron\" style={BUTTON_CHEVRON_SLOT}>\n {resolvedChevron}\n </span>\n ) : (\n <span\n data-testid=\"collapsible-chevron\"\n style={{\n ...BUTTON_CHEVRON_SLOT,\n transform: open ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: CHEVRON_TRANSITION,\n }}\n >\n <ChevronDown />\n </span>\n );\n\n return (\n <Box\n ref={ref}\n testID={testID || \"collapsible\"}\n data-open={open}\n className={className}\n width=\"100%\"\n style={rootStyle}\n {...rest}\n >\n {/* Trigger */}\n {isButton ? (\n /*\n * The real FlexButton, not a lookalike — typography, colour, and the\n * hover/press/disabled palettes all come from the component itself,\n * so this view cannot drift from `@xsolla/xui-button` (XUITSD-105).\n * `variant=\"brand\"` + `size=\"sm\"` + `background={false}` is the\n * Figma spec (Palette=Brand, Size=S, Background=False).\n *\n * It also renders a native <button>, so Enter/Space activation and\n * focus come from FlexButton and the manual key handlers above are\n * not wired here.\n */\n <FlexButton\n variant=\"brand\"\n size=\"sm\"\n background={false}\n aria-expanded={open}\n aria-controls={panelId}\n aria-label={resolvedAriaLabel}\n iconLeft={icon}\n iconRight={buttonChevron}\n onPress={handleToggle}\n testID=\"collapsible-trigger\"\n >\n {title}\n </FlexButton>\n ) : (\n <div\n role=\"button\"\n tabIndex={0}\n aria-expanded={open}\n aria-controls={panelId}\n aria-label={resolvedAriaLabel}\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 {!hideChevron &&\n (hasCustomChevron ? (\n <div\n data-testid=\"collapsible-chevron\"\n style={{ display: \"flex\", alignItems: \"center\" }}\n >\n {resolvedChevron}\n </div>\n ) : (\n <div\n data-testid=\"collapsible-chevron\"\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 ))}\n </div>\n </div>\n </div>\n )}\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 AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\n\n/**\n * Yoga has no inline formatting context, so RN's ViewStyle.display only\n * accepts \"flex\" | \"none\". Every inline-ish web value collapses to a plain\n * flex container — the box already fills only its content on native, which is\n * what those callers wanted on web anyway. Returning undefined (rather than\n * \"flex\") leaves RN's own default in place.\n */\nconst toNativeDisplay = (\n display: BoxProps[\"display\"]\n): ViewStyle[\"display\"] => (display === \"none\" ? \"none\" : undefined);\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 display,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n opacity,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\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 opacity: opacity ?? (disabled ? 0.5 : undefined),\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 display: toNativeDisplay(display),\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\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 flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\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 \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\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 accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\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 accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\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 accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\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 testID,\n \"data-testid\": dataTestId,\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={dataTestId || 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> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\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 (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAA0D;;;ACC1D,0BASO;AAqND;AAlNN,IAAM,0BAA6D;AAAA,EACjE,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,cAAc;AAAA,EACd,aAAa;AAAA,EACb,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,OAAO;AACT;AAGA,IAAM,aAAa,CAAC,QAAyD;AAC3E,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,QAAM,UAAU,sBAAsB,KAAK,GAAG;AAC9C,MAAI,QAAS,QAAO,OAAO,QAAQ,CAAC,CAAC;AACrC,QAAM,WAAW,OAAO,GAAG;AAC3B,SAAO,OAAO,SAAS,QAAQ,IAAI,WAAW;AAChD;AASA,IAAM,kBAAkB,CACtB,YAC0B,YAAY,SAAS,SAAS;AAEnD,IAAM,MAA0B,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,oBAAoB,CAAC,aAAkC;AAAA,IAC3D,iBACE,WAAW,YAAY,kBACnB,WAAW,kBACX;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,YAAY,WAAW,MAAM;AAAA,IACtC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,gBAAgB,OAAO;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,WAAW,GAAG;AAAA,IACnB,GAAI;AAAA,EACN;AAEA,QAAM,cAAc,cAAc;AAKlC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,IACb;AAAA,IACA,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,oBACH,OAAO,SAAS,YAAY,wBAAwB,IAAI,MACxD,OAAO,WAAW,WAAW;AAChC,QAAM,aAAa,QAAQ,YAAY,YAAY;AACnD,QAAM,qBAAqB;AAAA,IACzB,UAAU,cAAc;AAAA,IACxB,MAAM,QAAQ,QAAQ,KAAK;AAAA,EAC7B;AACA,QAAM,0BACJ,aAAa,YAAY,aAAa,cAAc,WAAW;AAGjE,MAAI,OAAO,SAAS,KAAK;AACvB,UAAM,aAAyB;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI;AAAA,IACN;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ,EAAE,KAAK,IAAI;AAAA,QACnB,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,oBAAoB,OAAO,cAAc,WAAW,YAAY;AAAA,QAChE,YAAW;AAAA,QACV,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AAIA,MAAI,WAAW,OAAO,UAAU;AAC9B,WACE;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,CAAC,cAAc,UAAU,UAAU;AAAA,QAC5C,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,CAAC,EAAE,QAAQ,MAAM,kBAAkB,OAAO;AAAA,QACjD,QAAQ;AAAA,QACR;AAAA,QACA,oBACE,OAAO,cAAc,WAAW,YAAY;AAAA,QAE9C;AAAA,QACA;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,kBAAkB;AAAA,MACzB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,oBAAoB,OAAO,cAAc,WAAW,YAAY;AAAA,MAChE;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;;;ACxRA,IAAAC,uBAKO;AAqEH,IAAAC,sBAAA;AAlEJ,IAAM,UAA6C;AAAA,EACjD,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,MAAM;AACR;AAEA,IAAM,oBAAoB,CACxB,UACuB;AACvB,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,SAAS,WAAW,KAAK;AAC/B,SAAO,MAAM,MAAM,IAAI,SAAY;AACrC;AAEO,IAAM,OAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,OAAO;AAAA,EACP,GAAG;AACL,MAAM;AACJ,MAAI,qBAAqB,aACrB,WAAW,MAAM,GAAG,EAAE,CAAC,EAAE,QAAQ,SAAS,EAAE,EAAE,KAAK,IACnD;AAEJ,MACE,uBAAuB,gBACvB,uBAAuB,qBACvB,uBAAuB,iBACvB;AACA,yBAAqB;AAAA,EACvB;AAEA,QAAM,gBAAgB,gCAAW,QAAQ,SAAS;AAElD,QAAM,YAAuB;AAAA,IAC3B,OAAO,SAAS,eAAe;AAAA,IAC/B,UAAU,OAAO,aAAa,WAAW,WAAW;AAAA,IACpD;AAAA,IACA,YAAY;AAAA,IACZ,oBAAoB,MAAM;AAAA,IAC1B,WAAW,aAAa,eAAe;AAAA,IACvC,YAAY,kBAAkB,cAAc,eAAe,UAAU;AAAA,IACrE,WAAW;AAAA,MACT,eAAe;AAAA,IACjB;AAAA,IACA,cAAc;AAAA,MACZ,eAAe;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,oBAAoB,OAAO,QAAQ,IAAI,IAAI;AAEjD,SACE;AAAA,IAAC,qBAAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,MACP;AAAA,MACA,QAAQ,cAAc,UAAU;AAAA,MAChC;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;;;ACpFA,mBAAkB;AAClB,IAAAC,uBAAgC;AA+B5B,IAAAC,sBAAA;AA5BG,IAAM,OAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AACjB,MAAM;AACJ,QAAM,QAAmB;AAAA,IACvB,OAAO,OAAO,SAAS,WAAW,OAAO;AAAA,IACzC,QAAQ,OAAO,SAAS,WAAW,OAAO;AAAA,IAC1C,YAAY;AAAA,IACZ,gBAAgB;AAAA,EAClB;AAIA,QAAM,oBAAoB,aAAAC,QAAM,SAAS,IAAI,UAAU,CAAC,UAAU;AAChE,QAAI,aAAAA,QAAM,eAAe,KAAK,GAAG;AAC/B,aAAO,aAAAA,QAAM,aAAa,OAAO;AAAA,QAC/B,OAAO,MAAM,MAAM,SAAS;AAAA;AAAA,QAE5B,MAAM,MAAM,MAAM,QAAQ;AAAA,MAC5B,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT,CAAC;AAED,SACE,6CAAC,6BAAK,OAAc,QAAQ,cAAc,QACvC,6BACH;AAEJ;;;AHjCA,sBAAiC;AACjC,4BAA4B;AAC5B,wBAA2B;AA+LrB,IAAAC,sBAAA;AA5LN,IAAM,mBACJ;AACF,IAAM,qBAAqB;AAU3B,IAAM,sBAA2C;AAAA,EAC/C,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,OAAO;AAAA,EACP,QAAQ;AACV;AAEO,IAAM,kBAAc;AAAA,EACzB,CACE;AAAA,IACE;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,UAAU;AAAA,IACV,OAAO;AAAA,IACP,MAAM;AAAA,IACN,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA;AAAA,IAEd;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,UAAU,eAAe;AAC/B,UAAM,WAAW,gBAAgB;AACjC,UAAM,uBAAuB,gBAAgB;AAG7C,UAAM,iBAAa,sBAAe;AAClC,QAAI,CAAC,WAAW,SAAS;AACvB,iBAAW,UAAU,qBAAqB,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,IACnF;AACA,UAAM,UAAU,WAAW;AAE3B,UAAM,EAAE,MAAM,QAAI,kCAAiB,EAAE,WAAW,oBAAoB,CAAC;AACrE,UAAM,SAAS,MAAM,OAAO,eAAe;AAE3C,UAAM,eAAe,aAAa;AAClC,UAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,WAAW;AACtD,UAAM,OAAO,eAAe,WAAY;AAExC,UAAM,mBAAe,2BAAY,MAAM;AACrC,YAAM,OAAO,CAAC;AACd,UAAI,CAAC,aAAc,cAAa,IAAI;AACpC,6BAAuB,IAAI;AAAA,IAC7B,GAAG,CAAC,MAAM,cAAc,oBAAoB,CAAC;AAE7C,UAAM,oBAAgB;AAAA,MACpB,CAAC,MAA2B;AAC1B,YAAI,EAAE,QAAQ,SAAS;AACrB,YAAE,eAAe;AACjB,uBAAa;AAAA,QACf,WAAW,EAAE,QAAQ,KAAK;AACxB,YAAE,eAAe;AAAA,QACnB;AAAA,MACF;AAAA,MACA,CAAC,YAAY;AAAA,IACf;AAEA,UAAM,kBAAc;AAAA,MAClB,CAAC,MAA2B;AAC1B,YAAI,EAAE,QAAQ,KAAK;AACjB,YAAE,eAAe;AACjB,uBAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,CAAC,YAAY;AAAA,IACf;AAEA,UAAM,UAAU,SAAS;AACzB,UAAM,SAAS,SAAS;AACxB,UAAM,YAAY,SAAS;AAC3B,UAAM,WAAW,SAAS;AAM1B,UAAM,aAAa,WAAW;AAG9B,UAAM,YAAiC;AAAA,MACrC,WAAW;AAAA,MACX,SAAS;AAAA,MACT,eAAe;AAAA;AAAA;AAAA;AAAA,MAIf,YAAY,WAAW,eAAe;AAAA;AAAA;AAAA,MAGtC,UAAU,WAAW,YAAY;AAAA,MACjC,iBAAiB,UACb,MAAM,OAAO,WAAW,UACxB,SACE,MAAM,OAAO,QAAQ,OACrB;AAAA,MACN,cAAc,aAAa,OAAO,gBAAgB;AAAA,MAClD,cAAc,YACV,aAAa,MAAM,OAAO,OAAO,SAAS,KAC1C;AAAA,IACN;AAEA,UAAM,YAAiC;AAAA,MACrC,WAAW;AAAA,MACX,SAAS;AAAA,MACT,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,KAAK,OAAO;AAAA,MACZ,OAAO;AAAA,MACP,WAAW,YAAY,OAAO,mBAAmB;AAAA,MACjD,SAAS,aAAa,OAAO,iBAAiB;AAAA,MAC9C,iBAAiB,UACb,MAAM,OAAO,WAAW,UACxB,SACE,MAAM,OAAO,QAAQ,OACrB;AAAA,MACN,cAAc,aACV,OACE,GAAG,OAAO,UAAU,MAAM,OAAO,UAAU,WAC3C,OAAO,aACT;AAAA,MACJ,cAAc,OACV,aAAa,MAAM,OAAO,OAAO,SAAS,KAC1C;AAAA,IACN;AAIA,UAAM,iBAAsC;AAAA,MAC1C,SAAS;AAAA,MACT,kBAAkB,OAAO,QAAQ;AAAA,MACjC,YAAY;AAAA,MACZ,OAAO;AAAA,IACT;AAEA,UAAM,kBAAuC;AAAA,MAC3C,UAAU;AAAA,IACZ;AAEA,UAAM,oBAAyC;AAAA,MAC7C,WAAW;AAAA,MACX,OAAO;AAAA,MACP,SAAS,OAAO;AAAA,IAClB;AAMA,UAAM,mBAAmB,gBAAgB,UAAa,gBAAgB;AACtE,UAAM,kBAAkB,mBACpB,OAAO,gBAAgB,aACrB,YAAY,IAAI,IAChB,cACF;AAEJ,UAAM,oBACJ,cAAc,OAAO,UAAU,WAAW,QAAQ;AAKpD,UAAM,gBAAgB,cAAc,SAAY,mBAC9C,6CAAC,UAAK,eAAY,uBAAsB,OAAO,qBAC5C,2BACH,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,eAAY;AAAA,QACZ,OAAO;AAAA,UACL,GAAG;AAAA,UACH,WAAW,OAAO,mBAAmB;AAAA,UACrC,YAAY;AAAA,QACd;AAAA,QAEA,uDAAC,qCAAY;AAAA;AAAA,IACf;AAGF,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAQ,UAAU;AAAA,QAClB,aAAW;AAAA,QACX;AAAA,QACA,OAAM;AAAA,QACN,OAAO;AAAA,QACN,GAAG;AAAA,QAGH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAYC;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,YAAY;AAAA,gBACZ,iBAAe;AAAA,gBACf,iBAAe;AAAA,gBACf,cAAY;AAAA,gBACZ,UAAU;AAAA,gBACV,WAAW;AAAA,gBACX,SAAS;AAAA,gBACT,QAAO;AAAA,gBAEN;AAAA;AAAA,YACH;AAAA,cAEA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,UAAU;AAAA,cACV,iBAAe;AAAA,cACf,iBAAe;AAAA,cACf,cAAY;AAAA,cACZ,SAAS;AAAA,cACT,WAAW;AAAA,cACX,SAAS;AAAA,cACT,OAAO,EAAE,WAAW,cAAc,OAAO,QAAQ,QAAQ,UAAU;AAAA,cAEnE,wDAAC,SAAI,OAAO,WAET;AAAA,wBACC;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,oBAClC,WAAW,CAAC,MAAM,EAAE,gBAAgB;AAAA,oBACpC,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,oBAClC,OAAO,EAAE,YAAY,GAAG,SAAS,QAAQ,YAAY,SAAS;AAAA,oBAE7D;AAAA;AAAA,gBACH;AAAA,gBAIF;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,eAAe;AAAA,sBACf,YAAY;AAAA,sBACZ,KAAK,OAAO;AAAA,sBACZ,UAAU;AAAA,oBACZ;AAAA,oBAEC;AAAA,6BAAO,UAAU,YAAY,OAAO,UAAU,WAC7C;AAAA,wBAAC;AAAA;AAAA,0BACC,OAAO,MAAM,OAAO,QAAQ;AAAA,0BAC5B,UAAU,OAAO;AAAA,0BACjB,YAAY,OAAO;AAAA,0BACnB,YAAW;AAAA,0BAEV;AAAA;AAAA,sBACH,IAEA;AAAA,sBAED,YAAY,WACV,OAAO,YAAY,YAAY,OAAO,YAAY,WACjD;AAAA,wBAAC;AAAA;AAAA,0BACC,OAAO,MAAM,OAAO,QAAQ;AAAA,0BAC5B,UAAU,OAAO;AAAA,0BACjB,YAAY,OAAO;AAAA,0BACnB,YAAW;AAAA,0BAEV;AAAA;AAAA,sBACH,IAEA;AAAA;AAAA;AAAA,gBAEN;AAAA,gBAGA;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,SAAS;AAAA,sBACT,eAAe;AAAA,sBACf,YAAY;AAAA,sBACZ,KAAK,OAAO;AAAA,sBACZ,YAAY;AAAA,oBACd;AAAA,oBAEC;AAAA,kCACC;AAAA,wBAAC;AAAA;AAAA,0BACC,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,0BAClC,WAAW,CAAC,MAAM,EAAE,gBAAgB;AAAA,0BACpC,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,0BAClC,OAAO,EAAE,SAAS,QAAQ,YAAY,SAAS;AAAA,0BAE9C;AAAA;AAAA,sBACH;AAAA,sBAED,CAAC,gBACC,mBACC;AAAA,wBAAC;AAAA;AAAA,0BACC,eAAY;AAAA,0BACZ,OAAO,EAAE,SAAS,QAAQ,YAAY,SAAS;AAAA,0BAE9C;AAAA;AAAA,sBACH,IAEA;AAAA,wBAAC;AAAA;AAAA,0BACC,eAAY;AAAA,0BACZ,OAAO;AAAA,4BACL,WAAW,OAAO,mBAAmB;AAAA,4BACrC,YAAY;AAAA,4BACZ,SAAS;AAAA,4BACT,YAAY;AAAA,0BACd;AAAA,0BAEA;AAAA,4BAAC;AAAA;AAAA,8BACC,OAAO,MAAM,OAAO,QAAQ;AAAA,8BAC5B,MAAM,OAAO;AAAA,8BAEb,uDAAC,qCAAY;AAAA;AAAA,0BACf;AAAA;AAAA,sBACF;AAAA;AAAA;AAAA,gBAEN;AAAA,iBACF;AAAA;AAAA,UACF;AAAA,UAIF,6CAAC,SAAI,IAAI,SAAS,OAAO,gBACvB,uDAAC,SAAI,OAAO,iBACV,uDAAC,SAAI,OAAO,mBAAoB,UAAS,GAC3C,GACF;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,YAAY,cAAc;","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_jsx_runtime"]}