diff --git a/packages/components/docs/sass.md b/packages/components/docs/sass.md
index 34dde05f1eba..0c662f2754a1 100644
--- a/packages/components/docs/sass.md
+++ b/packages/components/docs/sass.md
@@ -196,6 +196,7 @@
- [✅highlight [variable]](#highlight-variable)
- [✅decorative-01 [variable]](#decorative-01-variable)
- [✅hover-light-ui [variable]](#hover-light-ui-variable)
+ - [✅button-separator [variable]](#button-separator-variable)
- [✅skeleton-01 [variable]](#skeleton-01-variable)
- [✅skeleton-02 [variable]](#skeleton-02-variable)
- [✅⚠️brand-01 [variable]](#brand-01-variable)
@@ -4227,6 +4228,7 @@ Define theme variables from a map of tokens
$highlight: map-get($theme, 'highlight') !global;
$decorative-01: map-get($theme, 'decorative-01') !global;
$hover-light-ui: map-get($theme, 'hover-light-ui') !global;
+ $button-separator: map-get($theme, 'button-separator') !global;
$skeleton-01: map-get($theme, 'skeleton-01') !global;
$skeleton-02: map-get($theme, 'skeleton-02') !global;
$brand-01: map-get($theme, 'brand-01') !global;
@@ -4539,6 +4541,10 @@ Define theme variables from a map of tokens
--#{$custom-property-prefix}-hover-light-ui,
map-get($theme, 'hover-light-ui')
) !global;
+ $button-separator: var(
+ --#{$custom-property-prefix}-button-separator,
+ map-get($theme, 'button-separator')
+ ) !global;
$skeleton-01: var(
--#{$custom-property-prefix}-skeleton-01,
map-get($theme, 'skeleton-01')
@@ -5232,6 +5238,19 @@ Define theme variables from a map of tokens
);
}
+ @if should-emit(
+ $theme,
+ $parent-carbon-theme,
+ 'button-separator',
+ $emit-difference
+ )
+ {
+ @include custom-property(
+ 'button-separator',
+ map-get($theme, 'button-separator')
+ );
+ }
+
@if should-emit(
$theme,
$parent-carbon-theme,
@@ -6015,6 +6034,7 @@ Define theme variables from a map of tokens
- [highlight [variable]](#highlight-variable)
- [decorative-01 [variable]](#decorative-01-variable)
- [hover-light-ui [variable]](#hover-light-ui-variable)
+ - [button-separator [variable]](#button-separator-variable)
- [skeleton-01 [variable]](#skeleton-01-variable)
- [skeleton-02 [variable]](#skeleton-02-variable)
- [brand-01 [variable]](#brand-01-variable)
@@ -6171,6 +6191,7 @@ $carbon--theme--g90: map-merge(
highlight: #0043ce,
decorative-01: #6f6f6f,
hover-light-ui: #6f6f6f,
+ button-separator: #161616,
skeleton-01: #353535,
skeleton-02: #525252,
brand-02: #6f6f6f,
@@ -6246,6 +6267,7 @@ $carbon--theme--g100: map-merge(
highlight: #002d9c,
decorative-01: #525252,
hover-light-ui: #525252,
+ button-separator: #161616,
skeleton-01: #353535,
skeleton-02: #393939,
brand-02: #6f6f6f,
@@ -6412,6 +6434,7 @@ $carbon--theme: (
highlight: if(global-variable-exists('highlight'), $highlight, map-get($carbon--theme--white, 'highlight')),
decorative-01: if(global-variable-exists('decorative-01'), $decorative-01, map-get($carbon--theme--white, 'decorative-01')),
hover-light-ui: if(global-variable-exists('hover-light-ui'), $hover-light-ui, map-get($carbon--theme--white, 'hover-light-ui')),
+ button-separator: if(global-variable-exists('button-separator'), $button-separator, map-get($carbon--theme--white, 'button-separator')),
skeleton-01: if(global-variable-exists('skeleton-01'), $skeleton-01, map-get($carbon--theme--white, 'skeleton-01')),
skeleton-02: if(global-variable-exists('skeleton-02'), $skeleton-02, map-get($carbon--theme--white, 'skeleton-02')),
brand-01: if(global-variable-exists('brand-01'), $brand-01, map-get($carbon--theme--white, 'brand-01')),
@@ -8327,6 +8350,30 @@ $hover-light-ui: if(
- [carbon--theme [mixin]](#carbon--theme-mixin)
- [content-switcher [mixin]](#content-switcher-mixin)
+### ✅button-separator [variable]
+
+
+Source code
+
+```scss
+$button-separator: if(
+ global-variable-exists('carbon--theme') and map-has-key(
+ $carbon--theme,
+ 'button-separator'
+ ),
+ map-get($carbon--theme, 'button-separator'),
+ #e0e0e0
+);
+```
+
+
+
+- **Group**: [@carbon/themes](#carbonthemes)
+- **Type**: `{undefined}`
+- **Used by**:
+ - [carbon--theme [mixin]](#carbon--theme-mixin)
+ - [button [mixin]](#button-mixin)
+
### ✅skeleton-01 [variable]
Skeleton state of graphics
@@ -13823,17 +13870,43 @@ Button styles
display: flex;
}
- .#{$prefix}--btn-set > .#{$prefix}--btn {
+ .#{$prefix}--btn-set--stacked {
+ flex-direction: column;
+ }
+
+ .#{$prefix}--btn-set .#{$prefix}--btn {
width: 100%;
// 196px from design kit
max-width: rem(196px);
+
+ &:not(:first-of-type):not(:focus) {
+ box-shadow: rem(-1px) 0 0 0 $button-separator;
+ }
}
- .#{$prefix}--btn--secondary.#{$prefix}--btn--disabled
- + .#{$prefix}--btn--primary.#{$prefix}--btn--disabled,
- .#{$prefix}--btn--tertiary.#{$prefix}--btn--disabled
- + .#{$prefix}--btn--danger.#{$prefix}--btn--disabled {
+ .#{$prefix}--btn-set .#{$prefix}--btn:focus + .#{$prefix}--btn {
+ box-shadow: inherit;
+ }
+
+ .#{$prefix}--btn-set--stacked
+ .#{$prefix}--btn:not(:first-of-type):not(:focus) {
+ box-shadow: 0 rem(-1px) 0 0 $button-separator;
+ }
+
+ .#{$prefix}--btn-set .#{$prefix}--btn.#{$prefix}--btn--disabled {
box-shadow: rem(-1px) 0 0 0 $disabled-03;
+
+ &:first-of-type {
+ box-shadow: none;
+ }
+ }
+
+ .#{$prefix}--btn-set--stacked .#{$prefix}--btn.#{$prefix}--btn--disabled {
+ box-shadow: 0 rem(-1px) 0 0 $disabled-03;
+
+ &:first-of-type {
+ box-shadow: none;
+ }
}
.#{$prefix}--btn {
@@ -14091,6 +14164,7 @@ Button styles
- [button-base [mixin]](#button-base-mixin)
- [button-theme [mixin]](#button-theme-mixin)
- [prefix [variable]](#prefix-variable)
+ - [button-separator [variable]](#button-separator-variable)
- [disabled-03 [variable]](#disabled-03-variable)
- [interactive-01 [variable]](#interactive-01-variable)
- [text-04 [variable]](#text-04-variable)
diff --git a/packages/components/src/components/button/_button.scss b/packages/components/src/components/button/_button.scss
index c5862dccadb4..6554803a7dad 100644
--- a/packages/components/src/components/button/_button.scss
+++ b/packages/components/src/components/button/_button.scss
@@ -23,17 +23,50 @@
display: flex;
}
- .#{$prefix}--btn-set > .#{$prefix}--btn {
+ .#{$prefix}--btn-set--stacked {
+ flex-direction: column;
+ }
+
+ .#{$prefix}--btn-set .#{$prefix}--btn {
width: 100%;
// 196px from design kit
max-width: rem(196px);
+
+ &:not(:focus) {
+ box-shadow: rem(-1px) 0 0 0 $button-separator;
+ }
+
+ &:first-of-type:not(:focus) {
+ box-shadow: inherit;
+ }
+ }
+
+ .#{$prefix}--btn-set .#{$prefix}--btn:focus + .#{$prefix}--btn {
+ box-shadow: inherit;
+ }
+
+ .#{$prefix}--btn-set--stacked .#{$prefix}--btn:not(:focus) {
+ box-shadow: 0 rem(-1px) 0 0 $button-separator;
+ }
+
+ .#{$prefix}--btn-set--stacked .#{$prefix}--btn:first-of-type:not(:focus) {
+ box-shadow: inherit;
}
- .#{$prefix}--btn--secondary.#{$prefix}--btn--disabled
- + .#{$prefix}--btn--primary.#{$prefix}--btn--disabled,
- .#{$prefix}--btn--tertiary.#{$prefix}--btn--disabled
- + .#{$prefix}--btn--danger.#{$prefix}--btn--disabled {
+ .#{$prefix}--btn-set .#{$prefix}--btn.#{$prefix}--btn--disabled {
box-shadow: rem(-1px) 0 0 0 $disabled-03;
+
+ &:first-of-type {
+ box-shadow: none;
+ }
+ }
+
+ .#{$prefix}--btn-set--stacked .#{$prefix}--btn.#{$prefix}--btn--disabled {
+ box-shadow: 0 rem(-1px) 0 0 $disabled-03;
+
+ &:first-of-type {
+ box-shadow: none;
+ }
}
.#{$prefix}--btn {
diff --git a/packages/elements/docs/sass.md b/packages/elements/docs/sass.md
index f0694bab46c4..1e33ac99c836 100644
--- a/packages/elements/docs/sass.md
+++ b/packages/elements/docs/sass.md
@@ -196,6 +196,7 @@
- [✅highlight [variable]](#highlight-variable)
- [✅decorative-01 [variable]](#decorative-01-variable)
- [✅hover-light-ui [variable]](#hover-light-ui-variable)
+ - [✅button-separator [variable]](#button-separator-variable)
- [✅skeleton-01 [variable]](#skeleton-01-variable)
- [✅skeleton-02 [variable]](#skeleton-02-variable)
- [✅⚠️brand-01 [variable]](#brand-01-variable)
@@ -3848,6 +3849,7 @@ Define theme variables from a map of tokens
$highlight: map-get($theme, 'highlight') !global;
$decorative-01: map-get($theme, 'decorative-01') !global;
$hover-light-ui: map-get($theme, 'hover-light-ui') !global;
+ $button-separator: map-get($theme, 'button-separator') !global;
$skeleton-01: map-get($theme, 'skeleton-01') !global;
$skeleton-02: map-get($theme, 'skeleton-02') !global;
$brand-01: map-get($theme, 'brand-01') !global;
@@ -4160,6 +4162,10 @@ Define theme variables from a map of tokens
--#{$custom-property-prefix}-hover-light-ui,
map-get($theme, 'hover-light-ui')
) !global;
+ $button-separator: var(
+ --#{$custom-property-prefix}-button-separator,
+ map-get($theme, 'button-separator')
+ ) !global;
$skeleton-01: var(
--#{$custom-property-prefix}-skeleton-01,
map-get($theme, 'skeleton-01')
@@ -4853,6 +4859,19 @@ Define theme variables from a map of tokens
);
}
+ @if should-emit(
+ $theme,
+ $parent-carbon-theme,
+ 'button-separator',
+ $emit-difference
+ )
+ {
+ @include custom-property(
+ 'button-separator',
+ map-get($theme, 'button-separator')
+ );
+ }
+
@if should-emit(
$theme,
$parent-carbon-theme,
@@ -5636,6 +5655,7 @@ Define theme variables from a map of tokens
- [highlight [variable]](#highlight-variable)
- [decorative-01 [variable]](#decorative-01-variable)
- [hover-light-ui [variable]](#hover-light-ui-variable)
+ - [button-separator [variable]](#button-separator-variable)
- [skeleton-01 [variable]](#skeleton-01-variable)
- [skeleton-02 [variable]](#skeleton-02-variable)
- [brand-01 [variable]](#brand-01-variable)
@@ -5792,6 +5812,7 @@ $carbon--theme--g90: map-merge(
highlight: #0043ce,
decorative-01: #6f6f6f,
hover-light-ui: #6f6f6f,
+ button-separator: #161616,
skeleton-01: #353535,
skeleton-02: #525252,
brand-02: #6f6f6f,
@@ -5867,6 +5888,7 @@ $carbon--theme--g100: map-merge(
highlight: #002d9c,
decorative-01: #525252,
hover-light-ui: #525252,
+ button-separator: #161616,
skeleton-01: #353535,
skeleton-02: #393939,
brand-02: #6f6f6f,
@@ -6033,6 +6055,7 @@ $carbon--theme: (
highlight: if(global-variable-exists('highlight'), $highlight, map-get($carbon--theme--white, 'highlight')),
decorative-01: if(global-variable-exists('decorative-01'), $decorative-01, map-get($carbon--theme--white, 'decorative-01')),
hover-light-ui: if(global-variable-exists('hover-light-ui'), $hover-light-ui, map-get($carbon--theme--white, 'hover-light-ui')),
+ button-separator: if(global-variable-exists('button-separator'), $button-separator, map-get($carbon--theme--white, 'button-separator')),
skeleton-01: if(global-variable-exists('skeleton-01'), $skeleton-01, map-get($carbon--theme--white, 'skeleton-01')),
skeleton-02: if(global-variable-exists('skeleton-02'), $skeleton-02, map-get($carbon--theme--white, 'skeleton-02')),
brand-01: if(global-variable-exists('brand-01'), $brand-01, map-get($carbon--theme--white, 'brand-01')),
@@ -7599,6 +7622,29 @@ $hover-light-ui: if(
+- **Group**: [@carbon/themes](#carbonthemes)
+- **Type**: `{undefined}`
+- **Used by**:
+ - [carbon--theme [mixin]](#carbon--theme-mixin)
+
+### ✅button-separator [variable]
+
+
+Source code
+
+```scss
+$button-separator: if(
+ global-variable-exists('carbon--theme') and map-has-key(
+ $carbon--theme,
+ 'button-separator'
+ ),
+ map-get($carbon--theme, 'button-separator'),
+ #e0e0e0
+);
+```
+
+
+
- **Group**: [@carbon/themes](#carbonthemes)
- **Type**: `{undefined}`
- **Used by**:
diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
index a4923da640e9..d912b269c735 100644
--- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
+++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
@@ -216,6 +216,22 @@ Map {
},
"render": [Function],
},
+ "ButtonSet" => Object {
+ "$$typeof": Symbol(react.forward_ref),
+ "displayName": "ButtonSet",
+ "propTypes": Object {
+ "children": Object {
+ "type": "node",
+ },
+ "className": Object {
+ "type": "string",
+ },
+ "stacked": Object {
+ "type": "bool",
+ },
+ },
+ "render": [Function],
+ },
"Checkbox" => Object {
"$$typeof": Symbol(react.forward_ref),
"defaultProps": Object {
diff --git a/packages/react/src/__tests__/index-test.js b/packages/react/src/__tests__/index-test.js
index 3b62bea82004..180afdd51a7b 100644
--- a/packages/react/src/__tests__/index-test.js
+++ b/packages/react/src/__tests__/index-test.js
@@ -22,6 +22,7 @@ describe('Carbon Components React', () => {
"BreadcrumbItem",
"BreadcrumbSkeleton",
"Button",
+ "ButtonSet",
"ButtonSkeleton",
"Checkbox",
"CheckboxSkeleton",
diff --git a/packages/react/src/components/Button/Button-story.js b/packages/react/src/components/Button/Button-story.js
index c20068ab73e4..1f29feb8279a 100644
--- a/packages/react/src/components/Button/Button-story.js
+++ b/packages/react/src/components/Button/Button-story.js
@@ -9,13 +9,11 @@ import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { withKnobs, boolean, select, text } from '@storybook/addon-knobs';
-import { settings } from 'carbon-components';
import { iconAddSolid, iconSearch } from 'carbon-icons';
import { Add16, AddFilled16, Search16 } from '@carbon/icons-react';
import Button from '../Button';
import ButtonSkeleton from '../Button/Button.Skeleton';
-
-const { prefix } = settings;
+import ButtonSet from '../ButtonSet';
const icons = {
None: 'None',
@@ -109,6 +107,7 @@ const props = {
'Icon description (iconDescription)',
'Button icon'
),
+ stacked: boolean('Stack buttons vertically (stacked)', false),
onClick: action('onClick'),
onFocus: action('onFocus'),
};
@@ -197,22 +196,22 @@ storiesOf('Button', module)
.add(
'Sets of Buttons',
() => {
- const setProps = props.set();
+ const { stacked, ...buttonProps } = props.set();
return (
-
-
+
+
Secondary button
-
+
Primary button
-
+
);
},
{
info: {
text: `
- When an action required by the user has more than one option, always use a a negative action button (secondary) paired with a positive action button (primary) in that order. Negative action buttons will be on the left. Positive action buttons should be on the right. When these two types buttons are paired in the correct order, they will automatically space themselves apart.
+ When an action required by the user has more than one option, always use a negative action button (secondary) paired with a positive action button (primary) in that order. Negative action buttons will be on the left. Positive action buttons should be on the right. When these two types buttons are paired in the correct order, they will automatically space themselves apart.
`,
},
}
diff --git a/packages/react/src/components/ButtonSet/ButtonSet-test.js b/packages/react/src/components/ButtonSet/ButtonSet-test.js
new file mode 100644
index 000000000000..80f75bbebce0
--- /dev/null
+++ b/packages/react/src/components/ButtonSet/ButtonSet-test.js
@@ -0,0 +1,49 @@
+/**
+ * Copyright IBM Corp. 2016, 2018
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import ButtonSet from '../ButtonSet';
+import { shallow } from 'enzyme';
+import { settings } from 'carbon-components';
+
+const { prefix } = settings;
+
+describe('ButtonSet', () => {
+ let wrapper;
+
+ beforeEach(() => {
+ wrapper = shallow( );
+ });
+
+ it('should render empty set as expected', () => {
+ expect(wrapper.find('.child').length).toBe(0);
+ });
+
+ it('should render nonempty set as expected', () => {
+ wrapper = shallow(
+
+
+
+
+ );
+ expect(wrapper.find('.test-child').length).toBe(2);
+ });
+
+ it('should render wrapper as expected', () => {
+ expect(wrapper.length).toBe(1);
+ });
+
+ it('should have the expected classes in a horizontal set', () => {
+ expect(wrapper.hasClass(`${prefix}--btn-set`)).toEqual(true);
+ });
+
+ it('should have the expected classes in a vertical set', () => {
+ wrapper.setProps({ stacked: true });
+ expect(wrapper.hasClass(`${prefix}--btn-set`)).toEqual(true);
+ expect(wrapper.hasClass(`${prefix}--btn-set--stacked`)).toEqual(true);
+ });
+});
diff --git a/packages/react/src/components/ButtonSet/ButtonSet.js b/packages/react/src/components/ButtonSet/ButtonSet.js
new file mode 100644
index 000000000000..38b671dfc8e3
--- /dev/null
+++ b/packages/react/src/components/ButtonSet/ButtonSet.js
@@ -0,0 +1,47 @@
+/**
+ * Copyright IBM Corp. 2016, 2018
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import { settings } from 'carbon-components';
+
+const { prefix } = settings;
+const ButtonSet = React.forwardRef(function ButtonSet(
+ { children, className, stacked, ...rest },
+ ref
+) {
+ const buttonSetClasses = classNames(className, `${prefix}--btn-set`, {
+ [`${prefix}--btn-set--stacked`]: stacked,
+ });
+ return (
+
+ {children}
+
+ );
+});
+
+ButtonSet.displayName = 'ButtonSet';
+ButtonSet.propTypes = {
+ /**
+ * Specify the content of your ButtonSet
+ */
+ children: PropTypes.node,
+
+ /**
+ * Specify an optional className to be added to your ButtonSet
+ */
+ className: PropTypes.string,
+
+ /**
+ * Specify the button arrangement of the set (vertically stacked or
+ * horizontal)
+ */
+ stacked: PropTypes.bool,
+};
+
+export default ButtonSet;
diff --git a/packages/react/src/components/ButtonSet/index.js b/packages/react/src/components/ButtonSet/index.js
new file mode 100644
index 000000000000..c25ef0671462
--- /dev/null
+++ b/packages/react/src/components/ButtonSet/index.js
@@ -0,0 +1,8 @@
+/**
+ * Copyright IBM Corp. 2016, 2018
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+export default from './ButtonSet';
diff --git a/packages/react/src/components/ComposedModal/ComposedModal.js b/packages/react/src/components/ComposedModal/ComposedModal.js
index d8015bed3c69..cc4bd48aac52 100644
--- a/packages/react/src/components/ComposedModal/ComposedModal.js
+++ b/packages/react/src/components/ComposedModal/ComposedModal.js
@@ -8,6 +8,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Button from '../Button';
+import ButtonSet from '../ButtonSet';
import classNames from 'classnames';
import { settings } from 'carbon-components';
import { Close20 } from '@carbon/icons-react';
@@ -575,7 +576,7 @@ export class ModalFooter extends Component {
});
return (
-
+
{secondaryButtonText && (
+
);
}
}
diff --git a/packages/react/src/components/Modal/Modal.js b/packages/react/src/components/Modal/Modal.js
index 8c8768f00194..2fff9277ae19 100644
--- a/packages/react/src/components/Modal/Modal.js
+++ b/packages/react/src/components/Modal/Modal.js
@@ -12,6 +12,7 @@ import { settings } from 'carbon-components';
import { Close20 } from '@carbon/icons-react';
import toggleClass from '../../tools/toggleClass';
import Button from '../Button';
+import ButtonSet from '../ButtonSet';
import deprecate from '../../prop-types/deprecate';
import requiredIfGivenPropIsTruthy from '../../prop-types/requiredIfGivenPropIsTruthy';
import wrapFocus, {
@@ -419,7 +420,7 @@ export default class Modal extends Component {
)}
{!passiveModal && (
-
+
{secondaryButtonText}
@@ -430,7 +431,7 @@ export default class Modal extends Component {
ref={this.button}>
{primaryButtonText}
-
+
)}
);
diff --git a/packages/react/src/components/ModalWrapper/__snapshots__/ModalWrapper-test.js.snap b/packages/react/src/components/ModalWrapper/__snapshots__/ModalWrapper-test.js.snap
index cd00e70a0460..3aece0432c3e 100644
--- a/packages/react/src/components/ModalWrapper/__snapshots__/ModalWrapper-test.js.snap
+++ b/packages/react/src/components/ModalWrapper/__snapshots__/ModalWrapper-test.js.snap
@@ -149,46 +149,50 @@ exports[`ModalWrapper should render 1`] = `
Text
-
-
-
- Cancel
-
-
-
-
+ Cancel
+
+
+
- Save
-
-
-
+
+ Save
+
+
+
+
+- **Group**: [@carbon/themes](#carbonthemes)
+- **Type**: `{undefined}`
+- **Used by**:
+ - [carbon--theme [mixin]](#carbon--theme-mixin)
+
+### ✅button-separator [variable]
+
+
+Source code
+
+```scss
+$button-separator: if(
+ global-variable-exists('carbon--theme') and map-has-key(
+ $carbon--theme,
+ 'button-separator'
+ ),
+ map-get($carbon--theme, 'button-separator'),
+ #e0e0e0
+);
+```
+
+
+
- **Group**: [@carbon/themes](#carbonthemes)
- **Type**: `{undefined}`
- **Used by**:
diff --git a/packages/themes/src/g10.js b/packages/themes/src/g10.js
index a0d7f0bcb840..78832b7a2b77 100644
--- a/packages/themes/src/g10.js
+++ b/packages/themes/src/g10.js
@@ -130,6 +130,8 @@ export const decorative01 = gray20;
export const hoverLightUI = '#e5e5e5';
+export const buttonSeparator = '#e0e0e0';
+
export const skeleton01 = '#e5e5e5';
export const skeleton02 = gray30;
diff --git a/packages/themes/src/g100.js b/packages/themes/src/g100.js
index 5014ba6c087d..0dbcd2509378 100644
--- a/packages/themes/src/g100.js
+++ b/packages/themes/src/g100.js
@@ -129,6 +129,8 @@ export const decorative01 = gray70;
export const hoverLightUI = '#525252';
+export const buttonSeparator = '#161616';
+
export const skeleton01 = '#353535';
export const skeleton02 = gray80;
diff --git a/packages/themes/src/g90.js b/packages/themes/src/g90.js
index ea31594bf3ad..918691d02a51 100644
--- a/packages/themes/src/g90.js
+++ b/packages/themes/src/g90.js
@@ -131,6 +131,8 @@ export const decorative01 = gray60;
export const hoverLightUI = '#6f6f6f';
+export const buttonSeparator = '#161616';
+
export const skeleton01 = '#353535';
export const skeleton02 = gray70;
diff --git a/packages/themes/src/tokens.js b/packages/themes/src/tokens.js
index caeafb655511..35d60acbbb20 100644
--- a/packages/themes/src/tokens.js
+++ b/packages/themes/src/tokens.js
@@ -99,6 +99,8 @@ const colors = [
'hoverLightUI',
+ 'buttonSeparator',
+
'skeleton01',
'skeleton02',
@@ -233,6 +235,7 @@ export const unstable__meta = {
'hoverField',
'decorative01',
'hoverLightUI',
+ 'buttonSeparator',
],
},
],
diff --git a/packages/themes/src/v9.js b/packages/themes/src/v9.js
index 679c71e6e100..407e2469e488 100644
--- a/packages/themes/src/v9.js
+++ b/packages/themes/src/v9.js
@@ -94,6 +94,8 @@ export const decorative01 = '#EEF4FC';
export const hoverLightUI = '#EEF4FC';
+export const buttonSeparator = '#e0e0e0';
+
export const skeleton01 = 'rgba(61, 112, 178, .1)';
export const skeleton02 = 'rgba(61, 112, 178, .1)';
diff --git a/packages/themes/src/white.js b/packages/themes/src/white.js
index 45d58dc58450..b933910cdced 100644
--- a/packages/themes/src/white.js
+++ b/packages/themes/src/white.js
@@ -130,6 +130,8 @@ export const decorative01 = gray20;
export const hoverLightUI = '#e5e5e5';
+export const buttonSeparator = '#e0e0e0';
+
export const skeleton01 = '#e5e5e5';
export const skeleton02 = gray30;