Skip to content

Commit

Permalink
✨ iOS Select new collapse options (#483)
Browse files Browse the repository at this point in the history
* ♻️ CollapsiblePickerIOS animapte Picker method

* ✨ animate picker on isCollapsed prop

animate when component will receive locals.isCollapsed

* ✨ set Animated start value depending on isCollapsed

* ✨ add isCollapsed to get locals in Select Component

* ✅ tests for Select:isCollapes

* 🐛 use this for class methods

* ✅ test for Select:onCollapse

* 🎨 rename callback onCollapse => onCollapseChange

* 🎨 rename collapse method for Select

* ✨ trigger onCollapseChange callback, when collapse change

* 🎨 rename method collapsePicker to togglePicker

* 🎨 extract animatePicker method from togglePicker

use it in componentWillReceiveProps

* 📝 updating readme

add options description for isCollapsed and onCollapsedChange

* 🚨 removed lint warning with lint --fix

* 🐛 use old isCollapsed state on update, when option not set
  • Loading branch information
lukaszgoworko authored and alvaromb committed May 25, 2018
1 parent c89a85d commit d711ecc
Show file tree
Hide file tree
Showing 5 changed files with 1,208 additions and 592 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,36 @@ var options = {
};
```

### Options isCollapsed

You can determinate if Select is collapsed:

```js
var options = {
fields: {
gender: {
isCollapsed: false // default: true
}
}
};
```

If option not set, default is `true`

### Options onCollapseChange

You can set a callback, triggered, when collapse change:

```js
var options = {
fields: {
gender: {
onCollapseChange: () => { console.log('collapse changed'); }
}
}
};
```

## DatePicker component

Implementation: `DatePickerIOS`
Expand Down
22 changes: 16 additions & 6 deletions lib/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ function getFormComponent(type, options) {
case "irreducible":
return type === t.Boolean
? Checkbox
: type === t.Date ? DatePicker : Textbox;
: type === t.Date
? DatePicker
: Textbox;
case "struct":
return Struct;
case "list":
Expand Down Expand Up @@ -203,8 +205,9 @@ class Component extends React.Component {
// getTemplate is the only required implementation when extending Component
t.assert(
t.Function.is(this.getTemplate),
`[${SOURCE}] missing getTemplate method of component ${this.constructor
.name}`
`[${SOURCE}] missing getTemplate method of component ${
this.constructor.name
}`
);
const template = this.getTemplate();
return template(locals);
Expand Down Expand Up @@ -372,9 +375,16 @@ class Select extends Component {
getLocals() {
const locals = super.getLocals();
locals.options = this.getOptions();
["help", "enabled", "mode", "prompt", "itemStyle"].forEach(
name => (locals[name] = this.props.options[name])
);

[
"help",
"enabled",
"mode",
"prompt",
"itemStyle",
"isCollapsed",
"onCollapseChange"
].forEach(name => (locals[name] = this.props.options[name]));

return locals;
}
Expand Down
86 changes: 59 additions & 27 deletions lib/templates/bootstrap/select.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,66 @@ const UIPICKER_HEIGHT = 216;
class CollapsiblePickerIOS extends React.Component {
constructor(props) {
super(props);
const isCollapsed =
typeof this.props.locals.isCollapsed === typeof true
? this.props.locals.isCollapsed
: true;

this.state = {
isCollapsed: true,
height: new Animated.Value(0)
isCollapsed,
height: new Animated.Value(isCollapsed ? 0 : UIPICKER_HEIGHT)
};
this.animatePicker = this.animatePicker.bind(this);
this.togglePicker = this.togglePicker.bind(this);
}

componentWillReceiveProps(props) {
const isCollapsed =
typeof props.locals.isCollapsed === typeof true
? props.locals.isCollapsed
: this.props.locals.isCollapsed;
if (isCollapsed !== this.state.isCollapsed) {
this.animatePicker(isCollapsed);
this.setState({ isCollapsed });
if (typeof props.locals.onCollapseChange === "function") {
props.locals.onCollapseChange(isCollapsed);
}
}
}

animatePicker(isCollapsed) {
const locals = this.props.locals;
let animation = Animated.timing;
let animationConfig = {
duration: 200
};
if (locals.config) {
if (locals.config.animation) {
animation = locals.config.animation;
}
if (locals.config.animationConfig) {
animationConfig = locals.config.animationConfig;
}
}

animation(
this.state.height,
Object.assign(
{
toValue: isCollapsed ? 0 : UIPICKER_HEIGHT
},
animationConfig
)
).start();
}

togglePicker() {
this.setState({ isCollapsed: !this.state.isCollapsed }, () => {
this.animatePicker(this.state.isCollapsed);
if (typeof this.props.locals.onCollapseChange === "function") {
this.props.locals.onCollapseChange(this.state.isCollapsed);
}
});
}

render() {
Expand All @@ -29,19 +85,6 @@ class CollapsiblePickerIOS extends React.Component {
pickerValue = stylesheet.pickerValue.error;
}

let animation = Animated.timing;
let animationConfig = {
duration: 200
};
if (locals.config) {
if (locals.config.animation) {
animation = locals.config.animation;
}
if (locals.config.animationConfig) {
animationConfig = locals.config.animationConfig;
}
}

const options = locals.options.map(({ value, text }) => (
<Picker.Item key={value} value={value} label={text} />
));
Expand All @@ -62,18 +105,7 @@ class CollapsiblePickerIOS extends React.Component {
touchableStyle,
this.state.isCollapsed ? {} : touchableStyleActive
]}
onPress={() => {
animation(
this.state.height,
Object.assign(
{
toValue: this.state.isCollapsed ? UIPICKER_HEIGHT : 0
},
animationConfig
)
).start();
this.setState({ isCollapsed: !this.state.isCollapsed });
}}
onPress={this.togglePicker}
>
<Text style={pickerValue}>{selectedOption.text}</Text>
</TouchableOpacity>
Expand Down
Loading

0 comments on commit d711ecc

Please sign in to comment.