Skip to content

Instantly share code, notes, and snippets.

@Phoenix-GH
Created December 3, 2020 16:14
Show Gist options
  • Save Phoenix-GH/f1342c825b79d73cd88617aad7adda64 to your computer and use it in GitHub Desktop.
Save Phoenix-GH/f1342c825b79d73cd88617aad7adda64 to your computer and use it in GitHub Desktop.
GenericPickerStep
import * as React from "react";
import {Element} from "react-scroll/modules";
import {titleCase} from "../helpers/strings";
import {ICarouselItem} from "../models/ICarouselItem";
import leftArrow from '../assets/left-arrow-white.svg';
import rightArrow from '../assets/right-arrow-white.svg';
export const socialButtonSize = 40;
export interface IPickerProps {
id: string;
title: string;
subtitle?: string;
choices: ICarouselItem[];
selectedValues: string[];
onChange: (val: string[]) => void;
onCancel?: (e: any) => void;
onSubmit: () => void;
pickCount: number;
filterText?: string;
buttonColor?: string;
selectedButtonColor?: string;
showChoicesInitially: boolean;
}
export class GenericPickerStep extends React.Component<IPickerProps, {searchText: string, skip: number, take: number}> {
constructor(props: IPickerProps, context: any) {
super(props, context);
this.state = {searchText: '', skip: 0, take: 20};
}
public showPrev() {
this.setState({skip: this.state.skip - this.state.take});
}
public showMore() {
this.setState({skip: this.state.skip + this.state.take});
}
public selectedIndexOf(val: string): number {
const sv = this.props.selectedValues;
for (let i = 0; i < sv.length; i = i + 1) {
if (sv[i].toLowerCase() === val.toLowerCase()) {
return i;
}
}
return -1;
}
public select(e: any, val: string) {
e.preventDefault();
let selectedValues = this.props.selectedValues.slice(0);
const exist = this.selectedIndexOf(val);
if (exist > -1) {
// remove
selectedValues = selectedValues.filter((s) => s !== val);
} else {
// add
if (selectedValues.length >= this.props.pickCount) {
selectedValues.pop();
}
selectedValues.push(val);
}
this.props.onChange(selectedValues);
setTimeout(() => {
if (selectedValues.length >= this.props.pickCount) {
this.props.onSubmit();
} else {
this.setState({searchText: ''});
}
}, 50);
}
public render() {
const {id, title, subtitle, choices, selectedValues, onCancel, filterText, pickCount, showChoicesInitially, selectedButtonColor, buttonColor} = this.props;
if (pickCount < 1) {
return <div>Error: number should be at least 1.</div>;
}
if (typeof selectedValues.indexOf !== 'function') {
return <div>Typeof selectedValues is wrong: {(typeof selectedValues).toString()}</div>
}
const {skip, take, searchText} = this.state;
const showOptions = showChoicesInitially || (searchText || '').length > 0;
let searchResults = choices.slice(0);
searchResults = searchResults.filter((n) => {
return n.displayName.toLowerCase().startsWith(this.state.searchText.toLowerCase());
});
const resultCount = searchResults.length;
searchResults = searchResults.slice(skip, Math.min(skip + take, resultCount));
const rotate = {
transform: [{ rotate: '90deg'}]
};
return (
<Element name={id} className="step w-form">
<form className="form" id="step-2" onSubmit={(e) => {e.preventDefault();}}>
{onCancel && <div className="upward">
<button type="button" onClick={(e) => onCancel(e)}
className="social-button w-inline-block">
<img
src="https://uploads-ssl.webflow.com/5b9e87c40899a487ba8091e4/5b9e87c40899a46ffe809257_social-34-white.svg"
width={socialButtonSize}
alt="Up arrow (Go back)"
/>
</button>
</div>}
<h1 className="animated infinite pulse slower">{title}</h1>
{filterText && (
<input
type="search"
className="round-input w-input"
maxLength={256}
placeholder={filterText}
value={searchText}
onChange={(e) => this.setState({skip: 0, searchText: e.currentTarget.value})}
onClick={(e) => this.setState({skip: 0, searchText: ''})}
/>
)}
{showOptions && (
<div>
{subtitle && subtitle.length && <div className="label">{subtitle}</div>}
<div>
{searchResults.map((n) => (
<button
type="button"
key={n.apiName}
className={`button pill ${this.selectedIndexOf(n.apiName) !== -1 ? 'yellow' : ''} w-button`}
style={{
backgroundColor: this.selectedIndexOf(n.apiName) !== -1 ? (selectedButtonColor || '') : (buttonColor || '')
}}
onClick={(e) => this.select(e, n.apiName)}
>{(n.displayName)}</button>
))}
</div>
<div>
{skip > 0 && (
<button
type="button"
className="submit-pill w-button"
style={{
backgroundColor: 'transparent'
}}
onClick={() => this.showPrev()}
><img src={leftArrow} className="arrow" /></button>
)}
{resultCount > skip + take && (
<button
type="button"
className="submit-pill w-button"
style={{
backgroundColor: 'transparent'
}}
onClick={() => this.showMore()}
><img src={rightArrow} className="arrow" /></button>
)}
</div>
</div>
)}
</form>
</Element>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment