@consumidor-positivo/aurora 0.12.0 → 1.0.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.
Files changed (78) hide show
  1. package/dist/components/Alert/index.d.ts +6 -1
  2. package/dist/components/Alert/index.es.js +10 -1
  3. package/dist/components/Alert/index.es.js.map +1 -1
  4. package/dist/components/Alert/styles.css +1 -1
  5. package/dist/components/BadgeInfo/index.d.ts +0 -4
  6. package/dist/components/BadgeInfo/index.es.js +2 -1
  7. package/dist/components/BadgeInfo/index.es.js.map +1 -1
  8. package/dist/components/BadgeState/index.es.js +2 -1
  9. package/dist/components/BadgeState/index.es.js.map +1 -1
  10. package/dist/components/Button/index.d.ts +9 -0
  11. package/dist/components/Button/index.es.js.map +1 -1
  12. package/dist/components/Button/styles.css +1 -1
  13. package/dist/components/Calendar/index.es.js +2 -2
  14. package/dist/components/CalendarHeader/index.es.js +3 -2
  15. package/dist/components/CalendarHeader/index.es.js.map +1 -1
  16. package/dist/components/Checkbox/index.es.js +1 -1
  17. package/dist/components/Chip/index.es.js +1 -0
  18. package/dist/components/Chip/index.es.js.map +1 -1
  19. package/dist/components/Datepicker/index.es.js +4 -4
  20. package/dist/components/Drawer/index.d.ts +7 -1
  21. package/dist/components/Drawer/index.es.js +4 -1
  22. package/dist/components/Drawer/index.es.js.map +1 -1
  23. package/dist/components/Drawer/styles.css +1 -1
  24. package/dist/components/Footer/index.es.js +1 -0
  25. package/dist/components/Footer/index.es.js.map +1 -1
  26. package/dist/components/Header/index.es.js +1 -1
  27. package/dist/components/Icon/index.es.js +14 -2
  28. package/dist/components/Icon/index.es.js.map +1 -1
  29. package/dist/components/Image/index.es.js +1 -1
  30. package/dist/components/Label/index.es.js +2 -1
  31. package/dist/components/Label/index.es.js.map +1 -1
  32. package/dist/components/LinkButton/index.d.ts +27 -0
  33. package/dist/components/LinkButton/index.es.js +56 -0
  34. package/dist/components/LinkButton/index.es.js.map +1 -0
  35. package/dist/components/LinkButton/styles.css +1 -0
  36. package/dist/components/Modal/index.d.ts +3 -1
  37. package/dist/components/Modal/index.es.js +8 -0
  38. package/dist/components/Modal/index.es.js.map +1 -1
  39. package/dist/components/PortalHolder/index.es.js +1 -1
  40. package/dist/components/Segment/index.es.js +2 -1
  41. package/dist/components/Segment/index.es.js.map +1 -1
  42. package/dist/components/SelectField/index.es.js +1 -1
  43. package/dist/components/SpecialButton/SpecialButton.test.d.ts +1 -0
  44. package/dist/components/SpecialButton/index.d.ts +38 -0
  45. package/dist/components/SpecialButton/index.es.js +193 -0
  46. package/dist/components/SpecialButton/index.es.js.map +1 -0
  47. package/dist/components/SpecialButton/styles.css +1 -0
  48. package/dist/components/Spinner/index.d.ts +9 -5
  49. package/dist/components/Spinner/index.es.js +25 -15
  50. package/dist/components/Spinner/index.es.js.map +1 -1
  51. package/dist/components/SubHeader/index.es.js +1 -0
  52. package/dist/components/SubHeader/index.es.js.map +1 -1
  53. package/dist/components/Tabs/index.d.ts +3 -4
  54. package/dist/components/Tabs/index.es.js +80 -84
  55. package/dist/components/Tabs/index.es.js.map +1 -1
  56. package/dist/components/Tabs/styles.css +1 -1
  57. package/dist/components/Tag/index.es.js +8 -86
  58. package/dist/components/Tag/index.es.js.map +1 -1
  59. package/dist/components/TextareaField/index.es.js.map +1 -1
  60. package/dist/components/form/SelectField/types.d.ts +1 -0
  61. package/dist/components/form/TextareaField/index.d.ts +1 -0
  62. package/dist/components/icons/Icon.test/index.es.js +23 -5
  63. package/dist/components/icons/Icon.test/index.es.js.map +1 -1
  64. package/dist/{index-Dws33tXs.js → index-BgBOcVUP.js} +3 -3
  65. package/dist/{index-Dws33tXs.js.map → index-BgBOcVUP.js.map} +1 -1
  66. package/dist/{index-CnXw6SB7.js → index-DHwXRotU.js} +3 -3
  67. package/dist/{index-CnXw6SB7.js.map → index-DHwXRotU.js.map} +1 -1
  68. package/dist/{index-fyDB87KK.js → index-DnQGzfVW.js} +3 -3
  69. package/dist/{index-fyDB87KK.js.map → index-DnQGzfVW.js.map} +1 -1
  70. package/dist/main.d.ts +3 -1
  71. package/dist/main.es.js +21 -33
  72. package/dist/main.es.js.map +1 -1
  73. package/dist/{tokens-CKZdIZ5O.js → tokens-C4yCunfz.js} +15 -15
  74. package/dist/{tokens-CKZdIZ5O.js.map → tokens-C4yCunfz.js.map} +1 -1
  75. package/package.json +3 -3
  76. package/dist/components/Tag/index.d.ts +0 -22
  77. package/dist/components/Tag/styles.css +0 -1
  78. /package/dist/components/{Tag/Tag.test.d.ts → LinkButton/LinkButton.test.d.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
- import { B as BREAKPOINT_MD, a as BREAKPOINT_LG } from "../../tokens-CKZdIZ5O.js";
2
+ import { B as BREAKPOINT_MD, a as BREAKPOINT_LG } from "../../tokens-C4yCunfz.js";
3
3
  const Image = ({ srcMob, srcTablet, srcDesk, ...props }) => {
4
4
  return /* @__PURE__ */ jsxs("picture", { children: [
5
5
  /* @__PURE__ */ jsx("source", { media: `(max-width: ${BREAKPOINT_MD})`, srcSet: srcMob }),
@@ -1,10 +1,11 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import "../../index-C6Q03EyZ.js";
3
+ import "react";
3
4
  import "../Icon/index.es.js";
4
5
  import { IconAlertOctagon } from "../icons/IconAlertOctagon/index.es.js";
5
6
  import { IconCheck } from "../icons/IconCheck/index.es.js";
6
7
  import { IconSlash } from "../icons/IconSlash/index.es.js";
7
- import { C as COLOR_SUCCESS_50, b as COLOR_ERROR_50, c as COLOR_NEUTRAL_40 } from "../../tokens-CKZdIZ5O.js";
8
+ import { C as COLOR_SUCCESS_50, b as COLOR_ERROR_50, c as COLOR_NEUTRAL_40 } from "../../tokens-C4yCunfz.js";
8
9
  const FieldLabel = ({
9
10
  id,
10
11
  labelId,
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../../../lib/components/form/Field/Label/index.tsx"],"sourcesContent":["import { IconAlertOctagon, IconCheck, IconSlash } from '@components/icons'\nimport {\n COLOR_ERROR_50,\n COLOR_NEUTRAL_40,\n COLOR_SUCCESS_50,\n} from '@core/tokens'\n\ntype FieldLabelProps = {\n id?: string\n labelId?: string\n text?: string | React.ReactNode\n required?: boolean\n success?: boolean\n error?: boolean\n disabled?: boolean\n showOptionalLabel?: boolean\n}\n\nexport const FieldLabel = ({\n id,\n labelId,\n text,\n required,\n success,\n error,\n disabled,\n showOptionalLabel = true,\n}: FieldLabelProps) => {\n if (!text) return null\n\n const states = [\n {\n state: 'success',\n value: !!success,\n icon: <IconCheck rawColor={COLOR_SUCCESS_50} />,\n },\n {\n state: 'error',\n value: !!error,\n icon: <IconAlertOctagon rawColor={COLOR_ERROR_50} />,\n },\n {\n state: 'disabled',\n value: !!disabled,\n icon: <IconSlash rawColor={COLOR_NEUTRAL_40} />,\n },\n ]\n\n const currentState = states.find(({ value }) => !!value)\n\n return (\n <div className=\"au-field__header\">\n <label id={labelId} htmlFor={id} className=\"au-field__header-label\">\n {text}{' '}\n {showOptionalLabel && !required && (\n <span className=\"au-field__header-label--optional\">(Opcional)</span>\n )}\n {!showOptionalLabel && required && (\n <>\n <strong className=\"au-field__header-label--required\" aria-hidden=\"true\">*</strong>\n <span className=\"au-sr-only\">obrigatório</span>\n </>\n )}\n </label>\n <div className=\"au-field__header-icon\" aria-hidden=\"true\">{currentState?.icon}</div>\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;AAkBO,MAAM,aAAa,CAAC;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAoB;AACtB,MAAuB;AACrB,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,SAAS;AAAA,IACb;AAAA,MACE,OAAO;AAAA,MACP,OAAO,CAAC,CAAC;AAAA,MACT,MAAM,oBAAC,WAAA,EAAU,UAAU,iBAAA,CAAkB;AAAA,IAAA;AAAA,IAE/C;AAAA,MACE,OAAO;AAAA,MACP,OAAO,CAAC,CAAC;AAAA,MACT,MAAM,oBAAC,kBAAA,EAAiB,UAAU,eAAA,CAAgB;AAAA,IAAA;AAAA,IAEpD;AAAA,MACE,OAAO;AAAA,MACP,OAAO,CAAC,CAAC;AAAA,MACT,MAAM,oBAAC,WAAA,EAAU,UAAU,iBAAA,CAAkB;AAAA,IAAA;AAAA,EAC/C;AAGF,QAAM,eAAe,OAAO,KAAK,CAAC,EAAE,MAAA,MAAY,CAAC,CAAC,KAAK;AAEvD,SACE,qBAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,IAAA,qBAAC,WAAM,IAAI,SAAS,SAAS,IAAI,WAAU,0BACxC,UAAA;AAAA,MAAA;AAAA,MAAM;AAAA,MACN,qBAAqB,CAAC,gCACpB,QAAA,EAAK,WAAU,oCAAmC,UAAA,cAAU;AAAA,MAE9D,CAAC,qBAAqB,YACrB,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,oBAAC,UAAA,EAAO,WAAU,oCAAmC,eAAY,QAAO,UAAA,KAAC;AAAA,QACzE,oBAAC,QAAA,EAAK,WAAU,cAAa,UAAA,cAAA,CAAW;AAAA,MAAA,EAAA,CAC1C;AAAA,IAAA,GAEJ;AAAA,wBACC,OAAA,EAAI,WAAU,yBAAwB,eAAY,QAAQ,uDAAc,KAAA,CAAK;AAAA,EAAA,GAChF;AAEJ;"}
1
+ {"version":3,"file":"index.es.js","sources":["../../../lib/components/form/Field/Label/index.tsx"],"sourcesContent":["import { IconAlertOctagon, IconCheck, IconSlash } from '@components/icons'\nimport {\n COLOR_ERROR_50,\n COLOR_NEUTRAL_40,\n COLOR_SUCCESS_50,\n} from '@core/tokens'\n\ntype FieldLabelProps = {\n id?: string\n labelId?: string\n text?: string | React.ReactNode\n required?: boolean\n success?: boolean\n error?: boolean\n disabled?: boolean\n showOptionalLabel?: boolean\n}\n\nexport const FieldLabel = ({\n id,\n labelId,\n text,\n required,\n success,\n error,\n disabled,\n showOptionalLabel = true,\n}: FieldLabelProps) => {\n if (!text) return null\n\n const states = [\n {\n state: 'success',\n value: !!success,\n icon: <IconCheck rawColor={COLOR_SUCCESS_50} />,\n },\n {\n state: 'error',\n value: !!error,\n icon: <IconAlertOctagon rawColor={COLOR_ERROR_50} />,\n },\n {\n state: 'disabled',\n value: !!disabled,\n icon: <IconSlash rawColor={COLOR_NEUTRAL_40} />,\n },\n ]\n\n const currentState = states.find(({ value }) => !!value)\n\n return (\n <div className=\"au-field__header\">\n <label id={labelId} htmlFor={id} className=\"au-field__header-label\">\n {text}{' '}\n {showOptionalLabel && !required && (\n <span className=\"au-field__header-label--optional\">(Opcional)</span>\n )}\n {!showOptionalLabel && required && (\n <>\n <strong className=\"au-field__header-label--required\" aria-hidden=\"true\">*</strong>\n <span className=\"au-sr-only\">obrigatório</span>\n </>\n )}\n </label>\n <div className=\"au-field__header-icon\" aria-hidden=\"true\">{currentState?.icon}</div>\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;;AAkBO,MAAM,aAAa,CAAC;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAoB;AACtB,MAAuB;AACrB,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,SAAS;AAAA,IACb;AAAA,MACE,OAAO;AAAA,MACP,OAAO,CAAC,CAAC;AAAA,MACT,MAAM,oBAAC,WAAA,EAAU,UAAU,iBAAA,CAAkB;AAAA,IAAA;AAAA,IAE/C;AAAA,MACE,OAAO;AAAA,MACP,OAAO,CAAC,CAAC;AAAA,MACT,MAAM,oBAAC,kBAAA,EAAiB,UAAU,eAAA,CAAgB;AAAA,IAAA;AAAA,IAEpD;AAAA,MACE,OAAO;AAAA,MACP,OAAO,CAAC,CAAC;AAAA,MACT,MAAM,oBAAC,WAAA,EAAU,UAAU,iBAAA,CAAkB;AAAA,IAAA;AAAA,EAC/C;AAGF,QAAM,eAAe,OAAO,KAAK,CAAC,EAAE,MAAA,MAAY,CAAC,CAAC,KAAK;AAEvD,SACE,qBAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,IAAA,qBAAC,WAAM,IAAI,SAAS,SAAS,IAAI,WAAU,0BACxC,UAAA;AAAA,MAAA;AAAA,MAAM;AAAA,MACN,qBAAqB,CAAC,gCACpB,QAAA,EAAK,WAAU,oCAAmC,UAAA,cAAU;AAAA,MAE9D,CAAC,qBAAqB,YACrB,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,oBAAC,UAAA,EAAO,WAAU,oCAAmC,eAAY,QAAO,UAAA,KAAC;AAAA,QACzE,oBAAC,QAAA,EAAK,WAAU,cAAa,UAAA,cAAA,CAAW;AAAA,MAAA,EAAA,CAC1C;AAAA,IAAA,GAEJ;AAAA,wBACC,OAAA,EAAI,WAAU,yBAAwB,eAAY,QAAQ,uDAAc,KAAA,CAAK;AAAA,EAAA,GAChF;AAEJ;"}
@@ -0,0 +1,27 @@
1
+ import { default as React, ReactNode } from 'react';
2
+ export type LinkButtonProps = ({
3
+ as: 'a';
4
+ href: string;
5
+ target?: string;
6
+ } | {
7
+ as?: 'button';
8
+ href?: never;
9
+ target?: never;
10
+ }) & {
11
+ children?: ReactNode;
12
+ /**
13
+ * Token size (Figma: Link Button, Size). small = 14px text / 16px icons,
14
+ * medium = 16px / 20px, large = 20px / 20px.
15
+ * @default 'medium'
16
+ */
17
+ size?: 'small' | 'medium' | 'large';
18
+ /** Icon rendered before the label (Figma: Left Icon + Switch Icon Left). */
19
+ iconLeft?: ReactNode;
20
+ /** Icon rendered after the label (Figma: Right Icon + Switch Icon Right). */
21
+ iconRight?: ReactNode;
22
+ onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
23
+ disabled?: boolean;
24
+ className?: string;
25
+ 'data-testid'?: string;
26
+ };
27
+ export declare const LinkButton: ({ as, href, target, children, size, iconLeft, iconRight, onClick, disabled, className, "data-testid": dataTestId, }: LinkButtonProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,56 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { c as classNames } from "../../index-C6Q03EyZ.js";
3
+ import './styles.css';const LinkButton = ({
4
+ as,
5
+ href,
6
+ target,
7
+ children = "Link",
8
+ size = "medium",
9
+ iconLeft,
10
+ iconRight,
11
+ onClick,
12
+ disabled = false,
13
+ className,
14
+ "data-testid": dataTestId
15
+ }) => {
16
+ const classes = classNames(
17
+ "au-link-button",
18
+ {
19
+ [`au-link-button--size-${size}`]: !!size,
20
+ "au-link-button--disabled": disabled
21
+ },
22
+ className
23
+ );
24
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
25
+ iconLeft && /* @__PURE__ */ jsx("span", { className: "au-link-button__icon", "aria-hidden": "true", children: iconLeft }),
26
+ children,
27
+ iconRight && /* @__PURE__ */ jsx("span", { className: "au-link-button__icon", "aria-hidden": "true", children: iconRight })
28
+ ] });
29
+ if (as === "a") {
30
+ return /* @__PURE__ */ jsx(
31
+ "a",
32
+ {
33
+ className: classes,
34
+ href,
35
+ target,
36
+ "data-testid": dataTestId,
37
+ children: content
38
+ }
39
+ );
40
+ }
41
+ return /* @__PURE__ */ jsx(
42
+ "button",
43
+ {
44
+ type: "button",
45
+ className: classes,
46
+ onClick,
47
+ disabled,
48
+ "data-testid": dataTestId,
49
+ children: content
50
+ }
51
+ );
52
+ };
53
+ export {
54
+ LinkButton
55
+ };
56
+ //# sourceMappingURL=index.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","sources":["../../../lib/components/LinkButton/index.tsx"],"sourcesContent":["import classNames from 'classnames'\nimport React, { ReactNode } from 'react'\nimport './styles.scss'\n\nexport type LinkButtonProps = (\n | {\n as: 'a'\n href: string\n target?: string\n }\n | {\n as?: 'button'\n href?: never\n target?: never\n }\n) & {\n children?: ReactNode\n /**\n * Token size (Figma: Link Button, Size). small = 14px text / 16px icons,\n * medium = 16px / 20px, large = 20px / 20px.\n * @default 'medium'\n */\n size?: 'small' | 'medium' | 'large'\n /** Icon rendered before the label (Figma: Left Icon + Switch Icon Left). */\n iconLeft?: ReactNode\n /** Icon rendered after the label (Figma: Right Icon + Switch Icon Right). */\n iconRight?: ReactNode\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void\n disabled?: boolean\n className?: string\n 'data-testid'?: string\n}\n\nexport const LinkButton = ({\n as,\n href,\n target,\n children = 'Link',\n size = 'medium',\n iconLeft,\n iconRight,\n onClick,\n disabled = false,\n className,\n 'data-testid': dataTestId,\n}: LinkButtonProps) => {\n const classes = classNames(\n 'au-link-button',\n {\n [`au-link-button--size-${size}`]: !!size,\n 'au-link-button--disabled': disabled,\n },\n className,\n )\n\n const content = (\n <>\n {iconLeft && (\n <span className=\"au-link-button__icon\" aria-hidden=\"true\">\n {iconLeft}\n </span>\n )}\n {children}\n {iconRight && (\n <span className=\"au-link-button__icon\" aria-hidden=\"true\">\n {iconRight}\n </span>\n )}\n </>\n )\n\n if (as === 'a') {\n return (\n <a\n className={classes}\n href={href}\n target={target}\n data-testid={dataTestId}>\n {content}\n </a>\n )\n }\n\n return (\n <button\n type=\"button\"\n className={classes}\n onClick={onClick}\n disabled={disabled}\n data-testid={dataTestId}>\n {content}\n </button>\n )\n}\n"],"names":[],"mappings":";;AAiCO,MAAM,aAAa,CAAC;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA,eAAe;AACjB,MAAuB;AACrB,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,MACE,CAAC,wBAAwB,IAAI,EAAE,GAAG,CAAC,CAAC;AAAA,MACpC,4BAA4B;AAAA,IAAA;AAAA,IAE9B;AAAA,EAAA;AAGF,QAAM,UACJ,qBAAA,UAAA,EACG,UAAA;AAAA,IAAA,gCACE,QAAA,EAAK,WAAU,wBAAuB,eAAY,QAChD,UAAA,UACH;AAAA,IAED;AAAA,IACA,aACC,oBAAC,QAAA,EAAK,WAAU,wBAAuB,eAAY,QAChD,UAAA,UAAA,CACH;AAAA,EAAA,GAEJ;AAGF,MAAI,OAAO,KAAK;AACd,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA,eAAa;AAAA,QACZ,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,eAAa;AAAA,MACZ,UAAA;AAAA,IAAA;AAAA,EAAA;AAGP;"}
@@ -0,0 +1 @@
1
+ .au-link-button{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:0;border:none;background:transparent;color:#0048db;font-family:"Source Sans 3",sans-serif;font-weight:600;text-decoration:none;cursor:pointer}.au-link-button:hover,.au-link-button:focus,.au-link-button:active{color:#1737a4}.au-link-button .au-icon,.au-link-button .au-icon>svg{color:currentColor}.au-link-button__icon{display:inline-flex}.au-link-button--size-small{font-size:14px;line-height:22px}.au-link-button--size-small .au-icon,.au-link-button--size-small .au-icon>svg{width:16px;height:16px}.au-link-button--size-medium{font-size:16px;line-height:24px}.au-link-button--size-medium .au-icon,.au-link-button--size-medium .au-icon>svg{width:20px;height:20px}.au-link-button--size-large{font-size:20px;line-height:28px}.au-link-button--size-large .au-icon,.au-link-button--size-large .au-icon>svg{width:20px;height:20px}.au-link-button--disabled{color:#c4c9d4;cursor:not-allowed}.au-link-button--disabled:hover,.au-link-button--disabled:focus,.au-link-button--disabled:active{color:#c4c9d4}
@@ -3,6 +3,8 @@ type ModalLayoutMobile = 'default' | 'centralized' | 'full-screen';
3
3
  export type ModalProps = {
4
4
  isOpen: boolean;
5
5
  onClose?: () => void;
6
+ /** Calls onClose when the backdrop (area outside the container) is clicked */
7
+ closeOnBackdropClick?: boolean;
6
8
  headerContent?: React.ReactNode | string | JSX.Element | JSX.Element[];
7
9
  content?: React.ReactNode | string | JSX.Element | JSX.Element[];
8
10
  layoutMobile?: ModalLayoutMobile;
@@ -12,5 +14,5 @@ export type ModalProps = {
12
14
  ariaLabel?: string;
13
15
  'data-testid'?: string;
14
16
  };
15
- export declare const Modal: ({ isOpen, onClose, headerContent, content, layoutMobile, layoutDesktop, mobileModalTitle, handleHelpInfo, ariaLabel, "data-testid": dataTestId, }: ModalProps) => import("react/jsx-runtime").JSX.Element | null;
17
+ export declare const Modal: ({ isOpen, onClose, closeOnBackdropClick, headerContent, content, layoutMobile, layoutDesktop, mobileModalTitle, handleHelpInfo, ariaLabel, "data-testid": dataTestId, }: ModalProps) => import("react/jsx-runtime").JSX.Element | null;
16
18
  export {};
@@ -1,5 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { c as classNames } from "../../index-C6Q03EyZ.js";
3
+ import "react";
3
4
  import "../Icon/index.es.js";
4
5
  import { IconX } from "../icons/IconX/index.es.js";
5
6
  import { SubHeader } from "../SubHeader/index.es.js";
@@ -8,6 +9,7 @@ import { i as isMobile } from "../../isMobile-RyKhTreE.js";
8
9
  import './styles.css';const Modal = ({
9
10
  isOpen,
10
11
  onClose,
12
+ closeOnBackdropClick = false,
11
13
  headerContent,
12
14
  content,
13
15
  layoutMobile = "default",
@@ -24,6 +26,11 @@ import './styles.css';const Modal = ({
24
26
  "au-modal--mobile-centralized": layoutMobile === "centralized",
25
27
  "au-modal--desktop-centralized": layoutDesktop === "centralized"
26
28
  });
29
+ function handleBackdropClick(e) {
30
+ if (closeOnBackdropClick && e.target === e.currentTarget && onClose) {
31
+ onClose();
32
+ }
33
+ }
27
34
  return /* @__PURE__ */ jsx(
28
35
  "div",
29
36
  {
@@ -31,6 +38,7 @@ import './styles.css';const Modal = ({
31
38
  role: "dialog",
32
39
  "aria-modal": "true",
33
40
  "aria-label": ariaLabel ?? mobileModalTitle,
41
+ onClick: handleBackdropClick,
34
42
  "data-testid": dataTestId,
35
43
  children: /* @__PURE__ */ jsxs("div", { className: "au-modal__container", children: [
36
44
  /* @__PURE__ */ jsx("div", { className: "au-modal__header", children: /* @__PURE__ */ jsxs(If, { condition: layoutMobile !== "full-screen" || !isMobile(), children: [
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../../../lib/components/Modal/index.tsx"],"sourcesContent":["import { IconX } from '@components/icons'\nimport { SubHeader } from '@components/SubHeader'\nimport classNames from 'classnames'\nimport { If, IfElse, Then, Else } from '../misc'\n\nimport { isMobile } from '@core/utils/isMobile'\n\nimport './styles.scss'\n\ntype ModalLayout = 'default' | 'centralized'\ntype ModalLayoutMobile = 'default' | 'centralized' | 'full-screen'\n\nexport type ModalProps = {\n isOpen: boolean\n onClose?: () => void\n headerContent?: React.ReactNode | string | JSX.Element | JSX.Element[]\n content?: React.ReactNode | string | JSX.Element | JSX.Element[]\n layoutMobile?: ModalLayoutMobile\n layoutDesktop?: ModalLayout\n mobileModalTitle?: string\n handleHelpInfo?: () => void\n ariaLabel?: string\n 'data-testid'?: string\n}\n\nexport const Modal = ({\n isOpen,\n onClose,\n headerContent,\n content,\n layoutMobile = 'default',\n layoutDesktop = 'default',\n mobileModalTitle = 'Título',\n handleHelpInfo,\n ariaLabel,\n 'data-testid': dataTestId,\n}: ModalProps) => {\n if (!isOpen) return null\n\n const modalClasses = classNames('au-modal', {\n 'au-modal--is-open': isOpen,\n 'au-modal--mobile-full-screen': layoutMobile === 'full-screen',\n 'au-modal--mobile-centralized': layoutMobile === 'centralized',\n 'au-modal--desktop-centralized': layoutDesktop === 'centralized',\n })\n\n return (\n <div\n className={modalClasses}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={ariaLabel ?? mobileModalTitle}\n data-testid={dataTestId}>\n <div className=\"au-modal__container\">\n <div className=\"au-modal__header\">\n <IfElse condition={layoutMobile !== 'full-screen' || !isMobile()}>\n <Then>\n <If condition={!!onClose}>\n <button className=\"au-modal__header-close\" onClick={onClose} aria-label=\"Fechar\">\n <IconX className=\"au-modal__header-close-icon\" aria-hidden=\"true\" />\n </button>\n </If>\n {headerContent}\n </Then>\n <Else>\n <If condition={!!onClose}>\n <SubHeader\n title={mobileModalTitle}\n handleReturn={onClose!}\n handleHelpInfo={handleHelpInfo}\n />\n </If>\n </Else>\n </IfElse>\n </div>\n <div className=\"au-modal__content\">{content}</div>\n </div>\n </div>\n )\n}\n"],"names":["IfElse","If"],"mappings":";;;;;;;AAyBO,MAAM,QAAQ,CAAC;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB;AAAA,EACA;AAAA,EACA,eAAe;AACjB,MAAkB;AAChB,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,eAAe,WAAW,YAAY;AAAA,IAC1C,qBAAqB;AAAA,IACrB,gCAAgC,iBAAiB;AAAA,IACjD,gCAAgC,iBAAiB;AAAA,IACjD,iCAAiC,kBAAkB;AAAA,EAAA,CACpD;AAED,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,MACX,MAAK;AAAA,MACL,cAAW;AAAA,MACX,cAAY,aAAa;AAAA,MACzB,eAAa;AAAA,MACb,UAAA,qBAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,QAAA,oBAAC,OAAA,EAAI,WAAU,oBACb,UAAA,qBAACA,IAAA,EAAO,WAAW,iBAAiB,iBAAiB,CAAC,SAAA,GACpD,UAAA;AAAA,UAAA,qBAAC,MAAA,EACC,UAAA;AAAA,YAAA,oBAACC,MAAA,EAAG,WAAW,CAAC,CAAC,SACf,UAAA,oBAAC,UAAA,EAAO,WAAU,0BAAyB,SAAS,SAAS,cAAW,UACtE,8BAAC,OAAA,EAAM,WAAU,+BAA8B,eAAY,QAAO,GACpE,EAAA,CACF;AAAA,YACC;AAAA,UAAA,GACH;AAAA,8BACC,MAAA,EACC,UAAA,oBAACA,QAAG,WAAW,CAAC,CAAC,SACf,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP,cAAc;AAAA,cACd;AAAA,YAAA;AAAA,UAAA,GAEJ,EAAA,CACF;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QACA,oBAAC,OAAA,EAAI,WAAU,qBAAqB,UAAA,QAAA,CAAQ;AAAA,MAAA,EAAA,CAC9C;AAAA,IAAA;AAAA,EAAA;AAGN;"}
1
+ {"version":3,"file":"index.es.js","sources":["../../../lib/components/Modal/index.tsx"],"sourcesContent":["import { IconX } from '@components/icons'\nimport { SubHeader } from '@components/SubHeader'\nimport classNames from 'classnames'\nimport { If, IfElse, Then, Else } from '../misc'\n\nimport { isMobile } from '@core/utils/isMobile'\n\nimport './styles.scss'\n\ntype ModalLayout = 'default' | 'centralized'\ntype ModalLayoutMobile = 'default' | 'centralized' | 'full-screen'\n\nexport type ModalProps = {\n isOpen: boolean\n onClose?: () => void\n /** Calls onClose when the backdrop (area outside the container) is clicked */\n closeOnBackdropClick?: boolean\n headerContent?: React.ReactNode | string | JSX.Element | JSX.Element[]\n content?: React.ReactNode | string | JSX.Element | JSX.Element[]\n layoutMobile?: ModalLayoutMobile\n layoutDesktop?: ModalLayout\n mobileModalTitle?: string\n handleHelpInfo?: () => void\n ariaLabel?: string\n 'data-testid'?: string\n}\n\nexport const Modal = ({\n isOpen,\n onClose,\n closeOnBackdropClick = false,\n headerContent,\n content,\n layoutMobile = 'default',\n layoutDesktop = 'default',\n mobileModalTitle = 'Título',\n handleHelpInfo,\n ariaLabel,\n 'data-testid': dataTestId,\n}: ModalProps) => {\n if (!isOpen) return null\n\n const modalClasses = classNames('au-modal', {\n 'au-modal--is-open': isOpen,\n 'au-modal--mobile-full-screen': layoutMobile === 'full-screen',\n 'au-modal--mobile-centralized': layoutMobile === 'centralized',\n 'au-modal--desktop-centralized': layoutDesktop === 'centralized',\n })\n\n function handleBackdropClick(e: React.MouseEvent<HTMLDivElement>) {\n if (closeOnBackdropClick && e.target === e.currentTarget && onClose) {\n onClose()\n }\n }\n\n return (\n <div\n className={modalClasses}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={ariaLabel ?? mobileModalTitle}\n onClick={handleBackdropClick}\n data-testid={dataTestId}>\n <div className=\"au-modal__container\">\n <div className=\"au-modal__header\">\n <IfElse condition={layoutMobile !== 'full-screen' || !isMobile()}>\n <Then>\n <If condition={!!onClose}>\n <button className=\"au-modal__header-close\" onClick={onClose} aria-label=\"Fechar\">\n <IconX className=\"au-modal__header-close-icon\" aria-hidden=\"true\" />\n </button>\n </If>\n {headerContent}\n </Then>\n <Else>\n <If condition={!!onClose}>\n <SubHeader\n title={mobileModalTitle}\n handleReturn={onClose!}\n handleHelpInfo={handleHelpInfo}\n />\n </If>\n </Else>\n </IfElse>\n </div>\n <div className=\"au-modal__content\">{content}</div>\n </div>\n </div>\n )\n}\n"],"names":["IfElse","If"],"mappings":";;;;;;;;AA2BO,MAAM,QAAQ,CAAC;AAAA,EACpB;AAAA,EACA;AAAA,EACA,uBAAuB;AAAA,EACvB;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB;AAAA,EACA;AAAA,EACA,eAAe;AACjB,MAAkB;AAChB,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,eAAe,WAAW,YAAY;AAAA,IAC1C,qBAAqB;AAAA,IACrB,gCAAgC,iBAAiB;AAAA,IACjD,gCAAgC,iBAAiB;AAAA,IACjD,iCAAiC,kBAAkB;AAAA,EAAA,CACpD;AAED,WAAS,oBAAoB,GAAqC;AAChE,QAAI,wBAAwB,EAAE,WAAW,EAAE,iBAAiB,SAAS;AACnE,cAAA;AAAA,IACF;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,MACX,MAAK;AAAA,MACL,cAAW;AAAA,MACX,cAAY,aAAa;AAAA,MACzB,SAAS;AAAA,MACT,eAAa;AAAA,MACb,UAAA,qBAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,QAAA,oBAAC,OAAA,EAAI,WAAU,oBACb,UAAA,qBAACA,IAAA,EAAO,WAAW,iBAAiB,iBAAiB,CAAC,SAAA,GACpD,UAAA;AAAA,UAAA,qBAAC,MAAA,EACC,UAAA;AAAA,YAAA,oBAACC,MAAA,EAAG,WAAW,CAAC,CAAC,SACf,UAAA,oBAAC,UAAA,EAAO,WAAU,0BAAyB,SAAS,SAAS,cAAW,UACtE,8BAAC,OAAA,EAAM,WAAU,+BAA8B,eAAY,QAAO,GACpE,EAAA,CACF;AAAA,YACC;AAAA,UAAA,GACH;AAAA,8BACC,MAAA,EACC,UAAA,oBAACA,QAAG,WAAW,CAAC,CAAC,SACf,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP,cAAc;AAAA,cACd;AAAA,YAAA;AAAA,UAAA,GAEJ,EAAA,CACF;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QACA,oBAAC,OAAA,EAAI,WAAU,qBAAqB,UAAA,QAAA,CAAQ;AAAA,MAAA,EAAA,CAC9C;AAAA,IAAA;AAAA,EAAA;AAGN;"}
@@ -1,7 +1,7 @@
1
1
  import { jsx, Fragment } from "react/jsx-runtime";
2
2
  import { a as above } from "../../screen-DfYo7XQ_.js";
3
+ import { B as BREAKPOINT_MD } from "../../tokens-C4yCunfz.js";
3
4
  import { Portal } from "../Portal/index.es.js";
4
- import { B as BREAKPOINT_MD } from "../../tokens-CKZdIZ5O.js";
5
5
  const PortalHolder = ({ withPortal, children }) => {
6
6
  const shouldUsePortal = !above(BREAKPOINT_MD) && withPortal;
7
7
  if (shouldUsePortal) return /* @__PURE__ */ jsx(Portal, { children });
@@ -1,10 +1,11 @@
1
1
  import "react/jsx-runtime";
2
2
  import "../../index-C6Q03EyZ.js";
3
+ import "react";
3
4
  import "../Icon/index.es.js";
4
5
  import "../icons/IconChevronDown/index.es.js";
5
6
  import "../icons/IconChevronLeft/index.es.js";
6
7
  import "../icons/IconX/index.es.js";
7
- import { S } from "../../index-fyDB87KK.js";
8
+ import { S } from "../../index-DnQGzfVW.js";
8
9
  export {
9
10
  S as Segment
10
11
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
1
+ {"version":3,"file":"index.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -10,9 +10,9 @@ import { IconSlash } from "../icons/IconSlash/index.es.js";
10
10
  import { Modal } from "../Modal/index.es.js";
11
11
  import { Text } from "../Text/index.es.js";
12
12
  import { Conditional } from "../Conditional/index.es.js";
13
+ import { c as COLOR_NEUTRAL_40 } from "../../tokens-C4yCunfz.js";
13
14
  import { i as isMobile } from "../../isMobile-RyKhTreE.js";
14
15
  import { F as Field } from "../../index-ZE6zszxw.js";
15
- import { c as COLOR_NEUTRAL_40 } from "../../tokens-CKZdIZ5O.js";
16
16
  import './styles.css';const useSelectField = (options, initialValue, onChange, onBlur, disabled, register, autocomplete = false, fullScreenOptions = false) => {
17
17
  var _a;
18
18
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
@@ -0,0 +1,38 @@
1
+ import { ReactNode } from 'react';
2
+ export type SpecialButtonProps = {
3
+ /**
4
+ * Interaction mode: 'press' is hold-to-confirm (Figma: Press Button),
5
+ * 'slider' is swipe-to-confirm (Figma: Swipe Button).
6
+ * @default 'press'
7
+ */
8
+ type?: 'press' | 'slider';
9
+ children?: ReactNode;
10
+ /** Called once when the interaction completes (hold finished / knob dragged to the end). */
11
+ onConfirm?: () => void;
12
+ disabled?: boolean;
13
+ loading?: boolean;
14
+ /**
15
+ * Controlled success state. The component also enters success on its own
16
+ * right after a completed interaction.
17
+ */
18
+ success?: boolean;
19
+ /**
20
+ * Press only — time in milliseconds the user must keep pressing to confirm.
21
+ * @default 1500
22
+ */
23
+ holdDuration?: number;
24
+ /** Press only — stretches the button to fill the container width. */
25
+ expand?: 'x';
26
+ /** Slider only — visual variant (Figma: Swipe Button, ◇ Type Primary | Secondary). */
27
+ variant?: 'primary' | 'secondary';
28
+ /** Slider only — renders an empty skeleton placeholder. */
29
+ skeleton?: boolean;
30
+ /**
31
+ * Slider only — accessible label for the draggable knob. Pressing Enter or
32
+ * Space on the focused knob confirms directly (keyboard alternative to the
33
+ * swipe gesture).
34
+ */
35
+ knobAriaLabel?: string;
36
+ 'data-testid'?: string;
37
+ };
38
+ export declare const SpecialButton: ({ type, ...props }: SpecialButtonProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,193 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { c as classNames } from "../../index-C6Q03EyZ.js";
3
+ import { useRef, useState, useEffect } from "react";
4
+ import "../Icon/index.es.js";
5
+ import { IconArrowRight } from "../icons/IconArrowRight/index.es.js";
6
+ import { IconCheck } from "../icons/IconCheck/index.es.js";
7
+ import { IconLoader } from "../icons/IconLoader/index.es.js";
8
+ import { IconSlash } from "../icons/IconSlash/index.es.js";
9
+ import { Conditional } from "../Conditional/index.es.js";
10
+ import './styles.css';const KNOB_SIZE = 40;
11
+ const TRACK_PADDING = 4;
12
+ const CONFIRM_THRESHOLD = 0.85;
13
+ const _PressButton = ({
14
+ children = "Hold to confirm",
15
+ onConfirm,
16
+ holdDuration = 1500,
17
+ disabled = false,
18
+ loading = false,
19
+ success = false,
20
+ expand,
21
+ "data-testid": dataTestId
22
+ }) => {
23
+ const [holding, setHolding] = useState(false);
24
+ const [confirmed, setConfirmed] = useState(false);
25
+ const timerRef = useRef();
26
+ const isSuccess = success || confirmed;
27
+ const isInteractive = !disabled && !loading && !isSuccess;
28
+ useEffect(() => () => window.clearTimeout(timerRef.current), []);
29
+ function _startHold() {
30
+ if (!isInteractive || holding) return;
31
+ setHolding(true);
32
+ timerRef.current = window.setTimeout(() => {
33
+ setHolding(false);
34
+ setConfirmed(true);
35
+ if (onConfirm) onConfirm();
36
+ }, holdDuration);
37
+ }
38
+ function _cancelHold() {
39
+ if (!holding) return;
40
+ window.clearTimeout(timerRef.current);
41
+ setHolding(false);
42
+ }
43
+ function handleKeyDown(event) {
44
+ if ((event.key === "Enter" || event.key === " ") && !event.repeat) {
45
+ event.preventDefault();
46
+ _startHold();
47
+ }
48
+ }
49
+ function handleKeyUp(event) {
50
+ if (event.key === "Enter" || event.key === " ") _cancelHold();
51
+ }
52
+ const classes = classNames("au-special-button", "au-special-button--type-press", {
53
+ "au-special-button--holding": holding,
54
+ "au-special-button--disabled": disabled,
55
+ "au-special-button--loading": loading,
56
+ "au-special-button--success": isSuccess,
57
+ [`au-special-button--expand-${expand}`]: !!expand
58
+ });
59
+ return /* @__PURE__ */ jsxs(
60
+ "button",
61
+ {
62
+ type: "button",
63
+ className: classes,
64
+ style: {
65
+ "--au-special-button-duration": `${holdDuration}ms`
66
+ },
67
+ disabled: disabled || loading,
68
+ "aria-busy": loading,
69
+ onPointerDown: _startHold,
70
+ onPointerUp: _cancelHold,
71
+ onPointerLeave: _cancelHold,
72
+ onPointerCancel: _cancelHold,
73
+ onKeyDown: handleKeyDown,
74
+ onKeyUp: handleKeyUp,
75
+ "data-testid": dataTestId,
76
+ children: [
77
+ /* @__PURE__ */ jsx("span", { className: "au-special-button__fill", "aria-hidden": "true" }),
78
+ /* @__PURE__ */ jsx(
79
+ Conditional,
80
+ {
81
+ condition: loading,
82
+ renderIf: /* @__PURE__ */ jsx(IconLoader, {}),
83
+ renderElse: /* @__PURE__ */ jsxs("span", { className: "au-special-button__label", children: [
84
+ disabled && /* @__PURE__ */ jsx(IconSlash, { "aria-hidden": "true" }),
85
+ children
86
+ ] })
87
+ }
88
+ )
89
+ ]
90
+ }
91
+ );
92
+ };
93
+ const _SliderButton = ({
94
+ children = "Slide to action",
95
+ onConfirm,
96
+ variant = "primary",
97
+ disabled = false,
98
+ loading = false,
99
+ success = false,
100
+ skeleton = false,
101
+ knobAriaLabel = "Arraste para confirmar",
102
+ "data-testid": dataTestId
103
+ }) => {
104
+ const containerRef = useRef(null);
105
+ const startXRef = useRef(0);
106
+ const [dragging, setDragging] = useState(false);
107
+ const [dragX, setDragX] = useState(0);
108
+ const [confirmed, setConfirmed] = useState(false);
109
+ const isSuccess = success || confirmed;
110
+ const isInteractive = !disabled && !loading && !isSuccess && !skeleton;
111
+ function _maxDrag() {
112
+ const container = containerRef.current;
113
+ if (!container) return 0;
114
+ return container.clientWidth - KNOB_SIZE - TRACK_PADDING * 2;
115
+ }
116
+ function _confirm() {
117
+ setConfirmed(true);
118
+ if (onConfirm) onConfirm();
119
+ }
120
+ function handlePointerDown(event) {
121
+ var _a, _b;
122
+ if (!isInteractive) return;
123
+ setDragging(true);
124
+ startXRef.current = event.clientX;
125
+ (_b = (_a = event.currentTarget).setPointerCapture) == null ? void 0 : _b.call(_a, event.pointerId);
126
+ }
127
+ function handlePointerMove(event) {
128
+ if (!dragging) return;
129
+ const delta = event.clientX - startXRef.current;
130
+ setDragX(Math.min(Math.max(delta, 0), _maxDrag()));
131
+ }
132
+ function handlePointerEnd() {
133
+ if (!dragging) return;
134
+ setDragging(false);
135
+ const max = _maxDrag();
136
+ if (max > 0 && dragX >= max * CONFIRM_THRESHOLD) _confirm();
137
+ setDragX(0);
138
+ }
139
+ function handleKeyDown(event) {
140
+ if (!isInteractive) return;
141
+ if (event.key === "Enter" || event.key === " ") {
142
+ event.preventDefault();
143
+ _confirm();
144
+ }
145
+ }
146
+ const classes = classNames(
147
+ "au-special-button",
148
+ "au-special-button--type-slider",
149
+ {
150
+ [`au-special-button--variant-${variant}`]: !!variant,
151
+ "au-special-button--dragging": dragging,
152
+ "au-special-button--disabled": disabled,
153
+ "au-special-button--loading": loading,
154
+ "au-special-button--success": isSuccess,
155
+ "au-special-button--skeleton": skeleton
156
+ }
157
+ );
158
+ function _renderKnobIcon() {
159
+ if (isSuccess) return /* @__PURE__ */ jsx(IconCheck, { "aria-hidden": "true" });
160
+ if (disabled) return /* @__PURE__ */ jsx(IconSlash, { "aria-hidden": "true" });
161
+ return /* @__PURE__ */ jsx(IconArrowRight, { "aria-hidden": "true" });
162
+ }
163
+ return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: classes, "data-testid": dataTestId, children: [
164
+ loading && /* @__PURE__ */ jsx(IconLoader, {}),
165
+ !loading && !skeleton && /* @__PURE__ */ jsxs(Fragment, { children: [
166
+ /* @__PURE__ */ jsx("span", { className: "au-special-button__label", children }),
167
+ /* @__PURE__ */ jsx(
168
+ "button",
169
+ {
170
+ type: "button",
171
+ className: "au-special-button__knob",
172
+ "aria-label": knobAriaLabel,
173
+ disabled,
174
+ style: dragX > 0 ? { transform: `translateX(${dragX}px)` } : void 0,
175
+ onPointerDown: handlePointerDown,
176
+ onPointerMove: handlePointerMove,
177
+ onPointerUp: handlePointerEnd,
178
+ onPointerCancel: handlePointerEnd,
179
+ onKeyDown: handleKeyDown,
180
+ children: _renderKnobIcon()
181
+ }
182
+ )
183
+ ] })
184
+ ] });
185
+ };
186
+ const SpecialButton = ({ type = "press", ...props }) => {
187
+ if (type === "slider") return /* @__PURE__ */ jsx(_SliderButton, { ...props });
188
+ return /* @__PURE__ */ jsx(_PressButton, { ...props });
189
+ };
190
+ export {
191
+ SpecialButton
192
+ };
193
+ //# sourceMappingURL=index.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","sources":["../../../lib/components/SpecialButton/index.tsx"],"sourcesContent":["import classNames from 'classnames'\nimport React, { ReactNode, useEffect, useRef, useState } from 'react'\nimport {\n IconArrowRight,\n IconCheck,\n IconLoader,\n IconSlash,\n} from '../icons/default'\nimport { Conditional } from '../misc/Conditional'\nimport './styles.scss'\n\nconst KNOB_SIZE = 40\nconst TRACK_PADDING = 4\nconst CONFIRM_THRESHOLD = 0.85\n\nexport type SpecialButtonProps = {\n /**\n * Interaction mode: 'press' is hold-to-confirm (Figma: Press Button),\n * 'slider' is swipe-to-confirm (Figma: Swipe Button).\n * @default 'press'\n */\n type?: 'press' | 'slider'\n children?: ReactNode\n /** Called once when the interaction completes (hold finished / knob dragged to the end). */\n onConfirm?: () => void\n disabled?: boolean\n loading?: boolean\n /**\n * Controlled success state. The component also enters success on its own\n * right after a completed interaction.\n */\n success?: boolean\n /**\n * Press only — time in milliseconds the user must keep pressing to confirm.\n * @default 1500\n */\n holdDuration?: number\n /** Press only — stretches the button to fill the container width. */\n expand?: 'x'\n /** Slider only — visual variant (Figma: Swipe Button, ◇ Type Primary | Secondary). */\n variant?: 'primary' | 'secondary'\n /** Slider only — renders an empty skeleton placeholder. */\n skeleton?: boolean\n /**\n * Slider only — accessible label for the draggable knob. Pressing Enter or\n * Space on the focused knob confirms directly (keyboard alternative to the\n * swipe gesture).\n */\n knobAriaLabel?: string\n 'data-testid'?: string\n}\n\nconst _PressButton = ({\n children = 'Hold to confirm',\n onConfirm,\n holdDuration = 1500,\n disabled = false,\n loading = false,\n success = false,\n expand,\n 'data-testid': dataTestId,\n}: SpecialButtonProps) => {\n const [holding, setHolding] = useState(false)\n const [confirmed, setConfirmed] = useState(false)\n const timerRef = useRef<number>()\n\n const isSuccess = success || confirmed\n const isInteractive = !disabled && !loading && !isSuccess\n\n useEffect(() => () => window.clearTimeout(timerRef.current), [])\n\n function _startHold() {\n if (!isInteractive || holding) return\n setHolding(true)\n timerRef.current = window.setTimeout(() => {\n setHolding(false)\n setConfirmed(true)\n if (onConfirm) onConfirm()\n }, holdDuration)\n }\n\n function _cancelHold() {\n if (!holding) return\n window.clearTimeout(timerRef.current)\n setHolding(false)\n }\n\n function handleKeyDown(event: React.KeyboardEvent<HTMLButtonElement>) {\n if ((event.key === 'Enter' || event.key === ' ') && !event.repeat) {\n event.preventDefault()\n _startHold()\n }\n }\n\n function handleKeyUp(event: React.KeyboardEvent<HTMLButtonElement>) {\n if (event.key === 'Enter' || event.key === ' ') _cancelHold()\n }\n\n const classes = classNames('au-special-button', 'au-special-button--type-press', {\n 'au-special-button--holding': holding,\n 'au-special-button--disabled': disabled,\n 'au-special-button--loading': loading,\n 'au-special-button--success': isSuccess,\n [`au-special-button--expand-${expand}`]: !!expand,\n })\n\n return (\n <button\n type=\"button\"\n className={classes}\n style={\n {\n '--au-special-button-duration': `${holdDuration}ms`,\n } as React.CSSProperties\n }\n disabled={disabled || loading}\n aria-busy={loading}\n onPointerDown={_startHold}\n onPointerUp={_cancelHold}\n onPointerLeave={_cancelHold}\n onPointerCancel={_cancelHold}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n data-testid={dataTestId}>\n <span className=\"au-special-button__fill\" aria-hidden=\"true\" />\n <Conditional\n condition={loading}\n renderIf={<IconLoader />}\n renderElse={\n <span className=\"au-special-button__label\">\n {disabled && <IconSlash aria-hidden=\"true\" />}\n {children}\n </span>\n }\n />\n </button>\n )\n}\n\nconst _SliderButton = ({\n children = 'Slide to action',\n onConfirm,\n variant = 'primary',\n disabled = false,\n loading = false,\n success = false,\n skeleton = false,\n knobAriaLabel = 'Arraste para confirmar',\n 'data-testid': dataTestId,\n}: SpecialButtonProps) => {\n const containerRef = useRef<HTMLDivElement>(null)\n const startXRef = useRef(0)\n const [dragging, setDragging] = useState(false)\n const [dragX, setDragX] = useState(0)\n const [confirmed, setConfirmed] = useState(false)\n\n const isSuccess = success || confirmed\n const isInteractive = !disabled && !loading && !isSuccess && !skeleton\n\n function _maxDrag() {\n const container = containerRef.current\n if (!container) return 0\n return container.clientWidth - KNOB_SIZE - TRACK_PADDING * 2\n }\n\n function _confirm() {\n setConfirmed(true)\n if (onConfirm) onConfirm()\n }\n\n function handlePointerDown(event: React.PointerEvent<HTMLButtonElement>) {\n if (!isInteractive) return\n setDragging(true)\n startXRef.current = event.clientX\n event.currentTarget.setPointerCapture?.(event.pointerId)\n }\n\n function handlePointerMove(event: React.PointerEvent<HTMLButtonElement>) {\n if (!dragging) return\n const delta = event.clientX - startXRef.current\n setDragX(Math.min(Math.max(delta, 0), _maxDrag()))\n }\n\n function handlePointerEnd() {\n if (!dragging) return\n setDragging(false)\n const max = _maxDrag()\n if (max > 0 && dragX >= max * CONFIRM_THRESHOLD) _confirm()\n setDragX(0)\n }\n\n function handleKeyDown(event: React.KeyboardEvent<HTMLButtonElement>) {\n if (!isInteractive) return\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n _confirm()\n }\n }\n\n const classes = classNames(\n 'au-special-button',\n 'au-special-button--type-slider',\n {\n [`au-special-button--variant-${variant}`]: !!variant,\n 'au-special-button--dragging': dragging,\n 'au-special-button--disabled': disabled,\n 'au-special-button--loading': loading,\n 'au-special-button--success': isSuccess,\n 'au-special-button--skeleton': skeleton,\n },\n )\n\n function _renderKnobIcon() {\n if (isSuccess) return <IconCheck aria-hidden=\"true\" />\n if (disabled) return <IconSlash aria-hidden=\"true\" />\n return <IconArrowRight aria-hidden=\"true\" />\n }\n\n return (\n <div ref={containerRef} className={classes} data-testid={dataTestId}>\n {loading && <IconLoader />}\n {!loading && !skeleton && (\n <>\n <span className=\"au-special-button__label\">{children}</span>\n <button\n type=\"button\"\n className=\"au-special-button__knob\"\n aria-label={knobAriaLabel}\n disabled={disabled}\n style={\n dragX > 0 ? { transform: `translateX(${dragX}px)` } : undefined\n }\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerEnd}\n onPointerCancel={handlePointerEnd}\n onKeyDown={handleKeyDown}>\n {_renderKnobIcon()}\n </button>\n </>\n )}\n </div>\n )\n}\n\nexport const SpecialButton = ({ type = 'press', ...props }: SpecialButtonProps) => {\n if (type === 'slider') return <_SliderButton {...props} />\n return <_PressButton {...props} />\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ .au-special-button{position:relative;display:flex;align-items:center;justify-content:center;height:48px;border-radius:48px;overflow:hidden;background-color:#0048db;color:#fff;font-family:"Source Sans 3",sans-serif;font-size:16px;font-weight:600;-webkit-user-select:none;user-select:none}.au-special-button--type-press{display:inline-flex;gap:8px;padding:8px 16px;border:none;text-align:center;cursor:pointer;touch-action:none;-webkit-tap-highlight-color:transparent}.au-special-button--type-press .au-icon,.au-special-button--type-press .au-icon>svg{width:20px;height:20px;color:#fff}.au-special-button__fill{position:absolute;top:0;left:0;bottom:0;width:0;background-color:#18256c;transition:width .2s ease}.au-special-button__label{position:relative;display:inline-flex;align-items:center;gap:8px}.au-special-button--holding .au-special-button__fill{width:100%;transition:width var(--au-special-button-duration, 1.5s) linear}.au-special-button--type-press.au-special-button--success .au-special-button__fill,.au-special-button--type-press.au-special-button--loading .au-special-button__fill{width:100%;transition:width .3s ease}.au-special-button--type-press.au-special-button--disabled{background-color:#e2e4e9;color:#c4c9d4;cursor:not-allowed}.au-special-button--type-press.au-special-button--disabled .au-icon,.au-special-button--type-press.au-special-button--disabled .au-icon>svg{width:16px;height:16px;color:#c4c9d4}.au-special-button--type-press.au-special-button--loading{cursor:progress}.au-special-button--type-press.au-special-button--loading .au-icon{position:relative;animation:au-special-button-spin 1s infinite linear}.au-special-button--expand-x{width:100%}.au-special-button__knob{position:absolute;top:4px;left:4px;display:flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:none;border-radius:50%;background-color:#fff;box-shadow:0 24px 56px #7686ad14,0 12px 12px #0048db0a;cursor:grab;touch-action:none;transition:transform .2s ease}.au-special-button__knob .au-icon,.au-special-button__knob .au-icon>svg{width:24px;height:24px;color:#0048db}.au-special-button--dragging .au-special-button__knob{cursor:grabbing;transition:none}.au-special-button--type-slider .au-special-button__label{padding:8px 48px}.au-special-button--variant-secondary{background-color:#fff;border:1px solid #0048db;color:#0048db}.au-special-button--type-slider.au-special-button--disabled{background-color:#f6f7fa;border:none;color:#c4c9d4}.au-special-button--type-slider.au-special-button--disabled .au-special-button__knob{background-color:#e2e4e9;box-shadow:none;cursor:not-allowed}.au-special-button--type-slider.au-special-button--disabled .au-special-button__knob .au-icon,.au-special-button--type-slider.au-special-button--disabled .au-special-button__knob .au-icon>svg{color:#c4c9d4}.au-special-button--type-slider.au-special-button--success{background-color:#138040;border:none;color:#fff}.au-special-button--type-slider.au-special-button--success .au-special-button__knob{left:auto;right:4px;cursor:default}.au-special-button--type-slider.au-special-button--success .au-special-button__knob .au-icon,.au-special-button--type-slider.au-special-button--success .au-special-button__knob .au-icon>svg{color:#138040}.au-special-button--variant-secondary.au-special-button--success{background-color:#fff;border:1px solid #10593b;color:#10593b}.au-special-button--variant-secondary.au-special-button--success .au-special-button__knob .au-icon,.au-special-button--variant-secondary.au-special-button--success .au-special-button__knob .au-icon>svg{color:#10593b}.au-special-button--type-slider.au-special-button--loading{background-color:#10593b;border:none;cursor:progress}.au-special-button--type-slider.au-special-button--loading .au-icon{animation:au-special-button-spin 1s infinite linear}.au-special-button--type-slider.au-special-button--loading .au-icon,.au-special-button--type-slider.au-special-button--loading .au-icon>svg{width:20px;height:20px;color:#fff}.au-special-button--skeleton{background-color:#f6f7fa;border:none;animation:au-special-button-pulse 1.5s ease-in-out infinite}@keyframes au-special-button-spin{to{transform:rotate(360deg)}}@keyframes au-special-button-pulse{0%,to{opacity:1}50%{opacity:.6}}
@@ -1,7 +1,11 @@
1
- type SpinnerProps = {
2
- size: number;
3
- color: string;
1
+ export type SpinnerProps = {
2
+ /**
3
+ * Token size (Figma: Spinner, ↕ Size). small = 16px, medium = 20px, large = 32px.
4
+ * @default 'medium'
5
+ */
6
+ size?: 'small' | 'medium' | 'large';
7
+ /** White spinner for colored backgrounds (Figma: Negative). */
8
+ negative?: boolean;
4
9
  'data-testid'?: string;
5
10
  };
6
- export declare const Spinner: React.FC<SpinnerProps>;
7
- export {};
11
+ export declare const Spinner: ({ size, negative, "data-testid": dataTestId, }: SpinnerProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,14 +1,30 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import './styles.css';const Spinner = ({
3
- size,
4
- color,
2
+ import { useId } from "react";
3
+ import { c as classNames } from "../../index-C6Q03EyZ.js";
4
+ import { i as COLOR_NEUTRAL_00, j as COLOR_BRAND_BLUE_40 } from "../../tokens-C4yCunfz.js";
5
+ import './styles.css';const SIZE_MAP = {
6
+ small: 16,
7
+ medium: 20,
8
+ large: 32
9
+ };
10
+ const Spinner = ({
11
+ size = "medium",
12
+ negative = false,
5
13
  "data-testid": dataTestId
6
14
  }) => {
15
+ const uid = useId().replace(/[^a-zA-Z0-9]/g, "");
16
+ const gradientId = `au-spinner-gradient-${uid}`;
17
+ const px = SIZE_MAP[size];
18
+ const color = negative ? COLOR_NEUTRAL_00 : COLOR_BRAND_BLUE_40;
19
+ const classes = classNames("au-spinner", {
20
+ [`au-spinner--size-${size}`]: !!size,
21
+ "au-spinner--negative": negative
22
+ });
7
23
  return /* @__PURE__ */ jsx(
8
24
  "div",
9
25
  {
10
- className: "au-spinner",
11
- style: { width: size, height: size },
26
+ className: classes,
27
+ style: { width: px, height: px },
12
28
  role: "status",
13
29
  "aria-live": "polite",
14
30
  "aria-label": "Carregando",
@@ -19,14 +35,14 @@ import './styles.css';const Spinner = ({
19
35
  "aria-hidden": "true",
20
36
  xmlns: "http://www.w3.org/2000/svg",
21
37
  viewBox: "0 0 64 64",
22
- width: size,
23
- height: size,
38
+ width: px,
39
+ height: px,
24
40
  color,
25
41
  children: [
26
42
  /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
27
43
  "linearGradient",
28
44
  {
29
- id: `au-loading-${color}`,
45
+ id: gradientId,
30
46
  gradientUnits: "objectBoundingBox",
31
47
  x1: "10%",
32
48
  y1: "0%",
@@ -40,13 +56,7 @@ import './styles.css';const Spinner = ({
40
56
  ) }),
41
57
  /* @__PURE__ */ jsxs("g", { strokeWidth: "7", strokeLinecap: "round", fill: "none", children: [
42
58
  /* @__PURE__ */ jsx("path", { stroke: color, d: "M60,32 A28,28 0 1 1 4,32" }),
43
- /* @__PURE__ */ jsx(
44
- "path",
45
- {
46
- d: "M60,32 A28,28.5 0 1 0 4,32",
47
- stroke: `url(#au-loading-${color})`
48
- }
49
- )
59
+ /* @__PURE__ */ jsx("path", { d: "M60,32 A28,28.5 0 1 0 4,32", stroke: `url(#${gradientId})` })
50
60
  ] })
51
61
  ]
52
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../../../lib/components/Spinner/index.tsx"],"sourcesContent":["import './styles.scss'\n\ntype SpinnerProps = {\n size: number\n color: string\n 'data-testid'?: string\n}\n\nexport const Spinner: React.FC<SpinnerProps> = ({\n size,\n color,\n 'data-testid': dataTestId,\n}) => {\n return (\n <div\n className=\"au-spinner\"\n style={{ width: size, height: size }}\n role=\"status\"\n aria-live=\"polite\"\n aria-label=\"Carregando\"\n data-testid={dataTestId}>\n <svg\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 64 64\"\n width={size}\n height={size}\n color={color}>\n <defs>\n <linearGradient\n id={`au-loading-${color}`}\n gradientUnits=\"objectBoundingBox\"\n x1=\"10%\"\n y1=\"0%\"\n x2=\"90%\"\n y2=\"10%\">\n <stop offset=\"0\" stopColor={color} stopOpacity=\"1\" />\n <stop offset=\"1\" stopColor={color} stopOpacity=\"0\" />\n </linearGradient>\n </defs>\n <g strokeWidth=\"7\" strokeLinecap=\"round\" fill=\"none\">\n <path stroke={color} d=\"M60,32 A28,28 0 1 1 4,32\" />\n\n <path\n d=\"M60,32 A28,28.5 0 1 0 4,32\"\n stroke={`url(#au-loading-${color})`}\n />\n </g>\n </svg>\n </div>\n )\n}\n"],"names":[],"mappings":";AAQO,MAAM,UAAkC,CAAC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA,eAAe;AACjB,MAAM;AACJ,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,OAAO,MAAM,QAAQ,KAAA;AAAA,MAC9B,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAW;AAAA,MACX,eAAa;AAAA,MACb,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,eAAY;AAAA,UACZ,OAAM;AAAA,UACN,SAAQ;AAAA,UACR,OAAO;AAAA,UACP,QAAQ;AAAA,UACR;AAAA,UACA,UAAA;AAAA,YAAA,oBAAC,QAAA,EACC,UAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAI,cAAc,KAAK;AAAA,gBACvB,eAAc;AAAA,gBACd,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,UAAA;AAAA,kBAAA,oBAAC,UAAK,QAAO,KAAI,WAAW,OAAO,aAAY,KAAI;AAAA,sCAClD,QAAA,EAAK,QAAO,KAAI,WAAW,OAAO,aAAY,IAAA,CAAI;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA,GAEvD;AAAA,iCACC,KAAA,EAAE,aAAY,KAAI,eAAc,SAAQ,MAAK,QAC5C,UAAA;AAAA,cAAA,oBAAC,QAAA,EAAK,QAAQ,OAAO,GAAE,4BAA2B;AAAA,cAElD;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,GAAE;AAAA,kBACF,QAAQ,mBAAmB,KAAK;AAAA,gBAAA;AAAA,cAAA;AAAA,YAClC,EAAA,CACF;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN;"}
1
+ {"version":3,"file":"index.es.js","sources":["../../../lib/components/Spinner/index.tsx"],"sourcesContent":["import { useId } from 'react'\nimport classNames from 'classnames'\nimport { COLOR_BRAND_BLUE_40, COLOR_NEUTRAL_00 } from '@core/tokens'\nimport './styles.scss'\n\nconst SIZE_MAP = {\n small: 16,\n medium: 20,\n large: 32,\n}\n\nexport type SpinnerProps = {\n /**\n * Token size (Figma: Spinner, ↕ Size). small = 16px, medium = 20px, large = 32px.\n * @default 'medium'\n */\n size?: 'small' | 'medium' | 'large'\n /** White spinner for colored backgrounds (Figma: Negative). */\n negative?: boolean\n 'data-testid'?: string\n}\n\nexport const Spinner = ({\n size = 'medium',\n negative = false,\n 'data-testid': dataTestId,\n}: SpinnerProps) => {\n const uid = useId().replace(/[^a-zA-Z0-9]/g, '')\n const gradientId = `au-spinner-gradient-${uid}`\n const px = SIZE_MAP[size]\n const color = negative ? COLOR_NEUTRAL_00 : COLOR_BRAND_BLUE_40\n\n const classes = classNames('au-spinner', {\n [`au-spinner--size-${size}`]: !!size,\n 'au-spinner--negative': negative,\n })\n\n return (\n <div\n className={classes}\n style={{ width: px, height: px }}\n role=\"status\"\n aria-live=\"polite\"\n aria-label=\"Carregando\"\n data-testid={dataTestId}>\n <svg\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 64 64\"\n width={px}\n height={px}\n color={color}>\n <defs>\n <linearGradient\n id={gradientId}\n gradientUnits=\"objectBoundingBox\"\n x1=\"10%\"\n y1=\"0%\"\n x2=\"90%\"\n y2=\"10%\">\n <stop offset=\"0\" stopColor={color} stopOpacity=\"1\" />\n <stop offset=\"1\" stopColor={color} stopOpacity=\"0\" />\n </linearGradient>\n </defs>\n <g strokeWidth=\"7\" strokeLinecap=\"round\" fill=\"none\">\n <path stroke={color} d=\"M60,32 A28,28 0 1 1 4,32\" />\n\n <path d=\"M60,32 A28,28.5 0 1 0 4,32\" stroke={`url(#${gradientId})`} />\n </g>\n </svg>\n </div>\n )\n}\n"],"names":[],"mappings":";;;;AAKA,MAAM,WAAW;AAAA,EACf,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACT;AAaO,MAAM,UAAU,CAAC;AAAA,EACtB,OAAO;AAAA,EACP,WAAW;AAAA,EACX,eAAe;AACjB,MAAoB;AAClB,QAAM,MAAM,MAAA,EAAQ,QAAQ,iBAAiB,EAAE;AAC/C,QAAM,aAAa,uBAAuB,GAAG;AAC7C,QAAM,KAAK,SAAS,IAAI;AACxB,QAAM,QAAQ,WAAW,mBAAmB;AAE5C,QAAM,UAAU,WAAW,cAAc;AAAA,IACvC,CAAC,oBAAoB,IAAI,EAAE,GAAG,CAAC,CAAC;AAAA,IAChC,wBAAwB;AAAA,EAAA,CACzB;AAED,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,MACX,OAAO,EAAE,OAAO,IAAI,QAAQ,GAAA;AAAA,MAC5B,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAW;AAAA,MACX,eAAa;AAAA,MACb,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,eAAY;AAAA,UACZ,OAAM;AAAA,UACN,SAAQ;AAAA,UACR,OAAO;AAAA,UACP,QAAQ;AAAA,UACR;AAAA,UACA,UAAA;AAAA,YAAA,oBAAC,QAAA,EACC,UAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAI;AAAA,gBACJ,eAAc;AAAA,gBACd,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,UAAA;AAAA,kBAAA,oBAAC,UAAK,QAAO,KAAI,WAAW,OAAO,aAAY,KAAI;AAAA,sCAClD,QAAA,EAAK,QAAO,KAAI,WAAW,OAAO,aAAY,IAAA,CAAI;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA,GAEvD;AAAA,iCACC,KAAA,EAAE,aAAY,KAAI,eAAc,SAAQ,MAAK,QAC5C,UAAA;AAAA,cAAA,oBAAC,QAAA,EAAK,QAAQ,OAAO,GAAE,4BAA2B;AAAA,kCAEjD,QAAA,EAAK,GAAE,8BAA6B,QAAQ,QAAQ,UAAU,IAAA,CAAK;AAAA,YAAA,EAAA,CACtE;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN;"}