Changes Toggle to MultiButtonToggle in an attempt to differentiate it from an upstream PF component. Altered props to be a bit more concise as well as support more than two buttons.

This commit is contained in:
mabashian 2020-03-02 11:22:18 -05:00
parent a997b40852
commit 1f0acef844
9 changed files with 83 additions and 78 deletions

View File

@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import { string, node, number } from 'prop-types';
import { Split, SplitItem, TextListItemVariants } from '@patternfly/react-core';
import { DetailName, DetailValue } from '@components/DetailList';
import Toggle from '@components/Toggle';
import MultiButtonToggle from '@components/MultiButtonToggle';
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
import CodeMirrorInput from './CodeMirrorInput';
import { JSON_MODE, YAML_MODE } from './constants';
@ -50,12 +50,9 @@ function VariablesDetail({ value, label, rows }) {
</div>
</SplitItem>
<SplitItem>
<Toggle
leftLabel="YAML"
leftMode={YAML_MODE}
rightLabel="JSON"
rightMode={JSON_MODE}
currentMode={mode}
<MultiButtonToggle
buttons={[[YAML_MODE, 'YAML'], [JSON_MODE, 'JSON']]}
currentValue={mode}
onChange={newMode => {
try {
setCurrentValue(getValueAsMode(currentValue, newMode));

View File

@ -31,12 +31,12 @@ describe('<VariablesDetail>', () => {
const wrapper = shallow(
<VariablesDetail value="---foo: bar" label="Variables" />
);
wrapper.find('Toggle').invoke('onChange')('javascript');
wrapper.find('MultiButtonToggle').invoke('onChange')('javascript');
const input = wrapper.find('Styled(CodeMirrorInput)');
expect(input.prop('mode')).toEqual('javascript');
expect(input.prop('value')).toEqual('{\n "foo": "bar"\n}');
wrapper.find('Toggle').invoke('onChange')('yaml');
wrapper.find('MultiButtonToggle').invoke('onChange')('yaml');
const input2 = wrapper.find('Styled(CodeMirrorInput)');
expect(input2.prop('mode')).toEqual('yaml');
expect(input2.prop('value')).toEqual('foo: bar\n');
@ -53,7 +53,7 @@ describe('<VariablesDetail>', () => {
<VariablesDetail value="---foo: bar" label="Variables" />
);
act(() => {
wrapper.find('Toggle').invoke('onChange')('javascript');
wrapper.find('MultiButtonToggle').invoke('onChange')('javascript');
});
wrapper.setProps({
value: '---bar: baz',
@ -73,7 +73,7 @@ describe('<VariablesDetail>', () => {
test('should default empty json to "{}"', () => {
const wrapper = mount(<VariablesDetail value="" label="Variables" />);
act(() => {
wrapper.find('Toggle').invoke('onChange')('javascript');
wrapper.find('MultiButtonToggle').invoke('onChange')('javascript');
});
wrapper.setProps({ value: '' });
const input = wrapper.find('Styled(CodeMirrorInput)');

View File

@ -6,7 +6,7 @@ import { useField } from 'formik';
import styled from 'styled-components';
import { Split, SplitItem } from '@patternfly/react-core';
import { CheckboxField } from '@components/FormField';
import Toggle from '@components/Toggle';
import MultiButtonToggle from '@components/MultiButtonToggle';
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
import CodeMirrorInput from './CodeMirrorInput';
import { JSON_MODE, YAML_MODE } from './constants';
@ -34,12 +34,9 @@ function VariablesField({ i18n, id, name, label, readOnly, promptId }) {
</label>
</SplitItem>
<SplitItem>
<Toggle
leftLabel="YAML"
leftMode={YAML_MODE}
rightLabel="JSON"
rightMode={JSON_MODE}
currentMode={mode}
<MultiButtonToggle
buttons={[[YAML_MODE, 'YAML'], [JSON_MODE, 'JSON']]}
currentValue={mode}
onChange={newMode => {
try {
const newVal =

View File

@ -3,7 +3,7 @@ import { string, func, bool, number } from 'prop-types';
import { Split, SplitItem } from '@patternfly/react-core';
import styled from 'styled-components';
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
import Toggle from '@components/Toggle';
import MultiButtonToggle from '@components/MultiButtonToggle';
import CodeMirrorInput from './CodeMirrorInput';
import { JSON_MODE, YAML_MODE } from './constants';
@ -42,12 +42,9 @@ function VariablesInput(props) {
</label>
</SplitItem>
<SplitItemRight>
<Toggle
leftLabel="YAML"
leftMode={YAML_MODE}
rightLabel="JSON"
rightMode={JSON_MODE}
currentMode={mode}
<MultiButtonToggle
buttons={[[YAML_MODE, 'YAML'], [JSON_MODE, 'JSON']]}
currentValue={mode}
onChange={newMode => {
try {
if (mode === JSON_MODE) {

View File

@ -0,0 +1,66 @@
import React from 'react';
import { func, string } from 'prop-types';
import styled from 'styled-components';
import { Button } from '@patternfly/react-core';
import ButtonGroup from './ButtonGroup';
const SmallButton = styled(Button)`
padding: 3px 8px;
font-size: var(--pf-global--FontSize--xs);
`;
function MultiButtonToggle({ buttons, currentValue, onChange }) {
const setValue = newValue => {
if (currentValue !== newValue) {
onChange(newValue);
}
};
return (
<ButtonGroup>
{buttons.map(([value, label]) => (
<SmallButton
key={label}
onClick={() => setValue(value)}
variant={currentValue === value ? 'primary' : 'secondary'}
>
{label}
</SmallButton>
))}
</ButtonGroup>
);
}
const buttonsPropType = {
isRequired: ({ buttons }) => {
if (!buttons) {
return new Error(
`The prop buttons is marked as required in MultiButtonToggle, but its value is '${buttons}'`
);
}
// We expect this data structure to look like:
// [[value(unrestricted type), label(string)], [value(unrestricted type), label(string)], ...]
if (
!Array.isArray(buttons) ||
buttons.length < 2 ||
buttons.reduce(
(prevVal, button) => prevVal || typeof button[1] !== 'string',
false
)
) {
return new Error(
`Invalid prop buttons supplied to MultiButtonToggle. Validation failed.`
);
}
return null;
},
};
MultiButtonToggle.propTypes = {
buttons: buttonsPropType.isRequired,
currentValue: string.isRequired,
onChange: func.isRequired,
};
export default MultiButtonToggle;

View File

@ -0,0 +1 @@
export { default } from './MultiButtonToggle';

View File

@ -1,52 +0,0 @@
import React from 'react';
import { func, string } from 'prop-types';
import styled from 'styled-components';
import { Button } from '@patternfly/react-core';
import ButtonGroup from './ButtonGroup';
const SmallButton = styled(Button)`
padding: 3px 8px;
font-size: var(--pf-global--FontSize--xs);
`;
function Toggle({
leftLabel,
leftMode,
rightLabel,
rightMode,
currentMode,
onChange,
}) {
const setValue = newValue => {
if (currentMode !== newValue) {
onChange(newValue);
}
};
return (
<ButtonGroup>
<SmallButton
onClick={() => setValue(leftMode)}
variant={currentMode === leftMode ? 'primary' : 'secondary'}
>
{leftLabel}
</SmallButton>
<SmallButton
onClick={() => setValue(rightMode)}
variant={currentMode === rightMode ? 'primary' : 'secondary'}
>
{rightLabel}
</SmallButton>
</ButtonGroup>
);
}
Toggle.propTypes = {
leftLabel: string.isRequired,
leftMode: string.isRequired,
rightLabel: string.isRequired,
rightMode: string.isRequired,
currentMode: string.isRequired,
onChange: func.isRequired,
};
export default Toggle;

View File

@ -1 +0,0 @@
export { default } from './Toggle';