diff --git a/CHANGELOG.md b/CHANGELOG.md index ce9158d46..93e92d13e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ - Fix "Guidelines" documentation links rendering blank pages ([#1111](https://github.com/opensearch-project/oui/pull/1111)) - Fix bug in OuiButtonContent for showing info tooltip in icon-only buttons when hovered([#1160](https://github.com/opensearch-project/oui/pull/1160)) - Fix playground support check ([#1162](https://github.com/opensearch-project/oui/pull/1162)) +- Make a OuiSplitButton with no options present as a button ([#1208](https://github.com/opensearch-project/oui/pull/1208)) - Prevent collapsable button of a resizable from adding to the height when hidden ([#1241](https://github.com/opensearch-project/oui/pull/1241)) - Prevent action buttons of OuiDataGridCell from moving the content ([#1224](https://github.com/opensearch-project/oui/pull/1224)) - Fix vertical alignment and font weight of breadcrumbs that are buttons or links ([#1232](https://github.com/opensearch-project/oui/pull/1232)) diff --git a/src-docs/src/views/split_button/split_button_example.js b/src-docs/src/views/split_button/split_button_example.js index 69f0d89cd..66552a494 100644 --- a/src-docs/src/views/split_button/split_button_example.js +++ b/src-docs/src/views/split_button/split_button_example.js @@ -29,6 +29,15 @@ const splitButtonBasicSnippet = `Basic Split Button `; +import SplitButtonSimple from './split_button_simple'; +const splitButtonSimpleSource = require('!!raw-loader!./split_button_simple'); +const splitButtonSimpleHtml = renderToHtml(SplitButtonSimple); +const splitButtonSimpleSnippet = ` console.log("Primary clicked")} +>Simple Split Button +`; + import SplitButtonComplex from './split_button_complex'; const splitButtonComplexSource = require('!!raw-loader!./split_button_complex'); const splitButtonComplexHtml = renderToHtml(SplitButtonComplex); @@ -180,6 +189,30 @@ export const SplitButtonExample = { snippet: splitButtonBasicSnippet, demo: , }, + { + source: [ + { + type: GuideSectionTypes.JS, + code: splitButtonSimpleSource, + }, + { + type: GuideSectionTypes.HTML, + code: splitButtonSimpleHtml, + }, + ], + text: ( +
+

+ When no options are provided, SplitButton displays a simple Button + in it's place, even if other dropdown options are present (like + intiallyOpen) +

+
+ ), + props: { OuiSplitButton }, + snippet: splitButtonSimpleSnippet, + demo: , + }, { title: 'More complex', source: [ diff --git a/src-docs/src/views/split_button/split_button_simple.js b/src-docs/src/views/split_button/split_button_simple.js new file mode 100644 index 000000000..1e0a4149d --- /dev/null +++ b/src-docs/src/views/split_button/split_button_simple.js @@ -0,0 +1,18 @@ +/* + * copyright opensearch contributors + * spdx-license-identifier: apache-2.0 + */ + +import React from 'react'; + +import { OuiSplitButton } from '../../../../src/components'; + +export default () => { + const primaryClick = () => console.log('Primary clicked'); + + return ( + + Basic Split Button + + ); +}; diff --git a/src/components/split_button/__snapshots__/split_button.test.tsx.snap b/src/components/split_button/__snapshots__/split_button.test.tsx.snap index 3ef4d1321..b7fe6d03a 100644 --- a/src/components/split_button/__snapshots__/split_button.test.tsx.snap +++ b/src/components/split_button/__snapshots__/split_button.test.tsx.snap @@ -11,7 +11,7 @@ exports[`OuiSplitButton is rendered 1`] = ` class="ouiSplitButtonControl ouiSplitButtonColor--primary" > - @@ -64,6 +51,7 @@ exports[`OuiSplitButton onClick events selection list is opened on drop-down but - `; + +exports[`OuiSplitButton simple button display display simple button when options are blank 1`] = ` + + + Test + + } + className="ouiSplitButton" + closePopover={[Function]} + display="inlineBlock" + hasArrow={false} + isOpen={false} + ownFocus={false} + panelPaddingSize="none" + panelRef={[Function]} + > + +
+
+ +
+ + + + + +
+
+
+
+
+ + +`; + +exports[`OuiSplitButton simple button display ignore initiallyOpen when options are blank 1`] = ` + + + Test + + } + className="ouiSplitButton" + closePopover={[Function]} + display="inlineBlock" + hasArrow={false} + isOpen={false} + ownFocus={false} + panelPaddingSize="none" + panelRef={[Function]} + > + +
+
+ +
+ + + + + +
+
+
+
+
+
+
+`; diff --git a/src/components/split_button/__snapshots__/split_button_control.test.tsx.snap b/src/components/split_button/__snapshots__/split_button_control.test.tsx.snap index 46cd8059a..6c3ce1d5b 100644 --- a/src/components/split_button/__snapshots__/split_button_control.test.tsx.snap +++ b/src/components/split_button/__snapshots__/split_button_control.test.tsx.snap @@ -35,6 +35,28 @@ exports[`OuiSplitButtonControl is rendered 1`] = ` `; +exports[`OuiSplitButtonControl is rendered without dropdown 1`] = ` +
+ +
+`; + exports[`OuiSplitButtonControl props fullWidth is rendered 1`] = `
{ }); }); + describe('simple button display', () => { + test('display simple button when options are blank', () => { + const component = mount( + Test + ); + + expect(component.find('.ouiSplitButtonControl--dropdown')).toHaveLength( + 0 + ); + expect(component).toMatchSnapshot(); + }); + + test('ignore initiallyOpen when options are blank', () => { + const component = mount( + + Test + + ); + + expect(component.find('.ouiSplitButton__listbox')).toHaveLength(0); + expect(component).toMatchSnapshot(); + }); + }); + describe('onClick events', () => { test('selection list is opened on drop-down button click', async () => { const component = mount( diff --git a/src/components/split_button/split_button.tsx b/src/components/split_button/split_button.tsx index 860c52dc1..4dde8b2b4 100644 --- a/src/components/split_button/split_button.tsx +++ b/src/components/split_button/split_button.tsx @@ -111,8 +111,9 @@ export const OuiSplitButton = ({ buttonProps, ...rest }: OuiSplitButtonProps) => { + const displayDropdown = options.length > 0; const itemNodes: Array = useMemo(() => [], []); - const [isOpen, setIsOpen] = useState(!!initiallyOpen); + const [isOpen, setIsOpen] = useState(!!initiallyOpen && displayDropdown); const [panelEl, setPanelEl] = useState(null); const panelRef = (node: HTMLElement | null) => setPanelEl(node); @@ -239,6 +240,7 @@ export const OuiSplitButton = ({ const button = ( setIsOpen(!isOpen)} onClick={onPrimaryClick} diff --git a/src/components/split_button/split_button_control.test.tsx b/src/components/split_button/split_button_control.test.tsx index 411cad513..3797812d3 100644 --- a/src/components/split_button/split_button_control.test.tsx +++ b/src/components/split_button/split_button_control.test.tsx @@ -18,6 +18,24 @@ describe('OuiSplitButtonControl', () => { expect(component).toMatchSnapshot(); }); + test('is rendered without dropdown', () => { + const component = render( + + Test + + ); + + expect(component.find('.ouiSplitButtonControl--dropdown')).toHaveLength(0); + + expect( + component.find( + '.ouiSplitButtonControl--primary.ouiSplitButtonHairline--primary' + ) + ).toHaveLength(0); + + expect(component).toMatchSnapshot(); + }); + describe('props', () => { test('fullWidth is rendered', () => { const component = render( diff --git a/src/components/split_button/split_button_control.tsx b/src/components/split_button/split_button_control.tsx index b59b62797..c9b80a777 100644 --- a/src/components/split_button/split_button_control.tsx +++ b/src/components/split_button/split_button_control.tsx @@ -43,6 +43,12 @@ export interface OuiSplitButtonControlProps fill?: boolean; + /** + * Display dropdown button + * False renders SplitButton as a simple Button. + */ + displayDropdown?: boolean; + /** * Color of buttons and options */ @@ -88,6 +94,7 @@ export interface OuiSplitButtonControlProps export const OuiSplitButtonControl: FunctionComponent< OuiSplitButtonControlProps & OuiSplitButtonActionProps > = ({ + displayDropdown = true, fill, size, color = 'primary', @@ -115,9 +122,11 @@ export const OuiSplitButtonControl: FunctionComponent< const primaryButtonClasses = classNames( 'ouiSplitButtonControl', 'ouiSplitButtonControl--primary', - color && `ouiSplitButtonHairline${colorToClassNameMap[color]}`, - disabled && 'ouiSplitButtonHairline--isDisabled', - fill && 'ouiSplitButtonHairline--filled' + color && + displayDropdown && + `ouiSplitButtonHairline${colorToClassNameMap[color]}`, + disabled && displayDropdown && 'ouiSplitButtonHairline--isDisabled', + fill && displayDropdown && 'ouiSplitButtonHairline--filled' ); const actionProps = { @@ -141,22 +150,24 @@ export const OuiSplitButtonControl: FunctionComponent< {...buttonProps}> {children} - + {displayDropdown && ( + + )}
); };