jattac.libs.web.zest-button 1.2.9 → 1.4.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/ZestButton.d.ts +19 -2
- package/dist/ZestDropdownMenu.d.ts +16 -0
- package/dist/ZestDropdownMenuItem.d.ts +9 -0
- package/dist/index.cjs.js +163 -8
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +19 -2
- package/dist/index.esm.js +143 -9
- package/dist/index.esm.js.map +1 -1
- package/docs/e2e/critical-paths.md +75 -0
- package/docs/features/zest-button-dropdown-options/BRS.md +213 -0
- package/docs/guidelines/AI_ARCHITECTURE.md +455 -0
- package/docs/guidelines/AI_BRS.md +435 -0
- package/docs/guidelines/AI_CODE_REVIEW.md +198 -0
- package/docs/guidelines/AI_E2E_TESTING.md +227 -0
- package/docs/guidelines/AI_GIT_WORKFLOW.md +595 -0
- package/docs/guidelines/AI_KNOWLEDGE.md +213 -0
- package/docs/guidelines/AI_PITFALLS.md +245 -0
- package/docs/guidelines/AI_STYLE_GUIDE.md +162 -0
- package/docs/guidelines/AI_TESTING.md +275 -0
- package/docs/guidelines/AI_TEST_CONFIGURATION.md +529 -0
- package/docs/guidelines/AI_WORKFLOW.md +442 -0
- package/docs/guidelines/AI_WORKFLOW_TRIGGERS.md +222 -0
- package/docs/guidelines/ai-knowledge.md +154 -0
- package/docs/guidelines/decision-log.md +149 -0
- package/package.json +78 -69
- package/dist/ZestContext.d.ts +0 -9
- package/dist/ZestProvider.d.ts +0 -8
- package/dist/semanticTypeDefaults.d.ts +0 -4
- package/docs/api.md +0 -140
- package/docs/breaking-changes.md +0 -143
- package/docs/configuration.md +0 -214
- package/docs/development.md +0 -93
- package/docs/examples.md +0 -227
- package/docs/features.md +0 -126
package/dist/ZestButton.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ interface VisualOptions {
|
|
|
19
19
|
/**
|
|
20
20
|
* Behavior during async operations
|
|
21
21
|
*/
|
|
22
|
-
interface BusyOptions {
|
|
22
|
+
export interface BusyOptions {
|
|
23
23
|
handleInternally?: boolean;
|
|
24
24
|
preventRageClick?: boolean;
|
|
25
25
|
minBusyDurationMs?: number;
|
|
@@ -27,7 +27,7 @@ interface BusyOptions {
|
|
|
27
27
|
/**
|
|
28
28
|
* Behavior after a successful or failed click
|
|
29
29
|
*/
|
|
30
|
-
interface SuccessOptions {
|
|
30
|
+
export interface SuccessOptions {
|
|
31
31
|
showCheckmark?: boolean;
|
|
32
32
|
showFailIcon?: boolean;
|
|
33
33
|
autoResetAfterMs?: number;
|
|
@@ -36,6 +36,21 @@ export interface ConfirmOptions {
|
|
|
36
36
|
displayLabel: string;
|
|
37
37
|
timeoutSecs: number;
|
|
38
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* A single secondary action in a ZestButton's dropdown menu. Runs through the
|
|
41
|
+
* same busy/confirm machinery as the main button, independently per item.
|
|
42
|
+
*/
|
|
43
|
+
export interface ZestDropdownOption {
|
|
44
|
+
key?: string;
|
|
45
|
+
label: React.ReactNode;
|
|
46
|
+
icon?: React.ReactNode;
|
|
47
|
+
disabled?: boolean;
|
|
48
|
+
semanticType?: SemanticType;
|
|
49
|
+
onClick?: (e: Event) => void | Promise<void>;
|
|
50
|
+
busyOptions?: BusyOptions;
|
|
51
|
+
successOptions?: SuccessOptions;
|
|
52
|
+
confirmOptions?: ConfirmOptions;
|
|
53
|
+
}
|
|
39
54
|
export interface ZestCustomProps {
|
|
40
55
|
visualOptions?: VisualOptions;
|
|
41
56
|
busyOptions?: BusyOptions;
|
|
@@ -45,6 +60,8 @@ export interface ZestCustomProps {
|
|
|
45
60
|
theme?: ZestTheme;
|
|
46
61
|
buttonStyle?: ZestButtonStyle;
|
|
47
62
|
semanticType?: SemanticType;
|
|
63
|
+
dropdownOptions?: ZestDropdownOption[];
|
|
64
|
+
dropdownAriaLabel?: string;
|
|
48
65
|
}
|
|
49
66
|
/**
|
|
50
67
|
* All supported props
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ZestDropdownOption, ZestVariant, ZestSize, ZestButtonStyle } from "./ZestButton";
|
|
3
|
+
export interface ZestDropdownMenuProps {
|
|
4
|
+
options: ZestDropdownOption[];
|
|
5
|
+
ariaLabel: string;
|
|
6
|
+
open: boolean;
|
|
7
|
+
onOpenChange: (open: boolean) => void;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
onAnyItemBusyChange?: (busy: boolean) => void;
|
|
10
|
+
variant: ZestVariant;
|
|
11
|
+
size: ZestSize;
|
|
12
|
+
buttonStyle: ZestButtonStyle;
|
|
13
|
+
effectiveTheme: "light" | "dark";
|
|
14
|
+
}
|
|
15
|
+
declare const ZestDropdownMenu: React.FC<ZestDropdownMenuProps>;
|
|
16
|
+
export default ZestDropdownMenu;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ZestDropdownOption } from "./ZestButton";
|
|
3
|
+
export interface ZestDropdownMenuItemProps {
|
|
4
|
+
option: ZestDropdownOption;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
onBusyChange?: (busy: boolean) => void;
|
|
7
|
+
}
|
|
8
|
+
declare const ZestDropdownMenuItem: React.FC<ZestDropdownMenuItemProps>;
|
|
9
|
+
export default ZestDropdownMenuItem;
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
3
5
|
var require$$0 = require('react');
|
|
4
6
|
var fa6 = require('react-icons/fa6');
|
|
5
7
|
var fa = require('react-icons/fa');
|
|
8
|
+
var DropdownMenu = require('@radix-ui/react-dropdown-menu');
|
|
9
|
+
|
|
10
|
+
function _interopNamespaceDefault(e) {
|
|
11
|
+
var n = Object.create(null);
|
|
12
|
+
if (e) {
|
|
13
|
+
Object.keys(e).forEach(function (k) {
|
|
14
|
+
if (k !== 'default') {
|
|
15
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
16
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return e[k]; }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
n.default = e;
|
|
24
|
+
return Object.freeze(n);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var DropdownMenu__namespace = /*#__PURE__*/_interopNamespaceDefault(DropdownMenu);
|
|
6
28
|
|
|
7
29
|
var jsxRuntime = {exports: {}};
|
|
8
30
|
|
|
@@ -1386,8 +1408,8 @@ function styleInject(css, ref) {
|
|
|
1386
1408
|
}
|
|
1387
1409
|
}
|
|
1388
1410
|
|
|
1389
|
-
var css_248z = "/* Styles/ZestButton.module.css */\n\n/* Define base variables for light mode */\n:root {\n --zest-color-standard-bg: #1e40af;\n --zest-color-standard-bg-hover: #1a35a0;\n --zest-color-standard-text: white;\n --zest-color-standard-border: #1e40af;\n\n --zest-color-success-bg: #059669;\n --zest-color-success-bg-hover: #047857;\n --zest-color-success-text: white;\n --zest-color-success-border: #059669;\n\n --zest-color-danger-bg: #dc2626;\n --zest-color-danger-bg-hover: #b91c1c;\n --zest-color-danger-text: white;\n --zest-color-danger-border: #dc2626;\n\n --zest-color-disabled-bg: #cbd5e1;\n --zest-color-disabled-bg-hover: #aeb9c4;\n --zest-color-disabled-text: #6b7280;\n --zest-color-disabled-border: #cbd5e1;\n\n --zest-color-icon-success: #10b981;\n --zest-color-icon-fail: #ef4444;\n}\n\n/* Dark mode adjustments via system preference */\n@media (prefers-color-scheme: dark) {\n :root {\n --zest-color-standard-bg: #3b82f6;\n --zest-color-standard-bg-hover: #2563eb;\n --zest-color-standard-text: white;\n --zest-color-standard-border: #3b82f6;\n\n --zest-color-success-bg: #34d399;\n --zest-color-success-bg-hover: #10b981;\n --zest-color-success-text: white;\n --zest-color-success-border: #34d399;\n\n --zest-color-danger-bg: #ef4444;\n --zest-color-danger-bg-hover: #dc2626;\n --zest-color-danger-text: white;\n --zest-color-danger-border: #ef4444;\n\n --zest-color-disabled-bg: #4b5563;\n --zest-color-disabled-bg-hover: #6b7280;\n --zest-color-disabled-text: #9ca3af;\n --zest-color-disabled-border: #4b5563;\n\n --zest-color-icon-success: #34d399;\n --zest-color-icon-fail: #ef4444;\n }\n}\n\n/* Theme override classes */\n.ZestButton-module_force-light__zZTIZ {\n --zest-color-standard-bg: #1e40af;\n --zest-color-standard-bg-hover: #1a35a0;\n --zest-color-standard-text: white;\n --zest-color-standard-border: #1e40af;\n\n --zest-color-success-bg: #059669;\n --zest-color-success-bg-hover: #047857;\n --zest-color-success-text: white;\n --zest-color-success-border: #059669;\n\n --zest-color-danger-bg: #dc2626;\n --zest-color-danger-bg-hover: #b91c1c;\n --zest-color-danger-text: white;\n --zest-color-danger-border: #dc2626;\n\n --zest-color-disabled-bg: #cbd5e1;\n --zest-color-disabled-bg-hover: #aeb9c4;\n --zest-color-disabled-text: #6b7280;\n --zest-color-disabled-border: #cbd5e1;\n\n --zest-color-icon-success: #10b981;\n --zest-color-icon-fail: #ef4444;\n}\n\n.ZestButton-module_force-dark__cx74D {\n --zest-color-standard-bg: #3b82f6;\n --zest-color-standard-bg-hover: #2563eb;\n --zest-color-standard-text: white;\n --zest-color-standard-border: #3b82f6;\n\n --zest-color-success-bg: #34d399;\n --zest-color-success-bg-hover: #10b981;\n --zest-color-success-text: white;\n --zest-color-success-border: #34d399;\n\n --zest-color-danger-bg: #ef4444;\n --zest-color-danger-bg-hover: #dc2626;\n --zest-color-danger-text: white;\n --zest-color-danger-border: #ef4444;\n\n --zest-color-disabled-bg: #4b5563;\n --zest-color-disabled-bg-hover: #6b7280;\n --zest-color-disabled-text: #9ca3af;\n --zest-color-disabled-border: #4b5563;\n\n --zest-color-icon-success: #34d399;\n --zest-color-icon-fail: #ef4444;\n}\n\n\n.ZestButton-module_button__KDafc {\n font-family: \"Segoe UI\", Roboto, sans-serif;\n font-weight: 600;\n border-radius: 8px;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, border-color 0.2s ease;\n position: relative;\n padding: 0.6em 1.2em;\n overflow: hidden;\n border: none; /* Default to no border, overridden by outline/dashed */\n}\n\n/* Base styles for different button styles */\n.ZestButton-module_solid__cu4tr {\n background-color: var(--zest-color-standard-bg);\n color: var(--zest-color-standard-text);\n}\n.ZestButton-module_solid__cu4tr:hover:not(:disabled) {\n background-color: var(--zest-color-standard-bg-hover);\n}\n\n.ZestButton-module_outline__esgLq {\n background-color: transparent;\n border: 2px solid var(--zest-color-standard-border);\n color: var(--zest-color-standard-border);\n}\n.ZestButton-module_outline__esgLq:hover:not(:disabled) {\n background-color: var(--zest-color-standard-bg);\n color: var(--zest-color-standard-text);\n}\n\n.ZestButton-module_text__8X1xD {\n background-color: transparent;\n border: none;\n color: var(--zest-color-standard-bg);\n}\n.ZestButton-module_text__8X1xD:hover:not(:disabled) {\n background-color: rgba(var(--zest-color-standard-bg-rgb, 30, 64, 175), 0.1); /* Fallback RGB for text hover */\n}\n\n.ZestButton-module_dashed__ebKYF {\n background-color: transparent;\n border: 2px dashed var(--zest-color-standard-border);\n color: var(--zest-color-standard-border);\n}\n.ZestButton-module_dashed__ebKYF:hover:not(:disabled) {\n background-color: rgba(var(--zest-color-standard-bg-rgb, 30, 64, 175), 0.1); /* Fallback RGB for dashed hover */\n}\n\n\n/* Variant overrides for solid style */\n.ZestButton-module_solid__cu4tr.ZestButton-module_standard__T3EGM { /* Already handled by .solid base */ }\n.ZestButton-module_solid__cu4tr.ZestButton-module_success__XEptA {\n background-color: var(--zest-color-success-bg);\n color: var(--zest-color-success-text);\n}\n.ZestButton-module_solid__cu4tr.ZestButton-module_success__XEptA:hover:not(:disabled) {\n background-color: var(--zest-color-success-bg-hover);\n}\n.ZestButton-module_solid__cu4tr.ZestButton-module_danger__nJpJ- {\n background-color: var(--zest-color-danger-bg);\n color: var(--zest-color-danger-text);\n}\n.ZestButton-module_solid__cu4tr.ZestButton-module_danger__nJpJ-:hover:not(:disabled) {\n background-color: var(--zest-color-danger-bg-hover);\n}\n\n/* Variant overrides for outline style */\n.ZestButton-module_outline__esgLq.ZestButton-module_standard__T3EGM { /* Already handled by .outline base */ }\n.ZestButton-module_outline__esgLq.ZestButton-module_success__XEptA {\n border-color: var(--zest-color-success-border);\n color: var(--zest-color-success-border);\n}\n.ZestButton-module_outline__esgLq.ZestButton-module_success__XEptA:hover:not(:disabled) {\n background-color: var(--zest-color-success-bg);\n color: var(--zest-color-success-text);\n}\n.ZestButton-module_outline__esgLq.ZestButton-module_danger__nJpJ- {\n border-color: var(--zest-color-danger-border);\n color: var(--zest-color-danger-border);\n}\n.ZestButton-module_outline__esgLq.ZestButton-module_danger__nJpJ-:hover:not(:disabled) {\n background-color: var(--zest-color-danger-bg);\n color: var(--zest-color-danger-text);\n}\n\n/* Variant overrides for text style */\n.ZestButton-module_text__8X1xD.ZestButton-module_standard__T3EGM { /* Already handled by .text base */ }\n.ZestButton-module_text__8X1xD.ZestButton-module_success__XEptA {\n color: var(--zest-color-success-bg);\n}\n.ZestButton-module_text__8X1xD.ZestButton-module_success__XEptA:hover:not(:disabled) {\n background-color: rgba(var(--zest-color-success-bg-rgb, 5, 150, 105), 0.1);\n}\n.ZestButton-module_text__8X1xD.ZestButton-module_danger__nJpJ- {\n color: var(--zest-color-danger-bg);\n}\n.ZestButton-module_text__8X1xD.ZestButton-module_danger__nJpJ-:hover:not(:disabled) {\n background-color: rgba(var(--zest-color-danger-bg-rgb, 220, 38, 38), 0.1);\n}\n\n/* Variant overrides for dashed style */\n.ZestButton-module_dashed__ebKYF.ZestButton-module_standard__T3EGM { /* Already handled by .dashed base */ }\n.ZestButton-module_dashed__ebKYF.ZestButton-module_success__XEptA {\n border-color: var(--zest-color-success-border);\n color: var(--zest-color-success-border);\n}\n.ZestButton-module_dashed__ebKYF.ZestButton-module_success__XEptA:hover:not(:disabled) {\n background-color: rgba(var(--zest-color-success-bg-rgb, 5, 150, 105), 0.1);\n}\n.ZestButton-module_dashed__ebKYF.ZestButton-module_danger__nJpJ- {\n border-color: var(--zest-color-danger-border);\n color: var(--zest-color-danger-border);\n}\n.ZestButton-module_dashed__ebKYF.ZestButton-module_danger__nJpJ-:hover:not(:disabled) {\n background-color: rgba(var(--zest-color-danger-bg-rgb, 220, 38, 38), 0.1);\n}\n\n\n/* Disabled state overrides for different button styles */\n.ZestButton-module_solid__cu4tr:disabled, .ZestButton-module_solid__cu4tr.ZestButton-module_disabled__gw6y3 {\n background-color: var(--zest-color-disabled-bg);\n color: var(--zest-color-disabled-text);\n border-color: var(--zest-color-disabled-border);\n}\n.ZestButton-module_outline__esgLq:disabled, .ZestButton-module_outline__esgLq.ZestButton-module_disabled__gw6y3 {\n background-color: transparent;\n border-color: var(--zest-color-disabled-border);\n color: var(--zest-color-disabled-text);\n}\n.ZestButton-module_text__8X1xD:disabled, .ZestButton-module_text__8X1xD.ZestButton-module_disabled__gw6y3 {\n background-color: transparent;\n color: var(--zest-color-disabled-text);\n}\n.ZestButton-module_dashed__ebKYF:disabled, .ZestButton-module_dashed__ebKYF.ZestButton-module_disabled__gw6y3 {\n background-color: transparent;\n border-color: var(--zest-color-disabled-border);\n color: var(--zest-color-disabled-text);\n}\n\n\n/* Layout */\n.ZestButton-module_stretch__CTLNw {\n width: 100%;\n}\n\n.ZestButton-module_sm__G1vAP {\n font-size: 0.85rem;\n padding: 0.4em 0.8em;\n}\n\n.ZestButton-module_md__Y-PMO {\n font-size: 1rem;\n padding: 0.6em 1.2em;\n}\n\n.ZestButton-module_lg__AQgdf {\n font-size: 1.125rem;\n padding: 0.8em 1.6em;\n}\n\n.ZestButton-module_inner__1j2Fr {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n}\n\n.ZestButton-module_spinner__l2hLe {\n position: absolute;\n width: 1em;\n height: 1em;\n animation: ZestButton-module_spin__4asdw 0.75s linear infinite;\n color: currentColor; /* Inherit color from button text */\n}\n\n.ZestButton-module_content__hlea3 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5em;\n}\n\n.ZestButton-module_label__8x263 {\n display: inline-block;\n}\n\n.ZestButton-module_icon__B3DFi {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Success + Fail Icons */\n.ZestButton-module_animatedCheck__8K4K- {\n width: 1.25em;\n height: 1.25em;\n color: var(--zest-color-icon-success);\n animation: ZestButton-module_fadeIn__iEave 0.25s ease-out;\n}\n\n.ZestButton-module_animatedX__KQnt7 {\n width: 1.25em;\n height: 1.25em;\n color: var(--zest-color-icon-fail);\n animation: ZestButton-module_fadeIn__iEave 0.25s ease-out;\n}\n\n/* Stroke animations */\n.ZestButton-module_animatedCheck__8K4K- path {\n stroke-dasharray: 24;\n stroke-dashoffset: 24;\n animation: ZestButton-module_drawCheck__3DyjT 0.4s ease-out forwards;\n}\n\n.ZestButton-module_animatedX__KQnt7 line {\n stroke-dasharray: 24;\n stroke-dashoffset: 24;\n animation: ZestButton-module_drawCheck__3DyjT 0.4s ease-out forwards;\n}\n\n/* New: apply spacing between left icon and text */\n.ZestButton-module_icon__B3DFi:first-child {\n margin-right: 0.7em;\n}\n\n/* Optional override for iconRight if needed */\n.ZestButton-module_icon__B3DFi:last-child {\n margin-left: 0.7em;\n}\n\n/* Animations */\n@keyframes ZestButton-module_spin__4asdw {\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes ZestButton-module_drawCheck__3DyjT {\n to {\n stroke-dashoffset: 0;\n }\n}\n\n@keyframes ZestButton-module_fadeIn__iEave {\n from {\n opacity: 0;\n transform: scale(0.8);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes ZestButton-module_shakeIt__ox-R3 {\n 0%,\n 100% {\n transform: translateX(0);\n }\n 20%,\n 60% {\n transform: translateX(-4px);\n }\n 40%,\n 80% {\n transform: translateX(4px);\n }\n}\n\n.ZestButton-module_shake__NtIjf {\n animation: ZestButton-module_shakeIt__ox-R3 0.4s ease;\n box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.6);\n}\n\n/* Mobile-first adjustments for hit area */\n@media (max-width: 768px) {\n .ZestButton-module_button__KDafc {\n min-height: 44px; /* Ensure a minimum touch target size for accessibility */\n }\n\n .ZestButton-module_sm__G1vAP {\n padding: 0.6em 1em; /* Increase padding for small buttons on mobile */\n }\n\n .ZestButton-module_md__Y-PMO {\n padding: 0.8em 1.4em; /* Slightly increase padding for medium buttons on mobile */\n }\n}\n\n";
|
|
1390
|
-
var styles = {"force-light":"ZestButton-module_force-light__zZTIZ","force-dark":"ZestButton-module_force-dark__cx74D","button":"ZestButton-module_button__KDafc","solid":"ZestButton-module_solid__cu4tr","outline":"ZestButton-module_outline__esgLq","text":"ZestButton-module_text__8X1xD","dashed":"ZestButton-module_dashed__ebKYF","standard":"ZestButton-module_standard__T3EGM","success":"ZestButton-module_success__XEptA","danger":"ZestButton-module_danger__nJpJ-","disabled":"ZestButton-module_disabled__gw6y3","stretch":"ZestButton-module_stretch__CTLNw","sm":"ZestButton-module_sm__G1vAP","md":"ZestButton-module_md__Y-PMO","lg":"ZestButton-module_lg__AQgdf","inner":"ZestButton-module_inner__1j2Fr","spinner":"ZestButton-module_spinner__l2hLe","spin":"ZestButton-module_spin__4asdw","content":"ZestButton-module_content__hlea3","label":"ZestButton-module_label__8x263","icon":"ZestButton-module_icon__B3DFi","animatedCheck":"ZestButton-module_animatedCheck__8K4K-","fadeIn":"ZestButton-module_fadeIn__iEave","animatedX":"ZestButton-module_animatedX__KQnt7","drawCheck":"ZestButton-module_drawCheck__3DyjT","shake":"ZestButton-module_shake__NtIjf","shakeIt":"ZestButton-module_shakeIt__ox-R3"};
|
|
1411
|
+
var css_248z = "/* Styles/ZestButton.module.css */\r\n\r\n/* Define base variables for light mode */\r\n:root {\r\n --zest-color-standard-bg: #1e40af;\r\n --zest-color-standard-bg-hover: #1a35a0;\r\n --zest-color-standard-text: white;\r\n --zest-color-standard-border: #1e40af;\r\n\r\n --zest-color-success-bg: #059669;\r\n --zest-color-success-bg-hover: #047857;\r\n --zest-color-success-text: white;\r\n --zest-color-success-border: #059669;\r\n\r\n --zest-color-danger-bg: #dc2626;\r\n --zest-color-danger-bg-hover: #b91c1c;\r\n --zest-color-danger-text: white;\r\n --zest-color-danger-border: #dc2626;\r\n\r\n --zest-color-disabled-bg: #cbd5e1;\r\n --zest-color-disabled-bg-hover: #aeb9c4;\r\n --zest-color-disabled-text: #6b7280;\r\n --zest-color-disabled-border: #cbd5e1;\r\n\r\n --zest-color-icon-success: #10b981;\r\n --zest-color-icon-fail: #ef4444;\r\n}\r\n\r\n/* Dark mode adjustments via system preference */\r\n@media (prefers-color-scheme: dark) {\r\n :root {\r\n --zest-color-standard-bg: #3b82f6;\r\n --zest-color-standard-bg-hover: #2563eb;\r\n --zest-color-standard-text: white;\r\n --zest-color-standard-border: #3b82f6;\r\n\r\n --zest-color-success-bg: #34d399;\r\n --zest-color-success-bg-hover: #10b981;\r\n --zest-color-success-text: white;\r\n --zest-color-success-border: #34d399;\r\n\r\n --zest-color-danger-bg: #ef4444;\r\n --zest-color-danger-bg-hover: #dc2626;\r\n --zest-color-danger-text: white;\r\n --zest-color-danger-border: #ef4444;\r\n\r\n --zest-color-disabled-bg: #4b5563;\r\n --zest-color-disabled-bg-hover: #6b7280;\r\n --zest-color-disabled-text: #9ca3af;\r\n --zest-color-disabled-border: #4b5563;\r\n\r\n --zest-color-icon-success: #34d399;\r\n --zest-color-icon-fail: #ef4444;\r\n }\r\n}\r\n\r\n/* Theme override classes */\r\n.ZestButton-module_force-light__zZTIZ {\r\n --zest-color-standard-bg: #1e40af;\r\n --zest-color-standard-bg-hover: #1a35a0;\r\n --zest-color-standard-text: white;\r\n --zest-color-standard-border: #1e40af;\r\n\r\n --zest-color-success-bg: #059669;\r\n --zest-color-success-bg-hover: #047857;\r\n --zest-color-success-text: white;\r\n --zest-color-success-border: #059669;\r\n\r\n --zest-color-danger-bg: #dc2626;\r\n --zest-color-danger-bg-hover: #b91c1c;\r\n --zest-color-danger-text: white;\r\n --zest-color-danger-border: #dc2626;\r\n\r\n --zest-color-disabled-bg: #cbd5e1;\r\n --zest-color-disabled-bg-hover: #aeb9c4;\r\n --zest-color-disabled-text: #6b7280;\r\n --zest-color-disabled-border: #cbd5e1;\r\n\r\n --zest-color-icon-success: #10b981;\r\n --zest-color-icon-fail: #ef4444;\r\n}\r\n\r\n.ZestButton-module_force-dark__cx74D {\r\n --zest-color-standard-bg: #3b82f6;\r\n --zest-color-standard-bg-hover: #2563eb;\r\n --zest-color-standard-text: white;\r\n --zest-color-standard-border: #3b82f6;\r\n\r\n --zest-color-success-bg: #34d399;\r\n --zest-color-success-bg-hover: #10b981;\r\n --zest-color-success-text: white;\r\n --zest-color-success-border: #34d399;\r\n\r\n --zest-color-danger-bg: #ef4444;\r\n --zest-color-danger-bg-hover: #dc2626;\r\n --zest-color-danger-text: white;\r\n --zest-color-danger-border: #ef4444;\r\n\r\n --zest-color-disabled-bg: #4b5563;\r\n --zest-color-disabled-bg-hover: #6b7280;\r\n --zest-color-disabled-text: #9ca3af;\r\n --zest-color-disabled-border: #4b5563;\r\n\r\n --zest-color-icon-success: #34d399;\r\n --zest-color-icon-fail: #ef4444;\r\n}\r\n\r\n\r\n.ZestButton-module_button__KDafc {\r\n font-family: \"Segoe UI\", Roboto, sans-serif;\r\n font-weight: 600;\r\n border-radius: 8px;\r\n cursor: pointer;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: background-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, border-color 0.2s ease;\r\n position: relative;\r\n padding: 0.6em 1.2em;\r\n overflow: hidden;\r\n border: none; /* Default to no border, overridden by outline/dashed */\r\n}\r\n\r\n/* Base styles for different button styles */\r\n.ZestButton-module_solid__cu4tr {\r\n background-color: var(--zest-color-standard-bg);\r\n color: var(--zest-color-standard-text);\r\n}\r\n.ZestButton-module_solid__cu4tr:hover:not(:disabled) {\r\n background-color: var(--zest-color-standard-bg-hover);\r\n}\r\n\r\n.ZestButton-module_outline__esgLq {\r\n background-color: transparent;\r\n border: 2px solid var(--zest-color-standard-border);\r\n color: var(--zest-color-standard-border);\r\n}\r\n.ZestButton-module_outline__esgLq:hover:not(:disabled) {\r\n background-color: var(--zest-color-standard-bg);\r\n color: var(--zest-color-standard-text);\r\n}\r\n\r\n.ZestButton-module_text__8X1xD {\r\n background-color: transparent;\r\n border: none;\r\n color: var(--zest-color-standard-bg);\r\n}\r\n.ZestButton-module_text__8X1xD:hover:not(:disabled) {\r\n background-color: rgba(var(--zest-color-standard-bg-rgb, 30, 64, 175), 0.1); /* Fallback RGB for text hover */\r\n}\r\n\r\n.ZestButton-module_dashed__ebKYF {\r\n background-color: transparent;\r\n border: 2px dashed var(--zest-color-standard-border);\r\n color: var(--zest-color-standard-border);\r\n}\r\n.ZestButton-module_dashed__ebKYF:hover:not(:disabled) {\r\n background-color: rgba(var(--zest-color-standard-bg-rgb, 30, 64, 175), 0.1); /* Fallback RGB for dashed hover */\r\n}\r\n\r\n\r\n/* Variant overrides for solid style */\r\n.ZestButton-module_solid__cu4tr.ZestButton-module_standard__T3EGM { /* Already handled by .solid base */ }\r\n.ZestButton-module_solid__cu4tr.ZestButton-module_success__XEptA {\r\n background-color: var(--zest-color-success-bg);\r\n color: var(--zest-color-success-text);\r\n}\r\n.ZestButton-module_solid__cu4tr.ZestButton-module_success__XEptA:hover:not(:disabled) {\r\n background-color: var(--zest-color-success-bg-hover);\r\n}\r\n.ZestButton-module_solid__cu4tr.ZestButton-module_danger__nJpJ- {\r\n background-color: var(--zest-color-danger-bg);\r\n color: var(--zest-color-danger-text);\r\n}\r\n.ZestButton-module_solid__cu4tr.ZestButton-module_danger__nJpJ-:hover:not(:disabled) {\r\n background-color: var(--zest-color-danger-bg-hover);\r\n}\r\n\r\n/* Variant overrides for outline style */\r\n.ZestButton-module_outline__esgLq.ZestButton-module_standard__T3EGM { /* Already handled by .outline base */ }\r\n.ZestButton-module_outline__esgLq.ZestButton-module_success__XEptA {\r\n border-color: var(--zest-color-success-border);\r\n color: var(--zest-color-success-border);\r\n}\r\n.ZestButton-module_outline__esgLq.ZestButton-module_success__XEptA:hover:not(:disabled) {\r\n background-color: var(--zest-color-success-bg);\r\n color: var(--zest-color-success-text);\r\n}\r\n.ZestButton-module_outline__esgLq.ZestButton-module_danger__nJpJ- {\r\n border-color: var(--zest-color-danger-border);\r\n color: var(--zest-color-danger-border);\r\n}\r\n.ZestButton-module_outline__esgLq.ZestButton-module_danger__nJpJ-:hover:not(:disabled) {\r\n background-color: var(--zest-color-danger-bg);\r\n color: var(--zest-color-danger-text);\r\n}\r\n\r\n/* Variant overrides for text style */\r\n.ZestButton-module_text__8X1xD.ZestButton-module_standard__T3EGM { /* Already handled by .text base */ }\r\n.ZestButton-module_text__8X1xD.ZestButton-module_success__XEptA {\r\n color: var(--zest-color-success-bg);\r\n}\r\n.ZestButton-module_text__8X1xD.ZestButton-module_success__XEptA:hover:not(:disabled) {\r\n background-color: rgba(var(--zest-color-success-bg-rgb, 5, 150, 105), 0.1);\r\n}\r\n.ZestButton-module_text__8X1xD.ZestButton-module_danger__nJpJ- {\r\n color: var(--zest-color-danger-bg);\r\n}\r\n.ZestButton-module_text__8X1xD.ZestButton-module_danger__nJpJ-:hover:not(:disabled) {\r\n background-color: rgba(var(--zest-color-danger-bg-rgb, 220, 38, 38), 0.1);\r\n}\r\n\r\n/* Variant overrides for dashed style */\r\n.ZestButton-module_dashed__ebKYF.ZestButton-module_standard__T3EGM { /* Already handled by .dashed base */ }\r\n.ZestButton-module_dashed__ebKYF.ZestButton-module_success__XEptA {\r\n border-color: var(--zest-color-success-border);\r\n color: var(--zest-color-success-border);\r\n}\r\n.ZestButton-module_dashed__ebKYF.ZestButton-module_success__XEptA:hover:not(:disabled) {\r\n background-color: rgba(var(--zest-color-success-bg-rgb, 5, 150, 105), 0.1);\r\n}\r\n.ZestButton-module_dashed__ebKYF.ZestButton-module_danger__nJpJ- {\r\n border-color: var(--zest-color-danger-border);\r\n color: var(--zest-color-danger-border);\r\n}\r\n.ZestButton-module_dashed__ebKYF.ZestButton-module_danger__nJpJ-:hover:not(:disabled) {\r\n background-color: rgba(var(--zest-color-danger-bg-rgb, 220, 38, 38), 0.1);\r\n}\r\n\r\n\r\n/* Disabled state overrides for different button styles */\r\n.ZestButton-module_solid__cu4tr:disabled, .ZestButton-module_solid__cu4tr.ZestButton-module_disabled__gw6y3 {\r\n background-color: var(--zest-color-disabled-bg);\r\n color: var(--zest-color-disabled-text);\r\n border-color: var(--zest-color-disabled-border);\r\n}\r\n.ZestButton-module_outline__esgLq:disabled, .ZestButton-module_outline__esgLq.ZestButton-module_disabled__gw6y3 {\r\n background-color: transparent;\r\n border-color: var(--zest-color-disabled-border);\r\n color: var(--zest-color-disabled-text);\r\n}\r\n.ZestButton-module_text__8X1xD:disabled, .ZestButton-module_text__8X1xD.ZestButton-module_disabled__gw6y3 {\r\n background-color: transparent;\r\n color: var(--zest-color-disabled-text);\r\n}\r\n.ZestButton-module_dashed__ebKYF:disabled, .ZestButton-module_dashed__ebKYF.ZestButton-module_disabled__gw6y3 {\r\n background-color: transparent;\r\n border-color: var(--zest-color-disabled-border);\r\n color: var(--zest-color-disabled-text);\r\n}\r\n\r\n\r\n/* Layout */\r\n.ZestButton-module_stretch__CTLNw {\r\n width: 100%;\r\n}\r\n\r\n.ZestButton-module_sm__G1vAP {\r\n font-size: 0.85rem;\r\n padding: 0.4em 0.8em;\r\n}\r\n\r\n.ZestButton-module_md__Y-PMO {\r\n font-size: 1rem;\r\n padding: 0.6em 1.2em;\r\n}\r\n\r\n.ZestButton-module_lg__AQgdf {\r\n font-size: 1.125rem;\r\n padding: 0.8em 1.6em;\r\n}\r\n\r\n.ZestButton-module_inner__1j2Fr {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n position: relative;\r\n}\r\n\r\n.ZestButton-module_spinner__l2hLe {\r\n position: absolute;\r\n width: 1em;\r\n height: 1em;\r\n animation: ZestButton-module_spin__4asdw 0.75s linear infinite;\r\n color: currentColor; /* Inherit color from button text */\r\n}\r\n\r\n.ZestButton-module_content__hlea3 {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 0.5em;\r\n}\r\n\r\n.ZestButton-module_label__8x263 {\r\n display: inline-block;\r\n}\r\n\r\n.ZestButton-module_icon__B3DFi {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n/* Success + Fail Icons */\r\n.ZestButton-module_animatedCheck__8K4K- {\r\n width: 1.25em;\r\n height: 1.25em;\r\n color: var(--zest-color-icon-success);\r\n animation: ZestButton-module_fadeIn__iEave 0.25s ease-out;\r\n}\r\n\r\n.ZestButton-module_animatedX__KQnt7 {\r\n width: 1.25em;\r\n height: 1.25em;\r\n color: var(--zest-color-icon-fail);\r\n animation: ZestButton-module_fadeIn__iEave 0.25s ease-out;\r\n}\r\n\r\n/* Stroke animations */\r\n.ZestButton-module_animatedCheck__8K4K- path {\r\n stroke-dasharray: 24;\r\n stroke-dashoffset: 24;\r\n animation: ZestButton-module_drawCheck__3DyjT 0.4s ease-out forwards;\r\n}\r\n\r\n.ZestButton-module_animatedX__KQnt7 line {\r\n stroke-dasharray: 24;\r\n stroke-dashoffset: 24;\r\n animation: ZestButton-module_drawCheck__3DyjT 0.4s ease-out forwards;\r\n}\r\n\r\n/* New: apply spacing between left icon and text */\r\n.ZestButton-module_icon__B3DFi:first-child {\r\n margin-right: 0.7em;\r\n}\r\n\r\n/* Optional override for iconRight if needed */\r\n.ZestButton-module_icon__B3DFi:last-child {\r\n margin-left: 0.7em;\r\n}\r\n\r\n/* Animations */\r\n@keyframes ZestButton-module_spin__4asdw {\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n}\r\n\r\n@keyframes ZestButton-module_drawCheck__3DyjT {\r\n to {\r\n stroke-dashoffset: 0;\r\n }\r\n}\r\n\r\n@keyframes ZestButton-module_fadeIn__iEave {\r\n from {\r\n opacity: 0;\r\n transform: scale(0.8);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n}\r\n\r\n@keyframes ZestButton-module_shakeIt__ox-R3 {\r\n 0%,\r\n 100% {\r\n transform: translateX(0);\r\n }\r\n 20%,\r\n 60% {\r\n transform: translateX(-4px);\r\n }\r\n 40%,\r\n 80% {\r\n transform: translateX(4px);\r\n }\r\n}\r\n\r\n.ZestButton-module_shake__NtIjf {\r\n animation: ZestButton-module_shakeIt__ox-R3 0.4s ease;\r\n box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.6);\r\n}\r\n\r\n/* Mobile-first adjustments for hit area */\r\n@media (max-width: 768px) {\r\n .ZestButton-module_button__KDafc {\r\n min-height: 44px; /* Ensure a minimum touch target size for accessibility */\r\n }\r\n\r\n .ZestButton-module_sm__G1vAP {\r\n padding: 0.6em 1em; /* Increase padding for small buttons on mobile */\r\n }\r\n\r\n .ZestButton-module_md__Y-PMO {\r\n padding: 0.8em 1.4em; /* Slightly increase padding for medium buttons on mobile */\r\n }\r\n}\r\n\r\n/* ------------------------------------------------------------------ */\r\n/* Split button (zest.dropdownOptions) */\r\n/* ------------------------------------------------------------------ */\r\n\r\n.ZestButton-module_splitButtonContainer__UPOGd {\r\n display: inline-flex;\r\n align-items: stretch;\r\n}\r\n\r\n.ZestButton-module_splitButtonMain__F0cHX {\r\n border-top-right-radius: 0;\r\n border-bottom-right-radius: 0;\r\n border-right: none;\r\n}\r\n\r\n.ZestButton-module_dropdownTrigger__wqBMN {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n border-top-left-radius: 0;\r\n border-bottom-left-radius: 0;\r\n padding: 0 0.7em;\r\n min-width: 2.4em;\r\n}\r\n\r\n/* .solid/.text have no border of their own — add an explicit divider so the\r\n two segments still read as one control. .outline/.dashed already carry a\r\n full border via their own base rule, which already serves as the divider. */\r\n.ZestButton-module_dropdownTrigger__wqBMN.ZestButton-module_solid__cu4tr {\r\n border-left: 1px solid rgba(255, 255, 255, 0.3);\r\n}\r\n.ZestButton-module_dropdownTrigger__wqBMN.ZestButton-module_text__8X1xD {\r\n border-left: 1px solid rgba(0, 0, 0, 0.15);\r\n}\r\n\r\n.ZestButton-module_dropdownChevron__GMkdW {\r\n width: 0.85em;\r\n height: 0.85em;\r\n transition: transform 0.2s ease;\r\n}\r\n\r\n.ZestButton-module_dropdownChevronOpen__-2CEj {\r\n transform: rotate(180deg);\r\n}\r\n\r\n.ZestButton-module_dropdownMenuContent__wIHv- {\r\n min-width: 180px;\r\n width: max-content;\r\n max-width: 320px;\r\n padding: 0.4rem;\r\n border-radius: 8px;\r\n background: var(--zest-color-menu-bg, #ffffff);\r\n color: var(--zest-color-menu-text, #1f2937);\r\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);\r\n border: 1px solid rgba(0, 0, 0, 0.08);\r\n z-index: 1000;\r\n}\r\n\r\n.ZestButton-module_force-dark__cx74D.ZestButton-module_dropdownMenuContent__wIHv-,\r\n.ZestButton-module_dropdownMenuContent__wIHv-.ZestButton-module_force-dark__cx74D {\r\n background: #1f2937;\r\n color: #f3f4f6;\r\n border-color: rgba(255, 255, 255, 0.12);\r\n}\r\n\r\n.ZestButton-module_dropdownMenuItem__7vFFl {\r\n display: flex;\r\n align-items: center;\r\n gap: 0.5em;\r\n padding: 0.55em 0.75em;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n outline: none;\r\n font-family: \"Segoe UI\", Roboto, sans-serif;\r\n font-size: 0.9rem;\r\n}\r\n\r\n.ZestButton-module_dropdownMenuItem__7vFFl:hover,\r\n.ZestButton-module_dropdownMenuItem__7vFFl[data-highlighted] {\r\n background: rgba(0, 0, 0, 0.06);\r\n}\r\n\r\n.ZestButton-module_force-dark__cx74D .ZestButton-module_dropdownMenuItem__7vFFl:hover,\r\n.ZestButton-module_force-dark__cx74D .ZestButton-module_dropdownMenuItem__7vFFl[data-highlighted] {\r\n background: rgba(255, 255, 255, 0.1);\r\n}\r\n\r\n.ZestButton-module_dropdownMenuItem__7vFFl.ZestButton-module_disabled__gw6y3,\r\n.ZestButton-module_dropdownMenuItem__7vFFl[data-disabled] {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n}\r\n\r\n.ZestButton-module_dropdownMenuItemLabel__ArKh6 {\r\n flex: 1;\r\n}\r\n\r\n/* Mobile-first: chevron segment always meets the 44px touch-target minimum,\r\n independent of `size`, since it's a narrow tap target next to another one. */\r\n.ZestButton-module_dropdownTrigger__wqBMN {\r\n min-height: 44px;\r\n}\r\n\r\n@media (min-width: 769px) {\r\n /* Desktop-aware: once mis-tapping a neighbouring segment isn't a concern,\r\n let the chevron shrink to match the main button's own sizing. */\r\n .ZestButton-module_dropdownTrigger__wqBMN.ZestButton-module_sm__G1vAP {\r\n min-height: 0;\r\n padding: 0.4em 0.6em;\r\n }\r\n .ZestButton-module_dropdownTrigger__wqBMN.ZestButton-module_md__Y-PMO {\r\n min-height: 0;\r\n padding: 0.6em 0.7em;\r\n }\r\n .ZestButton-module_dropdownTrigger__wqBMN.ZestButton-module_lg__AQgdf {\r\n min-height: 0;\r\n padding: 0.8em 0.9em;\r\n }\r\n}\r\n\r\n";
|
|
1412
|
+
var styles = {"force-light":"ZestButton-module_force-light__zZTIZ","force-dark":"ZestButton-module_force-dark__cx74D","button":"ZestButton-module_button__KDafc","solid":"ZestButton-module_solid__cu4tr","outline":"ZestButton-module_outline__esgLq","text":"ZestButton-module_text__8X1xD","dashed":"ZestButton-module_dashed__ebKYF","standard":"ZestButton-module_standard__T3EGM","success":"ZestButton-module_success__XEptA","danger":"ZestButton-module_danger__nJpJ-","disabled":"ZestButton-module_disabled__gw6y3","stretch":"ZestButton-module_stretch__CTLNw","sm":"ZestButton-module_sm__G1vAP","md":"ZestButton-module_md__Y-PMO","lg":"ZestButton-module_lg__AQgdf","inner":"ZestButton-module_inner__1j2Fr","spinner":"ZestButton-module_spinner__l2hLe","spin":"ZestButton-module_spin__4asdw","content":"ZestButton-module_content__hlea3","label":"ZestButton-module_label__8x263","icon":"ZestButton-module_icon__B3DFi","animatedCheck":"ZestButton-module_animatedCheck__8K4K-","fadeIn":"ZestButton-module_fadeIn__iEave","animatedX":"ZestButton-module_animatedX__KQnt7","drawCheck":"ZestButton-module_drawCheck__3DyjT","shake":"ZestButton-module_shake__NtIjf","shakeIt":"ZestButton-module_shakeIt__ox-R3","splitButtonContainer":"ZestButton-module_splitButtonContainer__UPOGd","splitButtonMain":"ZestButton-module_splitButtonMain__F0cHX","dropdownTrigger":"ZestButton-module_dropdownTrigger__wqBMN","dropdownChevron":"ZestButton-module_dropdownChevron__GMkdW","dropdownChevronOpen":"ZestButton-module_dropdownChevronOpen__-2CEj","dropdownMenuContent":"ZestButton-module_dropdownMenuContent__wIHv-","dropdownMenuItem":"ZestButton-module_dropdownMenuItem__7vFFl","dropdownMenuItemLabel":"ZestButton-module_dropdownMenuItemLabel__ArKh6"};
|
|
1391
1413
|
styleInject(css_248z);
|
|
1392
1414
|
|
|
1393
1415
|
// Create the Zest Context with a default empty configuration
|
|
@@ -1740,12 +1762,136 @@ const useThemeDetection = () => {
|
|
|
1740
1762
|
return systemTheme;
|
|
1741
1763
|
};
|
|
1742
1764
|
|
|
1765
|
+
const AnimatedCheckmark$1 = () => (jsxRuntimeExports.jsx("svg", { className: styles.animatedCheck, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M5 13l4 4L19 7" }) }));
|
|
1766
|
+
const AnimatedX$1 = () => (jsxRuntimeExports.jsxs("svg", { className: styles.animatedX, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M6 6L18 18" }), jsxRuntimeExports.jsx("path", { d: "M6 18L18 6" })] }));
|
|
1767
|
+
const ZestDropdownMenuItem = ({ option, disabled: externallyDisabled = false, onBusyChange, }) => {
|
|
1768
|
+
const { label, icon, disabled: optionDisabled = false, onClick, busyOptions = {}, successOptions = {}, confirmOptions, } = option;
|
|
1769
|
+
const { handleInternally, minBusyDurationMs, showCheckmark, showFailIcon, internalBusy, wasSuccessful, wasFailed, startBusy, endBusy, } = useBusyState({ busyOptions, successOptions });
|
|
1770
|
+
const { awaitingConfirm, currentChildren, startConfirmation, stopConfirmation } = useConfirmation({
|
|
1771
|
+
confirmOptions,
|
|
1772
|
+
originalChildren: label,
|
|
1773
|
+
onConfirmFail: () => endBusy(false),
|
|
1774
|
+
});
|
|
1775
|
+
require$$0.useEffect(() => {
|
|
1776
|
+
onBusyChange?.(internalBusy);
|
|
1777
|
+
}, [internalBusy, onBusyChange]);
|
|
1778
|
+
const isDisabled = externallyDisabled || optionDisabled || internalBusy;
|
|
1779
|
+
const handleActivate = async (e) => {
|
|
1780
|
+
if (handleInternally && typeof onClick === "function") {
|
|
1781
|
+
try {
|
|
1782
|
+
startBusy();
|
|
1783
|
+
const startTime = Date.now();
|
|
1784
|
+
await onClick(e);
|
|
1785
|
+
const elapsed = Date.now() - startTime;
|
|
1786
|
+
const remaining = Math.max(minBusyDurationMs - elapsed, 0);
|
|
1787
|
+
if (remaining > 0) {
|
|
1788
|
+
await new Promise((resolve) => setTimeout(resolve, remaining));
|
|
1789
|
+
}
|
|
1790
|
+
endBusy(true);
|
|
1791
|
+
}
|
|
1792
|
+
catch (err) {
|
|
1793
|
+
console.error(err);
|
|
1794
|
+
endBusy(false);
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
else if (onClick) {
|
|
1798
|
+
onClick(e);
|
|
1799
|
+
}
|
|
1800
|
+
};
|
|
1801
|
+
const handleSelect = (e) => {
|
|
1802
|
+
if (isDisabled) {
|
|
1803
|
+
e.preventDefault();
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1806
|
+
if (awaitingConfirm) {
|
|
1807
|
+
// Keep the menu open through the confirm step; only the real
|
|
1808
|
+
// activation (below) decides whether the menu is allowed to close.
|
|
1809
|
+
e.preventDefault();
|
|
1810
|
+
stopConfirmation();
|
|
1811
|
+
void handleActivate(e);
|
|
1812
|
+
return;
|
|
1813
|
+
}
|
|
1814
|
+
if (confirmOptions) {
|
|
1815
|
+
e.preventDefault();
|
|
1816
|
+
if (!onClick) {
|
|
1817
|
+
console.warn("ZestButton dropdown item: 'confirmOptions' provided but 'onClick' is missing.");
|
|
1818
|
+
}
|
|
1819
|
+
startConfirmation();
|
|
1820
|
+
return;
|
|
1821
|
+
}
|
|
1822
|
+
if (handleInternally) {
|
|
1823
|
+
// Busy items keep the row open to show progress; Radix's default
|
|
1824
|
+
// close-on-select would hide the spinner/checkmark/shake feedback.
|
|
1825
|
+
e.preventDefault();
|
|
1826
|
+
void handleActivate(e);
|
|
1827
|
+
return;
|
|
1828
|
+
}
|
|
1829
|
+
// Plain synchronous item: let Radix close the menu as it normally would.
|
|
1830
|
+
void handleActivate(e);
|
|
1831
|
+
};
|
|
1832
|
+
const renderIcon = () => {
|
|
1833
|
+
if (internalBusy) {
|
|
1834
|
+
return (jsxRuntimeExports.jsx("span", { className: `${styles.icon} ${styles.fadeIn}`, children: jsxRuntimeExports.jsx(fa6.FaSpinner, { className: styles.spinner }) }));
|
|
1835
|
+
}
|
|
1836
|
+
if (wasSuccessful && showCheckmark) {
|
|
1837
|
+
return (jsxRuntimeExports.jsx("span", { className: `${styles.icon} ${styles.fadeIn}`, children: jsxRuntimeExports.jsx(AnimatedCheckmark$1, {}) }));
|
|
1838
|
+
}
|
|
1839
|
+
if (wasFailed && showFailIcon) {
|
|
1840
|
+
return (jsxRuntimeExports.jsx("span", { className: `${styles.icon} ${styles.fadeIn}`, children: jsxRuntimeExports.jsx(AnimatedX$1, {}) }));
|
|
1841
|
+
}
|
|
1842
|
+
if (icon) {
|
|
1843
|
+
return jsxRuntimeExports.jsx("span", { className: styles.icon, children: icon });
|
|
1844
|
+
}
|
|
1845
|
+
return null;
|
|
1846
|
+
};
|
|
1847
|
+
return (jsxRuntimeExports.jsxs(DropdownMenu__namespace.Item, { className: [
|
|
1848
|
+
styles.dropdownMenuItem,
|
|
1849
|
+
isDisabled ? styles.disabled : "",
|
|
1850
|
+
wasFailed ? styles.shake : "",
|
|
1851
|
+
]
|
|
1852
|
+
.join(" ")
|
|
1853
|
+
.trim(), disabled: isDisabled, onSelect: handleSelect, children: [renderIcon(), jsxRuntimeExports.jsx("span", { className: styles.dropdownMenuItemLabel, children: currentChildren })] }));
|
|
1854
|
+
};
|
|
1855
|
+
|
|
1856
|
+
const ZestDropdownMenu = ({ options, ariaLabel, open, onOpenChange, disabled = false, onAnyItemBusyChange, variant, size, buttonStyle, effectiveTheme, }) => {
|
|
1857
|
+
const busyKeysRef = require$$0.useRef(new Set());
|
|
1858
|
+
const handleItemBusyChange = require$$0.useCallback((key, busy) => {
|
|
1859
|
+
const busyKeys = busyKeysRef.current;
|
|
1860
|
+
const wasAnyBusy = busyKeys.size > 0;
|
|
1861
|
+
if (busy) {
|
|
1862
|
+
busyKeys.add(key);
|
|
1863
|
+
}
|
|
1864
|
+
else {
|
|
1865
|
+
busyKeys.delete(key);
|
|
1866
|
+
}
|
|
1867
|
+
const isAnyBusy = busyKeys.size > 0;
|
|
1868
|
+
if (isAnyBusy !== wasAnyBusy) {
|
|
1869
|
+
onAnyItemBusyChange?.(isAnyBusy);
|
|
1870
|
+
}
|
|
1871
|
+
}, [onAnyItemBusyChange]);
|
|
1872
|
+
return (jsxRuntimeExports.jsxs(DropdownMenu__namespace.Root, { open: open, onOpenChange: onOpenChange, modal: false, children: [jsxRuntimeExports.jsx(DropdownMenu__namespace.Trigger, { asChild: true, disabled: disabled, children: jsxRuntimeExports.jsx("button", { type: "button", "aria-label": ariaLabel, disabled: disabled, className: [
|
|
1873
|
+
styles.dropdownTrigger,
|
|
1874
|
+
styles[buttonStyle],
|
|
1875
|
+
styles[variant],
|
|
1876
|
+
styles[size],
|
|
1877
|
+
disabled ? styles.disabled : "",
|
|
1878
|
+
effectiveTheme === "light" ? styles["force-light"] : styles["force-dark"],
|
|
1879
|
+
]
|
|
1880
|
+
.join(" ")
|
|
1881
|
+
.trim(), children: jsxRuntimeExports.jsx(fa6.FaChevronDown, { className: [styles.dropdownChevron, open ? styles.dropdownChevronOpen : ""]
|
|
1882
|
+
.join(" ")
|
|
1883
|
+
.trim() }) }) }), jsxRuntimeExports.jsx(DropdownMenu__namespace.Portal, { children: jsxRuntimeExports.jsx(DropdownMenu__namespace.Content, { className: [
|
|
1884
|
+
styles.dropdownMenuContent,
|
|
1885
|
+
effectiveTheme === "light" ? styles["force-light"] : styles["force-dark"],
|
|
1886
|
+
].join(" "), sideOffset: 4, align: "end", collisionPadding: 8, children: options.map((option, index) => (jsxRuntimeExports.jsx(ZestDropdownMenuItem, { option: option, disabled: disabled, onBusyChange: (busy) => handleItemBusyChange(option.key ?? index, busy) }, option.key ?? index))) }) })] }));
|
|
1887
|
+
};
|
|
1888
|
+
|
|
1743
1889
|
// --- Components ---
|
|
1744
1890
|
const AnimatedCheckmark = () => (jsxRuntimeExports.jsx("svg", { className: styles.animatedCheck, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M5 13l4 4L19 7" }) }));
|
|
1745
1891
|
const AnimatedX = () => (jsxRuntimeExports.jsxs("svg", { className: styles.animatedX, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M6 6L18 18" }), jsxRuntimeExports.jsx("path", { d: "M6 18L18 6" })] }));
|
|
1746
1892
|
const ZestButton = ({ className = "", disabled, children, onClick, zest: localZestProps, ...props }) => {
|
|
1747
1893
|
const effectiveZestConfig = useZestConfig(localZestProps);
|
|
1748
|
-
const { visualOptions = {}, busyOptions = {}, successOptions = {}, confirmOptions, isDefault = false, theme = 'system', buttonStyle = 'solid', } = effectiveZestConfig;
|
|
1894
|
+
const { visualOptions = {}, busyOptions = {}, successOptions = {}, confirmOptions, isDefault = false, theme = 'system', buttonStyle = 'solid', dropdownOptions, dropdownAriaLabel = "More options", } = effectiveZestConfig;
|
|
1749
1895
|
const { variant = "standard", size = "md", stretch = false, iconLeft, iconRight, } = visualOptions;
|
|
1750
1896
|
const { handleInternally, minBusyDurationMs, preventRageClick, showCheckmark, showFailIcon, internalBusy, wasSuccessful, wasFailed, startBusy, endBusy, } = useBusyState({ busyOptions, successOptions });
|
|
1751
1897
|
const { awaitingConfirm, currentChildren, startConfirmation, stopConfirmation, } = useConfirmation({
|
|
@@ -1756,6 +1902,9 @@ const ZestButton = ({ className = "", disabled, children, onClick, zest: localZe
|
|
|
1756
1902
|
const buttonRef = require$$0.useRef(null);
|
|
1757
1903
|
const systemTheme = useThemeDetection();
|
|
1758
1904
|
const effectiveTheme = theme === 'system' ? systemTheme : theme;
|
|
1905
|
+
const hasDropdown = Boolean(dropdownOptions && dropdownOptions.length > 0);
|
|
1906
|
+
const [dropdownOpen, setDropdownOpen] = require$$0.useState(false);
|
|
1907
|
+
const [anyDropdownItemBusy, setAnyDropdownItemBusy] = require$$0.useState(false);
|
|
1759
1908
|
const effectiveBusy = typeof props["aria-busy"] === "boolean"
|
|
1760
1909
|
? Boolean(props["aria-busy"])
|
|
1761
1910
|
: handleInternally
|
|
@@ -1763,7 +1912,8 @@ const ZestButton = ({ className = "", disabled, children, onClick, zest: localZe
|
|
|
1763
1912
|
: false;
|
|
1764
1913
|
const isDisabled = disabled ||
|
|
1765
1914
|
effectiveBusy ||
|
|
1766
|
-
(preventRageClick && (wasSuccessful || wasFailed))
|
|
1915
|
+
(preventRageClick && (wasSuccessful || wasFailed)) ||
|
|
1916
|
+
anyDropdownItemBusy;
|
|
1767
1917
|
const handleClick = async (e) => {
|
|
1768
1918
|
if (preventRageClick && internalBusy)
|
|
1769
1919
|
return;
|
|
@@ -1805,7 +1955,7 @@ const ZestButton = ({ className = "", disabled, children, onClick, zest: localZe
|
|
|
1805
1955
|
}
|
|
1806
1956
|
};
|
|
1807
1957
|
require$$0.useEffect(() => {
|
|
1808
|
-
if (!isDefault || isDisabled)
|
|
1958
|
+
if (!isDefault || isDisabled || dropdownOpen)
|
|
1809
1959
|
return;
|
|
1810
1960
|
const listener = (e) => {
|
|
1811
1961
|
const target = e.target;
|
|
@@ -1822,7 +1972,7 @@ const ZestButton = ({ className = "", disabled, children, onClick, zest: localZe
|
|
|
1822
1972
|
};
|
|
1823
1973
|
document.addEventListener("keydown", listener);
|
|
1824
1974
|
return () => document.removeEventListener("keydown", listener);
|
|
1825
|
-
}, [isDefault, isDisabled]);
|
|
1975
|
+
}, [isDefault, isDisabled, dropdownOpen]);
|
|
1826
1976
|
const renderLeftIcon = () => {
|
|
1827
1977
|
if (effectiveBusy) {
|
|
1828
1978
|
return (jsxRuntimeExports.jsx("span", { className: `${styles.icon} ${styles.fadeIn}`, children: jsxRuntimeExports.jsx(fa6.FaSpinner, { className: styles.spinner }) }));
|
|
@@ -1838,7 +1988,7 @@ const ZestButton = ({ className = "", disabled, children, onClick, zest: localZe
|
|
|
1838
1988
|
}
|
|
1839
1989
|
return null;
|
|
1840
1990
|
};
|
|
1841
|
-
|
|
1991
|
+
const buttonElement = (jsxRuntimeExports.jsx("button", { ref: buttonRef, className: [
|
|
1842
1992
|
styles.button,
|
|
1843
1993
|
styles[buttonStyle],
|
|
1844
1994
|
styles[variant],
|
|
@@ -1847,15 +1997,20 @@ const ZestButton = ({ className = "", disabled, children, onClick, zest: localZe
|
|
|
1847
1997
|
isDisabled ? styles.disabled : "",
|
|
1848
1998
|
wasFailed ? styles.shake : "",
|
|
1849
1999
|
effectiveTheme === 'light' ? styles['force-light'] : styles['force-dark'],
|
|
2000
|
+
hasDropdown ? styles.splitButtonMain : "",
|
|
1850
2001
|
className,
|
|
1851
2002
|
].join(" "), disabled: isDisabled, "aria-busy": effectiveBusy, onClick: handleConfirmClick, ...props, children: jsxRuntimeExports.jsxs("span", { className: styles.inner, children: [renderLeftIcon(), jsxRuntimeExports.jsxs("span", { className: styles.content, children: [currentChildren, iconRight && jsxRuntimeExports.jsx("span", { className: styles.icon, children: iconRight })] })] }) }));
|
|
2003
|
+
if (!hasDropdown) {
|
|
2004
|
+
return buttonElement;
|
|
2005
|
+
}
|
|
2006
|
+
return (jsxRuntimeExports.jsxs("div", { className: styles.splitButtonContainer, children: [buttonElement, jsxRuntimeExports.jsx(ZestDropdownMenu, { options: dropdownOptions, ariaLabel: dropdownAriaLabel, open: dropdownOpen, onOpenChange: setDropdownOpen, disabled: isDisabled, onAnyItemBusyChange: setAnyDropdownItemBusy, variant: variant, size: size, buttonStyle: buttonStyle, effectiveTheme: effectiveTheme })] }));
|
|
1852
2007
|
};
|
|
1853
2008
|
|
|
1854
2009
|
const ZestButtonConfigProvider = ({ config, children }) => {
|
|
1855
2010
|
return (jsxRuntimeExports.jsx(ZestButtonConfigContext.Provider, { value: config, children: children }));
|
|
1856
2011
|
};
|
|
1857
2012
|
|
|
1858
|
-
exports.ZestButton = ZestButton;
|
|
1859
2013
|
exports.ZestButtonConfigProvider = ZestButtonConfigProvider;
|
|
2014
|
+
exports.default = ZestButton;
|
|
1860
2015
|
exports.useZestButtonConfig = useZestButtonConfig;
|
|
1861
2016
|
//# sourceMappingURL=index.cjs.js.map
|