@edux-design/buttons 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @edux-design/buttons
2
2
 
3
+ ## 0.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Popovers
8
+
3
9
  ## 0.0.2
4
10
 
5
11
  ### Patch Changes
@@ -0,0 +1,132 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ /**
4
+ * Props for the IconButton component.
5
+ *
6
+ * Extends all native HTML `<button>` attributes and accepts an icon prop.
7
+ * Designed for circular icon-only buttons that follow the same
8
+ * design-system patterns as the regular Button.
9
+ *
10
+ * @typedef {React.ButtonHTMLAttributes<HTMLButtonElement> & {
11
+ * icon: React.ReactNode,
12
+ * size?: "small"|"medium"|"large",
13
+ * isSecondary?: boolean,
14
+ * isDanger?: boolean,
15
+ * isBare?: boolean,
16
+ * disabled?: boolean,
17
+ * className?: string
18
+ * }} IconButtonProps
19
+ */
20
+ /**
21
+ * IconButton component.
22
+ *
23
+ * Provides a circular button used for icon-only actions, matching
24
+ * the design-system variants and states of the main Button component.
25
+ *
26
+ * @component
27
+ * @type {React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<HTMLButtonElement>>}
28
+ *
29
+ * @example
30
+ * ```jsx
31
+ * <IconButton icon={<XIcon />} aria-label="Close" />
32
+ * <IconButton icon={<EditIcon />} isSecondary />
33
+ * <IconButton icon={<TrashIcon />} isDanger disabled />
34
+ * ```
35
+ */
36
+ declare const IconButton: React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<HTMLButtonElement>>;
37
+ /**
38
+ * Props for the IconButton component.
39
+ *
40
+ * Extends all native HTML `<button>` attributes and accepts an icon prop.
41
+ * Designed for circular icon-only buttons that follow the same
42
+ * design-system patterns as the regular Button.
43
+ */
44
+ type IconButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
45
+ icon: React.ReactNode;
46
+ size?: "small" | "medium" | "large";
47
+ isSecondary?: boolean;
48
+ isDanger?: boolean;
49
+ isBare?: boolean;
50
+ disabled?: boolean;
51
+ className?: string;
52
+ };
53
+
54
+ /**
55
+ * Props for the Button component.
56
+ *
57
+ * Extends all native HTML `<button>` attributes, while adding
58
+ * design-system variants and state controls.
59
+ *
60
+ * @typedef {React.ButtonHTMLAttributes<HTMLButtonElement> & {
61
+ * children?: React.ReactNode,
62
+ * size?: "small"|"medium"|"large",
63
+ * isSecondary?: boolean,
64
+ * isDanger?: boolean,
65
+ * isBare?: boolean,
66
+ * isStretched?: boolean,
67
+ * disabled?: boolean,
68
+ * className?: string
69
+ * }} ButtonProps
70
+ */
71
+ /**
72
+ * Button component.
73
+ *
74
+ * Provides design-system styled button with support for
75
+ * multiple visual variants, sizing, and states.
76
+ *
77
+ * @component
78
+ * @type {React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>}
79
+ *
80
+ * @example
81
+ * ```jsx
82
+ * <Button size="small">Save</Button>
83
+ * <Button isSecondary>Cancel</Button>
84
+ * <Button isDanger disabled>Delete</Button>
85
+ * ```
86
+ */
87
+ declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
88
+ /**
89
+ * Props for the Button component.
90
+ *
91
+ * Extends all native HTML `<button>` attributes, while adding
92
+ * design-system variants and state controls.
93
+ */
94
+ type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
95
+ children?: React.ReactNode;
96
+ size?: "small" | "medium" | "large";
97
+ isSecondary?: boolean;
98
+ isDanger?: boolean;
99
+ isBare?: boolean;
100
+ isStretched?: boolean;
101
+ disabled?: boolean;
102
+ className?: string;
103
+ };
104
+
105
+ /**
106
+ * Props for the MenuButton component.
107
+ *
108
+ * @typedef {Object} MenuButtonProps
109
+ * @property {React.ReactNode} [children] - Content to display inside the button (usually label or icon).
110
+ * @property {"small"|"medium"} [size="medium"] - Size variant controlling button height.
111
+ */
112
+ /**
113
+ * MenuButton component.
114
+ *
115
+ * Provides a styled menu trigger button with optional sizing.
116
+ * It uses a `MenuButtonContext` provider to share internal state
117
+ * with child menu items.
118
+ *
119
+ * @component
120
+ * @type {React.FC<MenuButtonProps>}
121
+ *
122
+ * @example
123
+ * ```jsx
124
+ * <MenuButton size="small">Options</MenuButton>
125
+ * ```
126
+ */
127
+ declare function MenuButton({ children, size }: {
128
+ children: any;
129
+ size: any;
130
+ }): react_jsx_runtime.JSX.Element;
131
+
132
+ export { Button, IconButton, MenuButton };
@@ -0,0 +1,132 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ /**
4
+ * Props for the IconButton component.
5
+ *
6
+ * Extends all native HTML `<button>` attributes and accepts an icon prop.
7
+ * Designed for circular icon-only buttons that follow the same
8
+ * design-system patterns as the regular Button.
9
+ *
10
+ * @typedef {React.ButtonHTMLAttributes<HTMLButtonElement> & {
11
+ * icon: React.ReactNode,
12
+ * size?: "small"|"medium"|"large",
13
+ * isSecondary?: boolean,
14
+ * isDanger?: boolean,
15
+ * isBare?: boolean,
16
+ * disabled?: boolean,
17
+ * className?: string
18
+ * }} IconButtonProps
19
+ */
20
+ /**
21
+ * IconButton component.
22
+ *
23
+ * Provides a circular button used for icon-only actions, matching
24
+ * the design-system variants and states of the main Button component.
25
+ *
26
+ * @component
27
+ * @type {React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<HTMLButtonElement>>}
28
+ *
29
+ * @example
30
+ * ```jsx
31
+ * <IconButton icon={<XIcon />} aria-label="Close" />
32
+ * <IconButton icon={<EditIcon />} isSecondary />
33
+ * <IconButton icon={<TrashIcon />} isDanger disabled />
34
+ * ```
35
+ */
36
+ declare const IconButton: React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<HTMLButtonElement>>;
37
+ /**
38
+ * Props for the IconButton component.
39
+ *
40
+ * Extends all native HTML `<button>` attributes and accepts an icon prop.
41
+ * Designed for circular icon-only buttons that follow the same
42
+ * design-system patterns as the regular Button.
43
+ */
44
+ type IconButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
45
+ icon: React.ReactNode;
46
+ size?: "small" | "medium" | "large";
47
+ isSecondary?: boolean;
48
+ isDanger?: boolean;
49
+ isBare?: boolean;
50
+ disabled?: boolean;
51
+ className?: string;
52
+ };
53
+
54
+ /**
55
+ * Props for the Button component.
56
+ *
57
+ * Extends all native HTML `<button>` attributes, while adding
58
+ * design-system variants and state controls.
59
+ *
60
+ * @typedef {React.ButtonHTMLAttributes<HTMLButtonElement> & {
61
+ * children?: React.ReactNode,
62
+ * size?: "small"|"medium"|"large",
63
+ * isSecondary?: boolean,
64
+ * isDanger?: boolean,
65
+ * isBare?: boolean,
66
+ * isStretched?: boolean,
67
+ * disabled?: boolean,
68
+ * className?: string
69
+ * }} ButtonProps
70
+ */
71
+ /**
72
+ * Button component.
73
+ *
74
+ * Provides design-system styled button with support for
75
+ * multiple visual variants, sizing, and states.
76
+ *
77
+ * @component
78
+ * @type {React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>}
79
+ *
80
+ * @example
81
+ * ```jsx
82
+ * <Button size="small">Save</Button>
83
+ * <Button isSecondary>Cancel</Button>
84
+ * <Button isDanger disabled>Delete</Button>
85
+ * ```
86
+ */
87
+ declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
88
+ /**
89
+ * Props for the Button component.
90
+ *
91
+ * Extends all native HTML `<button>` attributes, while adding
92
+ * design-system variants and state controls.
93
+ */
94
+ type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
95
+ children?: React.ReactNode;
96
+ size?: "small" | "medium" | "large";
97
+ isSecondary?: boolean;
98
+ isDanger?: boolean;
99
+ isBare?: boolean;
100
+ isStretched?: boolean;
101
+ disabled?: boolean;
102
+ className?: string;
103
+ };
104
+
105
+ /**
106
+ * Props for the MenuButton component.
107
+ *
108
+ * @typedef {Object} MenuButtonProps
109
+ * @property {React.ReactNode} [children] - Content to display inside the button (usually label or icon).
110
+ * @property {"small"|"medium"} [size="medium"] - Size variant controlling button height.
111
+ */
112
+ /**
113
+ * MenuButton component.
114
+ *
115
+ * Provides a styled menu trigger button with optional sizing.
116
+ * It uses a `MenuButtonContext` provider to share internal state
117
+ * with child menu items.
118
+ *
119
+ * @component
120
+ * @type {React.FC<MenuButtonProps>}
121
+ *
122
+ * @example
123
+ * ```jsx
124
+ * <MenuButton size="small">Options</MenuButton>
125
+ * ```
126
+ */
127
+ declare function MenuButton({ children, size }: {
128
+ children: any;
129
+ size: any;
130
+ }): react_jsx_runtime.JSX.Element;
131
+
132
+ export { Button, IconButton, MenuButton };
package/dist/index.js CHANGED
@@ -30,14 +30,74 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  var index_exports = {};
31
31
  __export(index_exports, {
32
32
  Button: () => Button,
33
+ IconButton: () => IconButton,
33
34
  MenuButton: () => MenuButton
34
35
  });
35
36
  module.exports = __toCommonJS(index_exports);
36
37
 
37
- // src/elements/Button.jsx
38
+ // src/elements/IconButton.jsx
38
39
  var import_react = __toESM(require("react"));
39
40
  var import_utils = require("@edux-design/utils");
40
- var Button = (0, import_react.forwardRef)(
41
+ var import_jsx_runtime = require("react/jsx-runtime");
42
+ var IconButton = (0, import_react.forwardRef)(
43
+ ({
44
+ icon,
45
+ size = "medium",
46
+ isSecondary,
47
+ isDanger,
48
+ isBare,
49
+ disabled,
50
+ className,
51
+ ...props
52
+ }, ref) => {
53
+ let variant = "primary";
54
+ if (isBare) variant = "bare";
55
+ if (isSecondary) variant = "secondary";
56
+ if (isDanger) variant = "danger";
57
+ if (disabled) variant = "disabled";
58
+ if (process.env.NODE_ENV !== "production") {
59
+ const count = [isSecondary, isDanger, isBare].filter(Boolean).length;
60
+ if (count > 1) {
61
+ console.warn(
62
+ "[IconButton]: Multiple variant props passed. Using the highest priority only."
63
+ );
64
+ }
65
+ }
66
+ const defaults = "flex justify-center items-center focus:shadow-focus focus-visible:shadow-focus outline-none transition-all duration-300 ease-in-out rounded-full";
67
+ const sizes = {
68
+ small: "h-[36px] w-[36px] text-sm",
69
+ medium: "h-[44px] w-[44px] text-base",
70
+ large: "h-[56px] w-[56px] text-lg"
71
+ };
72
+ const variants = {
73
+ primary: "border-2 border-border-primary-emphasis bg-bg-primary-base text-white hover:bg-border-focus hover:text-fg-base hover:border-border-emphasis hover:shadow-md active:bg-border-focus active:bg-bg-focus-overlay active:text-fg-base",
74
+ secondary: "border-2 border-border-primary-base bg-bg-base text-fg-primary-emphasis hover:shadow-md hover:bg-bg-primary-subtle active:bg-bg-primary-subtle-90",
75
+ bare: "bg-bg-base text-fg-primary-emphasis hover:bg-bg-minimal active:bg-bg-minimal-5",
76
+ danger: "bg-bg-danger-base border-2 border-border-danger-emphasis text-white hover:bg-bg-danger-base-5 active:bg-bg-danger-base-10",
77
+ disabled: "border-2 border-border-subtle bg-bg-inactive text-fg-inactive hover:no-underline cursor-not-allowed"
78
+ };
79
+ const STYLES = (0, import_utils.cx)(defaults, sizes[size], variants[variant], className);
80
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
81
+ "button",
82
+ {
83
+ role: "button",
84
+ type: "button",
85
+ "aria-disabled": disabled,
86
+ disabled,
87
+ className: STYLES,
88
+ ref,
89
+ ...props,
90
+ children: icon
91
+ }
92
+ );
93
+ }
94
+ );
95
+
96
+ // src/elements/Button.jsx
97
+ var import_react2 = __toESM(require("react"));
98
+ var import_utils2 = require("@edux-design/utils");
99
+ var import_jsx_runtime2 = require("react/jsx-runtime");
100
+ var Button = (0, import_react2.forwardRef)(
41
101
  ({
42
102
  children,
43
103
  size = "medium",
@@ -77,8 +137,8 @@ var Button = (0, import_react.forwardRef)(
77
137
  danger: "bg-bg-danger-base border-2 border-border-danger-emphasis text-white hover:bg-bg-danger-base-5 active:bg-bg-danger-base-10",
78
138
  disabled: "border-2 border-border-subtle bg-bg-inactive text-fg-inactive hover:no-underline"
79
139
  };
80
- const STYLES = (0, import_utils.cx)(defaults, sizes[size], width, fonts, variants[variant]);
81
- return /* @__PURE__ */ import_react.default.createElement(
140
+ const STYLES = (0, import_utils2.cx)(defaults, sizes[size], width, fonts, variants[variant]);
141
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
82
142
  "button",
83
143
  {
84
144
  role: "button",
@@ -87,22 +147,22 @@ var Button = (0, import_react.forwardRef)(
87
147
  disabled,
88
148
  className: STYLES,
89
149
  ref,
90
- ...props
91
- },
92
- children
150
+ ...props,
151
+ children
152
+ }
93
153
  );
94
154
  }
95
155
  );
96
156
 
97
157
  // src/elements/MenuButton.jsx
98
- var import_react3 = __toESM(require("react"));
158
+ var import_react4 = __toESM(require("react"));
99
159
 
100
160
  // src/util/MenuButtonContext.jsx
101
- var import_react2 = __toESM(require("react"));
102
- var MenuButtonContext = (0, import_react2.createContext)();
161
+ var import_react3 = __toESM(require("react"));
162
+ var MenuButtonContext = (0, import_react3.createContext)();
103
163
 
104
164
  // src/elements/MenuButton.jsx
105
- var import_utils2 = require("@edux-design/utils");
165
+ var import_utils3 = require("@edux-design/utils");
106
166
 
107
167
  // ../icons/dist/index.mjs
108
168
  var __create2 = Object.create;
@@ -1759,19 +1819,19 @@ var require_react_jsx_runtime_development = __commonJS({
1759
1819
  function validateChildKeys(node) {
1760
1820
  "object" === typeof node && null !== node && node.$$typeof === REACT_ELEMENT_TYPE && node._store && (node._store.validated = 1);
1761
1821
  }
1762
- var React4 = require_react(), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler");
1763
- var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React4.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
1822
+ var React5 = require_react(), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler");
1823
+ var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React5.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
1764
1824
  return null;
1765
1825
  };
1766
- React4 = {
1826
+ React5 = {
1767
1827
  react_stack_bottom_frame: function(callStackForError) {
1768
1828
  return callStackForError();
1769
1829
  }
1770
1830
  };
1771
1831
  var specialPropKeyWarningShown;
1772
1832
  var didWarnAboutElementRef = {};
1773
- var unknownOwnerDebugStack = React4.react_stack_bottom_frame.bind(
1774
- React4,
1833
+ var unknownOwnerDebugStack = React5.react_stack_bottom_frame.bind(
1834
+ React5,
1775
1835
  UnknownOwner
1776
1836
  )();
1777
1837
  var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
@@ -1815,10 +1875,12 @@ var require_jsx_runtime = __commonJS({
1815
1875
  }
1816
1876
  }
1817
1877
  });
1818
- var import_jsx_runtime = __toESM2(require_jsx_runtime());
1819
- var import_jsx_runtime2 = __toESM2(require_jsx_runtime());
1820
1878
  var import_jsx_runtime3 = __toESM2(require_jsx_runtime());
1821
- var SvgChevron = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1879
+ var import_jsx_runtime22 = __toESM2(require_jsx_runtime());
1880
+ var import_jsx_runtime32 = __toESM2(require_jsx_runtime());
1881
+ var import_jsx_runtime4 = __toESM2(require_jsx_runtime());
1882
+ var import_jsx_runtime5 = __toESM2(require_jsx_runtime());
1883
+ var SvgChevron = (props) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1822
1884
  "svg",
1823
1885
  {
1824
1886
  xmlns: "http://www.w3.org/2000/svg",
@@ -1827,7 +1889,7 @@ var SvgChevron = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1827
1889
  fill: "none",
1828
1890
  viewBox: "0 0 24 24",
1829
1891
  ...props,
1830
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1892
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1831
1893
  "path",
1832
1894
  {
1833
1895
  fill: "currentColor",
@@ -1839,8 +1901,6 @@ var SvgChevron = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1839
1901
  }
1840
1902
  );
1841
1903
  var Chevron_default = SvgChevron;
1842
- var import_jsx_runtime4 = __toESM2(require_jsx_runtime());
1843
- var import_jsx_runtime5 = __toESM2(require_jsx_runtime());
1844
1904
  var import_jsx_runtime6 = __toESM2(require_jsx_runtime());
1845
1905
  var import_jsx_runtime7 = __toESM2(require_jsx_runtime());
1846
1906
  var import_jsx_runtime8 = __toESM2(require_jsx_runtime());
@@ -1857,7 +1917,7 @@ var import_jsx_runtime18 = __toESM2(require_jsx_runtime());
1857
1917
  var import_jsx_runtime19 = __toESM2(require_jsx_runtime());
1858
1918
  var import_jsx_runtime20 = __toESM2(require_jsx_runtime());
1859
1919
  var import_jsx_runtime21 = __toESM2(require_jsx_runtime());
1860
- var import_jsx_runtime22 = __toESM2(require_jsx_runtime());
1920
+ var import_jsx_runtime222 = __toESM2(require_jsx_runtime());
1861
1921
  var import_jsx_runtime23 = __toESM2(require_jsx_runtime());
1862
1922
  var import_jsx_runtime24 = __toESM2(require_jsx_runtime());
1863
1923
  var import_jsx_runtime25 = __toESM2(require_jsx_runtime());
@@ -1866,21 +1926,44 @@ var import_jsx_runtime27 = __toESM2(require_jsx_runtime());
1866
1926
  var import_jsx_runtime28 = __toESM2(require_jsx_runtime());
1867
1927
  var import_jsx_runtime29 = __toESM2(require_jsx_runtime());
1868
1928
  var import_jsx_runtime30 = __toESM2(require_jsx_runtime());
1929
+ var import_jsx_runtime31 = __toESM2(require_jsx_runtime());
1930
+ var import_jsx_runtime322 = __toESM2(require_jsx_runtime());
1931
+ var import_jsx_runtime33 = __toESM2(require_jsx_runtime());
1932
+ var import_jsx_runtime34 = __toESM2(require_jsx_runtime());
1933
+ var import_jsx_runtime35 = __toESM2(require_jsx_runtime());
1934
+ var import_jsx_runtime36 = __toESM2(require_jsx_runtime());
1935
+ var import_jsx_runtime37 = __toESM2(require_jsx_runtime());
1936
+ var import_jsx_runtime38 = __toESM2(require_jsx_runtime());
1937
+ var import_jsx_runtime39 = __toESM2(require_jsx_runtime());
1938
+ var import_jsx_runtime40 = __toESM2(require_jsx_runtime());
1939
+ var import_jsx_runtime41 = __toESM2(require_jsx_runtime());
1940
+ var import_jsx_runtime42 = __toESM2(require_jsx_runtime());
1941
+ var import_jsx_runtime43 = __toESM2(require_jsx_runtime());
1942
+ var import_jsx_runtime44 = __toESM2(require_jsx_runtime());
1943
+ var import_jsx_runtime45 = __toESM2(require_jsx_runtime());
1944
+ var import_jsx_runtime46 = __toESM2(require_jsx_runtime());
1945
+ var import_jsx_runtime47 = __toESM2(require_jsx_runtime());
1946
+ var import_jsx_runtime48 = __toESM2(require_jsx_runtime());
1869
1947
 
1870
1948
  // src/elements/MenuButton.jsx
1949
+ var import_jsx_runtime49 = require("react/jsx-runtime");
1871
1950
  function MenuButton({ children, size }) {
1872
- const SPLIT_BUTTON_STYLES = (0, import_utils2.cx)(
1951
+ const SPLIT_BUTTON_STYLES = (0, import_utils3.cx)(
1873
1952
  "w-[36px] border-l-[1px] border-l-black flex flex-row justify-center items-center",
1874
1953
  {
1875
1954
  "h-[32px]": size === "small",
1876
1955
  "h-[40px] py-2": size === "medium" || size === void 0
1877
1956
  }
1878
1957
  );
1879
- return /* @__PURE__ */ import_react3.default.createElement(MenuButtonContext.Provider, { value: true }, /* @__PURE__ */ import_react3.default.createElement("div", null, children), /* @__PURE__ */ import_react3.default.createElement(Chevron_default, null));
1958
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(MenuButtonContext.Provider, { value: true, children: [
1959
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: SPLIT_BUTTON_STYLES, children }),
1960
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Chevron_default, {})
1961
+ ] });
1880
1962
  }
1881
1963
  // Annotate the CommonJS export names for ESM import in node:
1882
1964
  0 && (module.exports = {
1883
1965
  Button,
1966
+ IconButton,
1884
1967
  MenuButton
1885
1968
  });
1886
1969
  /*! Bundled license information:
package/dist/index.mjs CHANGED
@@ -1,7 +1,66 @@
1
- // src/elements/Button.jsx
1
+ // src/elements/IconButton.jsx
2
2
  import React, { forwardRef } from "react";
3
3
  import { cx } from "@edux-design/utils";
4
- var Button = forwardRef(
4
+ import { jsx } from "react/jsx-runtime";
5
+ var IconButton = forwardRef(
6
+ ({
7
+ icon,
8
+ size = "medium",
9
+ isSecondary,
10
+ isDanger,
11
+ isBare,
12
+ disabled,
13
+ className,
14
+ ...props
15
+ }, ref) => {
16
+ let variant = "primary";
17
+ if (isBare) variant = "bare";
18
+ if (isSecondary) variant = "secondary";
19
+ if (isDanger) variant = "danger";
20
+ if (disabled) variant = "disabled";
21
+ if (process.env.NODE_ENV !== "production") {
22
+ const count = [isSecondary, isDanger, isBare].filter(Boolean).length;
23
+ if (count > 1) {
24
+ console.warn(
25
+ "[IconButton]: Multiple variant props passed. Using the highest priority only."
26
+ );
27
+ }
28
+ }
29
+ const defaults = "flex justify-center items-center focus:shadow-focus focus-visible:shadow-focus outline-none transition-all duration-300 ease-in-out rounded-full";
30
+ const sizes = {
31
+ small: "h-[36px] w-[36px] text-sm",
32
+ medium: "h-[44px] w-[44px] text-base",
33
+ large: "h-[56px] w-[56px] text-lg"
34
+ };
35
+ const variants = {
36
+ primary: "border-2 border-border-primary-emphasis bg-bg-primary-base text-white hover:bg-border-focus hover:text-fg-base hover:border-border-emphasis hover:shadow-md active:bg-border-focus active:bg-bg-focus-overlay active:text-fg-base",
37
+ secondary: "border-2 border-border-primary-base bg-bg-base text-fg-primary-emphasis hover:shadow-md hover:bg-bg-primary-subtle active:bg-bg-primary-subtle-90",
38
+ bare: "bg-bg-base text-fg-primary-emphasis hover:bg-bg-minimal active:bg-bg-minimal-5",
39
+ danger: "bg-bg-danger-base border-2 border-border-danger-emphasis text-white hover:bg-bg-danger-base-5 active:bg-bg-danger-base-10",
40
+ disabled: "border-2 border-border-subtle bg-bg-inactive text-fg-inactive hover:no-underline cursor-not-allowed"
41
+ };
42
+ const STYLES = cx(defaults, sizes[size], variants[variant], className);
43
+ return /* @__PURE__ */ jsx(
44
+ "button",
45
+ {
46
+ role: "button",
47
+ type: "button",
48
+ "aria-disabled": disabled,
49
+ disabled,
50
+ className: STYLES,
51
+ ref,
52
+ ...props,
53
+ children: icon
54
+ }
55
+ );
56
+ }
57
+ );
58
+
59
+ // src/elements/Button.jsx
60
+ import React2, { forwardRef as forwardRef2 } from "react";
61
+ import { cx as cx2 } from "@edux-design/utils";
62
+ import { jsx as jsx2 } from "react/jsx-runtime";
63
+ var Button = forwardRef2(
5
64
  ({
6
65
  children,
7
66
  size = "medium",
@@ -41,8 +100,8 @@ var Button = forwardRef(
41
100
  danger: "bg-bg-danger-base border-2 border-border-danger-emphasis text-white hover:bg-bg-danger-base-5 active:bg-bg-danger-base-10",
42
101
  disabled: "border-2 border-border-subtle bg-bg-inactive text-fg-inactive hover:no-underline"
43
102
  };
44
- const STYLES = cx(defaults, sizes[size], width, fonts, variants[variant]);
45
- return /* @__PURE__ */ React.createElement(
103
+ const STYLES = cx2(defaults, sizes[size], width, fonts, variants[variant]);
104
+ return /* @__PURE__ */ jsx2(
46
105
  "button",
47
106
  {
48
107
  role: "button",
@@ -51,22 +110,22 @@ var Button = forwardRef(
51
110
  disabled,
52
111
  className: STYLES,
53
112
  ref,
54
- ...props
55
- },
56
- children
113
+ ...props,
114
+ children
115
+ }
57
116
  );
58
117
  }
59
118
  );
60
119
 
61
120
  // src/elements/MenuButton.jsx
62
- import React3 from "react";
121
+ import React4 from "react";
63
122
 
64
123
  // src/util/MenuButtonContext.jsx
65
- import React2, { createContext, useContext } from "react";
124
+ import React3, { createContext, useContext } from "react";
66
125
  var MenuButtonContext = createContext();
67
126
 
68
127
  // src/elements/MenuButton.jsx
69
- import { cx as cx2 } from "@edux-design/utils";
128
+ import { cx as cx3 } from "@edux-design/utils";
70
129
 
71
130
  // ../icons/dist/index.mjs
72
131
  var __create = Object.create;
@@ -1723,19 +1782,19 @@ var require_react_jsx_runtime_development = __commonJS({
1723
1782
  function validateChildKeys(node) {
1724
1783
  "object" === typeof node && null !== node && node.$$typeof === REACT_ELEMENT_TYPE && node._store && (node._store.validated = 1);
1725
1784
  }
1726
- var React4 = require_react(), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler");
1727
- var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React4.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
1785
+ var React5 = require_react(), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler");
1786
+ var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React5.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
1728
1787
  return null;
1729
1788
  };
1730
- React4 = {
1789
+ React5 = {
1731
1790
  react_stack_bottom_frame: function(callStackForError) {
1732
1791
  return callStackForError();
1733
1792
  }
1734
1793
  };
1735
1794
  var specialPropKeyWarningShown;
1736
1795
  var didWarnAboutElementRef = {};
1737
- var unknownOwnerDebugStack = React4.react_stack_bottom_frame.bind(
1738
- React4,
1796
+ var unknownOwnerDebugStack = React5.react_stack_bottom_frame.bind(
1797
+ React5,
1739
1798
  UnknownOwner
1740
1799
  )();
1741
1800
  var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
@@ -1779,10 +1838,12 @@ var require_jsx_runtime = __commonJS({
1779
1838
  }
1780
1839
  }
1781
1840
  });
1782
- var import_jsx_runtime = __toESM(require_jsx_runtime());
1783
- var import_jsx_runtime2 = __toESM(require_jsx_runtime());
1784
1841
  var import_jsx_runtime3 = __toESM(require_jsx_runtime());
1785
- var SvgChevron = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1842
+ var import_jsx_runtime22 = __toESM(require_jsx_runtime());
1843
+ var import_jsx_runtime32 = __toESM(require_jsx_runtime());
1844
+ var import_jsx_runtime4 = __toESM(require_jsx_runtime());
1845
+ var import_jsx_runtime5 = __toESM(require_jsx_runtime());
1846
+ var SvgChevron = (props) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1786
1847
  "svg",
1787
1848
  {
1788
1849
  xmlns: "http://www.w3.org/2000/svg",
@@ -1791,7 +1852,7 @@ var SvgChevron = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1791
1852
  fill: "none",
1792
1853
  viewBox: "0 0 24 24",
1793
1854
  ...props,
1794
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1855
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1795
1856
  "path",
1796
1857
  {
1797
1858
  fill: "currentColor",
@@ -1803,8 +1864,6 @@ var SvgChevron = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1803
1864
  }
1804
1865
  );
1805
1866
  var Chevron_default = SvgChevron;
1806
- var import_jsx_runtime4 = __toESM(require_jsx_runtime());
1807
- var import_jsx_runtime5 = __toESM(require_jsx_runtime());
1808
1867
  var import_jsx_runtime6 = __toESM(require_jsx_runtime());
1809
1868
  var import_jsx_runtime7 = __toESM(require_jsx_runtime());
1810
1869
  var import_jsx_runtime8 = __toESM(require_jsx_runtime());
@@ -1821,7 +1880,7 @@ var import_jsx_runtime18 = __toESM(require_jsx_runtime());
1821
1880
  var import_jsx_runtime19 = __toESM(require_jsx_runtime());
1822
1881
  var import_jsx_runtime20 = __toESM(require_jsx_runtime());
1823
1882
  var import_jsx_runtime21 = __toESM(require_jsx_runtime());
1824
- var import_jsx_runtime22 = __toESM(require_jsx_runtime());
1883
+ var import_jsx_runtime222 = __toESM(require_jsx_runtime());
1825
1884
  var import_jsx_runtime23 = __toESM(require_jsx_runtime());
1826
1885
  var import_jsx_runtime24 = __toESM(require_jsx_runtime());
1827
1886
  var import_jsx_runtime25 = __toESM(require_jsx_runtime());
@@ -1830,20 +1889,43 @@ var import_jsx_runtime27 = __toESM(require_jsx_runtime());
1830
1889
  var import_jsx_runtime28 = __toESM(require_jsx_runtime());
1831
1890
  var import_jsx_runtime29 = __toESM(require_jsx_runtime());
1832
1891
  var import_jsx_runtime30 = __toESM(require_jsx_runtime());
1892
+ var import_jsx_runtime31 = __toESM(require_jsx_runtime());
1893
+ var import_jsx_runtime322 = __toESM(require_jsx_runtime());
1894
+ var import_jsx_runtime33 = __toESM(require_jsx_runtime());
1895
+ var import_jsx_runtime34 = __toESM(require_jsx_runtime());
1896
+ var import_jsx_runtime35 = __toESM(require_jsx_runtime());
1897
+ var import_jsx_runtime36 = __toESM(require_jsx_runtime());
1898
+ var import_jsx_runtime37 = __toESM(require_jsx_runtime());
1899
+ var import_jsx_runtime38 = __toESM(require_jsx_runtime());
1900
+ var import_jsx_runtime39 = __toESM(require_jsx_runtime());
1901
+ var import_jsx_runtime40 = __toESM(require_jsx_runtime());
1902
+ var import_jsx_runtime41 = __toESM(require_jsx_runtime());
1903
+ var import_jsx_runtime42 = __toESM(require_jsx_runtime());
1904
+ var import_jsx_runtime43 = __toESM(require_jsx_runtime());
1905
+ var import_jsx_runtime44 = __toESM(require_jsx_runtime());
1906
+ var import_jsx_runtime45 = __toESM(require_jsx_runtime());
1907
+ var import_jsx_runtime46 = __toESM(require_jsx_runtime());
1908
+ var import_jsx_runtime47 = __toESM(require_jsx_runtime());
1909
+ var import_jsx_runtime48 = __toESM(require_jsx_runtime());
1833
1910
 
1834
1911
  // src/elements/MenuButton.jsx
1912
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
1835
1913
  function MenuButton({ children, size }) {
1836
- const SPLIT_BUTTON_STYLES = cx2(
1914
+ const SPLIT_BUTTON_STYLES = cx3(
1837
1915
  "w-[36px] border-l-[1px] border-l-black flex flex-row justify-center items-center",
1838
1916
  {
1839
1917
  "h-[32px]": size === "small",
1840
1918
  "h-[40px] py-2": size === "medium" || size === void 0
1841
1919
  }
1842
1920
  );
1843
- return /* @__PURE__ */ React3.createElement(MenuButtonContext.Provider, { value: true }, /* @__PURE__ */ React3.createElement("div", null, children), /* @__PURE__ */ React3.createElement(Chevron_default, null));
1921
+ return /* @__PURE__ */ jsxs(MenuButtonContext.Provider, { value: true, children: [
1922
+ /* @__PURE__ */ jsx3("div", { className: SPLIT_BUTTON_STYLES, children }),
1923
+ /* @__PURE__ */ jsx3(Chevron_default, {})
1924
+ ] });
1844
1925
  }
1845
1926
  export {
1846
1927
  Button,
1928
+ IconButton,
1847
1929
  MenuButton
1848
1930
  };
1849
1931
  /*! Bundled license information:
package/package.json CHANGED
@@ -1,20 +1,22 @@
1
1
  {
2
2
  "name": "@edux-design/buttons",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "private": false,
5
5
  "sideEffects": [
6
6
  "**/*.css"
7
7
  ],
8
+ "types": "./dist/index.d.ts",
8
9
  "exports": {
9
10
  ".": {
10
11
  "import": "./dist/index.mjs",
11
- "require": "./dist/index.js"
12
+ "require": "./dist/index.js",
13
+ "types": "./dist/index.d.ts"
12
14
  }
13
15
  },
14
16
  "scripts": {
15
17
  "lint": "eslint . --max-warnings 0",
16
- "build": "tsup src/index.js --format esm,cjs",
17
- "dev": "tsup src/index.js --watch --format esm,cjs",
18
+ "build": "tsup src/index.js --format esm,cjs --dts",
19
+ "dev": "tsup src/index.js --watch --format esm,cjs --dts",
18
20
  "generate:component": "turbo gen react-component",
19
21
  "check-types": "tsc --noEmit"
20
22
  },
@@ -0,0 +1,84 @@
1
+ import React from "react";
2
+ import { Button, IconButton } from "./../index";
3
+ import { Close } from "@edux-design/icons";
4
+
5
+ export default {
6
+ title: "Components/Button",
7
+ component: Button,
8
+ argTypes: {
9
+ size: {
10
+ control: { type: "select" },
11
+ options: ["small", "medium", "large"],
12
+ },
13
+ isSecondary: { control: "boolean" },
14
+ isDanger: { control: "boolean" },
15
+ isBare: { control: "boolean" },
16
+ isStretched: { control: "boolean" },
17
+ disabled: { control: "boolean" },
18
+ children: { control: "text" },
19
+ },
20
+ };
21
+
22
+ // Base template
23
+ const Template = (args) => <Button {...args} />;
24
+
25
+ // Default story
26
+ export const Primary = Template.bind({});
27
+ Primary.args = {
28
+ children: "Primary Button",
29
+ size: "medium",
30
+ };
31
+
32
+ // Variants
33
+ export const Secondary = Template.bind({});
34
+ Secondary.args = {
35
+ children: "Secondary Button",
36
+ isSecondary: true,
37
+ };
38
+
39
+ export const Danger = Template.bind({});
40
+ Danger.args = {
41
+ children: "Delete",
42
+ isDanger: true,
43
+ };
44
+
45
+ export const Bare = Template.bind({});
46
+ Bare.args = {
47
+ children: "Bare Button",
48
+ isBare: true,
49
+ };
50
+
51
+ export const Disabled = Template.bind({});
52
+ Disabled.args = {
53
+ children: "Disabled",
54
+ disabled: true,
55
+ };
56
+
57
+ // Sizes
58
+ export const Small = Template.bind({});
59
+ Small.args = {
60
+ children: "Small",
61
+ size: "small",
62
+ };
63
+
64
+ export const Large = Template.bind({});
65
+ Large.args = {
66
+ children: "Large",
67
+ size: "large",
68
+ };
69
+
70
+ // Stretched (full width)
71
+ export const Stretched = Template.bind({});
72
+ Stretched.args = {
73
+ children: "Full Width",
74
+ isStretched: true,
75
+ };
76
+
77
+ export const Default = () => (
78
+ <div className="flex gap-4 items-center">
79
+ <IconButton icon={<Close />} aria-label="Close" isBare />
80
+ <IconButton icon={<Close />} isSecondary aria-label="Close" />
81
+ <IconButton icon={<Close />} isDanger aria-label="Delete" />
82
+ <IconButton icon={<Close />} disabled aria-label="Disabled" />
83
+ </div>
84
+ );
@@ -1,6 +1,40 @@
1
1
  import React, { forwardRef } from "react";
2
2
  import { cx } from "@edux-design/utils";
3
3
 
4
+ /**
5
+ * Props for the Button component.
6
+ *
7
+ * Extends all native HTML `<button>` attributes, while adding
8
+ * design-system variants and state controls.
9
+ *
10
+ * @typedef {React.ButtonHTMLAttributes<HTMLButtonElement> & {
11
+ * children?: React.ReactNode,
12
+ * size?: "small"|"medium"|"large",
13
+ * isSecondary?: boolean,
14
+ * isDanger?: boolean,
15
+ * isBare?: boolean,
16
+ * isStretched?: boolean,
17
+ * disabled?: boolean,
18
+ * className?: string
19
+ * }} ButtonProps
20
+ */
21
+
22
+ /**
23
+ * Button component.
24
+ *
25
+ * Provides design-system styled button with support for
26
+ * multiple visual variants, sizing, and states.
27
+ *
28
+ * @component
29
+ * @type {React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>}
30
+ *
31
+ * @example
32
+ * ```jsx
33
+ * <Button size="small">Save</Button>
34
+ * <Button isSecondary>Cancel</Button>
35
+ * <Button isDanger disabled>Delete</Button>
36
+ * ```
37
+ */
4
38
  export const Button = forwardRef(
5
39
  (
6
40
  {
@@ -22,8 +56,7 @@ export const Button = forwardRef(
22
56
  if (isDanger) variant = "danger";
23
57
  if (disabled) variant = "disabled";
24
58
 
25
- // handle conflicting props - the last bool wins. i.e. The priority we are accepting is isbare, isSecondary, isDanger, disabled
26
-
59
+ // handle conflicting props - the last bool wins
27
60
  if (process.env.NODE_ENV !== "production") {
28
61
  const count = [isSecondary, isDanger, isBare].filter(Boolean).length;
29
62
  if (count > 1) {
@@ -39,7 +72,6 @@ export const Button = forwardRef(
39
72
  const fonts =
40
73
  "text-bold tracking-normal hover:underline hover:underline-offset-(--underline-offset-btn) active:underline active:underline-offset-(--underline-offset-btn)";
41
74
 
42
- //FIX-ME - Remove hardcoded values
43
75
  const sizes = {
44
76
  small: "h-[36px] py-8 px-16 rounded-lg text-sm",
45
77
  medium: "h-[44px] py-8 px-16 rounded-lg text-base",
@@ -0,0 +1,104 @@
1
+ import React, { forwardRef } from "react";
2
+ import { cx } from "@edux-design/utils";
3
+
4
+ /**
5
+ * Props for the IconButton component.
6
+ *
7
+ * Extends all native HTML `<button>` attributes and accepts an icon prop.
8
+ * Designed for circular icon-only buttons that follow the same
9
+ * design-system patterns as the regular Button.
10
+ *
11
+ * @typedef {React.ButtonHTMLAttributes<HTMLButtonElement> & {
12
+ * icon: React.ReactNode,
13
+ * size?: "small"|"medium"|"large",
14
+ * isSecondary?: boolean,
15
+ * isDanger?: boolean,
16
+ * isBare?: boolean,
17
+ * disabled?: boolean,
18
+ * className?: string
19
+ * }} IconButtonProps
20
+ */
21
+
22
+ /**
23
+ * IconButton component.
24
+ *
25
+ * Provides a circular button used for icon-only actions, matching
26
+ * the design-system variants and states of the main Button component.
27
+ *
28
+ * @component
29
+ * @type {React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<HTMLButtonElement>>}
30
+ *
31
+ * @example
32
+ * ```jsx
33
+ * <IconButton icon={<XIcon />} aria-label="Close" />
34
+ * <IconButton icon={<EditIcon />} isSecondary />
35
+ * <IconButton icon={<TrashIcon />} isDanger disabled />
36
+ * ```
37
+ */
38
+ export const IconButton = forwardRef(
39
+ (
40
+ {
41
+ icon,
42
+ size = "medium",
43
+ isSecondary,
44
+ isDanger,
45
+ isBare,
46
+ disabled,
47
+ className,
48
+ ...props
49
+ },
50
+ ref
51
+ ) => {
52
+ let variant = "primary";
53
+ if (isBare) variant = "bare";
54
+ if (isSecondary) variant = "secondary";
55
+ if (isDanger) variant = "danger";
56
+ if (disabled) variant = "disabled";
57
+
58
+ if (process.env.NODE_ENV !== "production") {
59
+ const count = [isSecondary, isDanger, isBare].filter(Boolean).length;
60
+ if (count > 1) {
61
+ console.warn(
62
+ "[IconButton]: Multiple variant props passed. Using the highest priority only."
63
+ );
64
+ }
65
+ }
66
+
67
+ const defaults =
68
+ "flex justify-center items-center focus:shadow-focus focus-visible:shadow-focus outline-none transition-all duration-300 ease-in-out rounded-full";
69
+
70
+ const sizes = {
71
+ small: "h-[36px] w-[36px] text-sm",
72
+ medium: "h-[44px] w-[44px] text-base",
73
+ large: "h-[56px] w-[56px] text-lg",
74
+ };
75
+
76
+ const variants = {
77
+ primary:
78
+ "border-2 border-border-primary-emphasis bg-bg-primary-base text-white hover:bg-border-focus hover:text-fg-base hover:border-border-emphasis hover:shadow-md active:bg-border-focus active:bg-bg-focus-overlay active:text-fg-base",
79
+ secondary:
80
+ "border-2 border-border-primary-base bg-bg-base text-fg-primary-emphasis hover:shadow-md hover:bg-bg-primary-subtle active:bg-bg-primary-subtle-90",
81
+ bare: "bg-bg-base text-fg-primary-emphasis hover:bg-bg-minimal active:bg-bg-minimal-5",
82
+ danger:
83
+ "bg-bg-danger-base border-2 border-border-danger-emphasis text-white hover:bg-bg-danger-base-5 active:bg-bg-danger-base-10",
84
+ disabled:
85
+ "border-2 border-border-subtle bg-bg-inactive text-fg-inactive hover:no-underline cursor-not-allowed",
86
+ };
87
+
88
+ const STYLES = cx(defaults, sizes[size], variants[variant], className);
89
+
90
+ return (
91
+ <button
92
+ role="button"
93
+ type="button"
94
+ aria-disabled={disabled}
95
+ disabled={disabled}
96
+ className={STYLES}
97
+ ref={ref}
98
+ {...props}
99
+ >
100
+ {icon}
101
+ </button>
102
+ );
103
+ }
104
+ );
@@ -3,6 +3,29 @@ import { MenuButtonContext } from "../util/MenuButtonContext";
3
3
  import { cx } from "@edux-design/utils";
4
4
  import { Chevron } from "@edux-design/icons";
5
5
 
6
+ /**
7
+ * Props for the MenuButton component.
8
+ *
9
+ * @typedef {Object} MenuButtonProps
10
+ * @property {React.ReactNode} [children] - Content to display inside the button (usually label or icon).
11
+ * @property {"small"|"medium"} [size="medium"] - Size variant controlling button height.
12
+ */
13
+
14
+ /**
15
+ * MenuButton component.
16
+ *
17
+ * Provides a styled menu trigger button with optional sizing.
18
+ * It uses a `MenuButtonContext` provider to share internal state
19
+ * with child menu items.
20
+ *
21
+ * @component
22
+ * @type {React.FC<MenuButtonProps>}
23
+ *
24
+ * @example
25
+ * ```jsx
26
+ * <MenuButton size="small">Options</MenuButton>
27
+ * ```
28
+ */
6
29
  export function MenuButton({ children, size }) {
7
30
  const SPLIT_BUTTON_STYLES = cx(
8
31
  "w-[36px] border-l-[1px] border-l-black flex flex-row justify-center items-center",
@@ -11,9 +34,10 @@ export function MenuButton({ children, size }) {
11
34
  "h-[40px] py-2": size === "medium" || size === undefined,
12
35
  }
13
36
  );
37
+
14
38
  return (
15
39
  <MenuButtonContext.Provider value>
16
- <div>{children}</div>
40
+ <div className={SPLIT_BUTTON_STYLES}>{children}</div>
17
41
  <Chevron />
18
42
  </MenuButtonContext.Provider>
19
43
  );
package/src/index.js CHANGED
@@ -1,2 +1,3 @@
1
+ export { IconButton } from "./elements/IconButton";
1
2
  export { Button } from "./elements/Button";
2
3
  export { MenuButton } from "./elements/MenuButton";
package/tsconfig.json ADDED
@@ -0,0 +1,12 @@
1
+
2
+ {
3
+
4
+ "compilerOptions": {
5
+ "allowJs": true,
6
+ "checkJs": false,
7
+ "declaration": true,
8
+ "emitDeclarationOnly": true,
9
+ "jsx": "react-jsx",
10
+ "outDir": "dist"
11
+ }
12
+ }