@consumidor-positivo/aurora 1.0.0 → 1.1.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.
@@ -33,6 +33,12 @@ export type SpecialButtonProps = {
33
33
  * swipe gesture).
34
34
  */
35
35
  knobAriaLabel?: string;
36
+ /**
37
+ * Slider only — helper text shown below the button after an incomplete
38
+ * drag, guiding the user to slide all the way to the end.
39
+ * @default 'Arraste até o final para confirmar ação'
40
+ */
41
+ incompleteHint?: ReactNode;
36
42
  'data-testid'?: string;
37
43
  };
38
44
  export declare const SpecialButton: ({ type, ...props }: SpecialButtonProps) => import("react/jsx-runtime").JSX.Element;
@@ -9,7 +9,8 @@ import { IconSlash } from "../icons/IconSlash/index.es.js";
9
9
  import { Conditional } from "../Conditional/index.es.js";
10
10
  import './styles.css';const KNOB_SIZE = 40;
11
11
  const TRACK_PADDING = 4;
12
- const CONFIRM_THRESHOLD = 0.85;
12
+ const CONFIRM_THRESHOLD = 0.7;
13
+ const COMPLETE_ANIMATION_MS = 400;
13
14
  const _PressButton = ({
14
15
  children = "Hold to confirm",
15
16
  onConfirm,
@@ -99,15 +100,20 @@ const _SliderButton = ({
99
100
  success = false,
100
101
  skeleton = false,
101
102
  knobAriaLabel = "Arraste para confirmar",
103
+ incompleteHint = "Arraste até o final para confirmar ação",
102
104
  "data-testid": dataTestId
103
105
  }) => {
104
106
  const containerRef = useRef(null);
105
107
  const startXRef = useRef(0);
108
+ const completeTimerRef = useRef();
106
109
  const [dragging, setDragging] = useState(false);
107
110
  const [dragX, setDragX] = useState(0);
111
+ const [completing, setCompleting] = useState(false);
112
+ const [showHint, setShowHint] = useState(false);
108
113
  const [confirmed, setConfirmed] = useState(false);
109
114
  const isSuccess = success || confirmed;
110
- const isInteractive = !disabled && !loading && !isSuccess && !skeleton;
115
+ const isInteractive = !disabled && !loading && !isSuccess && !skeleton && !completing;
116
+ useEffect(() => () => window.clearTimeout(completeTimerRef.current), []);
111
117
  function _maxDrag() {
112
118
  const container = containerRef.current;
113
119
  if (!container) return 0;
@@ -117,6 +123,17 @@ const _SliderButton = ({
117
123
  setConfirmed(true);
118
124
  if (onConfirm) onConfirm();
119
125
  }
126
+ function _complete() {
127
+ setDragging(false);
128
+ setCompleting(true);
129
+ setShowHint(false);
130
+ setDragX(_maxDrag());
131
+ completeTimerRef.current = window.setTimeout(() => {
132
+ setCompleting(false);
133
+ setDragX(0);
134
+ _confirm();
135
+ }, COMPLETE_ANIMATION_MS);
136
+ }
120
137
  function handlePointerDown(event) {
121
138
  var _a, _b;
122
139
  if (!isInteractive) return;
@@ -126,14 +143,16 @@ const _SliderButton = ({
126
143
  }
127
144
  function handlePointerMove(event) {
128
145
  if (!dragging) return;
146
+ const max = _maxDrag();
129
147
  const delta = event.clientX - startXRef.current;
130
- setDragX(Math.min(Math.max(delta, 0), _maxDrag()));
148
+ const next = Math.min(Math.max(delta, 0), max);
149
+ setDragX(next);
150
+ if (max > 0 && next >= max * CONFIRM_THRESHOLD) _complete();
131
151
  }
132
152
  function handlePointerEnd() {
133
153
  if (!dragging) return;
134
154
  setDragging(false);
135
- const max = _maxDrag();
136
- if (max > 0 && dragX >= max * CONFIRM_THRESHOLD) _confirm();
155
+ if (dragX > 0) setShowHint(true);
137
156
  setDragX(0);
138
157
  }
139
158
  function handleKeyDown(event) {
@@ -149,6 +168,7 @@ const _SliderButton = ({
149
168
  {
150
169
  [`au-special-button--variant-${variant}`]: !!variant,
151
170
  "au-special-button--dragging": dragging,
171
+ "au-special-button--completing": completing,
152
172
  "au-special-button--disabled": disabled,
153
173
  "au-special-button--loading": loading,
154
174
  "au-special-button--success": isSuccess,
@@ -160,27 +180,43 @@ const _SliderButton = ({
160
180
  if (disabled) return /* @__PURE__ */ jsx(IconSlash, { "aria-hidden": "true" });
161
181
  return /* @__PURE__ */ jsx(IconArrowRight, { "aria-hidden": "true" });
162
182
  }
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
- ] })
183
+ const maxDrag = _maxDrag();
184
+ const dragProgress = maxDrag > 0 ? dragX / maxDrag : 0;
185
+ return /* @__PURE__ */ jsxs("div", { className: "au-special-button-wrapper", children: [
186
+ /* @__PURE__ */ jsxs(
187
+ "div",
188
+ {
189
+ ref: containerRef,
190
+ className: classes,
191
+ style: {
192
+ "--au-special-button-progress": dragProgress
193
+ },
194
+ "data-testid": dataTestId,
195
+ children: [
196
+ loading && /* @__PURE__ */ jsx(IconLoader, {}),
197
+ !loading && !skeleton && /* @__PURE__ */ jsxs(Fragment, { children: [
198
+ /* @__PURE__ */ jsx("span", { className: "au-special-button__label", children }),
199
+ /* @__PURE__ */ jsx(
200
+ "button",
201
+ {
202
+ type: "button",
203
+ className: "au-special-button__knob",
204
+ "aria-label": knobAriaLabel,
205
+ disabled,
206
+ style: dragX > 0 ? { transform: `translateX(${dragX}px)` } : void 0,
207
+ onPointerDown: handlePointerDown,
208
+ onPointerMove: handlePointerMove,
209
+ onPointerUp: handlePointerEnd,
210
+ onPointerCancel: handlePointerEnd,
211
+ onKeyDown: handleKeyDown,
212
+ children: _renderKnobIcon()
213
+ }
214
+ )
215
+ ] })
216
+ ]
217
+ }
218
+ ),
219
+ showHint && !isSuccess && /* @__PURE__ */ jsx("span", { className: "au-special-button__hint", role: "status", children: incompleteHint })
184
220
  ] });
185
221
  };
186
222
  const SpecialButton = ({ type = "press", ...props }) => {
@@ -1 +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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"}
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\n// Figma (Behavior): a partir de ~70% do trajeto a ação já conta como\n// confirmada e o botão se completa sozinho.\nconst CONFIRM_THRESHOLD = 0.7\nconst COMPLETE_ANIMATION_MS = 400\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 /**\n * Slider only — helper text shown below the button after an incomplete\n * drag, guiding the user to slide all the way to the end.\n * @default 'Arraste até o final para confirmar ação'\n */\n incompleteHint?: ReactNode\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 incompleteHint = 'Arraste até o final para confirmar ação',\n 'data-testid': dataTestId,\n}: SpecialButtonProps) => {\n const containerRef = useRef<HTMLDivElement>(null)\n const startXRef = useRef(0)\n const completeTimerRef = useRef<number>()\n const [dragging, setDragging] = useState(false)\n const [dragX, setDragX] = useState(0)\n const [completing, setCompleting] = useState(false)\n const [showHint, setShowHint] = useState(false)\n const [confirmed, setConfirmed] = useState(false)\n\n const isSuccess = success || confirmed\n const isInteractive =\n !disabled && !loading && !isSuccess && !skeleton && !completing\n\n useEffect(() => () => window.clearTimeout(completeTimerRef.current), [])\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 _complete() {\n setDragging(false)\n setCompleting(true)\n setShowHint(false)\n setDragX(_maxDrag())\n completeTimerRef.current = window.setTimeout(() => {\n setCompleting(false)\n setDragX(0)\n _confirm()\n }, COMPLETE_ANIMATION_MS)\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 max = _maxDrag()\n const delta = event.clientX - startXRef.current\n const next = Math.min(Math.max(delta, 0), max)\n setDragX(next)\n if (max > 0 && next >= max * CONFIRM_THRESHOLD) _complete()\n }\n\n function handlePointerEnd() {\n if (!dragging) return\n setDragging(false)\n if (dragX > 0) setShowHint(true)\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--completing': completing,\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 const maxDrag = _maxDrag()\n const dragProgress = maxDrag > 0 ? dragX / maxDrag : 0\n\n return (\n <div className=\"au-special-button-wrapper\">\n <div\n ref={containerRef}\n className={classes}\n style={\n {\n '--au-special-button-progress': dragProgress,\n } as React.CSSProperties\n }\n 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 {showHint && !isSuccess && (\n <span className=\"au-special-button__hint\" role=\"status\">\n {incompleteHint}\n </span>\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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"}
@@ -1 +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
+ .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--completing .au-special-button__knob{cursor:default;transition:transform .4s ease-out}.au-special-button--type-slider .au-special-button__label{padding:8px 48px;opacity:calc(1 - var(--au-special-button-progress, 0) * 1.4);transition:opacity .1s linear}.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__label{opacity:0}.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}.au-special-button__hint{display:block;margin-top:8px;text-align:center;font-family:"Source Sans 3",sans-serif;font-size:12px;font-weight:400;color:#313131}.au-special-button-wrapper{width:100%}@keyframes au-special-button-spin{to{transform:rotate(360deg)}}@keyframes au-special-button-pulse{0%,to{opacity:1}50%{opacity:.6}}
package/dist/main.d.ts CHANGED
@@ -26,7 +26,7 @@ export { Tabs } from './components/Tabs';
26
26
  export type { TabsProps, TabItemProps } from './components/Tabs';
27
27
  export { Skeleton } from './components/Skeleton';
28
28
  export { Spinner } from './components/Spinner';
29
- export { Image } from '../../../../../../lib/components/Image';
29
+ export { Image } from './components/Image';
30
30
  export { ProgressBar } from './components/ProgressBar';
31
31
  export { Modal } from './components/Modal';
32
32
  export { Tooltip } from './components/Tooltip';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@consumidor-positivo/aurora",
3
3
  "private": false,
4
- "version": "1.0.0",
4
+ "version": "1.1.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/AcordoCertoBR/aurora"