@12-apps/ui 6.3.0 → 6.3.1
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/{chunk-MXPXKORR.js → chunk-WFPXRSIZ.js} +2 -2
- package/dist/chunk-WFPXRSIZ.js.map +1 -0
- package/dist/data-display/CardKit.js +1 -1
- package/dist/data-display/DataViews.js +1 -1
- package/dist/feedback/ConfirmAction.js +1 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.parts.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx +8 -1
- package/dist/chunk-MXPXKORR.js.map +0 -1
|
@@ -122,7 +122,7 @@ function ConfirmActionDialog({
|
|
|
122
122
|
title,
|
|
123
123
|
description: confirmBody(description, copy, entityName),
|
|
124
124
|
confirmText,
|
|
125
|
-
cancelText,
|
|
125
|
+
cancelText: cancelText ?? copy.cancel,
|
|
126
126
|
loading: state.pending,
|
|
127
127
|
confirmDisabled: gateUnmet,
|
|
128
128
|
initialFocus: resolveInitialFocus(tone, initialFocus),
|
|
@@ -212,4 +212,4 @@ export {
|
|
|
212
212
|
withConfirmation,
|
|
213
213
|
createConfirmButton
|
|
214
214
|
};
|
|
215
|
-
//# sourceMappingURL=chunk-
|
|
215
|
+
//# sourceMappingURL=chunk-WFPXRSIZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/feedback/ConfirmAction/ConfirmAction.hooks.ts","../src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx","../src/components/feedback/ConfirmAction/ConfirmAction.tsx","../src/components/feedback/ConfirmAction/with-confirmation.tsx","../src/components/feedback/ConfirmAction/ConfirmButton.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport type { ConfirmHandler, UseConfirmActionResult } from './ConfirmAction.types';\n\n/** Used when the guarded action rejects and the caller supplied no wording. */\n\n\n/**\n * What the popup says after a failed attempt.\n *\n * A rejection carrying a message wins: the server's sentence (\"esta categoria\n * ainda tem produtos vinculados\") is the one the operator can act on, and it is\n * strictly better than the generic fallback. Handlers that have nothing useful\n * to say reject with nothing and get `errorText`.\n */\nfunction failureMessage(cause: unknown, errorText: string): string {\n if (cause instanceof Error && cause.message) return cause.message;\n return errorText;\n}\n\n/**\n * The confirmation state machine, headless.\n *\n * It is the whole safety contract in one place, so every consumer gets the same\n * behaviour: the action runs ONLY from `confirm`, never from opening the popup;\n * a second confirm while the first is in flight is dropped (a double-click\n * cannot send two deletes); a rejection keeps the popup open carrying the\n * failure instead of closing over a write that never happened.\n */\nexport function useConfirmAction(\n onConfirm: ConfirmHandler,\n errorText: string,\n): UseConfirmActionResult {\n const [open, setOpen] = useState(false);\n const [pending, setPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // `pending` is mirrored in a ref because the two guards that matter — drop a\n // second confirm, ignore a cancel mid-flight — are read inside callbacks that\n // must not be rebuilt on every state change. Reading the state variable there\n // would leave a stale closure holding `false` for the whole in-flight window,\n // which is exactly the double-submit this component exists to prevent.\n const busy = useRef(false);\n\n // The action can settle after the trigger has unmounted (a row deleted from\n // under its own menu), so the settle path must not touch state by then.\n const mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n\n const request = useCallback((): void => {\n setError(null);\n setOpen(true);\n }, []);\n\n const cancel = useCallback((): void => {\n // Inert mid-flight: the write has already left, and closing here would hide\n // its outcome.\n if (busy.current) return;\n setOpen(false);\n setError(null);\n }, []);\n\n const settle = useCallback((failure: string | null): void => {\n busy.current = false;\n if (!mounted.current) return;\n setPending(false);\n setError(failure);\n if (!failure) setOpen(false);\n }, []);\n\n const confirm = useCallback((): void => {\n if (busy.current) return;\n busy.current = true;\n setPending(true);\n setError(null);\n // The handler is invoked synchronously, exactly as a plain `onClick` would\n // be — only the OUTCOME is awaited. The try/catch is what puts a handler\n // that throws synchronously on the same failure path as one that returns a\n // rejected promise.\n try {\n const result = onConfirm();\n void Promise.resolve(result)\n .then(() => settle(null))\n .catch((cause: unknown) => settle(failureMessage(cause, errorText)));\n } catch (cause) {\n settle(failureMessage(cause, errorText));\n }\n }, [errorText, onConfirm, settle]);\n\n return { open, pending, error, request, cancel, confirm };\n}\n","import type { ConfirmActionCopy } from \"../../../copy\";\nimport { Alert, Stack, TextField, Typography } from '@mui/material';\nimport React, { type ReactNode } from 'react';\n\nimport { AlertDialog } from '../../data-display/AlertDialog';\n\nimport type {\n ConfirmInitialFocus,\n ConfirmOptions,\n ConfirmTone,\n UseConfirmActionResult,\n} from './ConfirmAction.types';\n\nconst DEFAULT_TEST_ID = 'confirm-action';\n\n/**\n * The popup's body: the row being acted on, then what happens to it.\n *\n * The NAME is rendered in its own right rather than woven into the sentence, so\n * it is there whatever the caller wrote — \"the popup names the specific entity\"\n * is the one thing that must not depend on each call site remembering to\n * mention it. A body with neither a name nor a description would leave the\n * operator with only the title to decide on, so a neutral fallback covers that.\n */\nfunction confirmBody(\n description: ReactNode,\n copy: ConfirmActionCopy,\n entityName?: string,\n): ReactNode {\n if (!entityName) return description ?? copy.irreversible;\n return (\n <>\n <Typography component=\"span\" sx={{ fontWeight: 600, display: \"block\" }}>\n {entityName}\n </Typography>\n {description}\n </>\n );\n}\n\n/** Destructive dialogs open on Cancel; anything else opens on the confirm. */\nfunction resolveInitialFocus(\n tone: ConfirmTone,\n initialFocus?: ConfirmInitialFocus,\n): ConfirmInitialFocus {\n if (initialFocus) return initialFocus;\n return tone === 'destructive' ? 'cancel' : 'confirm';\n}\n\n/**\n * The type-to-confirm field. Rendered only when `typeToConfirm` is set, which\n * should be rare: it is the guard for actions with NO recovery path, where a\n * click is too cheap a gesture. Comparison is exact — trimmed of surrounding\n * whitespace only, so a trailing space from a paste does not read as a mismatch.\n */\nfunction TypeToConfirmField({\n expected,\n label,\n value,\n onChange,\n disabled,\n dataTestId,\n}: {\n expected: string;\n label?: string;\n value: string;\n onChange: (next: string) => void;\n disabled: boolean;\n dataTestId: string;\n}): React.ReactElement {\n return (\n <Stack spacing={1} sx={{ mt: 2 }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {label ?? `Digite \"${expected}\" para confirmar.`}\n </Typography>\n <TextField\n size=\"small\"\n value={value}\n disabled={disabled}\n onChange={(event) => onChange(event.target.value)}\n // On the INPUT rather than the wrapper: a test id on MUI's TextField\n // lands on the outer div, which is not the node a test can type into.\n inputProps={{\n 'aria-label': label ?? `Digite ${expected} para confirmar`,\n 'data-testid': `${dataTestId}-type-to-confirm`,\n }}\n />\n </Stack>\n );\n}\n\nexport interface ConfirmActionDialogProps extends ConfirmOptions {\n /** The fallback body when no entity is named. REQUIRED — no default copy. */\n copy: ConfirmActionCopy;\n state: UseConfirmActionResult;\n}\n\n/**\n * The popup itself: an `AlertDialog` in its destructive skin, plus the two\n * things a bare AlertDialog has no opinion about — the failure the last attempt\n * produced (shown IN the dialog, which stays open, rather than closing over a\n * write that never landed) and the optional type-to-confirm gate.\n */\nexport function ConfirmActionDialog({\n state,\n title,\n description,\n entityName,\n confirmText,\n cancelText,\n typeToConfirm,\n typeToConfirmLabel,\n tone = 'destructive',\n initialFocus,\n dataTestId = DEFAULT_TEST_ID,\n copy,\n}: ConfirmActionDialogProps): React.ReactElement {\n const [typed, setTyped] = React.useState('');\n\n // Every fresh open starts from an empty field: carrying the previous answer\n // over would hand the next delete a pre-satisfied gate.\n React.useEffect(() => {\n if (state.open) setTyped('');\n }, [state.open]);\n\n const gateUnmet = typeToConfirm !== undefined && typed.trim() !== typeToConfirm;\n\n return (\n <AlertDialog\n open={state.open}\n variant={tone === 'destructive' ? 'destructive' : 'default'}\n title={title}\n description={confirmBody(description, copy, entityName)}\n confirmText={confirmText}\n // `copy.cancel` is the fallback, NOT `AlertDialog`'s own. The 6.3.0 copy\n // sweep deleted this component's `cancelText = 'Cancelar'` default and\n // put the word in `ConfirmActionCopy` — where nothing then read it, so\n // every confirmation that names no `cancelText` of its own fell through\n // to `AlertDialog`'s English `'Cancel'`, in a pt-BR dialog. That is the\n // precise failure the sweep exists to prevent, one layer down: a port\n // that is required, supplied, and ignored.\n cancelText={cancelText ?? copy.cancel}\n loading={state.pending}\n confirmDisabled={gateUnmet}\n initialFocus={resolveInitialFocus(tone, initialFocus)}\n onConfirm={state.confirm}\n onCancel={state.cancel}\n onClose={state.cancel}\n data-testid={dataTestId}\n >\n {state.error && (\n <Alert severity=\"error\" sx={{ mt: 1 }} data-testid={`${dataTestId}-error`}>\n {state.error}\n </Alert>\n )}\n {typeToConfirm !== undefined && (\n <TypeToConfirmField\n expected={typeToConfirm}\n label={typeToConfirmLabel}\n value={typed}\n onChange={setTyped}\n disabled={state.pending}\n dataTestId={dataTestId}\n />\n )}\n </AlertDialog>\n );\n}\n","import React from 'react';\n\nimport { useConfirmAction } from './ConfirmAction.hooks';\nimport { ConfirmActionDialog } from './ConfirmAction.parts';\nimport type { ConfirmActionProps } from './ConfirmAction.types';\n\n/**\n * Wraps any trigger in a confirmation popup.\n *\n * The trigger is a render prop rather than a fixed element, so the same guard\n * covers a button, a dropdown item, an icon or a table row action without this\n * component knowing what any of them look like. The guarded handler runs ONLY\n * after the operator confirms:\n *\n * ```tsx\n * <ConfirmAction\n * title=\"Excluir a categoria?\"\n * entityName={row.name}\n * description=\"Ela vai para a lixeira e pode ser restaurada de lá.\"\n * confirmText=\"Excluir\"\n * onConfirm={() => deleteCategoryAction({ tenantSlug, id: row.id })}\n * >\n * {(request) => <Button color=\"danger\" onClick={request}>Excluir</Button>}\n * </ConfirmAction>\n * ```\n *\n * For the common case — an existing button whose `onClick` is already the\n * destructive write — reach for {@link withConfirmation} instead, which needs\n * no restructuring of the call site.\n */\nexport function ConfirmAction({\n onConfirm,\n children,\n ...options\n}: ConfirmActionProps): React.ReactElement {\n const state = useConfirmAction(onConfirm, options.errorText);\n\n return (\n <>\n {children(state.request, { pending: state.pending })}\n <ConfirmActionDialog state={state} {...options} />\n </>\n );\n}\n\nConfirmAction.displayName = 'ConfirmAction';\n","import type { ConfirmActionCopy } from '../../../copy';\nimport React from 'react';\nimport type { ComponentType } from 'react';\n\nimport { useConfirmAction } from './ConfirmAction.hooks';\nimport { ConfirmActionDialog } from './ConfirmAction.parts';\nimport type {\n ConfirmHandler,\n ConfirmOptions,\n ConfirmableComponent,\n ConfirmableProps,\n WithConfirmationProps,\n} from './ConfirmAction.types';\n\n/**\n * Merge the HOC's baked-in defaults with the per-instance `confirm` prop.\n * Returns null when the instance opts out (`confirm={false}`) or when neither\n * side supplies the two fields a confirmation cannot be written without — the\n * question and the verb. A null result means \"render the plain component\",\n * which keeps the wrapped export usable in harmless contexts.\n */\nfunction resolveOptions(\n defaults: Partial<ConfirmOptions> | undefined,\n instance: Partial<ConfirmOptions> | false | undefined,\n): ConfirmOptions | null {\n if (instance === false) return null;\n const merged = { ...defaults, ...instance };\n if (!merged.title || !merged.confirmText) return null;\n return { ...merged, title: merged.title, confirmText: merged.confirmText };\n}\n\n/**\n * Adapt the wrapped component's `onClick` into a {@link ConfirmHandler}.\n *\n * The click argument is dropped (see `ConfirmHandler`) and the return value is\n * narrowed: a promise is handed back so the popup can hold its pending state\n * until the write settles, anything else becomes `undefined`. A component with\n * no `onClick` has nothing to guard, so confirming is a no-op.\n */\nfunction useGuardedHandler(onClick: ConfirmableProps['onClick']): ConfirmHandler {\n return React.useCallback((): void | Promise<unknown> => {\n const result = onClick?.();\n return result instanceof Promise ? result : undefined;\n }, [onClick]);\n}\n\n/**\n * Give any click-driven component a confirmation popup, without restructuring\n * the call site.\n *\n * The wrapped component's own `onClick` becomes the GUARDED action: clicking\n * now opens the popup, and the handler runs only if the operator confirms. It\n * inherits the whole contract from `useConfirmAction` — cancel sends nothing, a\n * returned promise holds the popup in its pending state so a double-click\n * cannot fire two writes, and a rejection keeps the popup open carrying the\n * error.\n *\n * ```tsx\n * const ConfirmButton = withConfirmation(Button);\n *\n * <ConfirmButton\n * color=\"danger\"\n * onClick={() => deleteCategoryAction({ tenantSlug, id: row.id })}\n * confirm={{\n * title: \"Excluir a categoria?\",\n * entityName: row.name,\n * description: \"Ela vai para a lixeira e pode ser restaurada de lá.\",\n * confirmText: \"Excluir\",\n * }}\n * >\n * Excluir\n * </ConfirmButton>\n * ```\n *\n * Bake the wording in once when the same guard repeats — `withConfirmation(Button,\n * { confirmText: \"Excluir\" })` — and let each instance override what differs.\n * `confirm={false}` falls through to the plain component.\n *\n * Refs are not forwarded: the HOC renders a fragment (trigger + popup), so there\n * is no single node to hand back. Wrap a component that needs a ref at its own\n * call site with {@link ConfirmAction} instead.\n */\nexport function withConfirmation<P extends ConfirmableProps>(\n Wrapped: ComponentType<P>,\n defaults: Partial<ConfirmOptions> & { errorText: string; copy: ConfirmActionCopy },\n): ConfirmableComponent<P> {\n function WithConfirmation(props: P & WithConfirmationProps): React.ReactElement {\n const { confirm, onClick } = props;\n const options = resolveOptions(defaults, confirm);\n const state = useConfirmAction(useGuardedHandler(onClick), defaults.errorText);\n\n // `confirm` is ours and must not reach the DOM — an unknown attribute on a\n // <button> is a React warning at every render. The cast is the standard HOC\n // one: TypeScript cannot prove `Omit<P & X, 'confirm'>` is still a `P`.\n const { confirm: _confirm, ...rest } = props;\n const forwarded = rest as unknown as P;\n\n if (!options) return <Wrapped {...forwarded} />;\n\n return (\n <>\n <Wrapped {...forwarded} onClick={state.request} />\n <ConfirmActionDialog state={state} {...options} copy={defaults.copy} />\n </>\n );\n }\n\n WithConfirmation.displayName = `withConfirmation(${\n Wrapped.displayName ?? Wrapped.name ?? 'Component'\n })`;\n\n return WithConfirmation;\n}\n","import type { ConfirmActionCopy } from '../../../copy';\nimport { Button } from '../../form/Button';\nimport type { ButtonProps } from '../../form/Button/Button.types';\n\nimport { withConfirmation } from './with-confirmation';\nimport type { ConfirmableComponent } from './ConfirmAction.types';\n\n/**\n * The library `Button`, already wrapped — the shape most call sites want.\n *\n * Adding the guard to an existing button is then an import swap plus the\n * `confirm` prop; the button's own props (colour, size, icon) are untouched.\n * The baked-in defaults are only the wording and tone every destructive\n * confirmation shares, and each instance can still override them.\n */\nexport function createConfirmButton(\n copy: ConfirmActionCopy,\n errorText: string,\n): ConfirmableComponent<ButtonProps> {\n return withConfirmation<ButtonProps>(Button, {\n cancelText: copy.cancel,\n tone: 'destructive',\n errorText,\n copy,\n });\n}\n"],"mappings":"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","names":["Fragment","jsx","jsxs","React","Fragment","jsx","jsxs","React"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfirmAction.parts.d.ts","sourceRoot":"","sources":["../../../../../src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,OAAO,KAAyB,MAAM,OAAO,CAAC;AAI9C,OAAO,KAAK,EAEV,cAAc,EAEd,sBAAsB,EACvB,MAAM,uBAAuB,CAAC;AAgF/B,MAAM,WAAW,wBAAyB,SAAQ,cAAc;IAC9D,6EAA6E;IAC7E,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,sBAAsB,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,KAAK,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,IAAoB,EACpB,YAAY,EACZ,UAA4B,EAC5B,IAAI,GACL,EAAE,wBAAwB,GAAG,KAAK,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"ConfirmAction.parts.d.ts","sourceRoot":"","sources":["../../../../../src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,OAAO,KAAyB,MAAM,OAAO,CAAC;AAI9C,OAAO,KAAK,EAEV,cAAc,EAEd,sBAAsB,EACvB,MAAM,uBAAuB,CAAC;AAgF/B,MAAM,WAAW,wBAAyB,SAAQ,cAAc;IAC9D,6EAA6E;IAC7E,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,sBAAsB,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,KAAK,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,IAAoB,EACpB,YAAY,EACZ,UAA4B,EAC5B,IAAI,GACL,EAAE,wBAAwB,GAAG,KAAK,CAAC,YAAY,CAmD/C"}
|
package/package.json
CHANGED
|
@@ -132,7 +132,14 @@ export function ConfirmActionDialog({
|
|
|
132
132
|
title={title}
|
|
133
133
|
description={confirmBody(description, copy, entityName)}
|
|
134
134
|
confirmText={confirmText}
|
|
135
|
-
|
|
135
|
+
// `copy.cancel` is the fallback, NOT `AlertDialog`'s own. The 6.3.0 copy
|
|
136
|
+
// sweep deleted this component's `cancelText = 'Cancelar'` default and
|
|
137
|
+
// put the word in `ConfirmActionCopy` — where nothing then read it, so
|
|
138
|
+
// every confirmation that names no `cancelText` of its own fell through
|
|
139
|
+
// to `AlertDialog`'s English `'Cancel'`, in a pt-BR dialog. That is the
|
|
140
|
+
// precise failure the sweep exists to prevent, one layer down: a port
|
|
141
|
+
// that is required, supplied, and ignored.
|
|
142
|
+
cancelText={cancelText ?? copy.cancel}
|
|
136
143
|
loading={state.pending}
|
|
137
144
|
confirmDisabled={gateUnmet}
|
|
138
145
|
initialFocus={resolveInitialFocus(tone, initialFocus)}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/feedback/ConfirmAction/ConfirmAction.hooks.ts","../src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx","../src/components/feedback/ConfirmAction/ConfirmAction.tsx","../src/components/feedback/ConfirmAction/with-confirmation.tsx","../src/components/feedback/ConfirmAction/ConfirmButton.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport type { ConfirmHandler, UseConfirmActionResult } from './ConfirmAction.types';\n\n/** Used when the guarded action rejects and the caller supplied no wording. */\n\n\n/**\n * What the popup says after a failed attempt.\n *\n * A rejection carrying a message wins: the server's sentence (\"esta categoria\n * ainda tem produtos vinculados\") is the one the operator can act on, and it is\n * strictly better than the generic fallback. Handlers that have nothing useful\n * to say reject with nothing and get `errorText`.\n */\nfunction failureMessage(cause: unknown, errorText: string): string {\n if (cause instanceof Error && cause.message) return cause.message;\n return errorText;\n}\n\n/**\n * The confirmation state machine, headless.\n *\n * It is the whole safety contract in one place, so every consumer gets the same\n * behaviour: the action runs ONLY from `confirm`, never from opening the popup;\n * a second confirm while the first is in flight is dropped (a double-click\n * cannot send two deletes); a rejection keeps the popup open carrying the\n * failure instead of closing over a write that never happened.\n */\nexport function useConfirmAction(\n onConfirm: ConfirmHandler,\n errorText: string,\n): UseConfirmActionResult {\n const [open, setOpen] = useState(false);\n const [pending, setPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // `pending` is mirrored in a ref because the two guards that matter — drop a\n // second confirm, ignore a cancel mid-flight — are read inside callbacks that\n // must not be rebuilt on every state change. Reading the state variable there\n // would leave a stale closure holding `false` for the whole in-flight window,\n // which is exactly the double-submit this component exists to prevent.\n const busy = useRef(false);\n\n // The action can settle after the trigger has unmounted (a row deleted from\n // under its own menu), so the settle path must not touch state by then.\n const mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n\n const request = useCallback((): void => {\n setError(null);\n setOpen(true);\n }, []);\n\n const cancel = useCallback((): void => {\n // Inert mid-flight: the write has already left, and closing here would hide\n // its outcome.\n if (busy.current) return;\n setOpen(false);\n setError(null);\n }, []);\n\n const settle = useCallback((failure: string | null): void => {\n busy.current = false;\n if (!mounted.current) return;\n setPending(false);\n setError(failure);\n if (!failure) setOpen(false);\n }, []);\n\n const confirm = useCallback((): void => {\n if (busy.current) return;\n busy.current = true;\n setPending(true);\n setError(null);\n // The handler is invoked synchronously, exactly as a plain `onClick` would\n // be — only the OUTCOME is awaited. The try/catch is what puts a handler\n // that throws synchronously on the same failure path as one that returns a\n // rejected promise.\n try {\n const result = onConfirm();\n void Promise.resolve(result)\n .then(() => settle(null))\n .catch((cause: unknown) => settle(failureMessage(cause, errorText)));\n } catch (cause) {\n settle(failureMessage(cause, errorText));\n }\n }, [errorText, onConfirm, settle]);\n\n return { open, pending, error, request, cancel, confirm };\n}\n","import type { ConfirmActionCopy } from \"../../../copy\";\nimport { Alert, Stack, TextField, Typography } from '@mui/material';\nimport React, { type ReactNode } from 'react';\n\nimport { AlertDialog } from '../../data-display/AlertDialog';\n\nimport type {\n ConfirmInitialFocus,\n ConfirmOptions,\n ConfirmTone,\n UseConfirmActionResult,\n} from './ConfirmAction.types';\n\nconst DEFAULT_TEST_ID = 'confirm-action';\n\n/**\n * The popup's body: the row being acted on, then what happens to it.\n *\n * The NAME is rendered in its own right rather than woven into the sentence, so\n * it is there whatever the caller wrote — \"the popup names the specific entity\"\n * is the one thing that must not depend on each call site remembering to\n * mention it. A body with neither a name nor a description would leave the\n * operator with only the title to decide on, so a neutral fallback covers that.\n */\nfunction confirmBody(\n description: ReactNode,\n copy: ConfirmActionCopy,\n entityName?: string,\n): ReactNode {\n if (!entityName) return description ?? copy.irreversible;\n return (\n <>\n <Typography component=\"span\" sx={{ fontWeight: 600, display: \"block\" }}>\n {entityName}\n </Typography>\n {description}\n </>\n );\n}\n\n/** Destructive dialogs open on Cancel; anything else opens on the confirm. */\nfunction resolveInitialFocus(\n tone: ConfirmTone,\n initialFocus?: ConfirmInitialFocus,\n): ConfirmInitialFocus {\n if (initialFocus) return initialFocus;\n return tone === 'destructive' ? 'cancel' : 'confirm';\n}\n\n/**\n * The type-to-confirm field. Rendered only when `typeToConfirm` is set, which\n * should be rare: it is the guard for actions with NO recovery path, where a\n * click is too cheap a gesture. Comparison is exact — trimmed of surrounding\n * whitespace only, so a trailing space from a paste does not read as a mismatch.\n */\nfunction TypeToConfirmField({\n expected,\n label,\n value,\n onChange,\n disabled,\n dataTestId,\n}: {\n expected: string;\n label?: string;\n value: string;\n onChange: (next: string) => void;\n disabled: boolean;\n dataTestId: string;\n}): React.ReactElement {\n return (\n <Stack spacing={1} sx={{ mt: 2 }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {label ?? `Digite \"${expected}\" para confirmar.`}\n </Typography>\n <TextField\n size=\"small\"\n value={value}\n disabled={disabled}\n onChange={(event) => onChange(event.target.value)}\n // On the INPUT rather than the wrapper: a test id on MUI's TextField\n // lands on the outer div, which is not the node a test can type into.\n inputProps={{\n 'aria-label': label ?? `Digite ${expected} para confirmar`,\n 'data-testid': `${dataTestId}-type-to-confirm`,\n }}\n />\n </Stack>\n );\n}\n\nexport interface ConfirmActionDialogProps extends ConfirmOptions {\n /** The fallback body when no entity is named. REQUIRED — no default copy. */\n copy: ConfirmActionCopy;\n state: UseConfirmActionResult;\n}\n\n/**\n * The popup itself: an `AlertDialog` in its destructive skin, plus the two\n * things a bare AlertDialog has no opinion about — the failure the last attempt\n * produced (shown IN the dialog, which stays open, rather than closing over a\n * write that never landed) and the optional type-to-confirm gate.\n */\nexport function ConfirmActionDialog({\n state,\n title,\n description,\n entityName,\n confirmText,\n cancelText,\n typeToConfirm,\n typeToConfirmLabel,\n tone = 'destructive',\n initialFocus,\n dataTestId = DEFAULT_TEST_ID,\n copy,\n}: ConfirmActionDialogProps): React.ReactElement {\n const [typed, setTyped] = React.useState('');\n\n // Every fresh open starts from an empty field: carrying the previous answer\n // over would hand the next delete a pre-satisfied gate.\n React.useEffect(() => {\n if (state.open) setTyped('');\n }, [state.open]);\n\n const gateUnmet = typeToConfirm !== undefined && typed.trim() !== typeToConfirm;\n\n return (\n <AlertDialog\n open={state.open}\n variant={tone === 'destructive' ? 'destructive' : 'default'}\n title={title}\n description={confirmBody(description, copy, entityName)}\n confirmText={confirmText}\n cancelText={cancelText}\n loading={state.pending}\n confirmDisabled={gateUnmet}\n initialFocus={resolveInitialFocus(tone, initialFocus)}\n onConfirm={state.confirm}\n onCancel={state.cancel}\n onClose={state.cancel}\n data-testid={dataTestId}\n >\n {state.error && (\n <Alert severity=\"error\" sx={{ mt: 1 }} data-testid={`${dataTestId}-error`}>\n {state.error}\n </Alert>\n )}\n {typeToConfirm !== undefined && (\n <TypeToConfirmField\n expected={typeToConfirm}\n label={typeToConfirmLabel}\n value={typed}\n onChange={setTyped}\n disabled={state.pending}\n dataTestId={dataTestId}\n />\n )}\n </AlertDialog>\n );\n}\n","import React from 'react';\n\nimport { useConfirmAction } from './ConfirmAction.hooks';\nimport { ConfirmActionDialog } from './ConfirmAction.parts';\nimport type { ConfirmActionProps } from './ConfirmAction.types';\n\n/**\n * Wraps any trigger in a confirmation popup.\n *\n * The trigger is a render prop rather than a fixed element, so the same guard\n * covers a button, a dropdown item, an icon or a table row action without this\n * component knowing what any of them look like. The guarded handler runs ONLY\n * after the operator confirms:\n *\n * ```tsx\n * <ConfirmAction\n * title=\"Excluir a categoria?\"\n * entityName={row.name}\n * description=\"Ela vai para a lixeira e pode ser restaurada de lá.\"\n * confirmText=\"Excluir\"\n * onConfirm={() => deleteCategoryAction({ tenantSlug, id: row.id })}\n * >\n * {(request) => <Button color=\"danger\" onClick={request}>Excluir</Button>}\n * </ConfirmAction>\n * ```\n *\n * For the common case — an existing button whose `onClick` is already the\n * destructive write — reach for {@link withConfirmation} instead, which needs\n * no restructuring of the call site.\n */\nexport function ConfirmAction({\n onConfirm,\n children,\n ...options\n}: ConfirmActionProps): React.ReactElement {\n const state = useConfirmAction(onConfirm, options.errorText);\n\n return (\n <>\n {children(state.request, { pending: state.pending })}\n <ConfirmActionDialog state={state} {...options} />\n </>\n );\n}\n\nConfirmAction.displayName = 'ConfirmAction';\n","import type { ConfirmActionCopy } from '../../../copy';\nimport React from 'react';\nimport type { ComponentType } from 'react';\n\nimport { useConfirmAction } from './ConfirmAction.hooks';\nimport { ConfirmActionDialog } from './ConfirmAction.parts';\nimport type {\n ConfirmHandler,\n ConfirmOptions,\n ConfirmableComponent,\n ConfirmableProps,\n WithConfirmationProps,\n} from './ConfirmAction.types';\n\n/**\n * Merge the HOC's baked-in defaults with the per-instance `confirm` prop.\n * Returns null when the instance opts out (`confirm={false}`) or when neither\n * side supplies the two fields a confirmation cannot be written without — the\n * question and the verb. A null result means \"render the plain component\",\n * which keeps the wrapped export usable in harmless contexts.\n */\nfunction resolveOptions(\n defaults: Partial<ConfirmOptions> | undefined,\n instance: Partial<ConfirmOptions> | false | undefined,\n): ConfirmOptions | null {\n if (instance === false) return null;\n const merged = { ...defaults, ...instance };\n if (!merged.title || !merged.confirmText) return null;\n return { ...merged, title: merged.title, confirmText: merged.confirmText };\n}\n\n/**\n * Adapt the wrapped component's `onClick` into a {@link ConfirmHandler}.\n *\n * The click argument is dropped (see `ConfirmHandler`) and the return value is\n * narrowed: a promise is handed back so the popup can hold its pending state\n * until the write settles, anything else becomes `undefined`. A component with\n * no `onClick` has nothing to guard, so confirming is a no-op.\n */\nfunction useGuardedHandler(onClick: ConfirmableProps['onClick']): ConfirmHandler {\n return React.useCallback((): void | Promise<unknown> => {\n const result = onClick?.();\n return result instanceof Promise ? result : undefined;\n }, [onClick]);\n}\n\n/**\n * Give any click-driven component a confirmation popup, without restructuring\n * the call site.\n *\n * The wrapped component's own `onClick` becomes the GUARDED action: clicking\n * now opens the popup, and the handler runs only if the operator confirms. It\n * inherits the whole contract from `useConfirmAction` — cancel sends nothing, a\n * returned promise holds the popup in its pending state so a double-click\n * cannot fire two writes, and a rejection keeps the popup open carrying the\n * error.\n *\n * ```tsx\n * const ConfirmButton = withConfirmation(Button);\n *\n * <ConfirmButton\n * color=\"danger\"\n * onClick={() => deleteCategoryAction({ tenantSlug, id: row.id })}\n * confirm={{\n * title: \"Excluir a categoria?\",\n * entityName: row.name,\n * description: \"Ela vai para a lixeira e pode ser restaurada de lá.\",\n * confirmText: \"Excluir\",\n * }}\n * >\n * Excluir\n * </ConfirmButton>\n * ```\n *\n * Bake the wording in once when the same guard repeats — `withConfirmation(Button,\n * { confirmText: \"Excluir\" })` — and let each instance override what differs.\n * `confirm={false}` falls through to the plain component.\n *\n * Refs are not forwarded: the HOC renders a fragment (trigger + popup), so there\n * is no single node to hand back. Wrap a component that needs a ref at its own\n * call site with {@link ConfirmAction} instead.\n */\nexport function withConfirmation<P extends ConfirmableProps>(\n Wrapped: ComponentType<P>,\n defaults: Partial<ConfirmOptions> & { errorText: string; copy: ConfirmActionCopy },\n): ConfirmableComponent<P> {\n function WithConfirmation(props: P & WithConfirmationProps): React.ReactElement {\n const { confirm, onClick } = props;\n const options = resolveOptions(defaults, confirm);\n const state = useConfirmAction(useGuardedHandler(onClick), defaults.errorText);\n\n // `confirm` is ours and must not reach the DOM — an unknown attribute on a\n // <button> is a React warning at every render. The cast is the standard HOC\n // one: TypeScript cannot prove `Omit<P & X, 'confirm'>` is still a `P`.\n const { confirm: _confirm, ...rest } = props;\n const forwarded = rest as unknown as P;\n\n if (!options) return <Wrapped {...forwarded} />;\n\n return (\n <>\n <Wrapped {...forwarded} onClick={state.request} />\n <ConfirmActionDialog state={state} {...options} copy={defaults.copy} />\n </>\n );\n }\n\n WithConfirmation.displayName = `withConfirmation(${\n Wrapped.displayName ?? Wrapped.name ?? 'Component'\n })`;\n\n return WithConfirmation;\n}\n","import type { ConfirmActionCopy } from '../../../copy';\nimport { Button } from '../../form/Button';\nimport type { ButtonProps } from '../../form/Button/Button.types';\n\nimport { withConfirmation } from './with-confirmation';\nimport type { ConfirmableComponent } from './ConfirmAction.types';\n\n/**\n * The library `Button`, already wrapped — the shape most call sites want.\n *\n * Adding the guard to an existing button is then an import swap plus the\n * `confirm` prop; the button's own props (colour, size, icon) are untouched.\n * The baked-in defaults are only the wording and tone every destructive\n * confirmation shares, and each instance can still override them.\n */\nexport function createConfirmButton(\n copy: ConfirmActionCopy,\n errorText: string,\n): ConfirmableComponent<ButtonProps> {\n return withConfirmation<ButtonProps>(Button, {\n cancelText: copy.cancel,\n tone: 'destructive',\n errorText,\n copy,\n });\n}\n"],"mappings":"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","names":["Fragment","jsx","jsxs","React","Fragment","jsx","jsxs","React"]}
|