@negative-space/button 2.4.2 → 2.6.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.mts CHANGED
@@ -1,8 +1,16 @@
1
- import React from 'react';
2
1
  import { FlexProps } from '@negative-space/flex';
3
2
  import { SpinnerProps } from '@negative-space/spinner';
3
+ import { ClickableAnimation } from '@negative-space/system';
4
+ import React from 'react';
4
5
 
5
- interface ButtonProps extends Omit<FlexProps<'button'>, 'as' | 'prefix' | 'className' | 'style'> {
6
+ type ButtonAccessibility = {
7
+ children: React.ReactNode;
8
+ ariaLabel?: string | false;
9
+ } | {
10
+ children?: never;
11
+ ariaLabel: string;
12
+ };
13
+ interface ButtonBaseProps extends Omit<FlexProps<'button'>, 'as' | 'prefix' | 'className' | 'style' | 'aria-label'> {
6
14
  prefix?: React.ReactNode;
7
15
  suffix?: React.ReactNode;
8
16
  classNames?: {
@@ -10,25 +18,27 @@ interface ButtonProps extends Omit<FlexProps<'button'>, 'as' | 'prefix' | 'class
10
18
  prefix?: string;
11
19
  content?: string;
12
20
  suffix?: string;
21
+ spinner?: string;
13
22
  };
14
23
  styles?: {
15
24
  btn?: React.CSSProperties;
16
25
  prefix?: React.CSSProperties;
17
26
  content?: React.CSSProperties;
18
27
  suffix?: React.CSSProperties;
28
+ spinner?: React.CSSProperties;
19
29
  };
30
+ animation?: ClickableAnimation;
20
31
  controlled?: boolean;
21
- isRippleDisabled?: boolean;
22
- isLoading?: boolean;
23
- spinner?: React.ReactNode;
32
+ loading?: boolean;
24
33
  spinnerPosition?: 'full' | 'prefix' | 'content' | 'suffix';
25
- spinnerProps?: Omit<SpinnerProps, 'isLoading'>;
34
+ spinnerProps?: Omit<SpinnerProps, 'loading' | 'className' | 'style'>;
26
35
  }
36
+ type ButtonProps = ButtonBaseProps & ButtonAccessibility;
27
37
  declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
28
38
 
29
39
  interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
30
40
  controlled?: boolean;
31
- isRippleDisabled?: boolean;
41
+ animation?: ClickableAnimation;
32
42
  }
33
43
  declare const IconButton: React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<HTMLButtonElement>>;
34
44
 
package/dist/index.d.ts CHANGED
@@ -1,8 +1,16 @@
1
- import React from 'react';
2
1
  import { FlexProps } from '@negative-space/flex';
3
2
  import { SpinnerProps } from '@negative-space/spinner';
3
+ import { ClickableAnimation } from '@negative-space/system';
4
+ import React from 'react';
4
5
 
5
- interface ButtonProps extends Omit<FlexProps<'button'>, 'as' | 'prefix' | 'className' | 'style'> {
6
+ type ButtonAccessibility = {
7
+ children: React.ReactNode;
8
+ ariaLabel?: string | false;
9
+ } | {
10
+ children?: never;
11
+ ariaLabel: string;
12
+ };
13
+ interface ButtonBaseProps extends Omit<FlexProps<'button'>, 'as' | 'prefix' | 'className' | 'style' | 'aria-label'> {
6
14
  prefix?: React.ReactNode;
7
15
  suffix?: React.ReactNode;
8
16
  classNames?: {
@@ -10,25 +18,27 @@ interface ButtonProps extends Omit<FlexProps<'button'>, 'as' | 'prefix' | 'class
10
18
  prefix?: string;
11
19
  content?: string;
12
20
  suffix?: string;
21
+ spinner?: string;
13
22
  };
14
23
  styles?: {
15
24
  btn?: React.CSSProperties;
16
25
  prefix?: React.CSSProperties;
17
26
  content?: React.CSSProperties;
18
27
  suffix?: React.CSSProperties;
28
+ spinner?: React.CSSProperties;
19
29
  };
30
+ animation?: ClickableAnimation;
20
31
  controlled?: boolean;
21
- isRippleDisabled?: boolean;
22
- isLoading?: boolean;
23
- spinner?: React.ReactNode;
32
+ loading?: boolean;
24
33
  spinnerPosition?: 'full' | 'prefix' | 'content' | 'suffix';
25
- spinnerProps?: Omit<SpinnerProps, 'isLoading'>;
34
+ spinnerProps?: Omit<SpinnerProps, 'loading' | 'className' | 'style'>;
26
35
  }
36
+ type ButtonProps = ButtonBaseProps & ButtonAccessibility;
27
37
  declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
28
38
 
29
39
  interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
30
40
  controlled?: boolean;
31
- isRippleDisabled?: boolean;
41
+ animation?: ClickableAnimation;
32
42
  }
33
43
  declare const IconButton: React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<HTMLButtonElement>>;
34
44
 
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var React = require('react');
4
- var system = require('@negative-space/system');
5
3
  var flex = require('@negative-space/flex');
6
- var spinner = require('@negative-space/spinner');
7
4
  var ripple = require('@negative-space/ripple');
5
+ var spinner = require('@negative-space/spinner');
6
+ var system = require('@negative-space/system');
7
+ var React = require('react');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
9
 
10
10
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -31,32 +31,33 @@ var Button = React__default.default.forwardRef(
31
31
  controlled,
32
32
  styles,
33
33
  disabled = false,
34
- isRippleDisabled,
34
+ animation,
35
35
  onClick,
36
- isLoading = false,
37
- spinner: spinner$1,
36
+ loading = false,
38
37
  spinnerPosition = "full",
39
38
  spinnerProps,
40
39
  alignItems = "center",
41
40
  justify = "center",
41
+ ariaLabel,
42
42
  ...props
43
43
  }, ref) => {
44
44
  const { global, components } = system.useNSUI();
45
45
  const context = useButtonContextConditional(!!controlled);
46
46
  const groupDisabled = context.disabled;
47
- const rippleDisabled = isRippleDisabled ?? components.button.isRippleDisabled;
47
+ const rippleDisabled = (animation ?? components.button.animation) !== "ripple";
48
48
  const { createRipple } = ripple.useRipple(`${global.prefixCls}-ripple`);
49
- const isDisabled = disabled || isLoading || (controlled ? groupDisabled : false);
50
- const resolvedSpinner = spinner$1 ?? /* @__PURE__ */ jsxRuntime.jsx(spinner.Spinner, { isLoading: true, ...spinnerProps });
49
+ const isDisabled = disabled || loading || (controlled ? groupDisabled : false);
50
+ const resolvedSpinner = /* @__PURE__ */ jsxRuntime.jsx(spinner.Spinner, { loading: true, className: classNames?.spinner, style: styles?.spinner, ...spinnerProps });
51
51
  const handleClick = (e) => {
52
52
  if (isDisabled) return;
53
53
  const isKeyboard = e.detail === 0;
54
54
  if (!rippleDisabled) createRipple(e, { centered: isKeyboard });
55
55
  onClick?.(e);
56
56
  };
57
- const showPrefix = prefix || isLoading && spinnerPosition === "prefix";
58
- const showContent = children || isLoading && spinnerPosition === "content";
59
- const showSuffix = suffix || isLoading && spinnerPosition === "suffix";
57
+ const showPrefix = prefix || loading && spinnerPosition === "prefix";
58
+ const showContent = children || loading && spinnerPosition === "content";
59
+ const showSuffix = suffix || loading && spinnerPosition === "suffix";
60
+ const resolvedAriaLabel = ariaLabel === false ? void 0 : ariaLabel ?? (typeof children === "string" ? children : void 0);
60
61
  return /* @__PURE__ */ jsxRuntime.jsx(
61
62
  flex.Flex,
62
63
  {
@@ -66,17 +67,19 @@ var Button = React__default.default.forwardRef(
66
67
  alignItems,
67
68
  justify,
68
69
  disabled: isDisabled,
70
+ "data-loading": loading,
69
71
  "data-disabled": isDisabled,
72
+ "aria-label": resolvedAriaLabel,
70
73
  onClick: handleClick,
71
74
  className: system.cn(`${global.prefixCls}-btn ${global.prefixCls}-clickable`, classNames?.btn),
72
75
  style: styles?.btn,
73
- children: spinnerPosition === "full" && isLoading ? resolvedSpinner : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
76
+ children: spinnerPosition === "full" && loading ? resolvedSpinner : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
74
77
  showPrefix && /* @__PURE__ */ jsxRuntime.jsx(
75
78
  "span",
76
79
  {
77
80
  className: system.cn(`${global.prefixCls}-btn-prefix`, classNames?.prefix),
78
81
  style: styles?.prefix,
79
- children: spinnerPosition === "prefix" && isLoading ? resolvedSpinner : prefix
82
+ children: spinnerPosition === "prefix" && loading ? resolvedSpinner : prefix
80
83
  }
81
84
  ),
82
85
  showContent && /* @__PURE__ */ jsxRuntime.jsx(
@@ -84,7 +87,7 @@ var Button = React__default.default.forwardRef(
84
87
  {
85
88
  className: system.cn(`${global.prefixCls}-btn-content`, classNames?.content),
86
89
  style: styles?.content,
87
- children: spinnerPosition === "content" && isLoading ? resolvedSpinner : children
90
+ children: spinnerPosition === "content" && loading ? resolvedSpinner : children
88
91
  }
89
92
  ),
90
93
  showSuffix && /* @__PURE__ */ jsxRuntime.jsx(
@@ -92,7 +95,7 @@ var Button = React__default.default.forwardRef(
92
95
  {
93
96
  className: system.cn(`${global.prefixCls}-btn-suffix`, classNames?.suffix),
94
97
  style: styles?.suffix,
95
- children: spinnerPosition === "suffix" && isLoading ? resolvedSpinner : suffix
98
+ children: spinnerPosition === "suffix" && loading ? resolvedSpinner : suffix
96
99
  }
97
100
  )
98
101
  ] })
@@ -102,9 +105,9 @@ var Button = React__default.default.forwardRef(
102
105
  );
103
106
  Button.displayName = "Button";
104
107
  var IconButton = React__default.default.forwardRef(
105
- ({ className, controlled, style, disabled, isRippleDisabled, onClick, ...props }, ref) => {
108
+ ({ className, controlled, style, disabled, animation, onClick, ...props }, ref) => {
106
109
  const { global, components } = system.useNSUI();
107
- const rippleDisabled = isRippleDisabled ?? components.iconButton.isRippleDisabled;
110
+ const rippleDisabled = (animation ?? components.iconButton.animation) !== "ripple";
108
111
  const context = useButtonContextConditional(!!controlled);
109
112
  const groupDisabled = context.disabled;
110
113
  const isDisabled = disabled || (controlled ? groupDisabled : false);
@@ -142,13 +145,15 @@ var ButtonGroup = React__default.default.forwardRef(
142
145
  style: styles?.root,
143
146
  children: items.map((item, index) => {
144
147
  if ("button" in item) {
148
+ const { children, ...buttonProps } = item.button;
145
149
  return /* @__PURE__ */ jsxRuntime.jsx(
146
150
  Button,
147
151
  {
148
152
  controlled: true,
149
- classNames: system.mergeCn(classNames?.button, item.button.classNames),
150
- styles: { ...styles?.button, ...item.button.styles },
151
- ...item.button
153
+ ...buttonProps,
154
+ classNames: system.mergeCn(classNames?.button, buttonProps.classNames),
155
+ styles: { ...styles?.button, ...buttonProps.styles },
156
+ children
152
157
  },
153
158
  index
154
159
  );
@@ -158,9 +163,9 @@ var ButtonGroup = React__default.default.forwardRef(
158
163
  IconButton,
159
164
  {
160
165
  controlled: true,
166
+ ...item.iconButton,
161
167
  className: system.cn(classNames?.iconButton, item.iconButton.className),
162
- style: { ...styles?.iconButton, ...item.iconButton.style },
163
- ...item.iconButton
168
+ style: { ...styles?.iconButton, ...item.iconButton.style }
164
169
  },
165
170
  index
166
171
  );
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ButtonContext.ts","../src/useButtonContext.ts","../src/Button.tsx","../src/IconButton.tsx","../src/ButtonGroup.tsx"],"names":["React","useContext","spinner","useNSUI","useRipple","jsx","Spinner","Flex","cn","jsxs","Fragment","mergeCn"],"mappings":"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","file":"index.js","sourcesContent":["import React from 'react'\n\nexport type ButtonContextValue = {\n disabled?: boolean\n}\n\nexport const ButtonContext = React.createContext<ButtonContextValue | null>(null)\n","import { useContext } from 'react'\nimport { ButtonContext, type ButtonContextValue } from './ButtonContext'\n\nexport const useButtonContextConditional = (\n controlled: boolean\n): ButtonContextValue | { disabled: false } => {\n const ctx = useContext(ButtonContext)\n\n if (controlled && !ctx) {\n throw new Error('Button components must be used within ButtonGroup')\n }\n\n return ctx ?? { disabled: false }\n}\n","import React from 'react'\nimport { cn, useNSUI } from '@negative-space/system'\nimport { Flex, FlexProps } from '@negative-space/flex'\nimport { Spinner, type SpinnerProps } from '@negative-space/spinner'\nimport { useRipple } from '@negative-space/ripple'\nimport { useButtonContextConditional } from './useButtonContext'\n\nexport interface ButtonProps extends Omit<\n FlexProps<'button'>,\n 'as' | 'prefix' | 'className' | 'style'\n> {\n prefix?: React.ReactNode\n suffix?: React.ReactNode\n classNames?: {\n btn?: string\n prefix?: string\n content?: string\n suffix?: string\n }\n styles?: {\n btn?: React.CSSProperties\n prefix?: React.CSSProperties\n content?: React.CSSProperties\n suffix?: React.CSSProperties\n }\n controlled?: boolean\n isRippleDisabled?: boolean\n isLoading?: boolean\n spinner?: React.ReactNode\n spinnerPosition?: 'full' | 'prefix' | 'content' | 'suffix'\n spinnerProps?: Omit<SpinnerProps, 'isLoading'>\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n children,\n prefix,\n suffix,\n classNames,\n controlled,\n styles,\n disabled = false,\n isRippleDisabled,\n onClick,\n isLoading = false,\n spinner,\n spinnerPosition = 'full',\n spinnerProps,\n alignItems = 'center',\n justify = 'center',\n ...props\n },\n ref\n ) => {\n const { global, components } = useNSUI()\n const context = useButtonContextConditional(!!controlled)\n const groupDisabled = context.disabled\n\n const rippleDisabled = isRippleDisabled ?? components.button.isRippleDisabled\n const { createRipple } = useRipple(`${global.prefixCls}-ripple`)\n\n const isDisabled = disabled || isLoading || (controlled ? groupDisabled : false)\n const resolvedSpinner = spinner ?? <Spinner isLoading {...spinnerProps} />\n\n const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {\n if (isDisabled) return\n const isKeyboard = e.detail === 0\n if (!rippleDisabled) createRipple(e, { centered: isKeyboard })\n\n onClick?.(e)\n }\n\n const showPrefix = prefix || (isLoading && spinnerPosition === 'prefix')\n const showContent = children || (isLoading && spinnerPosition === 'content')\n const showSuffix = suffix || (isLoading && spinnerPosition === 'suffix')\n\n return (\n <Flex\n {...props}\n ref={ref}\n as=\"button\"\n alignItems={alignItems}\n justify={justify}\n disabled={isDisabled}\n data-disabled={isDisabled}\n onClick={handleClick}\n className={cn(`${global.prefixCls}-btn ${global.prefixCls}-clickable`, classNames?.btn)}\n style={styles?.btn}\n >\n {spinnerPosition === 'full' && isLoading ? (\n resolvedSpinner\n ) : (\n <>\n {showPrefix && (\n <span\n className={cn(`${global.prefixCls}-btn-prefix`, classNames?.prefix)}\n style={styles?.prefix}\n >\n {spinnerPosition === 'prefix' && isLoading ? resolvedSpinner : prefix}\n </span>\n )}\n\n {showContent && (\n <span\n className={cn(`${global.prefixCls}-btn-content`, classNames?.content)}\n style={styles?.content}\n >\n {spinnerPosition === 'content' && isLoading ? resolvedSpinner : children}\n </span>\n )}\n\n {showSuffix && (\n <span\n className={cn(`${global.prefixCls}-btn-suffix`, classNames?.suffix)}\n style={styles?.suffix}\n >\n {spinnerPosition === 'suffix' && isLoading ? resolvedSpinner : suffix}\n </span>\n )}\n </>\n )}\n </Flex>\n )\n }\n)\n\nButton.displayName = 'Button'\n","import React from 'react'\nimport { useRipple } from '@negative-space/ripple'\nimport { cn, useNSUI } from '@negative-space/system'\nimport { useButtonContextConditional } from './useButtonContext'\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n controlled?: boolean\n isRippleDisabled?: boolean\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ className, controlled, style, disabled, isRippleDisabled, onClick, ...props }, ref) => {\n const { global, components } = useNSUI()\n const rippleDisabled = isRippleDisabled ?? components.iconButton.isRippleDisabled\n\n const context = useButtonContextConditional(!!controlled)\n const groupDisabled = context.disabled\n const isDisabled = disabled || (controlled ? groupDisabled : false)\n\n const { createRipple } = useRipple(`${global.prefixCls}-ripple`)\n\n const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {\n if (isDisabled) return\n const isKeyboard = e.detail === 0\n if (!rippleDisabled) createRipple(e, { centered: isKeyboard })\n\n onClick?.(e)\n }\n\n return (\n <button\n ref={ref}\n disabled={isDisabled}\n data-disabled={isDisabled}\n onClick={handleClick}\n className={cn(`${global.prefixCls}-icon-btn ${global.prefixCls}-clickable`, className)}\n style={style}\n {...props}\n />\n )\n }\n)\n\nIconButton.displayName = 'IconButton'\n","import React from 'react'\nimport { cn, mergeCn, useNSUI } from '@negative-space/system'\nimport { Flex, type FlexProps } from '@negative-space/flex'\nimport { Button, type ButtonProps } from './Button'\nimport { IconButton, type IconButtonProps } from './IconButton'\nimport { ButtonContext } from './ButtonContext'\n\nexport type ButtonComponent =\n | { button: Omit<ButtonProps, 'controlled'> }\n | { iconButton: Omit<IconButtonProps, 'controlled'> }\n\nexport interface ButtonGroupProps extends Omit<FlexProps, 'as' | 'className' | 'style'> {\n classNames?: {\n root?: string\n button?: {\n btn?: string\n content?: string\n prefix?: string\n suffix?: string\n }\n iconButton?: string\n }\n styles?: {\n root?: React.CSSProperties\n button?: {\n btn?: React.CSSProperties\n content?: React.CSSProperties\n prefix?: React.CSSProperties\n suffix?: React.CSSProperties\n }\n iconButton?: React.CSSProperties\n }\n disabled?: boolean\n items: ButtonComponent[]\n}\n\nexport const ButtonGroup = React.forwardRef<HTMLDivElement, ButtonGroupProps>(\n ({ items, classNames, styles, disabled, ...props }, ref) => {\n const { global } = useNSUI()\n\n return (\n <ButtonContext.Provider value={{ disabled }}>\n <Flex\n {...props}\n ref={ref}\n className={cn(`${global.prefixCls}-btn-group`, classNames?.root)}\n style={styles?.root}\n >\n {items.map((item, index) => {\n if ('button' in item) {\n return (\n <Button\n key={index}\n controlled\n classNames={mergeCn(classNames?.button, item.button.classNames)}\n styles={{ ...styles?.button, ...item.button.styles }}\n {...item.button}\n />\n )\n }\n\n if ('iconButton' in item) {\n return (\n <IconButton\n key={index}\n controlled\n className={cn(classNames?.iconButton, item.iconButton.className)}\n style={{ ...styles?.iconButton, ...item.iconButton.style }}\n {...item.iconButton}\n />\n )\n }\n\n return null\n })}\n </Flex>\n </ButtonContext.Provider>\n )\n }\n)\n\nButtonGroup.displayName = 'ButtonGroup'\n"]}
1
+ {"version":3,"sources":["../src/ButtonContext.ts","../src/useButtonContext.ts","../src/Button.tsx","../src/IconButton.tsx","../src/ButtonGroup.tsx"],"names":["React","useContext","useNSUI","useRipple","jsx","Spinner","Flex","cn","jsxs","Fragment","mergeCn"],"mappings":"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","file":"index.js","sourcesContent":["import React from 'react'\n\nexport type ButtonContextValue = {\n disabled?: boolean\n}\n\nexport const ButtonContext = React.createContext<ButtonContextValue | null>(null)\n","import { useContext } from 'react'\n\nimport { ButtonContext, type ButtonContextValue } from './ButtonContext'\n\nexport const useButtonContextConditional = (\n controlled: boolean\n): ButtonContextValue | { disabled: false } => {\n const ctx = useContext(ButtonContext)\n\n if (controlled && !ctx) {\n throw new Error('Button components must be used within ButtonGroup')\n }\n\n return ctx ?? { disabled: false }\n}\n","import { Flex, FlexProps } from '@negative-space/flex'\nimport { useRipple } from '@negative-space/ripple'\nimport { Spinner, type SpinnerProps } from '@negative-space/spinner'\nimport { type ClickableAnimation, cn, useNSUI } from '@negative-space/system'\nimport React from 'react'\n\nimport { useButtonContextConditional } from './useButtonContext'\n\ntype ButtonAccessibility =\n | {\n children: React.ReactNode\n ariaLabel?: string | false\n }\n | {\n children?: never\n ariaLabel: string\n }\n\ninterface ButtonBaseProps extends Omit<\n FlexProps<'button'>,\n 'as' | 'prefix' | 'className' | 'style' | 'aria-label'\n> {\n prefix?: React.ReactNode\n suffix?: React.ReactNode\n\n classNames?: {\n btn?: string\n prefix?: string\n content?: string\n suffix?: string\n spinner?: string\n }\n\n styles?: {\n btn?: React.CSSProperties\n prefix?: React.CSSProperties\n content?: React.CSSProperties\n suffix?: React.CSSProperties\n spinner?: React.CSSProperties\n }\n\n animation?: ClickableAnimation\n controlled?: boolean\n loading?: boolean\n spinnerPosition?: 'full' | 'prefix' | 'content' | 'suffix'\n spinnerProps?: Omit<SpinnerProps, 'loading' | 'className' | 'style'>\n}\n\nexport type ButtonProps = ButtonBaseProps & ButtonAccessibility\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n children,\n prefix,\n suffix,\n classNames,\n controlled,\n styles,\n disabled = false,\n animation,\n onClick,\n loading = false,\n spinnerPosition = 'full',\n spinnerProps,\n alignItems = 'center',\n justify = 'center',\n ariaLabel,\n ...props\n },\n ref\n ) => {\n const { global, components } = useNSUI()\n const context = useButtonContextConditional(!!controlled)\n const groupDisabled = context.disabled\n\n const rippleDisabled = (animation ?? components.button.animation) !== 'ripple'\n const { createRipple } = useRipple(`${global.prefixCls}-ripple`)\n\n const isDisabled = disabled || loading || (controlled ? groupDisabled : false)\n\n const resolvedSpinner = (\n <Spinner loading className={classNames?.spinner} style={styles?.spinner} {...spinnerProps} />\n )\n\n const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {\n if (isDisabled) return\n\n const isKeyboard = e.detail === 0\n\n if (!rippleDisabled) createRipple(e, { centered: isKeyboard })\n\n onClick?.(e)\n }\n\n const showPrefix = prefix || (loading && spinnerPosition === 'prefix')\n const showContent = children || (loading && spinnerPosition === 'content')\n const showSuffix = suffix || (loading && spinnerPosition === 'suffix')\n\n const resolvedAriaLabel =\n ariaLabel === false\n ? undefined\n : (ariaLabel ?? (typeof children === 'string' ? children : undefined))\n\n return (\n <Flex\n {...props}\n ref={ref}\n as=\"button\"\n alignItems={alignItems}\n justify={justify}\n disabled={isDisabled}\n data-loading={loading}\n data-disabled={isDisabled}\n aria-label={resolvedAriaLabel}\n onClick={handleClick}\n className={cn(`${global.prefixCls}-btn ${global.prefixCls}-clickable`, classNames?.btn)}\n style={styles?.btn}\n >\n {spinnerPosition === 'full' && loading ? (\n resolvedSpinner\n ) : (\n <>\n {showPrefix && (\n <span\n className={cn(`${global.prefixCls}-btn-prefix`, classNames?.prefix)}\n style={styles?.prefix}\n >\n {spinnerPosition === 'prefix' && loading ? resolvedSpinner : prefix}\n </span>\n )}\n\n {showContent && (\n <span\n className={cn(`${global.prefixCls}-btn-content`, classNames?.content)}\n style={styles?.content}\n >\n {spinnerPosition === 'content' && loading ? resolvedSpinner : children}\n </span>\n )}\n\n {showSuffix && (\n <span\n className={cn(`${global.prefixCls}-btn-suffix`, classNames?.suffix)}\n style={styles?.suffix}\n >\n {spinnerPosition === 'suffix' && loading ? resolvedSpinner : suffix}\n </span>\n )}\n </>\n )}\n </Flex>\n )\n }\n)\n\nButton.displayName = 'Button'\n","import { useRipple } from '@negative-space/ripple'\nimport { type ClickableAnimation, cn, useNSUI } from '@negative-space/system'\nimport React from 'react'\n\nimport { useButtonContextConditional } from './useButtonContext'\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n controlled?: boolean\n animation?: ClickableAnimation\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ className, controlled, style, disabled, animation, onClick, ...props }, ref) => {\n const { global, components } = useNSUI()\n const rippleDisabled = (animation ?? components.iconButton.animation) !== 'ripple'\n\n const context = useButtonContextConditional(!!controlled)\n const groupDisabled = context.disabled\n const isDisabled = disabled || (controlled ? groupDisabled : false)\n\n const { createRipple } = useRipple(`${global.prefixCls}-ripple`)\n\n const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {\n if (isDisabled) return\n const isKeyboard = e.detail === 0\n if (!rippleDisabled) createRipple(e, { centered: isKeyboard })\n\n onClick?.(e)\n }\n\n return (\n <button\n ref={ref}\n disabled={isDisabled}\n data-disabled={isDisabled}\n onClick={handleClick}\n className={cn(`${global.prefixCls}-icon-btn ${global.prefixCls}-clickable`, className)}\n style={style}\n {...props}\n />\n )\n }\n)\n\nIconButton.displayName = 'IconButton'\n","import { Flex, type FlexProps } from '@negative-space/flex'\nimport { cn, mergeCn, useNSUI } from '@negative-space/system'\nimport React from 'react'\n\nimport { Button, type ButtonProps } from './Button'\nimport { ButtonContext } from './ButtonContext'\nimport { IconButton, type IconButtonProps } from './IconButton'\n\nexport type ButtonComponent =\n | { button: Omit<ButtonProps, 'controlled'> }\n | { iconButton: Omit<IconButtonProps, 'controlled'> }\n\nexport interface ButtonGroupProps extends Omit<FlexProps, 'as' | 'className' | 'style'> {\n classNames?: {\n root?: string\n button?: {\n btn?: string\n content?: string\n prefix?: string\n suffix?: string\n }\n iconButton?: string\n }\n styles?: {\n root?: React.CSSProperties\n button?: {\n btn?: React.CSSProperties\n content?: React.CSSProperties\n prefix?: React.CSSProperties\n suffix?: React.CSSProperties\n }\n iconButton?: React.CSSProperties\n }\n disabled?: boolean\n items: ButtonComponent[]\n}\n\nexport const ButtonGroup = React.forwardRef<HTMLDivElement, ButtonGroupProps>(\n ({ items, classNames, styles, disabled, ...props }, ref) => {\n const { global } = useNSUI()\n\n return (\n <ButtonContext.Provider value={{ disabled }}>\n <Flex\n {...props}\n ref={ref}\n className={cn(`${global.prefixCls}-btn-group`, classNames?.root)}\n style={styles?.root}\n >\n {items.map((item, index) => {\n if ('button' in item) {\n const { children, ...buttonProps } = item.button\n\n return (\n <Button\n key={index}\n controlled\n {...buttonProps}\n classNames={mergeCn(classNames?.button, buttonProps.classNames)}\n styles={{ ...styles?.button, ...buttonProps.styles }}\n >\n {children}\n </Button>\n )\n }\n\n if ('iconButton' in item) {\n return (\n <IconButton\n key={index}\n controlled\n {...item.iconButton}\n className={cn(classNames?.iconButton, item.iconButton.className)}\n style={{ ...styles?.iconButton, ...item.iconButton.style }}\n />\n )\n }\n\n return null\n })}\n </Flex>\n </ButtonContext.Provider>\n )\n }\n)\n\nButtonGroup.displayName = 'ButtonGroup'\n"]}
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import React, { useContext } from 'react';
2
- import { useNSUI, cn, mergeCn } from '@negative-space/system';
3
1
  import { Flex } from '@negative-space/flex';
4
- import { Spinner } from '@negative-space/spinner';
5
2
  import { useRipple } from '@negative-space/ripple';
3
+ import { Spinner } from '@negative-space/spinner';
4
+ import { useNSUI, cn, mergeCn } from '@negative-space/system';
5
+ import React, { useContext } from 'react';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
 
8
8
  // src/Button.tsx
@@ -25,32 +25,33 @@ var Button = React.forwardRef(
25
25
  controlled,
26
26
  styles,
27
27
  disabled = false,
28
- isRippleDisabled,
28
+ animation,
29
29
  onClick,
30
- isLoading = false,
31
- spinner,
30
+ loading = false,
32
31
  spinnerPosition = "full",
33
32
  spinnerProps,
34
33
  alignItems = "center",
35
34
  justify = "center",
35
+ ariaLabel,
36
36
  ...props
37
37
  }, ref) => {
38
38
  const { global, components } = useNSUI();
39
39
  const context = useButtonContextConditional(!!controlled);
40
40
  const groupDisabled = context.disabled;
41
- const rippleDisabled = isRippleDisabled ?? components.button.isRippleDisabled;
41
+ const rippleDisabled = (animation ?? components.button.animation) !== "ripple";
42
42
  const { createRipple } = useRipple(`${global.prefixCls}-ripple`);
43
- const isDisabled = disabled || isLoading || (controlled ? groupDisabled : false);
44
- const resolvedSpinner = spinner ?? /* @__PURE__ */ jsx(Spinner, { isLoading: true, ...spinnerProps });
43
+ const isDisabled = disabled || loading || (controlled ? groupDisabled : false);
44
+ const resolvedSpinner = /* @__PURE__ */ jsx(Spinner, { loading: true, className: classNames?.spinner, style: styles?.spinner, ...spinnerProps });
45
45
  const handleClick = (e) => {
46
46
  if (isDisabled) return;
47
47
  const isKeyboard = e.detail === 0;
48
48
  if (!rippleDisabled) createRipple(e, { centered: isKeyboard });
49
49
  onClick?.(e);
50
50
  };
51
- const showPrefix = prefix || isLoading && spinnerPosition === "prefix";
52
- const showContent = children || isLoading && spinnerPosition === "content";
53
- const showSuffix = suffix || isLoading && spinnerPosition === "suffix";
51
+ const showPrefix = prefix || loading && spinnerPosition === "prefix";
52
+ const showContent = children || loading && spinnerPosition === "content";
53
+ const showSuffix = suffix || loading && spinnerPosition === "suffix";
54
+ const resolvedAriaLabel = ariaLabel === false ? void 0 : ariaLabel ?? (typeof children === "string" ? children : void 0);
54
55
  return /* @__PURE__ */ jsx(
55
56
  Flex,
56
57
  {
@@ -60,17 +61,19 @@ var Button = React.forwardRef(
60
61
  alignItems,
61
62
  justify,
62
63
  disabled: isDisabled,
64
+ "data-loading": loading,
63
65
  "data-disabled": isDisabled,
66
+ "aria-label": resolvedAriaLabel,
64
67
  onClick: handleClick,
65
68
  className: cn(`${global.prefixCls}-btn ${global.prefixCls}-clickable`, classNames?.btn),
66
69
  style: styles?.btn,
67
- children: spinnerPosition === "full" && isLoading ? resolvedSpinner : /* @__PURE__ */ jsxs(Fragment, { children: [
70
+ children: spinnerPosition === "full" && loading ? resolvedSpinner : /* @__PURE__ */ jsxs(Fragment, { children: [
68
71
  showPrefix && /* @__PURE__ */ jsx(
69
72
  "span",
70
73
  {
71
74
  className: cn(`${global.prefixCls}-btn-prefix`, classNames?.prefix),
72
75
  style: styles?.prefix,
73
- children: spinnerPosition === "prefix" && isLoading ? resolvedSpinner : prefix
76
+ children: spinnerPosition === "prefix" && loading ? resolvedSpinner : prefix
74
77
  }
75
78
  ),
76
79
  showContent && /* @__PURE__ */ jsx(
@@ -78,7 +81,7 @@ var Button = React.forwardRef(
78
81
  {
79
82
  className: cn(`${global.prefixCls}-btn-content`, classNames?.content),
80
83
  style: styles?.content,
81
- children: spinnerPosition === "content" && isLoading ? resolvedSpinner : children
84
+ children: spinnerPosition === "content" && loading ? resolvedSpinner : children
82
85
  }
83
86
  ),
84
87
  showSuffix && /* @__PURE__ */ jsx(
@@ -86,7 +89,7 @@ var Button = React.forwardRef(
86
89
  {
87
90
  className: cn(`${global.prefixCls}-btn-suffix`, classNames?.suffix),
88
91
  style: styles?.suffix,
89
- children: spinnerPosition === "suffix" && isLoading ? resolvedSpinner : suffix
92
+ children: spinnerPosition === "suffix" && loading ? resolvedSpinner : suffix
90
93
  }
91
94
  )
92
95
  ] })
@@ -96,9 +99,9 @@ var Button = React.forwardRef(
96
99
  );
97
100
  Button.displayName = "Button";
98
101
  var IconButton = React.forwardRef(
99
- ({ className, controlled, style, disabled, isRippleDisabled, onClick, ...props }, ref) => {
102
+ ({ className, controlled, style, disabled, animation, onClick, ...props }, ref) => {
100
103
  const { global, components } = useNSUI();
101
- const rippleDisabled = isRippleDisabled ?? components.iconButton.isRippleDisabled;
104
+ const rippleDisabled = (animation ?? components.iconButton.animation) !== "ripple";
102
105
  const context = useButtonContextConditional(!!controlled);
103
106
  const groupDisabled = context.disabled;
104
107
  const isDisabled = disabled || (controlled ? groupDisabled : false);
@@ -136,13 +139,15 @@ var ButtonGroup = React.forwardRef(
136
139
  style: styles?.root,
137
140
  children: items.map((item, index) => {
138
141
  if ("button" in item) {
142
+ const { children, ...buttonProps } = item.button;
139
143
  return /* @__PURE__ */ jsx(
140
144
  Button,
141
145
  {
142
146
  controlled: true,
143
- classNames: mergeCn(classNames?.button, item.button.classNames),
144
- styles: { ...styles?.button, ...item.button.styles },
145
- ...item.button
147
+ ...buttonProps,
148
+ classNames: mergeCn(classNames?.button, buttonProps.classNames),
149
+ styles: { ...styles?.button, ...buttonProps.styles },
150
+ children
146
151
  },
147
152
  index
148
153
  );
@@ -152,9 +157,9 @@ var ButtonGroup = React.forwardRef(
152
157
  IconButton,
153
158
  {
154
159
  controlled: true,
160
+ ...item.iconButton,
155
161
  className: cn(classNames?.iconButton, item.iconButton.className),
156
- style: { ...styles?.iconButton, ...item.iconButton.style },
157
- ...item.iconButton
162
+ style: { ...styles?.iconButton, ...item.iconButton.style }
158
163
  },
159
164
  index
160
165
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ButtonContext.ts","../src/useButtonContext.ts","../src/Button.tsx","../src/IconButton.tsx","../src/ButtonGroup.tsx"],"names":["React","useNSUI","useRipple","jsx","cn","Flex"],"mappings":";;;;;;;;AAMO,IAAM,aAAA,GAAgB,KAAA,CAAM,aAAA,CAAyC,IAAI,CAAA;;;ACHzE,IAAM,2BAAA,GAA8B,CACzC,UAAA,KAC6C;AAC7C,EAAA,MAAM,GAAA,GAAM,WAAW,aAAa,CAAA;AAEpC,EAAA,IAAI,UAAA,IAAc,CAAC,GAAA,EAAK;AACtB,IAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,EACrE;AAEA,EAAA,OAAO,GAAA,IAAO,EAAE,QAAA,EAAU,KAAA,EAAM;AAClC,CAAA;ACoBO,IAAM,SAASA,KAAAA,CAAM,UAAA;AAAA,EAC1B,CACE;AAAA,IACE,QAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,UAAA;AAAA,IACA,UAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA,GAAW,KAAA;AAAA,IACX,gBAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA,GAAY,KAAA;AAAA,IACZ,OAAA;AAAA,IACA,eAAA,GAAkB,MAAA;AAAA,IAClB,YAAA;AAAA,IACA,UAAA,GAAa,QAAA;AAAA,IACb,OAAA,GAAU,QAAA;AAAA,IACV,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,EAAE,MAAA,EAAQ,UAAA,EAAW,GAAI,OAAA,EAAQ;AACvC,IAAA,MAAM,OAAA,GAAU,2BAAA,CAA4B,CAAC,CAAC,UAAU,CAAA;AACxD,IAAA,MAAM,gBAAgB,OAAA,CAAQ,QAAA;AAE9B,IAAA,MAAM,cAAA,GAAiB,gBAAA,IAAoB,UAAA,CAAW,MAAA,CAAO,gBAAA;AAC7D,IAAA,MAAM,EAAE,YAAA,EAAa,GAAI,UAAU,CAAA,EAAG,MAAA,CAAO,SAAS,CAAA,OAAA,CAAS,CAAA;AAE/D,IAAA,MAAM,UAAA,GAAa,QAAA,IAAY,SAAA,KAAc,UAAA,GAAa,aAAA,GAAgB,KAAA,CAAA;AAC1E,IAAA,MAAM,kBAAkB,OAAA,oBAAW,GAAA,CAAC,WAAQ,SAAA,EAAS,IAAA,EAAE,GAAG,YAAA,EAAc,CAAA;AAExE,IAAA,MAAM,WAAA,GAA0D,CAAC,CAAA,KAAM;AACrE,MAAA,IAAI,UAAA,EAAY;AAChB,MAAA,MAAM,UAAA,GAAa,EAAE,MAAA,KAAW,CAAA;AAChC,MAAA,IAAI,CAAC,cAAA,EAAgB,YAAA,CAAa,GAAG,EAAE,QAAA,EAAU,YAAY,CAAA;AAE7D,MAAA,OAAA,GAAU,CAAC,CAAA;AAAA,IACb,CAAA;AAEA,IAAA,MAAM,UAAA,GAAa,MAAA,IAAW,SAAA,IAAa,eAAA,KAAoB,QAAA;AAC/D,IAAA,MAAM,WAAA,GAAc,QAAA,IAAa,SAAA,IAAa,eAAA,KAAoB,SAAA;AAClE,IAAA,MAAM,UAAA,GAAa,MAAA,IAAW,SAAA,IAAa,eAAA,KAAoB,QAAA;AAE/D,IAAA,uBACE,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACE,GAAG,KAAA;AAAA,QACJ,GAAA;AAAA,QACA,EAAA,EAAG,QAAA;AAAA,QACH,UAAA;AAAA,QACA,OAAA;AAAA,QACA,QAAA,EAAU,UAAA;AAAA,QACV,eAAA,EAAe,UAAA;AAAA,QACf,OAAA,EAAS,WAAA;AAAA,QACT,SAAA,EAAW,EAAA,CAAG,CAAA,EAAG,MAAA,CAAO,SAAS,QAAQ,MAAA,CAAO,SAAS,CAAA,UAAA,CAAA,EAAc,UAAA,EAAY,GAAG,CAAA;AAAA,QACtF,OAAO,MAAA,EAAQ,GAAA;AAAA,QAEd,QAAA,EAAA,eAAA,KAAoB,MAAA,IAAU,SAAA,GAC7B,eAAA,mBAEA,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,UAAA,UAAA,oBACC,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,WAAW,EAAA,CAAG,CAAA,EAAG,OAAO,SAAS,CAAA,WAAA,CAAA,EAAe,YAAY,MAAM,CAAA;AAAA,cAClE,OAAO,MAAA,EAAQ,MAAA;AAAA,cAEd,QAAA,EAAA,eAAA,KAAoB,QAAA,IAAY,SAAA,GAAY,eAAA,GAAkB;AAAA;AAAA,WACjE;AAAA,UAGD,WAAA,oBACC,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,WAAW,EAAA,CAAG,CAAA,EAAG,OAAO,SAAS,CAAA,YAAA,CAAA,EAAgB,YAAY,OAAO,CAAA;AAAA,cACpE,OAAO,MAAA,EAAQ,OAAA;AAAA,cAEd,QAAA,EAAA,eAAA,KAAoB,SAAA,IAAa,SAAA,GAAY,eAAA,GAAkB;AAAA;AAAA,WAClE;AAAA,UAGD,UAAA,oBACC,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,WAAW,EAAA,CAAG,CAAA,EAAG,OAAO,SAAS,CAAA,WAAA,CAAA,EAAe,YAAY,MAAM,CAAA;AAAA,cAClE,OAAO,MAAA,EAAQ,MAAA;AAAA,cAEd,QAAA,EAAA,eAAA,KAAoB,QAAA,IAAY,SAAA,GAAY,eAAA,GAAkB;AAAA;AAAA;AACjE,SAAA,EAEJ;AAAA;AAAA,KAEJ;AAAA,EAEJ;AACF;AAEA,MAAA,CAAO,WAAA,GAAc,QAAA;ACrHd,IAAM,aAAaA,KAAAA,CAAM,UAAA;AAAA,EAC9B,CAAC,EAAE,SAAA,EAAW,UAAA,EAAY,KAAA,EAAO,QAAA,EAAU,gBAAA,EAAkB,OAAA,EAAS,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACxF,IAAA,MAAM,EAAE,MAAA,EAAQ,UAAA,EAAW,GAAIC,OAAAA,EAAQ;AACvC,IAAA,MAAM,cAAA,GAAiB,gBAAA,IAAoB,UAAA,CAAW,UAAA,CAAW,gBAAA;AAEjE,IAAA,MAAM,OAAA,GAAU,2BAAA,CAA4B,CAAC,CAAC,UAAU,CAAA;AACxD,IAAA,MAAM,gBAAgB,OAAA,CAAQ,QAAA;AAC9B,IAAA,MAAM,UAAA,GAAa,QAAA,KAAa,UAAA,GAAa,aAAA,GAAgB,KAAA,CAAA;AAE7D,IAAA,MAAM,EAAE,YAAA,EAAa,GAAIC,UAAU,CAAA,EAAG,MAAA,CAAO,SAAS,CAAA,OAAA,CAAS,CAAA;AAE/D,IAAA,MAAM,WAAA,GAA0D,CAAC,CAAA,KAAM;AACrE,MAAA,IAAI,UAAA,EAAY;AAChB,MAAA,MAAM,UAAA,GAAa,EAAE,MAAA,KAAW,CAAA;AAChC,MAAA,IAAI,CAAC,cAAA,EAAgB,YAAA,CAAa,GAAG,EAAE,QAAA,EAAU,YAAY,CAAA;AAE7D,MAAA,OAAA,GAAU,CAAC,CAAA;AAAA,IACb,CAAA;AAEA,IAAA,uBACEC,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,QAAA,EAAU,UAAA;AAAA,QACV,eAAA,EAAe,UAAA;AAAA,QACf,OAAA,EAAS,WAAA;AAAA,QACT,SAAA,EAAWC,GAAG,CAAA,EAAG,MAAA,CAAO,SAAS,CAAA,UAAA,EAAa,MAAA,CAAO,SAAS,CAAA,UAAA,CAAA,EAAc,SAAS,CAAA;AAAA,QACrF,KAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AAEA,UAAA,CAAW,WAAA,GAAc,YAAA;ACPlB,IAAM,cAAcJ,KAAAA,CAAM,UAAA;AAAA,EAC/B,CAAC,EAAE,KAAA,EAAO,UAAA,EAAY,QAAQ,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAC1D,IAAA,MAAM,EAAE,MAAA,EAAO,GAAIC,OAAAA,EAAQ;AAE3B,IAAA,uBACEE,IAAC,aAAA,CAAc,QAAA,EAAd,EAAuB,KAAA,EAAO,EAAE,QAAA,EAAS,EACxC,QAAA,kBAAAA,GAAAA;AAAA,MAACE,IAAAA;AAAA,MAAA;AAAA,QACE,GAAG,KAAA;AAAA,QACJ,GAAA;AAAA,QACA,WAAWD,EAAAA,CAAG,CAAA,EAAG,OAAO,SAAS,CAAA,UAAA,CAAA,EAAc,YAAY,IAAI,CAAA;AAAA,QAC/D,OAAO,MAAA,EAAQ,IAAA;AAAA,QAEd,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,KAAU;AAC1B,UAAA,IAAI,YAAY,IAAA,EAAM;AACpB,YAAA,uBACED,GAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBAEC,UAAA,EAAU,IAAA;AAAA,gBACV,YAAY,OAAA,CAAQ,UAAA,EAAY,MAAA,EAAQ,IAAA,CAAK,OAAO,UAAU,CAAA;AAAA,gBAC9D,MAAA,EAAQ,EAAE,GAAG,MAAA,EAAQ,QAAQ,GAAG,IAAA,CAAK,OAAO,MAAA,EAAO;AAAA,gBAClD,GAAG,IAAA,CAAK;AAAA,eAAA;AAAA,cAJJ;AAAA,aAKP;AAAA,UAEJ;AAEA,UAAA,IAAI,gBAAgB,IAAA,EAAM;AACxB,YAAA,uBACEA,GAAAA;AAAA,cAAC,UAAA;AAAA,cAAA;AAAA,gBAEC,UAAA,EAAU,IAAA;AAAA,gBACV,WAAWC,EAAAA,CAAG,UAAA,EAAY,UAAA,EAAY,IAAA,CAAK,WAAW,SAAS,CAAA;AAAA,gBAC/D,KAAA,EAAO,EAAE,GAAG,MAAA,EAAQ,YAAY,GAAG,IAAA,CAAK,WAAW,KAAA,EAAM;AAAA,gBACxD,GAAG,IAAA,CAAK;AAAA,eAAA;AAAA,cAJJ;AAAA,aAKP;AAAA,UAEJ;AAEA,UAAA,OAAO,IAAA;AAAA,QACT,CAAC;AAAA;AAAA,KACH,EACF,CAAA;AAAA,EAEJ;AACF;AAEA,WAAA,CAAY,WAAA,GAAc,aAAA","file":"index.mjs","sourcesContent":["import React from 'react'\n\nexport type ButtonContextValue = {\n disabled?: boolean\n}\n\nexport const ButtonContext = React.createContext<ButtonContextValue | null>(null)\n","import { useContext } from 'react'\nimport { ButtonContext, type ButtonContextValue } from './ButtonContext'\n\nexport const useButtonContextConditional = (\n controlled: boolean\n): ButtonContextValue | { disabled: false } => {\n const ctx = useContext(ButtonContext)\n\n if (controlled && !ctx) {\n throw new Error('Button components must be used within ButtonGroup')\n }\n\n return ctx ?? { disabled: false }\n}\n","import React from 'react'\nimport { cn, useNSUI } from '@negative-space/system'\nimport { Flex, FlexProps } from '@negative-space/flex'\nimport { Spinner, type SpinnerProps } from '@negative-space/spinner'\nimport { useRipple } from '@negative-space/ripple'\nimport { useButtonContextConditional } from './useButtonContext'\n\nexport interface ButtonProps extends Omit<\n FlexProps<'button'>,\n 'as' | 'prefix' | 'className' | 'style'\n> {\n prefix?: React.ReactNode\n suffix?: React.ReactNode\n classNames?: {\n btn?: string\n prefix?: string\n content?: string\n suffix?: string\n }\n styles?: {\n btn?: React.CSSProperties\n prefix?: React.CSSProperties\n content?: React.CSSProperties\n suffix?: React.CSSProperties\n }\n controlled?: boolean\n isRippleDisabled?: boolean\n isLoading?: boolean\n spinner?: React.ReactNode\n spinnerPosition?: 'full' | 'prefix' | 'content' | 'suffix'\n spinnerProps?: Omit<SpinnerProps, 'isLoading'>\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n children,\n prefix,\n suffix,\n classNames,\n controlled,\n styles,\n disabled = false,\n isRippleDisabled,\n onClick,\n isLoading = false,\n spinner,\n spinnerPosition = 'full',\n spinnerProps,\n alignItems = 'center',\n justify = 'center',\n ...props\n },\n ref\n ) => {\n const { global, components } = useNSUI()\n const context = useButtonContextConditional(!!controlled)\n const groupDisabled = context.disabled\n\n const rippleDisabled = isRippleDisabled ?? components.button.isRippleDisabled\n const { createRipple } = useRipple(`${global.prefixCls}-ripple`)\n\n const isDisabled = disabled || isLoading || (controlled ? groupDisabled : false)\n const resolvedSpinner = spinner ?? <Spinner isLoading {...spinnerProps} />\n\n const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {\n if (isDisabled) return\n const isKeyboard = e.detail === 0\n if (!rippleDisabled) createRipple(e, { centered: isKeyboard })\n\n onClick?.(e)\n }\n\n const showPrefix = prefix || (isLoading && spinnerPosition === 'prefix')\n const showContent = children || (isLoading && spinnerPosition === 'content')\n const showSuffix = suffix || (isLoading && spinnerPosition === 'suffix')\n\n return (\n <Flex\n {...props}\n ref={ref}\n as=\"button\"\n alignItems={alignItems}\n justify={justify}\n disabled={isDisabled}\n data-disabled={isDisabled}\n onClick={handleClick}\n className={cn(`${global.prefixCls}-btn ${global.prefixCls}-clickable`, classNames?.btn)}\n style={styles?.btn}\n >\n {spinnerPosition === 'full' && isLoading ? (\n resolvedSpinner\n ) : (\n <>\n {showPrefix && (\n <span\n className={cn(`${global.prefixCls}-btn-prefix`, classNames?.prefix)}\n style={styles?.prefix}\n >\n {spinnerPosition === 'prefix' && isLoading ? resolvedSpinner : prefix}\n </span>\n )}\n\n {showContent && (\n <span\n className={cn(`${global.prefixCls}-btn-content`, classNames?.content)}\n style={styles?.content}\n >\n {spinnerPosition === 'content' && isLoading ? resolvedSpinner : children}\n </span>\n )}\n\n {showSuffix && (\n <span\n className={cn(`${global.prefixCls}-btn-suffix`, classNames?.suffix)}\n style={styles?.suffix}\n >\n {spinnerPosition === 'suffix' && isLoading ? resolvedSpinner : suffix}\n </span>\n )}\n </>\n )}\n </Flex>\n )\n }\n)\n\nButton.displayName = 'Button'\n","import React from 'react'\nimport { useRipple } from '@negative-space/ripple'\nimport { cn, useNSUI } from '@negative-space/system'\nimport { useButtonContextConditional } from './useButtonContext'\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n controlled?: boolean\n isRippleDisabled?: boolean\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ className, controlled, style, disabled, isRippleDisabled, onClick, ...props }, ref) => {\n const { global, components } = useNSUI()\n const rippleDisabled = isRippleDisabled ?? components.iconButton.isRippleDisabled\n\n const context = useButtonContextConditional(!!controlled)\n const groupDisabled = context.disabled\n const isDisabled = disabled || (controlled ? groupDisabled : false)\n\n const { createRipple } = useRipple(`${global.prefixCls}-ripple`)\n\n const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {\n if (isDisabled) return\n const isKeyboard = e.detail === 0\n if (!rippleDisabled) createRipple(e, { centered: isKeyboard })\n\n onClick?.(e)\n }\n\n return (\n <button\n ref={ref}\n disabled={isDisabled}\n data-disabled={isDisabled}\n onClick={handleClick}\n className={cn(`${global.prefixCls}-icon-btn ${global.prefixCls}-clickable`, className)}\n style={style}\n {...props}\n />\n )\n }\n)\n\nIconButton.displayName = 'IconButton'\n","import React from 'react'\nimport { cn, mergeCn, useNSUI } from '@negative-space/system'\nimport { Flex, type FlexProps } from '@negative-space/flex'\nimport { Button, type ButtonProps } from './Button'\nimport { IconButton, type IconButtonProps } from './IconButton'\nimport { ButtonContext } from './ButtonContext'\n\nexport type ButtonComponent =\n | { button: Omit<ButtonProps, 'controlled'> }\n | { iconButton: Omit<IconButtonProps, 'controlled'> }\n\nexport interface ButtonGroupProps extends Omit<FlexProps, 'as' | 'className' | 'style'> {\n classNames?: {\n root?: string\n button?: {\n btn?: string\n content?: string\n prefix?: string\n suffix?: string\n }\n iconButton?: string\n }\n styles?: {\n root?: React.CSSProperties\n button?: {\n btn?: React.CSSProperties\n content?: React.CSSProperties\n prefix?: React.CSSProperties\n suffix?: React.CSSProperties\n }\n iconButton?: React.CSSProperties\n }\n disabled?: boolean\n items: ButtonComponent[]\n}\n\nexport const ButtonGroup = React.forwardRef<HTMLDivElement, ButtonGroupProps>(\n ({ items, classNames, styles, disabled, ...props }, ref) => {\n const { global } = useNSUI()\n\n return (\n <ButtonContext.Provider value={{ disabled }}>\n <Flex\n {...props}\n ref={ref}\n className={cn(`${global.prefixCls}-btn-group`, classNames?.root)}\n style={styles?.root}\n >\n {items.map((item, index) => {\n if ('button' in item) {\n return (\n <Button\n key={index}\n controlled\n classNames={mergeCn(classNames?.button, item.button.classNames)}\n styles={{ ...styles?.button, ...item.button.styles }}\n {...item.button}\n />\n )\n }\n\n if ('iconButton' in item) {\n return (\n <IconButton\n key={index}\n controlled\n className={cn(classNames?.iconButton, item.iconButton.className)}\n style={{ ...styles?.iconButton, ...item.iconButton.style }}\n {...item.iconButton}\n />\n )\n }\n\n return null\n })}\n </Flex>\n </ButtonContext.Provider>\n )\n }\n)\n\nButtonGroup.displayName = 'ButtonGroup'\n"]}
1
+ {"version":3,"sources":["../src/ButtonContext.ts","../src/useButtonContext.ts","../src/Button.tsx","../src/IconButton.tsx","../src/ButtonGroup.tsx"],"names":["React","useNSUI","useRipple","jsx","cn","Flex"],"mappings":"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","file":"index.mjs","sourcesContent":["import React from 'react'\n\nexport type ButtonContextValue = {\n disabled?: boolean\n}\n\nexport const ButtonContext = React.createContext<ButtonContextValue | null>(null)\n","import { useContext } from 'react'\n\nimport { ButtonContext, type ButtonContextValue } from './ButtonContext'\n\nexport const useButtonContextConditional = (\n controlled: boolean\n): ButtonContextValue | { disabled: false } => {\n const ctx = useContext(ButtonContext)\n\n if (controlled && !ctx) {\n throw new Error('Button components must be used within ButtonGroup')\n }\n\n return ctx ?? { disabled: false }\n}\n","import { Flex, FlexProps } from '@negative-space/flex'\nimport { useRipple } from '@negative-space/ripple'\nimport { Spinner, type SpinnerProps } from '@negative-space/spinner'\nimport { type ClickableAnimation, cn, useNSUI } from '@negative-space/system'\nimport React from 'react'\n\nimport { useButtonContextConditional } from './useButtonContext'\n\ntype ButtonAccessibility =\n | {\n children: React.ReactNode\n ariaLabel?: string | false\n }\n | {\n children?: never\n ariaLabel: string\n }\n\ninterface ButtonBaseProps extends Omit<\n FlexProps<'button'>,\n 'as' | 'prefix' | 'className' | 'style' | 'aria-label'\n> {\n prefix?: React.ReactNode\n suffix?: React.ReactNode\n\n classNames?: {\n btn?: string\n prefix?: string\n content?: string\n suffix?: string\n spinner?: string\n }\n\n styles?: {\n btn?: React.CSSProperties\n prefix?: React.CSSProperties\n content?: React.CSSProperties\n suffix?: React.CSSProperties\n spinner?: React.CSSProperties\n }\n\n animation?: ClickableAnimation\n controlled?: boolean\n loading?: boolean\n spinnerPosition?: 'full' | 'prefix' | 'content' | 'suffix'\n spinnerProps?: Omit<SpinnerProps, 'loading' | 'className' | 'style'>\n}\n\nexport type ButtonProps = ButtonBaseProps & ButtonAccessibility\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n children,\n prefix,\n suffix,\n classNames,\n controlled,\n styles,\n disabled = false,\n animation,\n onClick,\n loading = false,\n spinnerPosition = 'full',\n spinnerProps,\n alignItems = 'center',\n justify = 'center',\n ariaLabel,\n ...props\n },\n ref\n ) => {\n const { global, components } = useNSUI()\n const context = useButtonContextConditional(!!controlled)\n const groupDisabled = context.disabled\n\n const rippleDisabled = (animation ?? components.button.animation) !== 'ripple'\n const { createRipple } = useRipple(`${global.prefixCls}-ripple`)\n\n const isDisabled = disabled || loading || (controlled ? groupDisabled : false)\n\n const resolvedSpinner = (\n <Spinner loading className={classNames?.spinner} style={styles?.spinner} {...spinnerProps} />\n )\n\n const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {\n if (isDisabled) return\n\n const isKeyboard = e.detail === 0\n\n if (!rippleDisabled) createRipple(e, { centered: isKeyboard })\n\n onClick?.(e)\n }\n\n const showPrefix = prefix || (loading && spinnerPosition === 'prefix')\n const showContent = children || (loading && spinnerPosition === 'content')\n const showSuffix = suffix || (loading && spinnerPosition === 'suffix')\n\n const resolvedAriaLabel =\n ariaLabel === false\n ? undefined\n : (ariaLabel ?? (typeof children === 'string' ? children : undefined))\n\n return (\n <Flex\n {...props}\n ref={ref}\n as=\"button\"\n alignItems={alignItems}\n justify={justify}\n disabled={isDisabled}\n data-loading={loading}\n data-disabled={isDisabled}\n aria-label={resolvedAriaLabel}\n onClick={handleClick}\n className={cn(`${global.prefixCls}-btn ${global.prefixCls}-clickable`, classNames?.btn)}\n style={styles?.btn}\n >\n {spinnerPosition === 'full' && loading ? (\n resolvedSpinner\n ) : (\n <>\n {showPrefix && (\n <span\n className={cn(`${global.prefixCls}-btn-prefix`, classNames?.prefix)}\n style={styles?.prefix}\n >\n {spinnerPosition === 'prefix' && loading ? resolvedSpinner : prefix}\n </span>\n )}\n\n {showContent && (\n <span\n className={cn(`${global.prefixCls}-btn-content`, classNames?.content)}\n style={styles?.content}\n >\n {spinnerPosition === 'content' && loading ? resolvedSpinner : children}\n </span>\n )}\n\n {showSuffix && (\n <span\n className={cn(`${global.prefixCls}-btn-suffix`, classNames?.suffix)}\n style={styles?.suffix}\n >\n {spinnerPosition === 'suffix' && loading ? resolvedSpinner : suffix}\n </span>\n )}\n </>\n )}\n </Flex>\n )\n }\n)\n\nButton.displayName = 'Button'\n","import { useRipple } from '@negative-space/ripple'\nimport { type ClickableAnimation, cn, useNSUI } from '@negative-space/system'\nimport React from 'react'\n\nimport { useButtonContextConditional } from './useButtonContext'\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n controlled?: boolean\n animation?: ClickableAnimation\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ className, controlled, style, disabled, animation, onClick, ...props }, ref) => {\n const { global, components } = useNSUI()\n const rippleDisabled = (animation ?? components.iconButton.animation) !== 'ripple'\n\n const context = useButtonContextConditional(!!controlled)\n const groupDisabled = context.disabled\n const isDisabled = disabled || (controlled ? groupDisabled : false)\n\n const { createRipple } = useRipple(`${global.prefixCls}-ripple`)\n\n const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {\n if (isDisabled) return\n const isKeyboard = e.detail === 0\n if (!rippleDisabled) createRipple(e, { centered: isKeyboard })\n\n onClick?.(e)\n }\n\n return (\n <button\n ref={ref}\n disabled={isDisabled}\n data-disabled={isDisabled}\n onClick={handleClick}\n className={cn(`${global.prefixCls}-icon-btn ${global.prefixCls}-clickable`, className)}\n style={style}\n {...props}\n />\n )\n }\n)\n\nIconButton.displayName = 'IconButton'\n","import { Flex, type FlexProps } from '@negative-space/flex'\nimport { cn, mergeCn, useNSUI } from '@negative-space/system'\nimport React from 'react'\n\nimport { Button, type ButtonProps } from './Button'\nimport { ButtonContext } from './ButtonContext'\nimport { IconButton, type IconButtonProps } from './IconButton'\n\nexport type ButtonComponent =\n | { button: Omit<ButtonProps, 'controlled'> }\n | { iconButton: Omit<IconButtonProps, 'controlled'> }\n\nexport interface ButtonGroupProps extends Omit<FlexProps, 'as' | 'className' | 'style'> {\n classNames?: {\n root?: string\n button?: {\n btn?: string\n content?: string\n prefix?: string\n suffix?: string\n }\n iconButton?: string\n }\n styles?: {\n root?: React.CSSProperties\n button?: {\n btn?: React.CSSProperties\n content?: React.CSSProperties\n prefix?: React.CSSProperties\n suffix?: React.CSSProperties\n }\n iconButton?: React.CSSProperties\n }\n disabled?: boolean\n items: ButtonComponent[]\n}\n\nexport const ButtonGroup = React.forwardRef<HTMLDivElement, ButtonGroupProps>(\n ({ items, classNames, styles, disabled, ...props }, ref) => {\n const { global } = useNSUI()\n\n return (\n <ButtonContext.Provider value={{ disabled }}>\n <Flex\n {...props}\n ref={ref}\n className={cn(`${global.prefixCls}-btn-group`, classNames?.root)}\n style={styles?.root}\n >\n {items.map((item, index) => {\n if ('button' in item) {\n const { children, ...buttonProps } = item.button\n\n return (\n <Button\n key={index}\n controlled\n {...buttonProps}\n classNames={mergeCn(classNames?.button, buttonProps.classNames)}\n styles={{ ...styles?.button, ...buttonProps.styles }}\n >\n {children}\n </Button>\n )\n }\n\n if ('iconButton' in item) {\n return (\n <IconButton\n key={index}\n controlled\n {...item.iconButton}\n className={cn(classNames?.iconButton, item.iconButton.className)}\n style={{ ...styles?.iconButton, ...item.iconButton.style }}\n />\n )\n }\n\n return null\n })}\n </Flex>\n </ButtonContext.Provider>\n )\n }\n)\n\nButtonGroup.displayName = 'ButtonGroup'\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@negative-space/button",
3
- "version": "2.4.2",
3
+ "version": "2.6.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -35,7 +35,7 @@
35
35
  "@negative-space/flex": "1.2.2",
36
36
  "@negative-space/ripple": "1.1.2",
37
37
  "@negative-space/system": "1.3.0",
38
- "@negative-space/spinner": "2.1.5"
38
+ "@negative-space/spinner": "2.2.0"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "react": "^19.2.3"