Skip to content

Commit 34930bb

Browse files
committed
fix(pf4): replace react-select with downshift
1 parent 0aa9b98 commit 34930bb

File tree

10 files changed

+223
-234
lines changed

10 files changed

+223
-234
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import componentTypes from '@data-driven-forms/react-form-renderer/dist/cjs/component-types';
2+
3+
const options = [
4+
{
5+
label: 'Morton',
6+
value: 'Jenifer'
7+
},
8+
{
9+
label: 'Vega',
10+
value: 'Cervantes'
11+
},
12+
{
13+
label: 'Gilbert',
14+
value: 'Wallace'
15+
},
16+
{
17+
label: 'Jami',
18+
value: 'Cecilia'
19+
},
20+
{
21+
label: 'Ebony',
22+
value: 'Kay'
23+
}
24+
];
25+
26+
const selectSchema = {
27+
fields: [
28+
{
29+
component: componentTypes.SELECT,
30+
name: 'simple-select',
31+
label: 'Simple-select',
32+
options
33+
}
34+
]
35+
};
36+
37+
export default selectSchema;

packages/pf4-component-mapper/demo/index.js

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import FormRenderer from '@data-driven-forms/react-form-renderer';
55
import miqSchema from './demo-schemas/miq-schema';
66
import { uiArraySchema, arraySchema, array1Schema, schema, uiSchema, conditionalSchema, arraySchemaDDF } from './demo-schemas/widget-schema';
77
import { componentMapper, FormTemplate } from '../src';
8-
import { Title, Button, Toolbar, ToolbarGroup } from '@patternfly/react-core';
8+
import { Title, Button, Toolbar, ToolbarGroup, ToolbarItem } from '@patternfly/react-core';
99
import { wizardSchema, wizardSchemaWithFunction, wizardSchemaSimple, wizardSchemaSubsteps, wizardSchemaMoreSubsteps } from './demo-schemas/wizard-schema';
1010
import sandboxSchema from './demo-schemas/sandbox';
1111
import dualSchema from './demo-schemas/dual-list-schema';
1212
import demoSchema from '@data-driven-forms/common/src/demoschema';
13+
import selectSchema from './demo-schemas/select-schema';
1314

1415
const Summary = props => <div>Custom summary component.</div>;
1516

@@ -23,7 +24,7 @@ const fieldArrayState = { schema: arraySchemaDDF, additionalOptions: {
2324
class App extends React.Component {
2425
constructor(props) {
2526
super(props);
26-
this.state = fieldArrayState
27+
this.state = {schema: selectSchema, additionalOptions: {}}
2728
}
2829

2930
render() {
@@ -32,19 +33,24 @@ class App extends React.Component {
3233
<Title headingLevel="h2" size="4xl">Pf4 component mapper</Title>
3334
<Toolbar style={{ marginBottom: 20, marginTop: 20 }}>
3435
<ToolbarGroup>
35-
<Button onClick={() => this.setState(state => ({ schema: wizardSchema, additionalOptions: { showFormControls: false, wizard: true } }))}>Wizard</Button>
36-
</ToolbarGroup>
37-
<ToolbarGroup>
38-
<Button onClick={() => this.setState(state => fieldArrayState)}>arraySchema</Button>
39-
</ToolbarGroup>
40-
<ToolbarGroup>
41-
<Button onClick={() => this.setState(state => ({ schema: sandboxSchema, additionalOptions: {}}))}>Sandbox</Button>
42-
</ToolbarGroup>
43-
<ToolbarGroup>
44-
<Button onClick={() => this.setState(state => ({ schema: demoSchema, additionalOptions: {}}))}>Super schema</Button>
45-
</ToolbarGroup>
46-
<ToolbarGroup>
47-
<Button onClick={() => this.setState(state => ({ schema: dualSchema, additionalOptions: {} }))}>Dual List</Button>
36+
<ToolbarItem>
37+
<Button onClick={() => this.setState(state => ({schema: selectSchema, additionalOptions: {}}))}>select schema</Button>
38+
</ToolbarItem>
39+
<ToolbarItem>
40+
<Button onClick={() => this.setState(state => ({ schema: wizardSchema, additionalOptions: { showFormControls: false, wizard: true } }))}>Wizard</Button>
41+
</ToolbarItem>
42+
<ToolbarItem>
43+
<Button onClick={() => this.setState(state => fieldArrayState)}>arraySchema</Button>
44+
</ToolbarItem>
45+
<ToolbarItem>
46+
<Button onClick={() => this.setState(state => ({ schema: sandboxSchema, additionalOptions: {}}))}>Sandbox</Button>
47+
</ToolbarItem>
48+
<ToolbarItem>
49+
<Button onClick={() => this.setState(state => ({ schema: demoSchema, additionalOptions: {}}))}>Super schema</Button>
50+
</ToolbarItem>
51+
<ToolbarItem>
52+
<Button onClick={() => this.setState(state => ({ schema: dualSchema, additionalOptions: {} }))}>Dual List</Button>
53+
</ToolbarItem>
4854
</ToolbarGroup>
4955
</Toolbar>
5056
<FormRenderer

packages/pf4-component-mapper/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,8 @@
7878
"@patternfly/react-icons": "^4.3.5"
7979
},
8080
"dependencies": {
81-
"@patternfly/patternfly-next": "^1.0.175",
8281
"prop-types": "^15.7.2",
83-
"react-select": "^3.0.4"
82+
"downshift": "^5.4.3"
8483
},
8584
"postpublish": "export RELEASE_DEMO=true"
8685
}
Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,37 @@
11
import React from 'react';
2-
import { components } from 'react-select';
32
import PropTypes from 'prop-types';
43

5-
const Input = (props) => <components.Input {...props} />;
4+
import './input.scss';
65

7-
Input.propTypes = {
8-
selectProps: PropTypes.shape({
9-
isMulti: PropTypes.bool
10-
}).isRequired
6+
const getInputLabel = (value) => {
7+
if (!value) {
8+
return '';
9+
}
10+
11+
if (Array.isArray(value)) {
12+
return value.map((item) => (typeof item === 'object' ? item.label : item)).join(',');
13+
}
14+
15+
if (typeof value === 'object') {
16+
return value.label;
17+
}
18+
19+
return value;
1120
};
1221

22+
const Input = ({ value, inputRef, isSearchable, ...props }) => {
23+
return (
24+
<input
25+
{...props}
26+
{...(!isSearchable && { tabIndex: '-1' })}
27+
className="ddorg__pf4-component-mapper__select-input"
28+
value={getInputLabel(value)}
29+
onClick={console.log}
30+
ref={inputRef}
31+
/>
32+
);
33+
};
34+
35+
Input.propTypes = {};
36+
1337
export default Input;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.ddorg__pf4-component-mapper__select-input {
2+
border: none;
3+
flex: 1;
4+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react';
2+
import Option from './option';
3+
4+
const Menu = ({ options, getItemProps, highlightedIndex, selectedItem }) => {
5+
return (
6+
<ul className="pf-c-select__menu">
7+
{options.map((item, index) => {
8+
const itemProps = getItemProps({
9+
item,
10+
index,
11+
isActive: highlightedIndex === index,
12+
isSelected: selectedItem === item.value
13+
});
14+
return <Option key={item.value} item={item} {...itemProps} />;
15+
})}
16+
</ul>
17+
);
18+
};
19+
20+
export default Menu;
Lines changed: 16 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,27 @@
11
import React from 'react';
2-
import { components } from 'react-select';
32
import PropTypes from 'prop-types';
4-
import { Checkbox } from '@patternfly/react-core';
53

64
import { CheckIcon } from '@patternfly/react-icons';
75

8-
const Option = (props) => (
9-
<div className={`ddorg__pf4-component-mapper__select__menu--option ${props.isFocused ? 'focused' : ''} ${props.isDisabled ? 'disabled' : ''}`}>
10-
{props.selectProps && props.selectProps && props.selectProps.isCheckbox && (
11-
<Checkbox
12-
isChecked={props.isSelected || (props.data && props.data.selected) || false}
13-
onChange={() => props.selectOption(props.data)}
14-
id={`${props.innerProps && props.innerProps.id}-checkbox`}
15-
/>
16-
)}
17-
<components.Option {...props} />
18-
{props.isSelected && props.selectProps && !props.selectProps.isCheckbox && <CheckIcon size="sm" />}
19-
</div>
6+
const Option = ({ item, isActive, isSelected, ...props }) => (
7+
<li>
8+
<button {...props} className={`pf-c-select__menu-item${isSelected ? ' pf-m-selected' : ''}${isActive ? ' pf-m-focus' : ''}`}>
9+
{item.label}
10+
{isSelected && (
11+
<span className="pf-c-select__menu-item-icon">
12+
<CheckIcon />
13+
</span>
14+
)}
15+
</button>
16+
</li>
2017
);
2118

2219
Option.propTypes = {
23-
isFocused: PropTypes.bool,
24-
isSelected: PropTypes.bool,
25-
getStyles: PropTypes.func.isRequired,
26-
selectOption: PropTypes.func,
27-
cx: PropTypes.func.isRequired,
28-
data: PropTypes.shape({
29-
selected: PropTypes.bool
30-
}),
31-
innerProps: PropTypes.shape({
32-
id: PropTypes.string
33-
}),
34-
selectProps: PropTypes.shape({
35-
isCheckbox: PropTypes.bool
36-
}),
37-
isDisabled: PropTypes.bool
38-
};
39-
40-
Option.defaultProps = {
41-
isFocused: false,
42-
isSelected: false,
43-
isDisabled: false,
44-
selectOption: () => undefined,
45-
selectProps: {
46-
isCheckbox: false
47-
},
48-
innerProps: {
49-
id: 'some-classname'
50-
}
20+
item: PropTypes.shape({
21+
label: PropTypes.node
22+
}).isRequired,
23+
isActive: PropTypes.bool,
24+
isSelected: PropTypes.bool
5125
};
5226

5327
export default Option;

packages/pf4-component-mapper/src/common/select/select-styles.scss

Lines changed: 4 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -67,124 +67,8 @@
6767
* z-index of menu has to be > 400 to show over pf4-modal
6868
*/
6969

70-
.ddorg__pf4-component-mapper__select__menu {
71-
cursor: pointer;
72-
border-radius: 0 !important;
73-
z-index: 1000 !important;
74-
}
75-
76-
.ddorg__pf4-component-mapper__select__menu--option {
77-
display: flex;
78-
align-items: center;
79-
color: var(--pf-global--Color--dark-100);
80-
81-
&.focused {
82-
background-color: var(--pf-global--Color--light-200);
83-
}
84-
85-
svg {
86-
width: 0.6em;
87-
margin-right: 10px;
88-
fill: var(--pf-global--active-color--100);
89-
}
90-
91-
div.pf-c-check {
92-
padding-left: 1rem;
93-
& + .ddorg__pf4-component-mapper__select__option {
94-
padding-left: 0;
95-
}
96-
}
97-
98-
&.disabled {
99-
cursor: default;
100-
}
101-
102-
&.disabled div {
103-
color: var(--pf-global--disabled-color--100);
104-
pointer-events: none;
105-
cursor: none;
106-
}
107-
}
108-
109-
.ddorg__pf4-component-mapper__select__menu--option div {
110-
background: transparent;
111-
cursor: pointer;
112-
color: var(--pf-global--Color--300);
113-
}
114-
115-
.ddorg__pf4-component-mapper__select__single-value {
116-
padding-left: 8px;
117-
}
118-
119-
.ddorg__pf4-component-mapper__select__multivalue--container {
120-
display: flex;
121-
flex-direction: row;
122-
flex-wrap: nowrap;
123-
align-items: center;
124-
box-sizing: border-box;
125-
line-height: 24px;
126-
position: relative;
127-
margin-right: 4px;
128-
font-size: 12px;
129-
max-height: 26px;
130-
131-
> .ddorg__pf4-component-mapper__select__multivalue--remove {
132-
display: flex;
133-
134-
svg {
135-
fill: var(--pf-global--Color--400);
136-
}
137-
138-
> :hover {
139-
background: transparent;
140-
svg {
141-
fill: var(--pf-global--Color--dark-100);
142-
}
143-
}
144-
}
145-
146-
&::before {
147-
position: absolute;
148-
top: 0;
149-
right: 0;
150-
bottom: 0;
151-
left: 0;
152-
content: "";
153-
border: var(--pf-global--BorderWidth--sm) solid var(--pf-global--Color--dark-200);
154-
border-radius: 3px;
155-
pointer-events: none;
156-
}
157-
}
158-
159-
.ddorg__pf4-component-mapper__select__value--container {
70+
.ddorg__pf4-component-mapper__select-toggle-wrapper {
71+
flex: 1;
16072
display: flex;
161-
padding-left: 8px;
162-
align-items: center;
163-
flex-wrap: wrap;
164-
max-width: calc(100% - 70px);
165-
166-
.ddorg__pf4-component-mapper__select__multivalue--container {
167-
align-items: initial;
168-
.ddorg__pf4-component-mapper__select__multi-value__label {
169-
max-width: 240px;
170-
overflow: hidden;
171-
text-overflow: ellipsis;
172-
display: inline-block;
173-
}
174-
}
175-
176-
.ddorg__pf4-component-mapper__select__value--container-chipgroup {
177-
padding: 4px 6px;
178-
font-size: 12px;
179-
background-color: var(--pf-global--BorderColor--300);
180-
border: var(--pf-global--BorderWidth--sm) solid var(--pf-global--BorderColor--300);
181-
margin: 0;
182-
max-height: 26px;
183-
&:hover{
184-
border-color: var(--pf-global--Color--dark-100);
185-
}
186-
> span {
187-
color: var(--pf-global--Color--dark-100);
188-
}
189-
}
190-
}
73+
justify-content: flex-start;
74+
}

0 commit comments

Comments
 (0)