@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.
- package/dist/components/Alert/index.d.ts +6 -1
- package/dist/components/Alert/index.es.js +10 -1
- package/dist/components/Alert/index.es.js.map +1 -1
- package/dist/components/Alert/styles.css +1 -1
- package/dist/components/BadgeInfo/index.d.ts +0 -4
- package/dist/components/BadgeInfo/index.es.js +2 -1
- package/dist/components/BadgeInfo/index.es.js.map +1 -1
- package/dist/components/BadgeState/index.es.js +2 -1
- package/dist/components/BadgeState/index.es.js.map +1 -1
- package/dist/components/Button/index.d.ts +9 -0
- package/dist/components/Button/index.es.js.map +1 -1
- package/dist/components/Button/styles.css +1 -1
- package/dist/components/Calendar/index.es.js +2 -2
- package/dist/components/CalendarHeader/index.es.js +3 -2
- package/dist/components/CalendarHeader/index.es.js.map +1 -1
- package/dist/components/Checkbox/index.es.js +1 -1
- package/dist/components/Chip/index.es.js +1 -0
- package/dist/components/Chip/index.es.js.map +1 -1
- package/dist/components/Datepicker/index.es.js +4 -4
- package/dist/components/Drawer/index.d.ts +7 -1
- package/dist/components/Drawer/index.es.js +4 -1
- package/dist/components/Drawer/index.es.js.map +1 -1
- package/dist/components/Drawer/styles.css +1 -1
- package/dist/components/Footer/index.es.js +1 -0
- package/dist/components/Footer/index.es.js.map +1 -1
- package/dist/components/Header/index.es.js +1 -1
- package/dist/components/Icon/index.es.js +14 -2
- package/dist/components/Icon/index.es.js.map +1 -1
- package/dist/components/Image/index.es.js +1 -1
- package/dist/components/Label/index.es.js +2 -1
- package/dist/components/Label/index.es.js.map +1 -1
- package/dist/components/LinkButton/index.d.ts +27 -0
- package/dist/components/LinkButton/index.es.js +56 -0
- package/dist/components/LinkButton/index.es.js.map +1 -0
- package/dist/components/LinkButton/styles.css +1 -0
- package/dist/components/Modal/index.d.ts +3 -1
- package/dist/components/Modal/index.es.js +8 -0
- package/dist/components/Modal/index.es.js.map +1 -1
- package/dist/components/PortalHolder/index.es.js +1 -1
- package/dist/components/Segment/index.es.js +2 -1
- package/dist/components/Segment/index.es.js.map +1 -1
- package/dist/components/SelectField/index.es.js +1 -1
- package/dist/components/SpecialButton/SpecialButton.test.d.ts +1 -0
- package/dist/components/SpecialButton/index.d.ts +38 -0
- package/dist/components/SpecialButton/index.es.js +193 -0
- package/dist/components/SpecialButton/index.es.js.map +1 -0
- package/dist/components/SpecialButton/styles.css +1 -0
- package/dist/components/Spinner/index.d.ts +9 -5
- package/dist/components/Spinner/index.es.js +25 -15
- package/dist/components/Spinner/index.es.js.map +1 -1
- package/dist/components/SubHeader/index.es.js +1 -0
- package/dist/components/SubHeader/index.es.js.map +1 -1
- package/dist/components/Tabs/index.d.ts +3 -4
- package/dist/components/Tabs/index.es.js +80 -84
- package/dist/components/Tabs/index.es.js.map +1 -1
- package/dist/components/Tabs/styles.css +1 -1
- package/dist/components/Tag/index.es.js +8 -86
- package/dist/components/Tag/index.es.js.map +1 -1
- package/dist/components/TextareaField/index.es.js.map +1 -1
- package/dist/components/form/SelectField/types.d.ts +1 -0
- package/dist/components/form/TextareaField/index.d.ts +1 -0
- package/dist/components/icons/Icon.test/index.es.js +23 -5
- package/dist/components/icons/Icon.test/index.es.js.map +1 -1
- package/dist/{index-Dws33tXs.js → index-BgBOcVUP.js} +3 -3
- package/dist/{index-Dws33tXs.js.map → index-BgBOcVUP.js.map} +1 -1
- package/dist/{index-CnXw6SB7.js → index-DHwXRotU.js} +3 -3
- package/dist/{index-CnXw6SB7.js.map → index-DHwXRotU.js.map} +1 -1
- package/dist/{index-fyDB87KK.js → index-DnQGzfVW.js} +3 -3
- package/dist/{index-fyDB87KK.js.map → index-DnQGzfVW.js.map} +1 -1
- package/dist/main.d.ts +3 -1
- package/dist/main.es.js +21 -33
- package/dist/main.es.js.map +1 -1
- package/dist/{tokens-CKZdIZ5O.js → tokens-C4yCunfz.js} +15 -15
- package/dist/{tokens-CKZdIZ5O.js.map → tokens-C4yCunfz.js.map} +1 -1
- package/package.json +3 -3
- package/dist/components/Tag/index.d.ts +0 -22
- package/dist/components/Tag/styles.css +0 -1
- /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-
|
|
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-
|
|
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":"
|
|
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":"
|
|
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-
|
|
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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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
|
-
|
|
3
|
-
|
|
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:
|
|
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
|
|
3
|
-
|
|
4
|
-
|
|
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:
|
|
11
|
-
style: { width:
|
|
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:
|
|
23
|
-
height:
|
|
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:
|
|
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\
|
|
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;"}
|