@cfast/joy 0.2.0 → 0.3.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/index.d.ts CHANGED
@@ -10,15 +10,27 @@ type JoyActionButtonProps = {
10
10
  children: ReactNode;
11
11
  whenForbidden?: WhenForbidden;
12
12
  confirmation?: string | ConfirmOptions;
13
+ /**
14
+ * When provided, renders a permission-gated Link instead of a form button.
15
+ */
16
+ href?: string;
17
+ /**
18
+ * When provided, submits a form with these values as hidden fields via
19
+ * a fetcher. Eliminates manual `<Form>` + `<input type="hidden">`.
20
+ */
21
+ input?: Record<string, string | number | boolean | null | undefined>;
13
22
  } & Omit<ButtonProps, "children" | "onClick" | "disabled" | "loading" | "action">;
14
23
  /**
15
24
  * Joy UI styled ActionButton.
16
25
  *
17
- * Takes an `ActionHookResult` from `useActions()` no hooks inside,
18
- * pure presentation component. All Joy Button props (sx, fullWidth, etc.)
19
- * are forwarded to the underlying Button.
26
+ * Takes an `ActionHookResult` from `useActions()` or `useCfastLoader()`.
27
+ * All Joy Button props (sx, fullWidth, etc.) are forwarded to the underlying
28
+ * Button.
29
+ *
30
+ * When `href` is provided, renders as a Link (permission-gated).
31
+ * When `input` is provided, submits form data via a fetcher.
20
32
  */
21
- declare function ActionButton({ action, children, whenForbidden, confirmation: _confirmation, variant, color, size, ...buttonProps }: JoyActionButtonProps): ReactElement | null;
33
+ declare function ActionButton({ action, children, whenForbidden, confirmation: _confirmation, href, input, variant, color, size, ...buttonProps }: JoyActionButtonProps): ReactElement | null;
22
34
 
23
35
  /**
24
36
  * Joy UI ConfirmDialog — Modal + ModalDialog based on the example app pattern.
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/action-button.tsx
2
2
  import "react";
3
+ import { useFetcher } from "react-router";
3
4
  import { Button as JoyButton } from "@mui/joy";
4
5
  import { Tooltip as JoyTooltip } from "@mui/joy";
5
6
  import { jsx } from "react/jsx-runtime";
@@ -8,11 +9,14 @@ function ActionButton({
8
9
  children,
9
10
  whenForbidden = "disable",
10
11
  confirmation: _confirmation,
12
+ href,
13
+ input,
11
14
  variant = "solid",
12
15
  color = "primary",
13
16
  size = "md",
14
17
  ...buttonProps
15
18
  }) {
19
+ const fetcher = useFetcher();
16
20
  if (action.invisible) {
17
21
  return null;
18
22
  }
@@ -20,13 +24,57 @@ function ActionButton({
20
24
  return null;
21
25
  }
22
26
  const disabled = !action.permitted && whenForbidden === "disable";
27
+ const pending = action.pending || fetcher.state !== "idle";
28
+ if (href) {
29
+ if (disabled) {
30
+ const disabledButton = /* @__PURE__ */ jsx(
31
+ JoyButton,
32
+ {
33
+ ...buttonProps,
34
+ disabled: true,
35
+ variant,
36
+ color,
37
+ size,
38
+ children
39
+ }
40
+ );
41
+ if (action.reason) {
42
+ return /* @__PURE__ */ jsx(JoyTooltip, { title: action.reason, children: /* @__PURE__ */ jsx("span", { children: disabledButton }) });
43
+ }
44
+ return disabledButton;
45
+ }
46
+ return /* @__PURE__ */ jsx(
47
+ JoyButton,
48
+ {
49
+ ...buttonProps,
50
+ ...{ component: "a", href },
51
+ variant,
52
+ color,
53
+ size,
54
+ children
55
+ }
56
+ );
57
+ }
58
+ const handleClick = () => {
59
+ if (input) {
60
+ const formData = new FormData();
61
+ for (const [key, value] of Object.entries(input)) {
62
+ if (value !== null && value !== void 0) {
63
+ formData.set(key, String(value));
64
+ }
65
+ }
66
+ fetcher.submit(formData, { method: "POST" });
67
+ } else {
68
+ action.submit();
69
+ }
70
+ };
23
71
  const button = /* @__PURE__ */ jsx(
24
72
  JoyButton,
25
73
  {
26
74
  ...buttonProps,
27
- onClick: () => action.submit(),
75
+ onClick: handleClick,
28
76
  disabled,
29
- loading: action.pending,
77
+ loading: pending,
30
78
  variant,
31
79
  color,
32
80
  size,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cfast/joy",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Joy UI plugin for @cfast/ui — styled components powered by MUI Joy",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -57,13 +57,13 @@
57
57
  }
58
58
  },
59
59
  "dependencies": {
60
- "@mui/material": "^6.5.0",
61
60
  "sonner": "^2.0.3"
62
61
  },
63
62
  "devDependencies": {
64
63
  "@emotion/react": "^11.14.0",
65
64
  "@emotion/styled": "^11.14.1",
66
65
  "@mui/joy": "^5.0.0-beta.52",
66
+ "@mui/material": "^6.5.0",
67
67
  "@storybook/react": "^8.6.14",
68
68
  "@storybook/react-vite": "^8.6.14",
69
69
  "@testing-library/react": "^16.3.0",
@@ -78,9 +78,9 @@
78
78
  "tsup": "^8",
79
79
  "typescript": "^5.7",
80
80
  "vitest": "^4.1.0",
81
- "@cfast/actions": "0.1.2",
82
- "@cfast/auth": "0.4.0",
83
- "@cfast/ui": "0.3.0"
81
+ "@cfast/auth": "0.6.0",
82
+ "@cfast/actions": "0.3.0",
83
+ "@cfast/ui": "0.4.0"
84
84
  },
85
85
  "scripts": {
86
86
  "build": "tsup src/index.ts --format esm --dts && node ../../scripts/fix-mui-joy-imports.mjs dist",