@soyfri/shared-library 2.0.0-beta.34 → 2.0.0-beta.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,19 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
1
17
  import { jsxs, jsx } from "react/jsx-runtime";
2
18
  import { Children, isValidElement, useState } from "react";
3
19
  import { Box, Tabs as Tabs$1, Tab as Tab$1 } from "@mui/material";
@@ -9,6 +25,7 @@ const TAB_DISPLAY_MAP = {
9
25
  const Tabs = ({
10
26
  children,
11
27
  defaultValue,
28
+ value: controlledValue,
12
29
  onChangeValue,
13
30
  centered = true,
14
31
  orientation = "horizontal",
@@ -19,6 +36,7 @@ const Tabs = ({
19
36
  className,
20
37
  allowScrollButtonsMobile = true,
21
38
  keepMounted = false,
39
+ nav = false,
22
40
  sx
23
41
  }) => {
24
42
  var _a, _b;
@@ -29,13 +47,16 @@ const Tabs = ({
29
47
  }
30
48
  );
31
49
  const firstValue = (_a = tabs[0]) == null ? void 0 : _a.props.value;
32
- const [currentValue, setCurrentValue] = useState(
50
+ const isControlled = controlledValue !== void 0;
51
+ const [internalValue, setInternalValue] = useState(
33
52
  (_b = defaultValue != null ? defaultValue : firstValue) != null ? _b : 0
34
53
  );
54
+ const currentValue = isControlled ? controlledValue : internalValue;
35
55
  const handleChange = (_event, newValue) => {
36
- setCurrentValue(newValue);
56
+ if (!isControlled && !nav) setInternalValue(newValue);
37
57
  onChangeValue == null ? void 0 : onChangeValue(newValue);
38
58
  };
59
+ const effectiveCentered = centered && variant !== "scrollable" && variant !== "fullWidth";
39
60
  const { display, flexDirection } = TAB_DISPLAY_MAP[orientation];
40
61
  return /* @__PURE__ */ jsxs(Box, { sx: { display, flexDirection }, children: [
41
62
  /* @__PURE__ */ jsx(
@@ -43,7 +64,7 @@ const Tabs = ({
43
64
  {
44
65
  value: currentValue,
45
66
  onChange: handleChange,
46
- centered,
67
+ centered: effectiveCentered,
47
68
  indicatorColor,
48
69
  orientation,
49
70
  scrollButtons,
@@ -61,11 +82,15 @@ const Tabs = ({
61
82
  wrapped,
62
83
  iconPosition,
63
84
  className: tabClassName,
64
- sx: tabSx
85
+ sx: tabSx,
86
+ component,
87
+ to,
88
+ href,
89
+ onClick
65
90
  } = tab.props;
66
91
  return /* @__PURE__ */ jsx(
67
92
  Tab$1,
68
- {
93
+ __spreadValues(__spreadValues(__spreadValues(__spreadValues({
69
94
  label,
70
95
  icon,
71
96
  value,
@@ -74,13 +99,13 @@ const Tabs = ({
74
99
  iconPosition,
75
100
  className: tabClassName,
76
101
  sx: tabSx
77
- },
102
+ }, component ? { component } : {}), to ? { to } : {}), href ? { href } : {}), onClick ? { onClick } : {}),
78
103
  value
79
104
  );
80
105
  })
81
106
  }
82
107
  ),
83
- /* @__PURE__ */ jsx(Box, { m: 2, sx: { width: "100%" }, children: keepMounted ? tabs.map((tab, idx) => {
108
+ !nav && /* @__PURE__ */ jsx(Box, { m: 2, sx: { width: "100%" }, children: keepMounted ? tabs.map((tab, idx) => {
84
109
  var _a2;
85
110
  const value = (_a2 = tab.props.value) != null ? _a2 : idx;
86
111
  const isActive = value === currentValue;
@@ -108,4 +133,4 @@ export {
108
133
  Tabs as T,
109
134
  Tab as a
110
135
  };
111
- //# sourceMappingURL=Tab-BxSxKJsP.js.map
136
+ //# sourceMappingURL=Tab-B1mpmXRC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tab-B1mpmXRC.js","sources":["../src/components/Tabs/_tabUtils.tsx","../src/components/Tabs/Tabs.tsx","../src/components/Tabs/Tab.tsx"],"sourcesContent":["export const TAB_DISPLAY_MAP: Record<\"horizontal\" | \"vertical\", { display: string, flexDirection: string }> = {\n horizontal: { display: \"flex\", flexDirection: \"column\" },\n vertical: { display: \"flex\", flexDirection: \"row\" }\n};","import {\n Children,\n isValidElement,\n useState,\n type FC,\n type ReactElement,\n type ReactNode,\n type SyntheticEvent,\n} from 'react';\nimport {\n Tabs as MuiTabs,\n Tab as MuiTab,\n Box,\n type TabsProps as MuiTabsProps,\n} from '@mui/material';\n\nimport { TabProps } from './Tab';\nimport { TAB_DISPLAY_MAP } from './_tabUtils';\nimport { mergeSx } from '../_shared/mergeSx';\n\ntype PickTabsProps = Pick<\n MuiTabsProps,\n | 'centered'\n | 'indicatorColor'\n | 'orientation'\n | 'scrollButtons'\n | 'variant'\n | 'className'\n | 'sx'\n | 'visibleScrollbar'\n | 'allowScrollButtonsMobile'\n>;\n\nexport interface TabsProps extends PickTabsProps {\n /** Uno o varios `<Tab>`. Children que no sean `<Tab>` se ignoran. */\n children: ReactNode;\n /** Valor del tab inicialmente activo. Si no se provee, toma el `value` del primer `<Tab>` o `0`. */\n defaultValue?: number | string;\n /**\n * Valor activo **controlado**. Si se provee, el consumer maneja el estado\n * (típico en modo `nav`, donde el valor lo dicta la ruta). `false` = ningún\n * tab activo (ej. ruta que no corresponde a ninguna tab).\n */\n value?: number | string | false;\n /** Callback al cambiar de tab. Recibe el `value` del tab nuevo. */\n onChangeValue?: (newValue: number | string) => void;\n labelColor?: 'primary' | 'secondary' | 'inherit';\n /**\n * Modo **navegación**: las tabs son enlaces (`<Tab component={Link} to=.. />`),\n * el `value` activo es controlado externamente (por la ruta) y **no** se\n * renderizan paneles. `<Tab>` reenvía `component`/`to`/`href`/`onClick`.\n */\n nav?: boolean;\n /**\n * Cómo se manejan los paneles al cambiar de tab:\n * - `false` (default): **unmount** — solo se renderiza el panel activo; los\n * demás se desmontan. El state interno de los hijos se pierde al navegar.\n * Menor uso de memoria.\n * - `true`: **keep mounted** — renderiza todos los paneles pero oculta los\n * no activos con `display: none`. El state se preserva (inputs, scroll,\n * timers, subscripciones) al navegar entre tabs.\n */\n keepMounted?: boolean;\n}\n\nexport const Tabs: FC<TabsProps> = ({\n children,\n defaultValue,\n value: controlledValue,\n onChangeValue,\n centered = true,\n orientation = 'horizontal',\n scrollButtons = 'auto',\n variant = 'standard',\n indicatorColor = 'primary',\n labelColor = 'primary',\n className,\n allowScrollButtonsMobile = true,\n keepMounted = false,\n nav = false,\n sx,\n}) => {\n // Filtra a solo <Tab> children — acepta arrays, single child, fragments,\n // y descarta cualquier otra cosa (strings, null, condicionales falsy).\n const tabs: ReactElement<TabProps>[] = Children.toArray(children).filter(\n (child): child is ReactElement<TabProps> =>\n isValidElement(child) &&\n (child.type as { displayName?: string })?.displayName === 'Tab',\n );\n\n const firstValue = tabs[0]?.props.value;\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState<string | number>(\n defaultValue ?? firstValue ?? 0,\n );\n const currentValue = isControlled ? controlledValue : internalValue;\n\n const handleChange = (_event: SyntheticEvent, newValue: number | string) => {\n // En modo nav (o controlado) el consumer/ruta maneja el valor.\n if (!isControlled && !nav) setInternalValue(newValue);\n onChangeValue?.(newValue);\n };\n\n // MUI no permite `centered` con variant scrollable/fullWidth.\n const effectiveCentered =\n centered && variant !== 'scrollable' && variant !== 'fullWidth';\n\n const { display, flexDirection } = TAB_DISPLAY_MAP[orientation];\n\n return (\n <Box sx={{ display, flexDirection }}>\n <MuiTabs\n value={currentValue}\n onChange={handleChange}\n centered={effectiveCentered}\n indicatorColor={indicatorColor}\n orientation={orientation}\n scrollButtons={scrollButtons}\n variant={variant}\n className={className}\n textColor={labelColor}\n allowScrollButtonsMobile={allowScrollButtonsMobile}\n sx={mergeSx({}, sx)}\n >\n {tabs.map((tab, idx) => {\n const {\n label,\n icon,\n value = idx,\n disabled,\n wrapped,\n iconPosition,\n className: tabClassName,\n sx: tabSx,\n component,\n to,\n href,\n onClick,\n } = tab.props;\n return (\n <MuiTab\n key={value}\n label={label}\n icon={icon}\n value={value}\n disabled={disabled}\n wrapped={wrapped}\n iconPosition={iconPosition}\n className={tabClassName}\n sx={tabSx}\n // Modo nav: reenvía props de enlace/click.\n {...(component ? { component } : {})}\n {...(to ? { to } : {})}\n {...(href ? { href } : {})}\n {...(onClick ? { onClick } : {})}\n />\n );\n })}\n </MuiTabs>\n\n {!nav && (\n <Box m={2} sx={{ width: '100%' }}>\n {keepMounted\n ? tabs.map((tab, idx) => {\n const value = tab.props.value ?? idx;\n const isActive = value === currentValue;\n return (\n <Box\n key={value}\n role=\"tabpanel\"\n // `display: none` mantiene el nodo en el DOM — state de los\n // hijos (inputs, useState, etc.) no se pierde al navegar.\n sx={{ display: isActive ? 'block' : 'none' }}\n aria-hidden={!isActive}\n >\n {tab.props.children}\n </Box>\n );\n })\n : tabs.map((tab, idx) => {\n const value = tab.props.value ?? idx;\n if (value !== currentValue) return null;\n return (\n <Box key={value} role=\"tabpanel\">\n {tab.props.children}\n </Box>\n );\n })}\n </Box>\n )}\n </Box>\n );\n};\n\nexport default Tabs;\n","import React from \"react\";\nimport { TabProps as MuiTabProps } from \"@mui/material\";\n\ntype PickMuiTabProps = Pick<\n MuiTabProps,\n \"label\" | \"icon\" | \"disabled\" | \"sx\" | \"value\" | \"wrapped\" | \"iconPosition\" | \"className\" | \"disabled\"| 'disableRipple'\n>;\n\nexport interface TabProps extends Omit<PickMuiTabProps, 'value'> {\n value?: number | string;\n onChange?: () => void;\n children?: React.ReactNode;\n /**\n * Componente a renderizar (modo `nav`): ej. `Link` de react-router.\n * Junto con `to`/`href` convierte la tab en un enlace de navegación.\n */\n component?: React.ElementType;\n /** Destino de navegación (react-router `Link`). Solo en modo `nav`. */\n to?: string;\n /** Destino de navegación (ancla nativa). Solo en modo `nav`. */\n href?: string;\n /** Click handler (ej. para tabs de navegación sin router). */\n onClick?: () => void;\n}\n\nexport const Tab = (_: TabProps): null => null;\n\nTab.displayName = \"Tab\";\n\nexport default Tab;\n"],"names":["_a","MuiTabs","MuiTab"],"mappings":"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"}
@@ -1,4 +1,20 @@
1
1
  "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __spreadValues = (a, b) => {
8
+ for (var prop in b || (b = {}))
9
+ if (__hasOwnProp.call(b, prop))
10
+ __defNormalProp(a, prop, b[prop]);
11
+ if (__getOwnPropSymbols)
12
+ for (var prop of __getOwnPropSymbols(b)) {
13
+ if (__propIsEnum.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ }
16
+ return a;
17
+ };
2
18
  const jsxRuntime = require("react/jsx-runtime");
3
19
  const React = require("react");
4
20
  const material = require("@mui/material");
@@ -10,6 +26,7 @@ const TAB_DISPLAY_MAP = {
10
26
  const Tabs = ({
11
27
  children,
12
28
  defaultValue,
29
+ value: controlledValue,
13
30
  onChangeValue,
14
31
  centered = true,
15
32
  orientation = "horizontal",
@@ -20,6 +37,7 @@ const Tabs = ({
20
37
  className,
21
38
  allowScrollButtonsMobile = true,
22
39
  keepMounted = false,
40
+ nav = false,
23
41
  sx
24
42
  }) => {
25
43
  var _a, _b;
@@ -30,13 +48,16 @@ const Tabs = ({
30
48
  }
31
49
  );
32
50
  const firstValue = (_a = tabs[0]) == null ? void 0 : _a.props.value;
33
- const [currentValue, setCurrentValue] = React.useState(
51
+ const isControlled = controlledValue !== void 0;
52
+ const [internalValue, setInternalValue] = React.useState(
34
53
  (_b = defaultValue != null ? defaultValue : firstValue) != null ? _b : 0
35
54
  );
55
+ const currentValue = isControlled ? controlledValue : internalValue;
36
56
  const handleChange = (_event, newValue) => {
37
- setCurrentValue(newValue);
57
+ if (!isControlled && !nav) setInternalValue(newValue);
38
58
  onChangeValue == null ? void 0 : onChangeValue(newValue);
39
59
  };
60
+ const effectiveCentered = centered && variant !== "scrollable" && variant !== "fullWidth";
40
61
  const { display, flexDirection } = TAB_DISPLAY_MAP[orientation];
41
62
  return /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display, flexDirection }, children: [
42
63
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -44,7 +65,7 @@ const Tabs = ({
44
65
  {
45
66
  value: currentValue,
46
67
  onChange: handleChange,
47
- centered,
68
+ centered: effectiveCentered,
48
69
  indicatorColor,
49
70
  orientation,
50
71
  scrollButtons,
@@ -62,11 +83,15 @@ const Tabs = ({
62
83
  wrapped,
63
84
  iconPosition,
64
85
  className: tabClassName,
65
- sx: tabSx
86
+ sx: tabSx,
87
+ component,
88
+ to,
89
+ href,
90
+ onClick
66
91
  } = tab.props;
67
92
  return /* @__PURE__ */ jsxRuntime.jsx(
68
93
  material.Tab,
69
- {
94
+ __spreadValues(__spreadValues(__spreadValues(__spreadValues({
70
95
  label,
71
96
  icon,
72
97
  value,
@@ -75,13 +100,13 @@ const Tabs = ({
75
100
  iconPosition,
76
101
  className: tabClassName,
77
102
  sx: tabSx
78
- },
103
+ }, component ? { component } : {}), to ? { to } : {}), href ? { href } : {}), onClick ? { onClick } : {}),
79
104
  value
80
105
  );
81
106
  })
82
107
  }
83
108
  ),
84
- /* @__PURE__ */ jsxRuntime.jsx(material.Box, { m: 2, sx: { width: "100%" }, children: keepMounted ? tabs.map((tab, idx) => {
109
+ !nav && /* @__PURE__ */ jsxRuntime.jsx(material.Box, { m: 2, sx: { width: "100%" }, children: keepMounted ? tabs.map((tab, idx) => {
85
110
  var _a2;
86
111
  const value = (_a2 = tab.props.value) != null ? _a2 : idx;
87
112
  const isActive = value === currentValue;
@@ -107,4 +132,4 @@ const Tab = (_) => null;
107
132
  Tab.displayName = "Tab";
108
133
  exports.Tab = Tab;
109
134
  exports.Tabs = Tabs;
110
- //# sourceMappingURL=Tab-BbP8jBcK.cjs.map
135
+ //# sourceMappingURL=Tab-D-zNS5TI.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tab-D-zNS5TI.cjs","sources":["../src/components/Tabs/_tabUtils.tsx","../src/components/Tabs/Tabs.tsx","../src/components/Tabs/Tab.tsx"],"sourcesContent":["export const TAB_DISPLAY_MAP: Record<\"horizontal\" | \"vertical\", { display: string, flexDirection: string }> = {\n horizontal: { display: \"flex\", flexDirection: \"column\" },\n vertical: { display: \"flex\", flexDirection: \"row\" }\n};","import {\n Children,\n isValidElement,\n useState,\n type FC,\n type ReactElement,\n type ReactNode,\n type SyntheticEvent,\n} from 'react';\nimport {\n Tabs as MuiTabs,\n Tab as MuiTab,\n Box,\n type TabsProps as MuiTabsProps,\n} from '@mui/material';\n\nimport { TabProps } from './Tab';\nimport { TAB_DISPLAY_MAP } from './_tabUtils';\nimport { mergeSx } from '../_shared/mergeSx';\n\ntype PickTabsProps = Pick<\n MuiTabsProps,\n | 'centered'\n | 'indicatorColor'\n | 'orientation'\n | 'scrollButtons'\n | 'variant'\n | 'className'\n | 'sx'\n | 'visibleScrollbar'\n | 'allowScrollButtonsMobile'\n>;\n\nexport interface TabsProps extends PickTabsProps {\n /** Uno o varios `<Tab>`. Children que no sean `<Tab>` se ignoran. */\n children: ReactNode;\n /** Valor del tab inicialmente activo. Si no se provee, toma el `value` del primer `<Tab>` o `0`. */\n defaultValue?: number | string;\n /**\n * Valor activo **controlado**. Si se provee, el consumer maneja el estado\n * (típico en modo `nav`, donde el valor lo dicta la ruta). `false` = ningún\n * tab activo (ej. ruta que no corresponde a ninguna tab).\n */\n value?: number | string | false;\n /** Callback al cambiar de tab. Recibe el `value` del tab nuevo. */\n onChangeValue?: (newValue: number | string) => void;\n labelColor?: 'primary' | 'secondary' | 'inherit';\n /**\n * Modo **navegación**: las tabs son enlaces (`<Tab component={Link} to=.. />`),\n * el `value` activo es controlado externamente (por la ruta) y **no** se\n * renderizan paneles. `<Tab>` reenvía `component`/`to`/`href`/`onClick`.\n */\n nav?: boolean;\n /**\n * Cómo se manejan los paneles al cambiar de tab:\n * - `false` (default): **unmount** — solo se renderiza el panel activo; los\n * demás se desmontan. El state interno de los hijos se pierde al navegar.\n * Menor uso de memoria.\n * - `true`: **keep mounted** — renderiza todos los paneles pero oculta los\n * no activos con `display: none`. El state se preserva (inputs, scroll,\n * timers, subscripciones) al navegar entre tabs.\n */\n keepMounted?: boolean;\n}\n\nexport const Tabs: FC<TabsProps> = ({\n children,\n defaultValue,\n value: controlledValue,\n onChangeValue,\n centered = true,\n orientation = 'horizontal',\n scrollButtons = 'auto',\n variant = 'standard',\n indicatorColor = 'primary',\n labelColor = 'primary',\n className,\n allowScrollButtonsMobile = true,\n keepMounted = false,\n nav = false,\n sx,\n}) => {\n // Filtra a solo <Tab> children — acepta arrays, single child, fragments,\n // y descarta cualquier otra cosa (strings, null, condicionales falsy).\n const tabs: ReactElement<TabProps>[] = Children.toArray(children).filter(\n (child): child is ReactElement<TabProps> =>\n isValidElement(child) &&\n (child.type as { displayName?: string })?.displayName === 'Tab',\n );\n\n const firstValue = tabs[0]?.props.value;\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState<string | number>(\n defaultValue ?? firstValue ?? 0,\n );\n const currentValue = isControlled ? controlledValue : internalValue;\n\n const handleChange = (_event: SyntheticEvent, newValue: number | string) => {\n // En modo nav (o controlado) el consumer/ruta maneja el valor.\n if (!isControlled && !nav) setInternalValue(newValue);\n onChangeValue?.(newValue);\n };\n\n // MUI no permite `centered` con variant scrollable/fullWidth.\n const effectiveCentered =\n centered && variant !== 'scrollable' && variant !== 'fullWidth';\n\n const { display, flexDirection } = TAB_DISPLAY_MAP[orientation];\n\n return (\n <Box sx={{ display, flexDirection }}>\n <MuiTabs\n value={currentValue}\n onChange={handleChange}\n centered={effectiveCentered}\n indicatorColor={indicatorColor}\n orientation={orientation}\n scrollButtons={scrollButtons}\n variant={variant}\n className={className}\n textColor={labelColor}\n allowScrollButtonsMobile={allowScrollButtonsMobile}\n sx={mergeSx({}, sx)}\n >\n {tabs.map((tab, idx) => {\n const {\n label,\n icon,\n value = idx,\n disabled,\n wrapped,\n iconPosition,\n className: tabClassName,\n sx: tabSx,\n component,\n to,\n href,\n onClick,\n } = tab.props;\n return (\n <MuiTab\n key={value}\n label={label}\n icon={icon}\n value={value}\n disabled={disabled}\n wrapped={wrapped}\n iconPosition={iconPosition}\n className={tabClassName}\n sx={tabSx}\n // Modo nav: reenvía props de enlace/click.\n {...(component ? { component } : {})}\n {...(to ? { to } : {})}\n {...(href ? { href } : {})}\n {...(onClick ? { onClick } : {})}\n />\n );\n })}\n </MuiTabs>\n\n {!nav && (\n <Box m={2} sx={{ width: '100%' }}>\n {keepMounted\n ? tabs.map((tab, idx) => {\n const value = tab.props.value ?? idx;\n const isActive = value === currentValue;\n return (\n <Box\n key={value}\n role=\"tabpanel\"\n // `display: none` mantiene el nodo en el DOM — state de los\n // hijos (inputs, useState, etc.) no se pierde al navegar.\n sx={{ display: isActive ? 'block' : 'none' }}\n aria-hidden={!isActive}\n >\n {tab.props.children}\n </Box>\n );\n })\n : tabs.map((tab, idx) => {\n const value = tab.props.value ?? idx;\n if (value !== currentValue) return null;\n return (\n <Box key={value} role=\"tabpanel\">\n {tab.props.children}\n </Box>\n );\n })}\n </Box>\n )}\n </Box>\n );\n};\n\nexport default Tabs;\n","import React from \"react\";\nimport { TabProps as MuiTabProps } from \"@mui/material\";\n\ntype PickMuiTabProps = Pick<\n MuiTabProps,\n \"label\" | \"icon\" | \"disabled\" | \"sx\" | \"value\" | \"wrapped\" | \"iconPosition\" | \"className\" | \"disabled\"| 'disableRipple'\n>;\n\nexport interface TabProps extends Omit<PickMuiTabProps, 'value'> {\n value?: number | string;\n onChange?: () => void;\n children?: React.ReactNode;\n /**\n * Componente a renderizar (modo `nav`): ej. `Link` de react-router.\n * Junto con `to`/`href` convierte la tab en un enlace de navegación.\n */\n component?: React.ElementType;\n /** Destino de navegación (react-router `Link`). Solo en modo `nav`. */\n to?: string;\n /** Destino de navegación (ancla nativa). Solo en modo `nav`. */\n href?: string;\n /** Click handler (ej. para tabs de navegación sin router). */\n onClick?: () => void;\n}\n\nexport const Tab = (_: TabProps): null => null;\n\nTab.displayName = \"Tab\";\n\nexport default Tab;\n"],"names":["Children","isValidElement","_a","useState","Box","jsx","MuiTabs","mergeSx","MuiTab"],"mappings":"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"}
@@ -1,10 +1,21 @@
1
1
  import { default as React } from 'react';
2
2
  import { TabProps as MuiTabProps } from '@mui/material';
3
3
  type PickMuiTabProps = Pick<MuiTabProps, "label" | "icon" | "disabled" | "sx" | "value" | "wrapped" | "iconPosition" | "className" | "disabled" | 'disableRipple'>;
4
- export interface TabProps extends PickMuiTabProps {
5
- value?: number;
4
+ export interface TabProps extends Omit<PickMuiTabProps, 'value'> {
5
+ value?: number | string;
6
6
  onChange?: () => void;
7
7
  children?: React.ReactNode;
8
+ /**
9
+ * Componente a renderizar (modo `nav`): ej. `Link` de react-router.
10
+ * Junto con `to`/`href` convierte la tab en un enlace de navegación.
11
+ */
12
+ component?: React.ElementType;
13
+ /** Destino de navegación (react-router `Link`). Solo en modo `nav`. */
14
+ to?: string;
15
+ /** Destino de navegación (ancla nativa). Solo en modo `nav`. */
16
+ href?: string;
17
+ /** Click handler (ej. para tabs de navegación sin router). */
18
+ onClick?: () => void;
8
19
  }
9
20
  export declare const Tab: {
10
21
  (_: TabProps): null;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const Tab = require("../../Tab-BbP8jBcK.cjs");
3
+ const Tab = require("../../Tab-D-zNS5TI.cjs");
4
4
  exports.Tab = Tab.Tab;
5
5
  exports.Tabs = Tab.Tabs;
6
6
  exports.default = Tab.Tabs;
@@ -6,9 +6,21 @@ export interface TabsProps extends PickTabsProps {
6
6
  children: ReactNode;
7
7
  /** Valor del tab inicialmente activo. Si no se provee, toma el `value` del primer `<Tab>` o `0`. */
8
8
  defaultValue?: number | string;
9
+ /**
10
+ * Valor activo **controlado**. Si se provee, el consumer maneja el estado
11
+ * (típico en modo `nav`, donde el valor lo dicta la ruta). `false` = ningún
12
+ * tab activo (ej. ruta que no corresponde a ninguna tab).
13
+ */
14
+ value?: number | string | false;
9
15
  /** Callback al cambiar de tab. Recibe el `value` del tab nuevo. */
10
16
  onChangeValue?: (newValue: number | string) => void;
11
17
  labelColor?: 'primary' | 'secondary' | 'inherit';
18
+ /**
19
+ * Modo **navegación**: las tabs son enlaces (`<Tab component={Link} to=.. />`),
20
+ * el `value` activo es controlado externamente (por la ruta) y **no** se
21
+ * renderizan paneles. `<Tab>` reenvía `component`/`to`/`href`/`onClick`.
22
+ */
23
+ nav?: boolean;
12
24
  /**
13
25
  * Cómo se manejan los paneles al cambiar de tab:
14
26
  * - `false` (default): **unmount** — solo se renderiza el panel activo; los
@@ -1,4 +1,4 @@
1
- import { a, T, T as T2 } from "../../Tab-BxSxKJsP.js";
1
+ import { a, T, T as T2 } from "../../Tab-B1mpmXRC.js";
2
2
  export {
3
3
  a as Tab,
4
4
  T as Tabs,
package/index.cjs CHANGED
@@ -15,7 +15,7 @@ const Divider = require("./Divider-CIY0JK4U.cjs");
15
15
  const ButtonGroup = require("./ButtonGroup-CNunDofQ.cjs");
16
16
  const Breadcrumbs = require("./Breadcrumbs-B9I3vxPb.cjs");
17
17
  const Step = require("./Step-Nd7SJbRZ.cjs");
18
- const Tab = require("./Tab-BbP8jBcK.cjs");
18
+ const Tab = require("./Tab-D-zNS5TI.cjs");
19
19
  const Table = require("./Table-C4OM6rrC.cjs");
20
20
  const StatusMessage = require("./StatusMessage-B3nXpuRl.cjs");
21
21
  const Modal = require("./Modal-D_6ZdSzw.cjs");
package/index.js CHANGED
@@ -13,7 +13,7 @@ import { D as D2 } from "./Divider-BApcM5CV.js";
13
13
  import { B as B2 } from "./ButtonGroup-CcKUZ-lT.js";
14
14
  import { B as B3 } from "./Breadcrumbs-C41SPbtX.js";
15
15
  import { a, S as S3 } from "./Step-BArsou1V.js";
16
- import { a as a2, T } from "./Tab-BxSxKJsP.js";
16
+ import { a as a2, T } from "./Tab-B1mpmXRC.js";
17
17
  import { T as T2 } from "./Table-C2LbW0B1.js";
18
18
  import { S as S4 } from "./StatusMessage-D0WgSBx7.js";
19
19
  import { M, b, c, a as a3 } from "./Modal-C_QY7ZzY.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soyfri/shared-library",
3
- "version": "2.0.0-beta.34",
3
+ "version": "2.0.0-beta.36",
4
4
  "main": "./index.cjs",
5
5
  "module": "./index.js",
6
6
  "types": "./index.d.ts",
@@ -1 +0,0 @@
1
- {"version":3,"file":"Tab-BbP8jBcK.cjs","sources":["../src/components/Tabs/_tabUtils.tsx","../src/components/Tabs/Tabs.tsx","../src/components/Tabs/Tab.tsx"],"sourcesContent":["export const TAB_DISPLAY_MAP: Record<\"horizontal\" | \"vertical\", { display: string, flexDirection: string }> = {\n horizontal: { display: \"flex\", flexDirection: \"column\" },\n vertical: { display: \"flex\", flexDirection: \"row\" }\n};","import {\n Children,\n isValidElement,\n useState,\n type FC,\n type ReactElement,\n type ReactNode,\n type SyntheticEvent,\n} from 'react';\nimport {\n Tabs as MuiTabs,\n Tab as MuiTab,\n Box,\n type TabsProps as MuiTabsProps,\n} from '@mui/material';\n\nimport { TabProps } from './Tab';\nimport { TAB_DISPLAY_MAP } from './_tabUtils';\nimport { mergeSx } from '../_shared/mergeSx';\n\ntype PickTabsProps = Pick<\n MuiTabsProps,\n | 'centered'\n | 'indicatorColor'\n | 'orientation'\n | 'scrollButtons'\n | 'variant'\n | 'className'\n | 'sx'\n | 'visibleScrollbar'\n | 'allowScrollButtonsMobile'\n>;\n\nexport interface TabsProps extends PickTabsProps {\n /** Uno o varios `<Tab>`. Children que no sean `<Tab>` se ignoran. */\n children: ReactNode;\n /** Valor del tab inicialmente activo. Si no se provee, toma el `value` del primer `<Tab>` o `0`. */\n defaultValue?: number | string;\n /** Callback al cambiar de tab. Recibe el `value` del tab nuevo. */\n onChangeValue?: (newValue: number | string) => void;\n labelColor?: 'primary' | 'secondary' | 'inherit';\n /**\n * Cómo se manejan los paneles al cambiar de tab:\n * - `false` (default): **unmount** — solo se renderiza el panel activo; los\n * demás se desmontan. El state interno de los hijos se pierde al navegar.\n * Menor uso de memoria.\n * - `true`: **keep mounted** — renderiza todos los paneles pero oculta los\n * no activos con `display: none`. El state se preserva (inputs, scroll,\n * timers, subscripciones) al navegar entre tabs.\n */\n keepMounted?: boolean;\n}\n\nexport const Tabs: FC<TabsProps> = ({\n children,\n defaultValue,\n onChangeValue,\n centered = true,\n orientation = 'horizontal',\n scrollButtons = 'auto',\n variant = 'standard',\n indicatorColor = 'primary',\n labelColor = 'primary',\n className,\n allowScrollButtonsMobile = true,\n keepMounted = false,\n sx,\n}) => {\n // Filtra a solo <Tab> children — acepta arrays, single child, fragments,\n // y descarta cualquier otra cosa (strings, null, condicionales falsy).\n const tabs: ReactElement<TabProps>[] = Children.toArray(children).filter(\n (child): child is ReactElement<TabProps> =>\n isValidElement(child) &&\n (child.type as { displayName?: string })?.displayName === 'Tab',\n );\n\n const firstValue = tabs[0]?.props.value;\n const [currentValue, setCurrentValue] = useState<string | number>(\n defaultValue ?? firstValue ?? 0,\n );\n\n const handleChange = (_event: SyntheticEvent, newValue: number | string) => {\n setCurrentValue(newValue);\n onChangeValue?.(newValue);\n };\n\n const { display, flexDirection } = TAB_DISPLAY_MAP[orientation];\n\n return (\n <Box sx={{ display, flexDirection }}>\n <MuiTabs\n value={currentValue}\n onChange={handleChange}\n centered={centered}\n indicatorColor={indicatorColor}\n orientation={orientation}\n scrollButtons={scrollButtons}\n variant={variant}\n className={className}\n textColor={labelColor}\n allowScrollButtonsMobile={allowScrollButtonsMobile}\n sx={mergeSx({}, sx)}\n >\n {tabs.map((tab, idx) => {\n const {\n label,\n icon,\n value = idx,\n disabled,\n wrapped,\n iconPosition,\n className: tabClassName,\n sx: tabSx,\n } = tab.props;\n return (\n <MuiTab\n key={value}\n label={label}\n icon={icon}\n value={value}\n disabled={disabled}\n wrapped={wrapped}\n iconPosition={iconPosition}\n className={tabClassName}\n sx={tabSx}\n />\n );\n })}\n </MuiTabs>\n\n <Box m={2} sx={{ width: '100%' }}>\n {keepMounted\n ? tabs.map((tab, idx) => {\n const value = tab.props.value ?? idx;\n const isActive = value === currentValue;\n return (\n <Box\n key={value}\n role=\"tabpanel\"\n // `display: none` mantiene el nodo en el DOM — state de los\n // hijos (inputs, useState, etc.) no se pierde al navegar.\n sx={{ display: isActive ? 'block' : 'none' }}\n aria-hidden={!isActive}\n >\n {tab.props.children}\n </Box>\n );\n })\n : tabs.map((tab, idx) => {\n const value = tab.props.value ?? idx;\n if (value !== currentValue) return null;\n return (\n <Box key={value} role=\"tabpanel\">\n {tab.props.children}\n </Box>\n );\n })}\n </Box>\n </Box>\n );\n};\n\nexport default Tabs;\n","import React from \"react\";\nimport { TabProps as MuiTabProps } from \"@mui/material\";\n\ntype PickMuiTabProps = Pick<\n MuiTabProps,\n \"label\" | \"icon\" | \"disabled\" | \"sx\" | \"value\" | \"wrapped\" | \"iconPosition\" | \"className\" | \"disabled\"| 'disableRipple'\n>;\n\nexport interface TabProps extends PickMuiTabProps {\n value?: number;\n onChange?: () => void;\n children?: React.ReactNode;\n}\n\nexport const Tab = (_: TabProps): null => null;\n\nTab.displayName = \"Tab\";\n\nexport default Tab;\n"],"names":["Children","isValidElement","_a","useState","Box","jsx","MuiTabs","mergeSx","MuiTab"],"mappings":";;;;;AAAO,MAAM,kBAAiG;AAAA,EAC5G,YAAY,EAAE,SAAS,QAAQ,eAAe,SAAA;AAAA,EAC9C,UAAU,EAAE,SAAS,QAAQ,eAAe,MAAA;AAC9C;ACkDO,MAAM,OAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb;AAAA,EACA,2BAA2B;AAAA,EAC3B,cAAc;AAAA,EACd;AACF,MAAM;;AAGJ,QAAM,OAAiCA,MAAAA,SAAS,QAAQ,QAAQ,EAAE;AAAA,IAChE,CAAC,UAAA;;AACCC,mBAAAA,eAAe,KAAK,OACnBC,MAAA,MAAM,SAAN,gBAAAA,IAAyC,iBAAgB;AAAA;AAAA,EAAA;AAG9D,QAAM,cAAa,UAAK,CAAC,MAAN,mBAAS,MAAM;AAClC,QAAM,CAAC,cAAc,eAAe,IAAIC,MAAAA;AAAAA,KACtC,2CAAgB,eAAhB,YAA8B;AAAA,EAAA;AAGhC,QAAM,eAAe,CAAC,QAAwB,aAA8B;AAC1E,oBAAgB,QAAQ;AACxB,mDAAgB;AAAA,EAClB;AAEA,QAAM,EAAE,SAAS,kBAAkB,gBAAgB,WAAW;AAE9D,yCACGC,SAAAA,KAAA,EAAI,IAAI,EAAE,SAAS,iBAClB,UAAA;AAAA,IAAAC,2BAAAA;AAAAA,MAACC,SAAAA;AAAAA,MAAA;AAAA,QACC,OAAO;AAAA,QACP,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX;AAAA,QACA,IAAIC,QAAAA,QAAQ,CAAA,GAAI,EAAE;AAAA,QAEjB,UAAA,KAAK,IAAI,CAAC,KAAK,QAAQ;AACtB,gBAAM;AAAA,YACJ;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,YACR;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAW;AAAA,YACX,IAAI;AAAA,UAAA,IACF,IAAI;AACR,iBACEF,2BAAAA;AAAAA,YAACG,SAAAA;AAAAA,YAAA;AAAA,cAEC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,WAAW;AAAA,cACX,IAAI;AAAA,YAAA;AAAA,YARC;AAAA,UAAA;AAAA,QAWX,CAAC;AAAA,MAAA;AAAA,IAAA;AAAA,IAGHH,2BAAAA,IAACD,SAAAA,KAAA,EAAI,GAAG,GAAG,IAAI,EAAE,OAAO,OAAA,GACrB,UAAA,cACG,KAAK,IAAI,CAAC,KAAK,QAAQ;;AACvB,YAAM,SAAQF,MAAA,IAAI,MAAM,UAAV,OAAAA,MAAmB;AACjC,YAAM,WAAW,UAAU;AAC3B,aACEG,2BAAAA;AAAAA,QAACD,SAAAA;AAAAA,QAAA;AAAA,UAEC,MAAK;AAAA,UAGL,IAAI,EAAE,SAAS,WAAW,UAAU,OAAA;AAAA,UACpC,eAAa,CAAC;AAAA,UAEb,cAAI,MAAM;AAAA,QAAA;AAAA,QAPN;AAAA,MAAA;AAAA,IAUX,CAAC,IACC,KAAK,IAAI,CAAC,KAAK,QAAQ;;AACvB,YAAM,SAAQF,MAAA,IAAI,MAAM,UAAV,OAAAA,MAAmB;AACjC,UAAI,UAAU,aAAc,QAAO;AACnC,4CACGE,SAAAA,KAAA,EAAgB,MAAK,YACnB,UAAA,IAAI,MAAM,YADH,KAEV;AAAA,IAEJ,CAAC,EAAA,CACL;AAAA,EAAA,GACF;AAEJ;AClJO,MAAM,MAAM,CAAC,MAAsB;AAE1C,IAAI,cAAc;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Tab-BxSxKJsP.js","sources":["../src/components/Tabs/_tabUtils.tsx","../src/components/Tabs/Tabs.tsx","../src/components/Tabs/Tab.tsx"],"sourcesContent":["export const TAB_DISPLAY_MAP: Record<\"horizontal\" | \"vertical\", { display: string, flexDirection: string }> = {\n horizontal: { display: \"flex\", flexDirection: \"column\" },\n vertical: { display: \"flex\", flexDirection: \"row\" }\n};","import {\n Children,\n isValidElement,\n useState,\n type FC,\n type ReactElement,\n type ReactNode,\n type SyntheticEvent,\n} from 'react';\nimport {\n Tabs as MuiTabs,\n Tab as MuiTab,\n Box,\n type TabsProps as MuiTabsProps,\n} from '@mui/material';\n\nimport { TabProps } from './Tab';\nimport { TAB_DISPLAY_MAP } from './_tabUtils';\nimport { mergeSx } from '../_shared/mergeSx';\n\ntype PickTabsProps = Pick<\n MuiTabsProps,\n | 'centered'\n | 'indicatorColor'\n | 'orientation'\n | 'scrollButtons'\n | 'variant'\n | 'className'\n | 'sx'\n | 'visibleScrollbar'\n | 'allowScrollButtonsMobile'\n>;\n\nexport interface TabsProps extends PickTabsProps {\n /** Uno o varios `<Tab>`. Children que no sean `<Tab>` se ignoran. */\n children: ReactNode;\n /** Valor del tab inicialmente activo. Si no se provee, toma el `value` del primer `<Tab>` o `0`. */\n defaultValue?: number | string;\n /** Callback al cambiar de tab. Recibe el `value` del tab nuevo. */\n onChangeValue?: (newValue: number | string) => void;\n labelColor?: 'primary' | 'secondary' | 'inherit';\n /**\n * Cómo se manejan los paneles al cambiar de tab:\n * - `false` (default): **unmount** — solo se renderiza el panel activo; los\n * demás se desmontan. El state interno de los hijos se pierde al navegar.\n * Menor uso de memoria.\n * - `true`: **keep mounted** — renderiza todos los paneles pero oculta los\n * no activos con `display: none`. El state se preserva (inputs, scroll,\n * timers, subscripciones) al navegar entre tabs.\n */\n keepMounted?: boolean;\n}\n\nexport const Tabs: FC<TabsProps> = ({\n children,\n defaultValue,\n onChangeValue,\n centered = true,\n orientation = 'horizontal',\n scrollButtons = 'auto',\n variant = 'standard',\n indicatorColor = 'primary',\n labelColor = 'primary',\n className,\n allowScrollButtonsMobile = true,\n keepMounted = false,\n sx,\n}) => {\n // Filtra a solo <Tab> children — acepta arrays, single child, fragments,\n // y descarta cualquier otra cosa (strings, null, condicionales falsy).\n const tabs: ReactElement<TabProps>[] = Children.toArray(children).filter(\n (child): child is ReactElement<TabProps> =>\n isValidElement(child) &&\n (child.type as { displayName?: string })?.displayName === 'Tab',\n );\n\n const firstValue = tabs[0]?.props.value;\n const [currentValue, setCurrentValue] = useState<string | number>(\n defaultValue ?? firstValue ?? 0,\n );\n\n const handleChange = (_event: SyntheticEvent, newValue: number | string) => {\n setCurrentValue(newValue);\n onChangeValue?.(newValue);\n };\n\n const { display, flexDirection } = TAB_DISPLAY_MAP[orientation];\n\n return (\n <Box sx={{ display, flexDirection }}>\n <MuiTabs\n value={currentValue}\n onChange={handleChange}\n centered={centered}\n indicatorColor={indicatorColor}\n orientation={orientation}\n scrollButtons={scrollButtons}\n variant={variant}\n className={className}\n textColor={labelColor}\n allowScrollButtonsMobile={allowScrollButtonsMobile}\n sx={mergeSx({}, sx)}\n >\n {tabs.map((tab, idx) => {\n const {\n label,\n icon,\n value = idx,\n disabled,\n wrapped,\n iconPosition,\n className: tabClassName,\n sx: tabSx,\n } = tab.props;\n return (\n <MuiTab\n key={value}\n label={label}\n icon={icon}\n value={value}\n disabled={disabled}\n wrapped={wrapped}\n iconPosition={iconPosition}\n className={tabClassName}\n sx={tabSx}\n />\n );\n })}\n </MuiTabs>\n\n <Box m={2} sx={{ width: '100%' }}>\n {keepMounted\n ? tabs.map((tab, idx) => {\n const value = tab.props.value ?? idx;\n const isActive = value === currentValue;\n return (\n <Box\n key={value}\n role=\"tabpanel\"\n // `display: none` mantiene el nodo en el DOM — state de los\n // hijos (inputs, useState, etc.) no se pierde al navegar.\n sx={{ display: isActive ? 'block' : 'none' }}\n aria-hidden={!isActive}\n >\n {tab.props.children}\n </Box>\n );\n })\n : tabs.map((tab, idx) => {\n const value = tab.props.value ?? idx;\n if (value !== currentValue) return null;\n return (\n <Box key={value} role=\"tabpanel\">\n {tab.props.children}\n </Box>\n );\n })}\n </Box>\n </Box>\n );\n};\n\nexport default Tabs;\n","import React from \"react\";\nimport { TabProps as MuiTabProps } from \"@mui/material\";\n\ntype PickMuiTabProps = Pick<\n MuiTabProps,\n \"label\" | \"icon\" | \"disabled\" | \"sx\" | \"value\" | \"wrapped\" | \"iconPosition\" | \"className\" | \"disabled\"| 'disableRipple'\n>;\n\nexport interface TabProps extends PickMuiTabProps {\n value?: number;\n onChange?: () => void;\n children?: React.ReactNode;\n}\n\nexport const Tab = (_: TabProps): null => null;\n\nTab.displayName = \"Tab\";\n\nexport default Tab;\n"],"names":["_a","MuiTabs","MuiTab"],"mappings":";;;;AAAO,MAAM,kBAAiG;AAAA,EAC5G,YAAY,EAAE,SAAS,QAAQ,eAAe,SAAA;AAAA,EAC9C,UAAU,EAAE,SAAS,QAAQ,eAAe,MAAA;AAC9C;ACkDO,MAAM,OAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb;AAAA,EACA,2BAA2B;AAAA,EAC3B,cAAc;AAAA,EACd;AACF,MAAM;;AAGJ,QAAM,OAAiC,SAAS,QAAQ,QAAQ,EAAE;AAAA,IAChE,CAAC,UAAA;;AACC,4BAAe,KAAK,OACnBA,MAAA,MAAM,SAAN,gBAAAA,IAAyC,iBAAgB;AAAA;AAAA,EAAA;AAG9D,QAAM,cAAa,UAAK,CAAC,MAAN,mBAAS,MAAM;AAClC,QAAM,CAAC,cAAc,eAAe,IAAI;AAAA,KACtC,2CAAgB,eAAhB,YAA8B;AAAA,EAAA;AAGhC,QAAM,eAAe,CAAC,QAAwB,aAA8B;AAC1E,oBAAgB,QAAQ;AACxB,mDAAgB;AAAA,EAClB;AAEA,QAAM,EAAE,SAAS,kBAAkB,gBAAgB,WAAW;AAE9D,8BACG,KAAA,EAAI,IAAI,EAAE,SAAS,iBAClB,UAAA;AAAA,IAAA;AAAA,MAACC;AAAAA,MAAA;AAAA,QACC,OAAO;AAAA,QACP,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX;AAAA,QACA,IAAI,QAAQ,CAAA,GAAI,EAAE;AAAA,QAEjB,UAAA,KAAK,IAAI,CAAC,KAAK,QAAQ;AACtB,gBAAM;AAAA,YACJ;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,YACR;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAW;AAAA,YACX,IAAI;AAAA,UAAA,IACF,IAAI;AACR,iBACE;AAAA,YAACC;AAAAA,YAAA;AAAA,cAEC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,WAAW;AAAA,cACX,IAAI;AAAA,YAAA;AAAA,YARC;AAAA,UAAA;AAAA,QAWX,CAAC;AAAA,MAAA;AAAA,IAAA;AAAA,IAGH,oBAAC,KAAA,EAAI,GAAG,GAAG,IAAI,EAAE,OAAO,OAAA,GACrB,UAAA,cACG,KAAK,IAAI,CAAC,KAAK,QAAQ;;AACvB,YAAM,SAAQF,MAAA,IAAI,MAAM,UAAV,OAAAA,MAAmB;AACjC,YAAM,WAAW,UAAU;AAC3B,aACE;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,MAAK;AAAA,UAGL,IAAI,EAAE,SAAS,WAAW,UAAU,OAAA;AAAA,UACpC,eAAa,CAAC;AAAA,UAEb,cAAI,MAAM;AAAA,QAAA;AAAA,QAPN;AAAA,MAAA;AAAA,IAUX,CAAC,IACC,KAAK,IAAI,CAAC,KAAK,QAAQ;;AACvB,YAAM,SAAQA,MAAA,IAAI,MAAM,UAAV,OAAAA,MAAmB;AACjC,UAAI,UAAU,aAAc,QAAO;AACnC,iCACG,KAAA,EAAgB,MAAK,YACnB,UAAA,IAAI,MAAM,YADH,KAEV;AAAA,IAEJ,CAAC,EAAA,CACL;AAAA,EAAA,GACF;AAEJ;AClJO,MAAM,MAAM,CAAC,MAAsB;AAE1C,IAAI,cAAc;"}