Skip to content

Commit 3115dd1

Browse files
authored
feat: re-export Spectrum ButtonGroup (#2028)
- Added Spectrum ButtonGroup support to DH Button - Re-exported Spectrum ButtonGroup resolves #2016
1 parent 30d9d3c commit 3115dd1

84 files changed

Lines changed: 67 additions & 48 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/code-studio/src/styleguide/Buttons.tsx

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import React, { Component, ReactElement } from 'react';
2-
import { Button, SocketedButton, Flex } from '@deephaven/components';
2+
import {
3+
Button,
4+
SocketedButton,
5+
Flex,
6+
ButtonGroup,
7+
} from '@deephaven/components';
38

49
import { dhTruck } from '@deephaven/icons';
510
import SampleSection from './SampleSection';
@@ -17,7 +22,7 @@ class Buttons extends Component<Record<string, never>, ButtonsState> {
1722
<>
1823
<h5>Button Kinds</h5>
1924
<SampleSection name="buttons-regular" style={{ padding: '1rem 0' }}>
20-
<Flex gap="size-100">
25+
<ButtonGroup>
2126
<Button kind="primary" onClick={noOp}>
2227
Primary
2328
</Button>
@@ -39,7 +44,7 @@ class Buttons extends Component<Record<string, never>, ButtonsState> {
3944
<Button kind="ghost" onClick={noOp}>
4045
Ghost
4146
</Button>
42-
</Flex>
47+
</ButtonGroup>
4348
</SampleSection>
4449
</>
4550
);
@@ -74,41 +79,21 @@ class Buttons extends Component<Record<string, never>, ButtonsState> {
7479
return (
7580
<SampleSection name="buttons-socketed">
7681
<h5>Socketed Buttons (for linker)</h5>
77-
<SocketedButton
78-
style={{ marginBottom: '1rem', marginRight: '1rem' }}
79-
onClick={noOp}
80-
>
81-
Unlinked
82-
</SocketedButton>
83-
<SocketedButton
84-
style={{ marginBottom: '1rem', marginRight: '1rem' }}
85-
isLinked
86-
onClick={noOp}
87-
>
88-
Linked
89-
</SocketedButton>
90-
<SocketedButton
91-
style={{ marginBottom: '1rem', marginRight: '1rem' }}
92-
isLinkedSource
93-
onClick={noOp}
94-
>
95-
Linked Source
96-
</SocketedButton>
97-
<SocketedButton
98-
style={{ marginBottom: '1rem', marginRight: '1rem' }}
99-
isLinked
100-
isInvalid
101-
onClick={noOp}
102-
>
103-
Error
104-
</SocketedButton>
105-
<SocketedButton
106-
style={{ marginBottom: '1rem', marginRight: '1rem' }}
107-
disabled
108-
onClick={noOp}
109-
>
110-
Disabled
111-
</SocketedButton>
82+
<ButtonGroup marginBottom="1rem">
83+
<SocketedButton onClick={noOp}>Unlinked</SocketedButton>
84+
<SocketedButton isLinked onClick={noOp}>
85+
Linked
86+
</SocketedButton>
87+
<SocketedButton isLinkedSource onClick={noOp}>
88+
Linked Source
89+
</SocketedButton>
90+
<SocketedButton isLinked isInvalid onClick={noOp}>
91+
Error
92+
</SocketedButton>
93+
<SocketedButton disabled onClick={noOp}>
94+
Disabled
95+
</SocketedButton>
96+
</ButtonGroup>
11297
</SampleSection>
11398
);
11499
}

packages/components/src/Button.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import { useSlotProps } from '@react-spectrum/utils';
23
import PropTypes from 'prop-types';
34
import classNames from 'classnames';
45
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -83,7 +84,7 @@ function getVariantClasses(kind: VariantKind): string {
8384
}
8485
}
8586

86-
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
87+
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
8788
(props: ButtonProps, ref) => {
8889
const {
8990
kind,
@@ -109,6 +110,16 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
109110
...rest
110111
} = props;
111112

113+
// Spectrum container components such as `ButtonGroup` provide
114+
// UNSAFE_className prop for the `button` slot via a SlotProvider (
115+
// https://github.com/adobe/react-spectrum/blob/%40adobe/react-spectrum%403.33.1/packages/%40react-spectrum/buttongroup/src/ButtonGroup.tsx#L104-L107)
116+
// This can be retrieved via `useSlotProps` to allow our buttons to be styled
117+
// correctly inside the container.
118+
const { UNSAFE_className } = useSlotProps<{ UNSAFE_className?: string }>(
119+
{},
120+
'button'
121+
);
122+
112123
let variantClassName;
113124
if (variant) {
114125
variantClassName = getVariantClasses(variant);
@@ -157,7 +168,8 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
157168
btnClassName,
158169
variantClassName,
159170
{ active },
160-
className
171+
className,
172+
UNSAFE_className
161173
)}
162174
onClick={onClick}
163175
onContextMenu={onContextMenu}

packages/components/src/SocketedButton.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import React from 'react';
22
import classNames from 'classnames';
3-
import { dhExclamation, vsLink } from '@deephaven/icons';
43
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
4+
import { useSlotProps } from '@react-spectrum/utils';
5+
import { dhExclamation, vsLink } from '@deephaven/icons';
56

67
import './SocketedButton.scss';
78

@@ -36,6 +37,17 @@ const SocketedButton = React.forwardRef<HTMLButtonElement, SocketedButtonProps>(
3637
style,
3738
'data-testid': dataTestId,
3839
} = props;
40+
41+
// Spectrum container components such as `ButtonGroup` provide
42+
// UNSAFE_className prop for the `button` slot via a SlotProvider (
43+
// https://github.com/adobe/react-spectrum/blob/%40adobe/react-spectrum%403.33.1/packages/%40react-spectrum/buttongroup/src/ButtonGroup.tsx#L104-L107)
44+
// This can be retrieved via `useSlotProps` to allow our buttons to be styled
45+
// correctly inside the container.
46+
const { UNSAFE_className } = useSlotProps<{ UNSAFE_className?: string }>(
47+
{},
48+
'button'
49+
);
50+
3951
return (
4052
<button
4153
ref={ref}
@@ -48,7 +60,8 @@ const SocketedButton = React.forwardRef<HTMLButtonElement, SocketedButtonProps>(
4860
},
4961
{ 'btn-socketed-linked-source': isLinkedSource },
5062
{ 'is-invalid': isInvalid },
51-
className
63+
className,
64+
UNSAFE_className
5265
)}
5366
id={id}
5467
onClick={onClick}

packages/components/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export * from './actions';
33
export { default as AutoCompleteInput } from './AutoCompleteInput';
44
export { default as AutoResizeTextarea } from './AutoResizeTextarea';
55
export { default as BasicModal } from './BasicModal';
6-
export { default as Button } from './Button';
6+
export * from './Button';
77
export * from './BulkActionBar';
88
export { default as CardFlip } from './CardFlip';
99
export * from './context-actions';

packages/components/src/spectrum/buttons.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ export {
22
ActionButton,
33
type SpectrumActionButtonProps as ActionButtonProps,
44
// Button - we want to use our own `Button` component instead of Spectrum's
5-
// ButtonGroup - will re-export once our `Button` is compatible
5+
ButtonGroup,
6+
type SpectrumButtonGroupProps as ButtonGroupProps,
67
// FileTrigger - we aren't planning to support this component
78
LogicButton,
89
type SpectrumLogicButtonProps as LogicButtonProps,

packages/components/src/theme/theme-spectrum/theme-spectrum-overrides.css

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,25 @@ svg[class*='spectrum-Textfield-validationIcon'] {
6565
);
6666
}
6767

68-
button[class*='spectrum-Button'] {
68+
/**
69+
Adjust Spectrum button text and icon alignment to account for DH using a
70+
different font and smaller icons. Spectrum `ButtonGroup` will add additional
71+
`-spectrum-ButtonGroup` classes to child buttons (including DH ones), so we
72+
explicitly exclude our buttons from the selector.
73+
*/
74+
button[class*='spectrum-Button']:not(.btn):not(.btn-socketed) {
6975
/* make the icon closer to the text */
7076
--spectrum-button-primary-text-gap: var(--spectrum-global-dimension-size-75);
7177

7278
/* Center the text vertically. We use a different font then spectrum so we require different custom centering */
7379
padding-bottom: calc(var(--spectrum-global-dimension-size-50) - 1px);
7480
padding-top: calc(var(--spectrum-global-dimension-size-50));
7581
}
76-
77-
button[class*='spectrum-Button'] svg {
78-
/* our icons are smaller, center them too */
82+
button[class*='spectrum-Button']:not(.btn):not(.btn-socketed) svg {
83+
/*
84+
We use smaller icons than Spectrum, so we need to adjust the padding to
85+
center when we use our icons inside of Spectrum buttons.
86+
*/
7987
padding-bottom: var(--spectrum-global-dimension-size-25);
8088
}
8189

56 Bytes
10 Bytes
8 Bytes
52 Bytes

0 commit comments

Comments
 (0)