@synerise/ds-button 2.0.4 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,33 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [2.1.1](https://github.com/synerise/synerise-design/compare/@synerise/ds-button@2.1.0...@synerise/ds-button@2.1.1) (2026-09-24)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * make single-icon button width follow size and block ([a1c9ff2](https://github.com/synerise/synerise-design/commit/a1c9ff251800239489388647f8471da6d244dd17))
12
+
13
+
14
+
15
+
16
+
17
+ # [2.1.0](https://github.com/synerise/synerise-design/compare/@synerise/ds-button@2.0.4...@synerise/ds-button@2.1.0) (2026-09-22)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **core:** move test helpers to a ./testing subpath export ([b38cd82](https://github.com/synerise/synerise-design/commit/b38cd82c956111d2331d5c1e0efd1935366f1139))
23
+
24
+
25
+ ### Features
26
+
27
+ * add @synerise/ds-condition-blocks — building blocks for filtering-condition layouts ([ed332ce](https://github.com/synerise/synerise-design/commit/ed332cefddd418a293a73c51c57e9a4c1ed4f22f))
28
+
29
+
30
+
31
+
32
+
6
33
  ## [2.0.4](https://github.com/synerise/synerise-design/compare/@synerise/ds-button@2.0.3...@synerise/ds-button@2.0.4) (2026-09-18)
7
34
 
8
35
  **Note:** Version bump only for package @synerise/ds-button
package/CLAUDE.md CHANGED
@@ -60,6 +60,8 @@ Uses `:focus-visible` (not `:focus`) so the focus ring only appears on keyboard
60
60
  | `loading` | `boolean \| { delay?: number }` | `false` | Shows spinning overlay |
61
61
  | `error` | `boolean` | `undefined` | Red error styling |
62
62
  | `readOnly` | `boolean` | `undefined` | Disables ripple, freezes hover/focus styles |
63
+ | `size` | `'small' \| 'middle' \| 'large'` | `'middle'` | Height 28/32/48px; also drives width in `mode="single-icon"` |
64
+ | `block` | `boolean` | `false` | Full-width layout (applies in every `mode`) |
63
65
  | `tagProps` | `TagProps` | `undefined` | Renders a pill tag after the label |
64
66
  | `tooltipProps` | `TooltipProps` | `undefined` | Wraps label in a tooltip |
65
67
  | `onClick` | `(event: MouseEvent<HTMLElement>) => void` | `undefined` | Click handler (also triggers ripple) |
@@ -72,7 +74,7 @@ Additional variant types handled by `Button.variants.ts`: `'danger' | 'success'
72
74
  #### `ButtonMode` values
73
75
  | Value | Description |
74
76
  |-------|-------------|
75
- | `'single-icon'` | 32×32px icon-only; no min-width |
77
+ | `'single-icon'` | Square icon-only, no min-width. Width tracks `size`: 28px (`small`), 32px (default), 48px (`large`); `block` overrides it with `100%` |
76
78
  | `'split'` | label + right icon with a divider |
77
79
  | `'two-icons'` | left icon + label + right icon |
78
80
  | `'label-icon'` | label then icon |
package/README.md CHANGED
@@ -57,6 +57,7 @@ import { AngleDownS } from '@synerise/ds-icon';
57
57
 
58
58
  | Property | Description | Type | Default |
59
59
  | -------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
60
+ | block | Defines if the button should take all available space. | boolean | `false` |
60
61
  | color | Defines color of `custom-color` button. | `green` / `grey` / `yellow` / `blue` / `pink`/ `mars`/ `orange`/ `fern`/ `cyan`/ `purple` / `violet` | `red` |
61
62
  | disabled | Defines if the button is disabled. | boolean | `false` |
62
63
  | groupVariant | Defines shape of the button | `left-rounded` / `squared` / `right-rounded` | - |
@@ -68,6 +69,7 @@ import { AngleDownS } from '@synerise/ds-icon';
68
69
  | iconColor | Defines color of `icon` in button. | `green` / `grey` / `yellow` / `blue` / `pink`/ `mars`/ `orange`/ `fern`/ `cyan`/ `purple` / `violet` | - |
69
70
  | error | Defines if the button has error button styles . | boolean | `false` |
70
71
  | readOnly | Disables ripple and freezes hover/focus styles (cursor: default). | boolean | - |
72
+ | size | Defines the size of the button. Sets the height, and in `mode="single-icon"` the width too (28 / 32 / 48px square). | `small` / `middle` / `large` | `middle` |
71
73
  | tagProps | Renders a status tag next to button label | TagProps see ds-tag | - |
72
74
  | tooltipProps | Wraps the button label in a tooltip. | TooltipProps see ds-tooltip | - |
73
75
 
@@ -1,5 +1,5 @@
1
1
  import styled from "styled-components";
2
- const dsProps = /* @__PURE__ */ new Set(["mode", "justifyContent", "groupVariant", "customColor", "pressed", "iconColor", "error", "readOnly", "expanderSize", "expanded", "htmlType", "loading"]);
2
+ const dsProps = /* @__PURE__ */ new Set(["mode", "justifyContent", "groupVariant", "customColor", "pressed", "iconColor", "error", "readOnly", "expanderSize", "expanded", "htmlType", "loading", "fluidMinWidth"]);
3
3
  const Button = /* @__PURE__ */ styled.button.withConfig({
4
4
  shouldForwardProp: (prop) => !dsProps.has(prop)
5
5
  }).withConfig({
package/dist/Button.d.ts CHANGED
@@ -15,5 +15,6 @@ declare const Button: React.ForwardRefExoticComponent<Omit<import('./BaseButton.
15
15
  readOnly?: boolean;
16
16
  tagProps?: import('@synerise/ds-tag').TagProps;
17
17
  tooltipProps?: import('@synerise/ds-tooltip').TooltipProps;
18
+ fluidMinWidth?: string | number;
18
19
  } & React.RefAttributes<HTMLButtonElement>>;
19
20
  export default Button;
@@ -34,9 +34,11 @@ type StyledButtonProps = {
34
34
  readOnly?: boolean;
35
35
  type: string;
36
36
  size?: string;
37
+ block?: boolean;
37
38
  loading?: boolean | {
38
39
  delay?: number;
39
40
  };
41
+ fluidMinWidth?: string | number;
40
42
  };
41
43
  export declare const StyledButton: import('styled-components').StyledComponent<import('react').ForwardRefExoticComponent<Omit<import('react').ButtonHTMLAttributes<HTMLButtonElement>, "type" | "onClick"> & {
42
44
  onClick?: (event: import('react').MouseEvent<HTMLElement>) => void;
@@ -1,6 +1,7 @@
1
1
  import styled, { css, keyframes } from "styled-components";
2
2
  import { IconContainer } from "@synerise/ds-icon";
3
3
  import DSTag from "@synerise/ds-tag";
4
+ import { toCssSize } from "@synerise/ds-utils";
4
5
  import BaseButton from "./BaseButton.js";
5
6
  import { getVariantStyles } from "./Button.variants.js";
6
7
  const RIPPLE_ANIMATION_TIME = 500;
@@ -9,6 +10,20 @@ const leftIcon = "0 4px 0 8px";
9
10
  const rightIcon = "0 8px 0 4px";
10
11
  const rippleInitialSize = 20;
11
12
  const splitTypes = ["secondary", "tertiary"];
13
+ const SINGLE_ICON_WIDTHS = {
14
+ small: "28px",
15
+ large: "48px"
16
+ };
17
+ const SINGLE_ICON_DEFAULT_WIDTH = "32px";
18
+ const singleIconWidth = ({
19
+ block,
20
+ size
21
+ }) => {
22
+ if (block) {
23
+ return "100%";
24
+ }
25
+ return size && SINGLE_ICON_WIDTHS[size] || SINGLE_ICON_DEFAULT_WIDTH;
26
+ };
12
27
  const pressedStyles = (props) => css(["color:", ";background:", ";&.ant-btn .btn-focus{box-shadow:inset 0 0 0 1px ", ";}", " > .ds-icon:before{background-color:", ";}"], props.theme.palette["blue-600"], props.theme.palette["blue-100"], props.theme.palette["blue-300"], ButtonLabel, props.theme.palette["blue-200"]);
13
28
  const spinnerAnimation = /* @__PURE__ */ keyframes(["from{transform:rotateZ(0deg);}to{transform:rotateZ(360deg);}"]);
14
29
  const rippleAnimation = /* @__PURE__ */ keyframes(["from{opacity:1;transform:scale(1);}to{opacity:0;transform:scale(20);}"]);
@@ -38,7 +53,7 @@ const ButtonLabel = /* @__PURE__ */ styled.div.withConfig({
38
53
  const StyledButton = /* @__PURE__ */ styled(BaseButton).withConfig({
39
54
  displayName: "Buttonstyles__StyledButton",
40
55
  componentId: "sc-3lgta1-5"
41
- })(["&&{", " -webkit-mask-image:-webkit-radial-gradient(white,black);display:inline-flex;align-items:center;padding:0 12px;position:relative;overflow:hidden;", " > *:not(.btn-focus){position:relative;z-index:1;}", " > .ds-icon,> .ds-icon{display:flex;align-items:center;justify-content:center;margin:0;width:24px;height:24px;}", " &&.ant-btn-default:not(.ds-expander):not(.ds-button-creator):not(.read-only):not([disabled]),&&.ant-btn-secondary:not(.ds-expander):not(.ds-button-creator):not(.read-only):not([disabled]){.btn-ripple{background-color:", ";}&.pressed{", " color:", ";}&:focus-visible:not(.pressed){color:", ";background:", ";}&:hover:not(:disabled):not(:focus-visible):not(.pressed){background-color:", ";&.ant-btn .btn-focus{box-shadow:inset 0 0 0 1px ", ";}", " > .ds-icon:before{background-color:", ";}}}", " ", ";", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " &:hover:not(:disabled):not(:focus-visible):not(.pressed){", " span{color:", ";cursor:inherit;}}}"], (props) => getVariantStyles(props.type, props.theme.palette), ButtonLabel, ButtonLabel, (props) => props.mode !== "single-icon" && css(["&.ant-btn:not(.ds-expander):not(.ds-button-creator):not( .btn-search ):not(.btn-search-open){min-width:54px;}"]), (props) => props.theme.palette["blue-100"], (props) => pressedStyles(props), (props) => props.theme.palette["blue-600"], (props) => props.error ? props.theme.palette["red-600"] : props.theme.palette["grey-600"], (props) => props.theme.palette["grey-050"], (props) => props.theme.palette["blue-050"], (props) => props.theme.palette["blue-300"], ButtonLabel, (props) => props.theme.palette["blue-200"], (props) => props.readOnly && props.type !== "custom-color-ghost" && css(["&&.ant-btn{cursor:default;transition:none;}&&.ant-btn-secondary{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:inset 0 0 0 1px ", ";}color:", ";}}&&.ant-btn-primary{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:inset 0 0 0 1px ", ";}color:", ";}}&&.ant-btn-tertiary{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-tertiary-white{&:hover,&:focus-visible{background:rgba(219,224,227,0.15);.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-ghost-primary{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-ghost{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-ghost-white{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-danger{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-success{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-warning{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}"], props.theme.palette["grey-050"], props.theme.palette["grey-300"], props.theme.palette["grey-700"], props.theme.palette["blue-600"], props.theme.palette["blue-600"], props.theme.palette["grey-050"], props.theme.palette["grey-100"], props.theme.palette["grey-700"], props.theme.palette["grey-050"], props.theme.palette.white, props.theme.palette["blue-600"], props.theme.palette.white, props.theme.palette["grey-600"], props.theme.palette["grey-600"], props.theme.palette["grey-050"], props.theme.palette["red-600"], props.theme.palette.white, props.theme.palette["green-600"], props.theme.palette.white, props.theme.palette["yellow-600"], props.theme.palette.white), (props) => props.loading && css(["> *:not(.btn-focus){opacity:0;visibility:hidden;}", "{opacity:1;visibility:visible;}"], Spinner), (props) => props.iconColor && css(["&.ant-btn:not(:disabled){color:", ";&:hover{color:inherit;}}"], props.theme.palette[`${props.iconColor}-600`]), (props) => props.mode === "split" && css(["&.ant-btn{padding-right:0;transition:0s;", "{position:relative;}", " > .ds-icon{margin:0 4px 0 15px;position:relative;&:before{content:'';background-color:", ";top:", ";height:", ";width:1px;left:-4px;position:absolute;transition:all 0.3s ease;}}}"], ButtonLabel, ButtonLabel, !splitTypes.includes(props.type) ? `rgba(255, 255, 255, 0.15);` : props.theme.palette["grey-300"], props.size === "large" ? "-12px" : "-4px", props.size === "large" ? "48px" : "32px"), (props) => props.mode === "two-icons" && css(["&.ant-btn{padding:0;transition:0s;", " > ", ":first-of-type,", " > .ds-icon:first-of-type,& > ", ":first-of-type,& > .ds-icon:first-of-type{margin:", ";}", " > ", ":nth-of-type(2),", " > .ds-icon:nth-of-type(2),& > ", ":nth-of-type(2),& > .ds-icon:nth-of-type(2){margin:", ";}}", "{margin:0 12px 0 0;}"], ButtonLabel, IconContainer, ButtonLabel, IconContainer, leftIcon, ButtonLabel, IconContainer, ButtonLabel, IconContainer, rightIcon, Tag), (props) => props.mode === "label-icon" && css(["&.ant-btn{padding-right:0;transition:0s;", " > ", ",", " > .ds-icon,& > ", ",& > .ds-icon{margin:", ";}}", "{margin:0 12px 0 0;}"], ButtonLabel, IconContainer, ButtonLabel, IconContainer, rightIcon, Tag), (props) => props.mode === "icon-label" && css(["&.ant-btn{padding-left:0;transition:0s;", " > ", ",", " > .ds-icon,& > ", ",& > .ds-icon{margin:", ";}}"], ButtonLabel, IconContainer, ButtonLabel, IconContainer, leftIcon), (props) => props.mode === "single-icon" && css(["&.ant-btn:not(.ds-expander){display:flex;align-items:center;justify-content:center;padding:0;transition:0s;width:32px;", " > ", ",", " > .ds-icon,& > ", ",& > .ds-icon{margin:0 4px 0 4px;}}"], ButtonLabel, IconContainer, ButtonLabel, IconContainer), (props) => props.mode === "single-icon" && props.size === "large" && css(["&.ant-btn{width:48px;}"]), (props) => props.groupVariant === "squared" && css(["&.ant-btn{border-radius:0;}"]), (props) => props.groupVariant === "left-rounded" && css(["&.ant-btn{border-radius:3px 0 0 3px;}"]), (props) => props.groupVariant === "right-rounded" && css(["&.ant-btn{border-radius:0 3px 3px 0;}"]), (props) => props.error && css(["&.ant-btn{background-color:", ";box-shadow:inset 0 0 0 1px ", ";color:", ";.btn-focus{box-shadow:none;}&&:hover:not(:disabled):not(:focus-visible):not(.pressed){background-color:", ";box-shadow:inset 0 0 0 1px ", ";color:", ";}&.pressed{background-color:", ";box-shadow:none;color:", ";}&&:focus-visible:not(.pressed){border:none !important;background-color:", ";color:", ";.btn-focus{box-shadow:inset 0 0 0 2px ", ";}}}", "{background-color:", ";}"], props.theme.palette[`red-100`], props.theme.palette["red-600"], props.theme.palette[`red-600`], props.theme.palette[`red-200`], props.theme.palette["red-600"], props.theme.palette[`red-600`], props.theme.palette[`red-700`], props.theme.palette.white, props.theme.palette[`red-100`], props.theme.palette[`red-600`], props.theme.palette["blue-600"], RippleEffect, props.theme.palette[`red-700`]), (props) => props.error && props.type === "secondary" && css(["&&&.ant-btn{color:", ";.btn-focus{box-shadow:none;}&&&:hover{background-color:", ";.btn-focus{box-shadow:none;}}&&&:focus-visible:not(.pressed){.btn-focus{box-shadow:inset 0 0 0 2px ", ";}}&&&.pressed{background-color:", ";color:", ";}", "{background-color:", ";}}"], props.theme.palette[`red-600`], props.theme.palette[`red-200`], props.theme.palette["blue-600"], props.theme.palette[`red-700`], props.theme.palette.white, RippleEffect, props.theme.palette[`red-700`]), (props) => props.type === "custom-color" && !props.error && css(["&.ant-btn{background-color:", ";border:0 solid transparent;color:", ";", "{box-shadow:inset 0 0 0 0px transparent;}", "{background-color:", ";}&:focus-visible:not(.read-only){", "{box-shadow:inset 0 0 0 2px ", ";}}&:hover:not(:disabled):not(:focus-visible):not(.pressed){background-color:", ";color:", ";}&.pressed{background-color:", ";color:", ";}&:disabled{opacity:0.4;background-color:", ";color:", ";}}"], props.theme.palette[`${props.customColor}-600`], props.theme.palette.white, ButtonFocus, RippleEffect, props.theme.palette[`${props.customColor}-700`], ButtonFocus, props.theme.palette["blue-600"], props.theme.palette[props.readOnly ? `${props.customColor}-600` : `${props.customColor}-500`], props.theme.palette.white, props.theme.palette[`${props.customColor}-700`], props.theme.palette.white, props.theme.palette[`${props.customColor}-600`], props.theme.palette.white), (props) => props.type === "custom-color-ghost" && !props.error && css(["&&{color:", ";&:hover:not(:disabled){color:", ";}&:disabled{opacity:0.4;color:", ";}}"], props.theme.palette[`${props.customColor}-600`], props.theme.palette[`${props.customColor}-600`], props.theme.palette[`${props.customColor}-600`]), (props) => props.readOnly && props.type === "custom-color-ghost" && css(["&&.ant-btn{cursor:default;transition:none;}&&.ant-btn-custom-color-ghost{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:inset 0 0 0 0 ", ";}color:", ";}}"], props.theme.palette.white, props.theme.palette.white, props.theme.palette[`${props.customColor}-600`]), Tag, (props) => props.theme.palette.white);
56
+ })(["&&{", " -webkit-mask-image:-webkit-radial-gradient(white,black);display:inline-flex;align-items:center;padding:0 12px;position:relative;overflow:hidden;", " > *:not(.btn-focus){position:relative;z-index:1;}", " > .ds-icon,> .ds-icon{display:flex;align-items:center;justify-content:center;margin:0;width:24px;height:24px;}", " &&.ant-btn-default:not(.ds-expander):not(.ds-button-creator):not(.read-only):not([disabled]),&&.ant-btn-secondary:not(.ds-expander):not(.ds-button-creator):not(.read-only):not([disabled]){.btn-ripple{background-color:", ";}&.pressed{", " color:", ";}&:focus-visible:not(.pressed){color:", ";background:", ";}&:hover:not(:disabled):not(:focus-visible):not(.pressed){background-color:", ";&.ant-btn .btn-focus{box-shadow:inset 0 0 0 1px ", ";}", " > .ds-icon:before{background-color:", ";}}}", " ", ";", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " &:hover:not(:disabled):not(:focus-visible):not(.pressed){", " span{color:", ";cursor:inherit;}}", "}"], (props) => getVariantStyles(props.type, props.theme.palette), ButtonLabel, ButtonLabel, (props) => props.mode !== "single-icon" && css(["&.ant-btn:not(.ds-expander):not(.ds-button-creator):not( .btn-search ):not(.btn-search-open){min-width:54px;}"]), (props) => props.theme.palette["blue-100"], (props) => pressedStyles(props), (props) => props.theme.palette["blue-600"], (props) => props.error ? props.theme.palette["red-600"] : props.theme.palette["grey-600"], (props) => props.theme.palette["grey-050"], (props) => props.theme.palette["blue-050"], (props) => props.theme.palette["blue-300"], ButtonLabel, (props) => props.theme.palette["blue-200"], (props) => props.readOnly && props.type !== "custom-color-ghost" && css(["&&.ant-btn{cursor:default;transition:none;}&&.ant-btn-secondary{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:inset 0 0 0 1px ", ";}color:", ";}}&&.ant-btn-primary{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:inset 0 0 0 1px ", ";}color:", ";}}&&.ant-btn-tertiary{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-tertiary-white{&:hover,&:focus-visible{background:rgba(219,224,227,0.15);.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-ghost-primary{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-ghost{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-ghost-white{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-danger{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-success{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}&&.ant-btn-warning{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:none;}color:", ";}}"], props.theme.palette["grey-050"], props.theme.palette["grey-300"], props.theme.palette["grey-700"], props.theme.palette["blue-600"], props.theme.palette["blue-600"], props.theme.palette["grey-050"], props.theme.palette["grey-100"], props.theme.palette["grey-700"], props.theme.palette["grey-050"], props.theme.palette.white, props.theme.palette["blue-600"], props.theme.palette.white, props.theme.palette["grey-600"], props.theme.palette["grey-600"], props.theme.palette["grey-050"], props.theme.palette["red-600"], props.theme.palette.white, props.theme.palette["green-600"], props.theme.palette.white, props.theme.palette["yellow-600"], props.theme.palette.white), (props) => props.loading && css(["> *:not(.btn-focus){opacity:0;visibility:hidden;}", "{opacity:1;visibility:visible;}"], Spinner), (props) => props.iconColor && css(["&.ant-btn:not(:disabled){color:", ";&:hover{color:inherit;}}"], props.theme.palette[`${props.iconColor}-600`]), (props) => props.mode === "split" && css(["&.ant-btn{padding-right:0;transition:0s;", "{position:relative;}", " > .ds-icon{margin:0 4px 0 15px;position:relative;&:before{content:'';background-color:", ";top:", ";height:", ";width:1px;left:-4px;position:absolute;transition:all 0.3s ease;}}}"], ButtonLabel, ButtonLabel, !splitTypes.includes(props.type) ? `rgba(255, 255, 255, 0.15);` : props.theme.palette["grey-300"], props.size === "large" ? "-12px" : "-4px", props.size === "large" ? "48px" : "32px"), (props) => props.mode === "two-icons" && css(["&.ant-btn{padding:0;transition:0s;", " > ", ":first-of-type,", " > .ds-icon:first-of-type,& > ", ":first-of-type,& > .ds-icon:first-of-type{margin:", ";}", " > ", ":nth-of-type(2),", " > .ds-icon:nth-of-type(2),& > ", ":nth-of-type(2),& > .ds-icon:nth-of-type(2){margin:", ";}}", "{margin:0 12px 0 0;}"], ButtonLabel, IconContainer, ButtonLabel, IconContainer, leftIcon, ButtonLabel, IconContainer, ButtonLabel, IconContainer, rightIcon, Tag), (props) => props.mode === "label-icon" && css(["&.ant-btn{padding-right:0;transition:0s;", " > ", ",", " > .ds-icon,& > ", ",& > .ds-icon{margin:", ";}}", "{margin:0 12px 0 0;}"], ButtonLabel, IconContainer, ButtonLabel, IconContainer, rightIcon, Tag), (props) => props.mode === "icon-label" && css(["&.ant-btn{padding-left:0;transition:0s;", " > ", ",", " > .ds-icon,& > ", ",& > .ds-icon{margin:", ";}}"], ButtonLabel, IconContainer, ButtonLabel, IconContainer, leftIcon), (props) => props.mode === "single-icon" && css(["&.ant-btn:not(.ds-expander){display:flex;align-items:center;justify-content:center;padding:0;transition:0s;width:", ";", " > ", ",", " > .ds-icon,& > ", ",& > .ds-icon{margin:0 4px 0 4px;}}"], singleIconWidth(props), ButtonLabel, IconContainer, ButtonLabel, IconContainer), (props) => props.groupVariant === "squared" && css(["&.ant-btn{border-radius:0;}"]), (props) => props.groupVariant === "left-rounded" && css(["&.ant-btn{border-radius:3px 0 0 3px;}"]), (props) => props.groupVariant === "right-rounded" && css(["&.ant-btn{border-radius:0 3px 3px 0;}"]), (props) => props.error && css(["&.ant-btn{background-color:", ";box-shadow:inset 0 0 0 1px ", ";color:", ";.btn-focus{box-shadow:none;}&&:hover:not(:disabled):not(:focus-visible):not(.pressed){background-color:", ";box-shadow:inset 0 0 0 1px ", ";color:", ";}&.pressed{background-color:", ";box-shadow:none;color:", ";}&&:focus-visible:not(.pressed){border:none !important;background-color:", ";color:", ";.btn-focus{box-shadow:inset 0 0 0 2px ", ";}}}", "{background-color:", ";}"], props.theme.palette[`red-100`], props.theme.palette["red-600"], props.theme.palette[`red-600`], props.theme.palette[`red-200`], props.theme.palette["red-600"], props.theme.palette[`red-600`], props.theme.palette[`red-700`], props.theme.palette.white, props.theme.palette[`red-100`], props.theme.palette[`red-600`], props.theme.palette["blue-600"], RippleEffect, props.theme.palette[`red-700`]), (props) => props.error && props.type === "secondary" && css(["&&&.ant-btn{color:", ";.btn-focus{box-shadow:none;}&&&:hover{background-color:", ";.btn-focus{box-shadow:none;}}&&&:focus-visible:not(.pressed){.btn-focus{box-shadow:inset 0 0 0 2px ", ";}}&&&.pressed{background-color:", ";color:", ";}", "{background-color:", ";}}"], props.theme.palette[`red-600`], props.theme.palette[`red-200`], props.theme.palette["blue-600"], props.theme.palette[`red-700`], props.theme.palette.white, RippleEffect, props.theme.palette[`red-700`]), (props) => props.type === "custom-color" && !props.error && css(["&.ant-btn{background-color:", ";border:0 solid transparent;color:", ";", "{box-shadow:inset 0 0 0 0px transparent;}", "{background-color:", ";}&:focus-visible:not(.read-only){", "{box-shadow:inset 0 0 0 2px ", ";}}&:hover:not(:disabled):not(:focus-visible):not(.pressed){background-color:", ";color:", ";}&.pressed{background-color:", ";color:", ";}&:disabled{opacity:0.4;background-color:", ";color:", ";}}"], props.theme.palette[`${props.customColor}-600`], props.theme.palette.white, ButtonFocus, RippleEffect, props.theme.palette[`${props.customColor}-700`], ButtonFocus, props.theme.palette["blue-600"], props.theme.palette[props.readOnly ? `${props.customColor}-600` : `${props.customColor}-500`], props.theme.palette.white, props.theme.palette[`${props.customColor}-700`], props.theme.palette.white, props.theme.palette[`${props.customColor}-600`], props.theme.palette.white), (props) => props.type === "custom-color-ghost" && !props.error && css(["&&{color:", ";&:hover:not(:disabled){color:", ";}&:disabled{opacity:0.4;color:", ";}}"], props.theme.palette[`${props.customColor}-600`], props.theme.palette[`${props.customColor}-600`], props.theme.palette[`${props.customColor}-600`]), (props) => props.readOnly && props.type === "custom-color-ghost" && css(["&&.ant-btn{cursor:default;transition:none;}&&.ant-btn-custom-color-ghost{&:hover,&:focus-visible{background:", ";.btn-focus{box-shadow:inset 0 0 0 0 ", ";}color:", ";}}"], props.theme.palette.white, props.theme.palette.white, props.theme.palette[`${props.customColor}-600`]), Tag, (props) => props.theme.palette.white, (props) => props.fluidMinWidth !== void 0 && css(["", "{min-width:", ";max-width:none;}"], ButtonLabel, toCssSize(props.fluidMinWidth)));
42
57
  export {
43
58
  ACTIVE_DELAY,
44
59
  ButtonFocus,
@@ -56,6 +56,12 @@ export type ButtonProps = Omit<BaseButtonProps, 'type'> & {
56
56
  tagProps?: TagProps;
57
57
  /** Wraps the button label in a tooltip */
58
58
  tooltipProps?: TooltipProps;
59
+ /**
60
+ * Lets the label stretch instead of clipping at a fixed max-width, floored at this min width
61
+ * (a number is treated as px). For buttons whose label must grow to fill the available space
62
+ * (e.g. filter parameter buttons) while never collapsing below this width.
63
+ */
64
+ fluidMinWidth?: string | number;
59
65
  };
60
66
  /** @deprecated - use ButtonProps instead */
61
67
  export type Props = ButtonProps;
package/dist/index.d.ts CHANGED
@@ -37,6 +37,7 @@ declare const _default: import('react').ForwardRefExoticComponent<Omit<import('.
37
37
  readOnly?: boolean;
38
38
  tagProps?: import('@synerise/ds-tag').TagProps;
39
39
  tooltipProps?: import('@synerise/ds-tooltip').TooltipProps;
40
+ fluidMinWidth?: string | number;
40
41
  } & import('react').RefAttributes<HTMLButtonElement>> & {
41
42
  /** @deprecated - use named export `Creator` */
42
43
  Creator: import('react').ForwardRefExoticComponent<Omit<import('./Creator/Creator.types').CreatorProps, "ref"> & import('react').RefAttributes<HTMLButtonElement>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-button",
3
- "version": "2.0.4",
3
+ "version": "2.1.1",
4
4
  "description": "Button UI Component for the Synerise Design System",
5
5
  "license": "ISC",
6
6
  "repository": "synerise/synerise-design",
@@ -39,10 +39,10 @@
39
39
  "sideEffects": false,
40
40
  "types": "dist/index.d.ts",
41
41
  "dependencies": {
42
- "@synerise/ds-icon": "^2.1.2",
43
- "@synerise/ds-tag": "^2.0.4",
44
- "@synerise/ds-tooltip": "^2.0.4",
45
- "@synerise/ds-utils": "^2.1.1",
42
+ "@synerise/ds-icon": "^2.2.0",
43
+ "@synerise/ds-tag": "^2.0.6",
44
+ "@synerise/ds-tooltip": "^2.0.6",
45
+ "@synerise/ds-utils": "^2.2.0",
46
46
  "classnames": "^2.5.1",
47
47
  "csstype": "^2.6.9"
48
48
  },
@@ -52,5 +52,5 @@
52
52
  "styled-components": "^5.3.3",
53
53
  "vitest": "4"
54
54
  },
55
- "gitHead": "b1d905617dfb186b5d80966d63ce55bf29df743d"
55
+ "gitHead": "6b725db2b0de1a2dfc6e9a3744f6c2fb2a04cc04"
56
56
  }