@astra-kit/ui 0.0.0-stage → 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/CHANGELOG.md +21 -0
- package/LICENSE.md +21 -0
- package/README.md +330 -2
- package/THIRD_PARTY_NOTICES.md +31 -0
- package/assets/fonts/geist-LICENSE.txt +93 -0
- package/assets/fonts/geist-latin-variable.woff2 +0 -0
- package/assets/fonts/ibm-plex-mono-latin-400.woff2 +0 -0
- package/assets/fonts/ibm-plex-mono-latin-500.woff2 +0 -0
- package/assets/fonts/ibmplexmono-LICENSE.txt +93 -0
- package/assets/fonts/inter-LICENSE.txt +93 -0
- package/assets/fonts/inter-latin-variable.woff2 +0 -0
- package/dist/adapters/unpic-image.d.ts +3 -0
- package/dist/adapters/unpic-image.js +98 -0
- package/dist/components/account-menu.d.ts +67 -0
- package/dist/components/account-menu.js +440 -0
- package/dist/components/action-button.d.ts +25 -0
- package/dist/components/action-button.js +264 -0
- package/dist/components/alert.d.ts +31 -0
- package/dist/components/alert.js +503 -0
- package/dist/components/animated-collapse.d.ts +19 -0
- package/dist/components/animated-collapse.js +170 -0
- package/dist/components/animated-count.d.ts +13 -0
- package/dist/components/animated-count.js +105 -0
- package/dist/components/animated-list-item.d.ts +25 -0
- package/dist/components/animated-list-item.js +134 -0
- package/dist/components/animated-theme-toggler.d.ts +12 -0
- package/dist/components/animated-theme-toggler.js +200 -0
- package/dist/components/avatar.d.ts +65 -0
- package/dist/components/avatar.js +463 -0
- package/dist/components/badge.d.ts +21 -0
- package/dist/components/badge.js +297 -0
- package/dist/components/button-interaction.d.ts +23 -0
- package/dist/components/button-interaction.js +22 -0
- package/dist/components/button-label.d.ts +8 -0
- package/dist/components/button-label.js +203 -0
- package/dist/components/button.d.ts +23 -0
- package/dist/components/button.js +145 -0
- package/dist/components/calendar.d.ts +47 -0
- package/dist/components/calendar.js +155 -0
- package/dist/components/card.d.ts +38 -0
- package/dist/components/card.js +904 -0
- package/dist/components/carousel.d.ts +71 -0
- package/dist/components/carousel.js +585 -0
- package/dist/components/checkbox.d.ts +15 -0
- package/dist/components/checkbox.js +324 -0
- package/dist/components/control-button.d.ts +16 -0
- package/dist/components/control-button.js +215 -0
- package/dist/components/data-table.d.ts +118 -0
- package/dist/components/data-table.js +895 -0
- package/dist/components/dialog-surface.d.ts +49 -0
- package/dist/components/dialog-surface.js +220 -0
- package/dist/components/dialog.d.ts +92 -0
- package/dist/components/dialog.js +320 -0
- package/dist/components/dropdown-menu.d.ts +58 -0
- package/dist/components/dropdown-menu.js +135 -0
- package/dist/components/field.d.ts +53 -0
- package/dist/components/field.js +710 -0
- package/dist/components/file-upload.d.ts +88 -0
- package/dist/components/file-upload.js +776 -0
- package/dist/components/filter-presets-bar.d.ts +73 -0
- package/dist/components/filter-presets-bar.js +510 -0
- package/dist/components/filter-query-bar.d.ts +21 -0
- package/dist/components/filter-query-bar.js +881 -0
- package/dist/components/filter-query-grammar.d.ts +188 -0
- package/dist/components/filter-query-grammar.js +875 -0
- package/dist/components/form.d.ts +29 -0
- package/dist/components/form.js +330 -0
- package/dist/components/highlighter.d.ts +15 -0
- package/dist/components/highlighter.js +152 -0
- package/dist/components/hover-card.d.ts +50 -0
- package/dist/components/hover-card.js +80 -0
- package/dist/components/input-group.d.ts +16 -0
- package/dist/components/input-group.js +277 -0
- package/dist/components/input.d.ts +17 -0
- package/dist/components/input.js +120 -0
- package/dist/components/label.d.ts +4 -0
- package/dist/components/label.js +43 -0
- package/dist/components/link.d.ts +9 -0
- package/dist/components/link.js +43 -0
- package/dist/components/morph-text.d.ts +14 -0
- package/dist/components/morph-text.js +210 -0
- package/dist/components/pagination.d.ts +59 -0
- package/dist/components/pagination.js +190 -0
- package/dist/components/popover.d.ts +17 -0
- package/dist/components/popover.js +40 -0
- package/dist/components/presence-swap.d.ts +22 -0
- package/dist/components/presence-swap.js +209 -0
- package/dist/components/primitives/alert-dialog.d.ts +68 -0
- package/dist/components/primitives/alert-dialog.js +629 -0
- package/dist/components/primitives/avatar.d.ts +46 -0
- package/dist/components/primitives/avatar.js +265 -0
- package/dist/components/primitives/calendar.d.ts +37 -0
- package/dist/components/primitives/calendar.js +1250 -0
- package/dist/components/primitives/carousel.d.ts +106 -0
- package/dist/components/primitives/carousel.js +928 -0
- package/dist/components/primitives/dialog.d.ts +62 -0
- package/dist/components/primitives/dialog.js +490 -0
- package/dist/components/primitives/dropdown-menu-items.d.ts +59 -0
- package/dist/components/primitives/dropdown-menu-items.js +265 -0
- package/dist/components/primitives/dropdown-menu.d.ts +64 -0
- package/dist/components/primitives/dropdown-menu.js +560 -0
- package/dist/components/primitives/hover-card.d.ts +50 -0
- package/dist/components/primitives/hover-card.js +507 -0
- package/dist/components/primitives/pagination.d.ts +65 -0
- package/dist/components/primitives/pagination.js +373 -0
- package/dist/components/primitives/popover.d.ts +22 -0
- package/dist/components/primitives/popover.js +213 -0
- package/dist/components/primitives/select.d.ts +37 -0
- package/dist/components/primitives/select.js +428 -0
- package/dist/components/primitives/tooltip.d.ts +30 -0
- package/dist/components/primitives/tooltip.js +277 -0
- package/dist/components/progress-ring.d.ts +20 -0
- package/dist/components/progress-ring.js +53 -0
- package/dist/components/radio-group.d.ts +34 -0
- package/dist/components/radio-group.js +392 -0
- package/dist/components/reaction-button.d.ts +30 -0
- package/dist/components/reaction-button.js +189 -0
- package/dist/components/rich-link-editor.d.ts +25 -0
- package/dist/components/rich-link-editor.js +320 -0
- package/dist/components/rich-markdown-content.d.ts +10 -0
- package/dist/components/rich-markdown-content.js +56 -0
- package/dist/components/rich-text-content.d.ts +19 -0
- package/dist/components/rich-text-content.js +26 -0
- package/dist/components/select.d.ts +55 -0
- package/dist/components/select.js +188 -0
- package/dist/components/separator.d.ts +3 -0
- package/dist/components/separator.js +48 -0
- package/dist/components/sheet.d.ts +19 -0
- package/dist/components/sheet.js +420 -0
- package/dist/components/sidebar-panel-context.d.ts +17 -0
- package/dist/components/sidebar-panel-context.js +14 -0
- package/dist/components/sidebar.d.ts +195 -0
- package/dist/components/sidebar.js +2041 -0
- package/dist/components/skeleton.d.ts +23 -0
- package/dist/components/skeleton.js +334 -0
- package/dist/components/split-button.d.ts +36 -0
- package/dist/components/split-button.js +306 -0
- package/dist/components/svgs/whatsappIcon.d.ts +3 -0
- package/dist/components/svgs/whatsappIcon.js +14 -0
- package/dist/components/switch.d.ts +13 -0
- package/dist/components/switch.js +444 -0
- package/dist/components/table.d.ts +10 -0
- package/dist/components/table.js +298 -0
- package/dist/components/tabs.d.ts +36 -0
- package/dist/components/tabs.js +636 -0
- package/dist/components/textarea.d.ts +16 -0
- package/dist/components/textarea.js +111 -0
- package/dist/components/themed-toaster.d.ts +7 -0
- package/dist/components/themed-toaster.js +86 -0
- package/dist/components/toaster.d.ts +12 -0
- package/dist/components/toaster.js +62 -0
- package/dist/components/tooltip.d.ts +43 -0
- package/dist/components/tooltip.js +65 -0
- package/dist/components/typing-animation.d.ts +34 -0
- package/dist/components/typing-animation.js +389 -0
- package/dist/constants/action-button.d.ts +20 -0
- package/dist/constants/action-button.js +17 -0
- package/dist/constants/alert.d.ts +16 -0
- package/dist/constants/alert.js +13 -0
- package/dist/constants/avatar.d.ts +38 -0
- package/dist/constants/avatar.js +32 -0
- package/dist/constants/badge.d.ts +6 -0
- package/dist/constants/badge.js +6 -0
- package/dist/constants/button.d.ts +16 -0
- package/dist/constants/button.js +16 -0
- package/dist/constants/calendar.d.ts +36 -0
- package/dist/constants/calendar.js +34 -0
- package/dist/constants/card.d.ts +23 -0
- package/dist/constants/card.js +20 -0
- package/dist/constants/carousel.d.ts +55 -0
- package/dist/constants/carousel.js +74 -0
- package/dist/constants/checkbox.d.ts +17 -0
- package/dist/constants/checkbox.js +17 -0
- package/dist/constants/dialog.d.ts +11 -0
- package/dist/constants/dialog.js +10 -0
- package/dist/constants/dropdown-menu.d.ts +17 -0
- package/dist/constants/dropdown-menu.js +48 -0
- package/dist/constants/field.d.ts +24 -0
- package/dist/constants/field.js +24 -0
- package/dist/constants/hover-card.d.ts +37 -0
- package/dist/constants/hover-card.js +85 -0
- package/dist/constants/morph-text.d.ts +13 -0
- package/dist/constants/morph-text.js +13 -0
- package/dist/constants/motion.d.ts +12 -0
- package/dist/constants/motion.js +12 -0
- package/dist/constants/pagination.d.ts +20 -0
- package/dist/constants/pagination.js +20 -0
- package/dist/constants/popover.d.ts +7 -0
- package/dist/constants/popover.js +33 -0
- package/dist/constants/radio-group.d.ts +10 -0
- package/dist/constants/radio-group.js +10 -0
- package/dist/constants/select.d.ts +7 -0
- package/dist/constants/select.js +34 -0
- package/dist/constants/sidebar.d.ts +9 -0
- package/dist/constants/sidebar.js +17 -0
- package/dist/constants/skeleton.d.ts +17 -0
- package/dist/constants/skeleton.js +17 -0
- package/dist/constants/split-button.d.ts +7 -0
- package/dist/constants/split-button.js +5 -0
- package/dist/constants/switch.d.ts +33 -0
- package/dist/constants/switch.js +41 -0
- package/dist/constants/tabs.d.ts +17 -0
- package/dist/constants/tabs.js +17 -0
- package/dist/constants/toast.d.ts +3 -0
- package/dist/constants/toast.js +3 -0
- package/dist/constants/tooltip.d.ts +13 -0
- package/dist/constants/tooltip.js +52 -0
- package/dist/hooks/use-horizontal-swipe.d.ts +23 -0
- package/dist/hooks/use-horizontal-swipe.js +80 -0
- package/dist/hooks/use-is-hydrated.d.ts +6 -0
- package/dist/hooks/use-is-hydrated.js +20 -0
- package/dist/hooks/use-mobile.d.ts +1 -0
- package/dist/hooks/use-mobile.js +19 -0
- package/dist/hooks/use-prefers-reduced-motion.d.ts +2 -0
- package/dist/hooks/use-prefers-reduced-motion.js +27 -0
- package/dist/hooks/use-rich-link-editor.d.ts +55 -0
- package/dist/hooks/use-rich-link-editor.js +515 -0
- package/dist/hooks/use-sidebar-persistence.d.ts +6 -0
- package/dist/hooks/use-sidebar-persistence.js +52 -0
- package/dist/hooks/use-today.d.ts +7 -0
- package/dist/hooks/use-today.js +50 -0
- package/dist/hooks/use-viewer-time-zone.d.ts +6 -0
- package/dist/hooks/use-viewer-time-zone.js +20 -0
- package/dist/hooks.d.ts +11 -0
- package/dist/hooks.js +11 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.js +69 -0
- package/dist/lib/browser-clipboard.d.ts +13 -0
- package/dist/lib/browser-clipboard.js +48 -0
- package/dist/lib/column-filter-value.d.ts +12 -0
- package/dist/lib/column-filter-value.js +52 -0
- package/dist/lib/file-acceptance.d.ts +43 -0
- package/dist/lib/file-acceptance.js +107 -0
- package/dist/lib/format-file-size.d.ts +16 -0
- package/dist/lib/format-file-size.js +34 -0
- package/dist/lib/fuzzy-search.d.ts +17 -0
- package/dist/lib/fuzzy-search.js +183 -0
- package/dist/lib/horizontal-swipe.d.ts +23 -0
- package/dist/lib/horizontal-swipe.js +29 -0
- package/dist/lib/image-dimensions.d.ts +2 -0
- package/dist/lib/image-dimensions.js +7 -0
- package/dist/lib/name-initials.d.ts +7 -0
- package/dist/lib/name-initials.js +11 -0
- package/dist/lib/rich-text/link-markdown-constants.d.ts +147 -0
- package/dist/lib/rich-text/link-markdown-constants.js +458 -0
- package/dist/lib/rich-text/link-markdown-types.d.ts +53 -0
- package/dist/lib/rich-text/link-markdown-types.js +1 -0
- package/dist/lib/rich-text/link-markdown.d.ts +193 -0
- package/dist/lib/rich-text/link-markdown.js +592 -0
- package/dist/lib/rich-text/rich-markdown.d.ts +41 -0
- package/dist/lib/rich-text/rich-markdown.js +105 -0
- package/dist/lib/rich-text/rich-text-editor-dom.d.ts +26 -0
- package/dist/lib/rich-text/rich-text-editor-dom.js +79 -0
- package/dist/lib/toast-layer.d.ts +24 -0
- package/dist/lib/toast-layer.js +76 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +2 -0
- package/dist/lib/year-month-filter.d.ts +16 -0
- package/dist/lib/year-month-filter.js +46 -0
- package/dist/motion/arc-floating-slot.d.ts +40 -0
- package/dist/motion/arc-floating-slot.js +177 -0
- package/dist/motion/arc-press.d.ts +6 -0
- package/dist/motion/arc-press.js +59 -0
- package/dist/motion/arc-swap.d.ts +22 -0
- package/dist/motion/arc-swap.js +49 -0
- package/dist/motion/arc-tokens.d.ts +53 -0
- package/dist/motion/arc-tokens.js +73 -0
- package/dist/motion/glide-indicator.d.ts +69 -0
- package/dist/motion/glide-indicator.js +309 -0
- package/dist/motion/glide-slot.d.ts +9 -0
- package/dist/motion/glide-slot.js +71 -0
- package/dist/motion/motion-slot.d.ts +12 -0
- package/dist/motion/motion-slot.js +376 -0
- package/dist/motion/overlay-warmth.d.ts +24 -0
- package/dist/motion/overlay-warmth.js +70 -0
- package/dist/motion/presence.d.ts +40 -0
- package/dist/motion/presence.js +101 -0
- package/dist/motion/surface-keyframes.d.ts +24 -0
- package/dist/motion/surface-keyframes.js +141 -0
- package/dist/motion/tokens.d.ts +81 -0
- package/dist/motion/tokens.js +67 -0
- package/dist/motion/use-attached-element.d.ts +7 -0
- package/dist/motion/use-attached-element.js +22 -0
- package/dist/motion/use-morph-width.d.ts +13 -0
- package/dist/motion/use-morph-width.js +59 -0
- package/dist/next.d.ts +14 -0
- package/dist/next.js +79 -0
- package/dist/providers/astra-ui-provider.d.ts +27 -0
- package/dist/providers/astra-ui-provider.js +100 -0
- package/dist/providers/native-provider.d.ts +4 -0
- package/dist/providers/native-provider.js +45 -0
- package/dist/sonner.d.ts +7 -0
- package/dist/sonner.js +8 -0
- package/dist/styles.css +2 -0
- package/dist/tanstack.d.ts +11 -0
- package/dist/tanstack.js +50 -0
- package/dist/theme.d.ts +3 -0
- package/dist/theme.js +1 -0
- package/dist/types/data-table.d.ts +27 -0
- package/dist/types/data-table.js +1 -0
- package/fonts.css +5 -0
- package/package.json +450 -4
- package/styles.css +4 -0
- package/theme.css +248 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ButtonProps } from "./button.js";
|
|
2
|
+
export type ActionButtonProps = Omit<ButtonProps, "children" | "loading" | "onClick"> & {
|
|
3
|
+
/** Idle label and the button's accessible name. */
|
|
4
|
+
label: string;
|
|
5
|
+
/** Runs on press; the pending state lasts until its promise settles. */
|
|
6
|
+
onAction: () => void | Promise<void>;
|
|
7
|
+
/** Label while `onAction` runs. */
|
|
8
|
+
pendingLabel?: string;
|
|
9
|
+
/** Label after `onAction` resolves. */
|
|
10
|
+
successLabel?: string;
|
|
11
|
+
/** Delay before returning to idle after success; `0` keeps the success state. */
|
|
12
|
+
resetAfterMs?: number;
|
|
13
|
+
/** Called when `onAction` rejects; the button returns to idle. Without it, the error is logged to the console. */
|
|
14
|
+
onActionError?: (error: unknown) => void;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* A single async commit, such as Save, Publish or Submit, whose result shows on the button itself. While the
|
|
18
|
+
* action runs the button stays focusable (`aria-disabled` and `aria-busy` instead of `disabled`) and ignores new
|
|
19
|
+
* presses; a polite status region announces the pending and success labels. For a plain form submit without a
|
|
20
|
+
* success state, use `Button` with `loading`.
|
|
21
|
+
* @param props - Labels, the action, its error handler, the reset delay and `Button` props except `onClick`.
|
|
22
|
+
* @returns The button followed by its visually hidden status region.
|
|
23
|
+
*/
|
|
24
|
+
declare function ActionButton({ label, onAction, pendingLabel, successLabel, resetAfterMs, onActionError, ...props }: ActionButtonProps): import("react").JSX.Element;
|
|
25
|
+
export { ActionButton };
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { c as _c } from "react/compiler-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Arc's ActionButton (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md) on top of @astra-kit/ui's `Button`: a
|
|
5
|
+
* call to action with a trailing arrow that runs an async action and morphs, letter by letter, through a pending
|
|
6
|
+
* and a success label before returning to idle on its own.
|
|
7
|
+
*/
|
|
8
|
+
import { useEffect, useRef, useState } from "react";
|
|
9
|
+
import { AnimatePresence, motion } from "motion/react";
|
|
10
|
+
import { ArrowRight } from "lucide-react";
|
|
11
|
+
import { ACTION_BUTTON_ARROW_OFFSET_PX, ACTION_BUTTON_CHECK_DRAW_DELAY_S, ACTION_BUTTON_DEFAULT_RESET_AFTER_MS, ACTION_BUTTON_ICON_SIZE_PX, ACTION_BUTTON_STATE } from "../constants/action-button.js";
|
|
12
|
+
import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
|
|
13
|
+
import { ARC_BLUR, ARC_DURATION, ARC_EASE } from "../motion/arc-tokens.js";
|
|
14
|
+
import { ARC_ICON_ENTER as iconEnter, ARC_ICON_EXIT as iconExit, ARC_ICON_TRANSITION as iconTransition, ARC_REDUCED_ENTER as reducedEnter, ARC_REDUCED_EXIT as reducedExit, ARC_REDUCED_TRANSITION as reducedTransition, ARC_SWAP_EXIT_TRANSITION as exitTransition, ARC_SWAP_REST as restState } from "../motion/arc-swap.js";
|
|
15
|
+
import { useMorphWidth } from "../motion/use-morph-width.js";
|
|
16
|
+
import { Button } from "./button.js";
|
|
17
|
+
import { MorphText } from "./morph-text.js";
|
|
18
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
19
|
+
/** The arrow leaves in the direction of the action and returns from behind once the button resets. */
|
|
20
|
+
const arrowEnter = {
|
|
21
|
+
opacity: 0,
|
|
22
|
+
x: ACTION_BUTTON_ARROW_OFFSET_PX.enter,
|
|
23
|
+
filter: `blur(${ARC_BLUR.subtle}px)`
|
|
24
|
+
};
|
|
25
|
+
const arrowExit = {
|
|
26
|
+
opacity: 0,
|
|
27
|
+
x: ACTION_BUTTON_ARROW_OFFSET_PX.exit,
|
|
28
|
+
filter: `blur(${ARC_BLUR.subtle}px)`,
|
|
29
|
+
transition: exitTransition
|
|
30
|
+
};
|
|
31
|
+
const iconSlotStyle = {
|
|
32
|
+
width: ACTION_BUTTON_ICON_SIZE_PX,
|
|
33
|
+
height: ACTION_BUTTON_ICON_SIZE_PX
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* The success tick draws itself from its short stroke, the way a hand would write it.
|
|
37
|
+
* @param props - Whether the user prefers reduced motion, which shows the tick at once.
|
|
38
|
+
* @returns The check icon.
|
|
39
|
+
*/
|
|
40
|
+
function DrawnCheck(t0) {
|
|
41
|
+
const $ = _c(6);
|
|
42
|
+
const { reduceMotion } = t0;
|
|
43
|
+
let t1;
|
|
44
|
+
if ($[0] !== reduceMotion) {
|
|
45
|
+
t1 = reduceMotion ? false : {
|
|
46
|
+
pathLength: 0,
|
|
47
|
+
opacity: 0
|
|
48
|
+
};
|
|
49
|
+
$[0] = reduceMotion;
|
|
50
|
+
$[1] = t1;
|
|
51
|
+
} else {
|
|
52
|
+
t1 = $[1];
|
|
53
|
+
}
|
|
54
|
+
let t2;
|
|
55
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
56
|
+
t2 = {
|
|
57
|
+
pathLength: 1,
|
|
58
|
+
opacity: 1
|
|
59
|
+
};
|
|
60
|
+
$[2] = t2;
|
|
61
|
+
} else {
|
|
62
|
+
t2 = $[2];
|
|
63
|
+
}
|
|
64
|
+
let t3;
|
|
65
|
+
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
|
66
|
+
t3 = {
|
|
67
|
+
pathLength: {
|
|
68
|
+
duration: ARC_DURATION.standard,
|
|
69
|
+
ease: [...ARC_EASE.enter],
|
|
70
|
+
delay: ACTION_BUTTON_CHECK_DRAW_DELAY_S
|
|
71
|
+
},
|
|
72
|
+
opacity: {
|
|
73
|
+
duration: ACTION_BUTTON_CHECK_DRAW_DELAY_S,
|
|
74
|
+
delay: ACTION_BUTTON_CHECK_DRAW_DELAY_S
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
$[3] = t3;
|
|
78
|
+
} else {
|
|
79
|
+
t3 = $[3];
|
|
80
|
+
}
|
|
81
|
+
let t4;
|
|
82
|
+
if ($[4] !== t1) {
|
|
83
|
+
t4 = /* @__PURE__ */ _jsx("svg", {
|
|
84
|
+
width: ACTION_BUTTON_ICON_SIZE_PX,
|
|
85
|
+
height: ACTION_BUTTON_ICON_SIZE_PX,
|
|
86
|
+
viewBox: "0 0 24 24",
|
|
87
|
+
fill: "none",
|
|
88
|
+
stroke: "currentColor",
|
|
89
|
+
strokeWidth: 2,
|
|
90
|
+
strokeLinecap: "round",
|
|
91
|
+
strokeLinejoin: "round",
|
|
92
|
+
children: /* @__PURE__ */ _jsx(motion.path, {
|
|
93
|
+
d: "M4 12l5 5L20 6",
|
|
94
|
+
initial: t1,
|
|
95
|
+
animate: t2,
|
|
96
|
+
transition: t3
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
$[4] = t1;
|
|
100
|
+
$[5] = t4;
|
|
101
|
+
} else {
|
|
102
|
+
t4 = $[5];
|
|
103
|
+
}
|
|
104
|
+
return t4;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Visible content of the button: the morphing label, whose width follows on a spring, and a slot that swaps the
|
|
108
|
+
* arrow, the spinner and the check.
|
|
109
|
+
* @param props - Current state, the text it shows and whether the user prefers reduced motion.
|
|
110
|
+
* @returns Content hidden from assistive tech; the button's name and status region carry its meaning.
|
|
111
|
+
*/
|
|
112
|
+
function ActionButtonContent(t0) {
|
|
113
|
+
const $ = _c(20);
|
|
114
|
+
const { state, text, reduceMotion } = t0;
|
|
115
|
+
const rowRef = useRef(null);
|
|
116
|
+
const width = useMorphWidth(rowRef, text, reduceMotion);
|
|
117
|
+
const isIdle = state === ACTION_BUTTON_STATE.idle;
|
|
118
|
+
let t1;
|
|
119
|
+
if ($[0] !== width) {
|
|
120
|
+
t1 = { width };
|
|
121
|
+
$[0] = width;
|
|
122
|
+
$[1] = t1;
|
|
123
|
+
} else {
|
|
124
|
+
t1 = $[1];
|
|
125
|
+
}
|
|
126
|
+
let t2;
|
|
127
|
+
if ($[2] !== reduceMotion || $[3] !== text) {
|
|
128
|
+
t2 = /* @__PURE__ */ _jsx(MorphText, {
|
|
129
|
+
ref: rowRef,
|
|
130
|
+
text,
|
|
131
|
+
reduceMotion
|
|
132
|
+
});
|
|
133
|
+
$[2] = reduceMotion;
|
|
134
|
+
$[3] = text;
|
|
135
|
+
$[4] = t2;
|
|
136
|
+
} else {
|
|
137
|
+
t2 = $[4];
|
|
138
|
+
}
|
|
139
|
+
let t3;
|
|
140
|
+
if ($[5] !== t1 || $[6] !== t2) {
|
|
141
|
+
t3 = /* @__PURE__ */ _jsx(motion.span, {
|
|
142
|
+
"data-slot": "action-button-label",
|
|
143
|
+
className: "inline-flex min-w-0 data-morphing:[clip-path:inset(-0.6em_0_-0.6em_-0.3em)]",
|
|
144
|
+
style: t1,
|
|
145
|
+
children: t2
|
|
146
|
+
});
|
|
147
|
+
$[5] = t1;
|
|
148
|
+
$[6] = t2;
|
|
149
|
+
$[7] = t3;
|
|
150
|
+
} else {
|
|
151
|
+
t3 = $[7];
|
|
152
|
+
}
|
|
153
|
+
const t4 = reduceMotion ? reducedEnter : isIdle ? arrowEnter : iconEnter;
|
|
154
|
+
const t5 = reduceMotion ? reducedExit : isIdle ? arrowExit : iconExit;
|
|
155
|
+
const t6 = reduceMotion ? reducedTransition : iconTransition;
|
|
156
|
+
let t7;
|
|
157
|
+
if ($[8] !== reduceMotion || $[9] !== state) {
|
|
158
|
+
t7 = state === ACTION_BUTTON_STATE.pending ? /* @__PURE__ */ _jsx("span", { className: "size-4 animate-spin rounded-full border-[1.5px] border-current border-r-transparent motion-reduce:animate-none" }) : state === ACTION_BUTTON_STATE.success ? /* @__PURE__ */ _jsx(DrawnCheck, { reduceMotion }) : /* @__PURE__ */ _jsx(ArrowRight, {
|
|
159
|
+
width: ACTION_BUTTON_ICON_SIZE_PX,
|
|
160
|
+
height: ACTION_BUTTON_ICON_SIZE_PX
|
|
161
|
+
});
|
|
162
|
+
$[8] = reduceMotion;
|
|
163
|
+
$[9] = state;
|
|
164
|
+
$[10] = t7;
|
|
165
|
+
} else {
|
|
166
|
+
t7 = $[10];
|
|
167
|
+
}
|
|
168
|
+
let t8;
|
|
169
|
+
if ($[11] !== state || $[12] !== t4 || $[13] !== t5 || $[14] !== t6 || $[15] !== t7) {
|
|
170
|
+
t8 = /* @__PURE__ */ _jsx("span", {
|
|
171
|
+
className: "grid flex-none place-items-center",
|
|
172
|
+
style: iconSlotStyle,
|
|
173
|
+
children: /* @__PURE__ */ _jsx(AnimatePresence, {
|
|
174
|
+
initial: false,
|
|
175
|
+
children: /* @__PURE__ */ _jsx(motion.span, {
|
|
176
|
+
className: "col-start-1 row-start-1 grid place-items-center",
|
|
177
|
+
style: iconSlotStyle,
|
|
178
|
+
initial: t4,
|
|
179
|
+
animate: restState,
|
|
180
|
+
exit: t5,
|
|
181
|
+
transition: t6,
|
|
182
|
+
children: t7
|
|
183
|
+
}, state)
|
|
184
|
+
})
|
|
185
|
+
});
|
|
186
|
+
$[11] = state;
|
|
187
|
+
$[12] = t4;
|
|
188
|
+
$[13] = t5;
|
|
189
|
+
$[14] = t6;
|
|
190
|
+
$[15] = t7;
|
|
191
|
+
$[16] = t8;
|
|
192
|
+
} else {
|
|
193
|
+
t8 = $[16];
|
|
194
|
+
}
|
|
195
|
+
let t9;
|
|
196
|
+
if ($[17] !== t3 || $[18] !== t8) {
|
|
197
|
+
t9 = /* @__PURE__ */ _jsxs("span", {
|
|
198
|
+
className: "inline-flex items-center justify-center gap-[inherit] whitespace-nowrap",
|
|
199
|
+
"aria-hidden": "true",
|
|
200
|
+
children: [t3, t8]
|
|
201
|
+
});
|
|
202
|
+
$[17] = t3;
|
|
203
|
+
$[18] = t8;
|
|
204
|
+
$[19] = t9;
|
|
205
|
+
} else {
|
|
206
|
+
t9 = $[19];
|
|
207
|
+
}
|
|
208
|
+
return t9;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* A single async commit, such as Save, Publish or Submit, whose result shows on the button itself. While the
|
|
212
|
+
* action runs the button stays focusable (`aria-disabled` and `aria-busy` instead of `disabled`) and ignores new
|
|
213
|
+
* presses; a polite status region announces the pending and success labels. For a plain form submit without a
|
|
214
|
+
* success state, use `Button` with `loading`.
|
|
215
|
+
* @param props - Labels, the action, its error handler, the reset delay and `Button` props except `onClick`.
|
|
216
|
+
* @returns The button followed by its visually hidden status region.
|
|
217
|
+
*/
|
|
218
|
+
function ActionButton({ label, onAction, pendingLabel = "Guardando", successLabel = "Guardado", resetAfterMs = ACTION_BUTTON_DEFAULT_RESET_AFTER_MS, onActionError, ...props }) {
|
|
219
|
+
const [state, setState] = useState(ACTION_BUTTON_STATE.idle);
|
|
220
|
+
const resetTimer = useRef(null);
|
|
221
|
+
const isRunning = useRef(false);
|
|
222
|
+
const reduceMotion = usePrefersReducedMotion();
|
|
223
|
+
const isPending = state === ACTION_BUTTON_STATE.pending;
|
|
224
|
+
const text = isPending ? pendingLabel : state === ACTION_BUTTON_STATE.success ? successLabel : label;
|
|
225
|
+
useEffect(() => () => {
|
|
226
|
+
if (resetTimer.current) clearTimeout(resetTimer.current);
|
|
227
|
+
}, []);
|
|
228
|
+
async function runAction() {
|
|
229
|
+
if (isRunning.current) return;
|
|
230
|
+
isRunning.current = true;
|
|
231
|
+
if (resetTimer.current) clearTimeout(resetTimer.current);
|
|
232
|
+
setState(ACTION_BUTTON_STATE.pending);
|
|
233
|
+
try {
|
|
234
|
+
await onAction();
|
|
235
|
+
setState(ACTION_BUTTON_STATE.success);
|
|
236
|
+
if (resetAfterMs > 0) resetTimer.current = setTimeout(() => setState(ACTION_BUTTON_STATE.idle), resetAfterMs);
|
|
237
|
+
} catch (error) {
|
|
238
|
+
setState(ACTION_BUTTON_STATE.idle);
|
|
239
|
+
if (onActionError) onActionError(error);
|
|
240
|
+
else console.error(`ActionButton:onAction failed for "${label}"; pass onActionError to handle it.`, error);
|
|
241
|
+
} finally {
|
|
242
|
+
isRunning.current = false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return /* @__PURE__ */ _jsxs(_Fragment, { children: [/* @__PURE__ */ _jsx(Button, {
|
|
246
|
+
...props,
|
|
247
|
+
"data-slot": "action-button",
|
|
248
|
+
"data-action-state": state,
|
|
249
|
+
"aria-label": label,
|
|
250
|
+
"aria-busy": isPending || undefined,
|
|
251
|
+
"aria-disabled": isPending || props["aria-disabled"] || undefined,
|
|
252
|
+
onClick: runAction,
|
|
253
|
+
children: /* @__PURE__ */ _jsx(ActionButtonContent, {
|
|
254
|
+
state,
|
|
255
|
+
text,
|
|
256
|
+
reduceMotion
|
|
257
|
+
})
|
|
258
|
+
}), /* @__PURE__ */ _jsx("span", {
|
|
259
|
+
className: "sr-only",
|
|
260
|
+
role: "status",
|
|
261
|
+
children: isPending ? pendingLabel : state === ACTION_BUTTON_STATE.success ? successLabel : ""
|
|
262
|
+
})] });
|
|
263
|
+
}
|
|
264
|
+
export { ActionButton };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from "react";
|
|
2
|
+
import type { AlertTone } from "../constants/alert.js";
|
|
3
|
+
export type { AlertTone };
|
|
4
|
+
export type AlertProps = Omit<ComponentProps<"div">, "title" | "children"> & {
|
|
5
|
+
/** Headline. A new title rises in over the old one. */
|
|
6
|
+
title: string;
|
|
7
|
+
/**
|
|
8
|
+
* Colour and icon: `info` (default), `success`, `warning` or `danger`. Danger interrupts with `role="alert"`; the
|
|
9
|
+
* rest are announced politely with `role="status"`.
|
|
10
|
+
*/
|
|
11
|
+
tone?: AlertTone;
|
|
12
|
+
/** Details under the title. String details rise in over the old ones when they change. */
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
/** Controls presence: hiding the alert collapses its height while it fades out. */
|
|
15
|
+
open?: boolean;
|
|
16
|
+
/** Shows a dismiss button. An uncontrolled alert collapses first and then calls this. */
|
|
17
|
+
onDismiss?: () => void;
|
|
18
|
+
/** Accessible name of the dismiss button; defaults to "Descartar aviso: " followed by the title. */
|
|
19
|
+
dismissLabel?: string;
|
|
20
|
+
/** Replaces the tone icon, or hides it with `false`. */
|
|
21
|
+
icon?: ReactNode;
|
|
22
|
+
/** A control beside the copy, such as a button that resolves the alert. */
|
|
23
|
+
action?: ReactNode;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* A persistent, in-flow message with a tone icon, a title and optional details, action and dismissal.
|
|
27
|
+
* @param props - Title, tone, details, presence and dismissal, extensions and native div attributes.
|
|
28
|
+
* @returns The alert; with `open` or `onDismiss` it collapses its own height when hidden.
|
|
29
|
+
*/
|
|
30
|
+
declare function Alert({ open, onDismiss, ref: consumerRef, ...props }: AlertProps): import("react").JSX.Element;
|
|
31
|
+
export { Alert };
|