Skip to content

Commit

Permalink
Feat: 303 added closeOnClickInput support
Browse files Browse the repository at this point in the history
  • Loading branch information
musasahinkundakci committed Dec 7, 2023
1 parent 41ce2e0 commit 62d6383
Show file tree
Hide file tree
Showing 8 changed files with 358 additions and 262 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ const options = [
| valueField | string | "value" | Field in data to use for value |
| color | string | "#0074D9" | Base color to use in component, also can be overwritten via CSS |
| closeOnScroll | bool | false | If true, scrolling the page will close the dropdown |
| closeOnSelect | bool | false | If true, selecting option will close the dropdown |
| closeOnSelect | bool | false | If true, selecting option will close the dropdown
| closeOnClickInput | bool | false | If true, clicking input will close the dropdown if you are not searching. |
| [dropdownPosition](https://sanusart.github.io/react-dropdown-select/prop/dropdown-position) | string | "bottom" | Available options are "auto", "top" and "bottom" defaults to "bottom". Auto will adjust itself according Select's position on the page |
| keepSelectedInList | bool | true | If false, selected item will not appear in a list |
| portal | DOM element | false | If valid dom element specified - dropdown will break out to render inside the specified element |
Expand Down
13 changes: 13 additions & 0 deletions docs/src/pages/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export class Demo extends React.Component {
color: '#0074D9',
keepSelectedInList: true,
closeOnSelect: false,
closeOnClickInput: false,
dropdownPosition: 'bottom',
direction: 'ltr',
dropdownHeight: '300px'
Expand Down Expand Up @@ -198,6 +199,7 @@ export class Demo extends React.Component {
onChange={(values) => this.setValues(values)}
noDataLabel="No matches found"
closeOnSelect={this.state.closeOnSelect}
closeOnClickInput={this.state.closeOnClickInput}
noDataRenderer={this.state.noDataRenderer ? () => this.noDataRenderer() : undefined}
dropdownPosition={this.state.dropdownPosition}
itemRenderer={
Expand Down Expand Up @@ -385,6 +387,17 @@ export class Demo extends React.Component {
/>{' '}
Close dropdown on select/deselect
<br />
<input
type="checkbox"
checked={this.state.closeOnClickInput}
onChange={() =>
this.setState({
closeOnClickInput: !this.state.closeOnClickInput
})
}
/>{' '}
Close dropdown on click input
<br />
Custom color{' '}
<input
type="color"
Expand Down
14 changes: 13 additions & 1 deletion src/components/Content.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import Option from './Option';
import Input from './Input';
import { LIB_NAME } from '../constants';
import {getByPath} from '../util';
import SelectPropsModel from '../models/SelectPropsModel';
import SelectMethodsModel from '../models/SelectMethodsModel';
import SelectStateModel from '../models/SelectStateModel';

const Content = ({ props, state, methods }) => {
return (
Expand All @@ -14,7 +17,11 @@ const Content = ({ props, state, methods }) => {
}`}
onClick={(event) => {
event.stopPropagation();
methods.dropDown('open');
if (state.dropdown == true && props.closeOnClickInput && !state.search) {
return methods.dropDown('close');
} else {
return methods.dropDown('open');
}
}}>
{props.contentRenderer ? (
props.contentRenderer({ props, state, methods })
Expand All @@ -40,6 +47,11 @@ const Content = ({ props, state, methods }) => {
);
};

Content.propTypes = {
props: SelectPropsModel,
state: SelectStateModel,
methods: SelectMethodsModel,
};
const ContentComponent = styled.div`
display: flex;
flex: 1;
Expand Down
262 changes: 2 additions & 260 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import styled from '@emotion/styled';
import ClickOutside from './components/ClickOutside';

Expand All @@ -21,267 +20,10 @@ import {
isomorphicWindow
} from './util';
import { LIB_NAME } from './constants';
import SelectPropsModel from './models/SelectPropsModel';

export class Select extends Component {
static propTypes = {
/**
* Secondary placeholder on search field if any value selected
*/
addPlaceholder: PropTypes.string,
/**
* Additional props to pass to Select
*/
additionalProps: PropTypes.object,
/**
* If true, and searchable, dropdown will autofocus
*/
autoFocus: PropTypes.bool,
/**
* If true, backspace key will delete last value
*/
backspaceDelete: PropTypes.bool,
/**
* CSS class attribute to pass to select
*/
className: PropTypes.string,
/**
* Label for "Clear all"
*/
clearAllLabel: PropTypes.string,
/**
* If true, and searchable, search value will be cleared on blur
*/
clearOnBlur: PropTypes.bool,
/**
* If true, and searchable, search value will be cleared upon value select/de-select
*/
clearOnSelect: PropTypes.bool,
/**
* Overrides internal clear button
*/
clearRenderer: PropTypes.func,
/**
* Clear all indicator
*/
clearable: PropTypes.bool,
/**
* If true, scrolling the page will close the dropdown
*/
closeOnScroll: PropTypes.bool,
/**
* If true, selecting option will close the dropdown
*/
closeOnSelect: PropTypes.bool,
/**
* Base color (any css compatible) to use in component, also can be overwritten via CSS
*/
color: PropTypes.string,
/**
* Compare values override function
*/
compareValuesFunc: PropTypes.func,
/**
* Overrides internal content component (the contents of the select component)
* | <a href="https://sanusart.github.io/react-dropdown-select/prop/content-renderer">example</a>
*/
contentRenderer: PropTypes.func,
/**
* If true, select will create value from search string and fire onCreateNew callback prop
*/
create: PropTypes.bool,
/**
* If create set to true, this will be the label of the "add new" component. {search} will be replaced by search value
*/
createNewLabel: PropTypes.string,
/**
* Debounce Delay for updates upon component interactions
*/
debounceDelay: PropTypes.number,

/**
* Direction of a dropdown "ltr", "rtl" or "auto"
*/
direction: PropTypes.string,
/**
* Disable select and all interactions
*/
disabled: PropTypes.bool,
/**
* Label shown on disabled field (after) the text
*/
disabledLabel: PropTypes.string,
/**
* Gap between select element and dropdown
*/
dropdownGap: PropTypes.number,
/**
* Show or hide dropdown handle to open/close dropdown
*/
dropdownHandle: PropTypes.bool,
/**
* Overrides internal dropdown handle
*/
dropdownHandleRenderer: PropTypes.func,
/**
* Minimum height of a dropdown
*/
dropdownHeight: PropTypes.string,
/**
* Available options are "auto", "top" and "bottom" defaults to "bottom". Auto will adjust itself according Select's position on the page
* | <a href="https://sanusart.github.io/react-dropdown-select/prop/dropdown-position">example</a>
*/
dropdownPosition: PropTypes.oneOf(['top', 'bottom', 'auto']),
/**
* Overrides internal dropdown handle
*/
dropdownRenderer: PropTypes.func,
/**
* Overrides internal keyDown function
*/
handleKeyDownFn: PropTypes.func,
/**
* Overrides internal input text
*/
inputRenderer: PropTypes.func,
/**
* Overrides internal item in a dropdown
*/
itemRenderer: PropTypes.func,
/**
* If true, dropdown will always stay open (good for debugging)
*/
keepOpen: PropTypes.bool,
/**
* If false, selected item will not appear in a list
*/
keepSelectedInList: PropTypes.bool,
/**
* Field in data to use for label
*/
labelField: PropTypes.string,
/**
* Loading indicator
*/
loading: PropTypes.bool,
/**
* Overrides internal loading
*/
loadingRenderer: PropTypes.func,
/**
* If true - will act as multi-select, if false - only one option will be selected at the time
*/
multi: PropTypes.bool,
/**
* If set, input type hidden would be added in the component with the value of the `name` prop as `name` and select's `values` as `value`
* Useful for html forms
*/
name: PropTypes.string,
/**
* Label for "No data"
*/
noDataLabel: PropTypes.string,
/**
* Overrides internal "no data" (shown where search has no results)
*/
noDataRenderer: PropTypes.func,
/**
* onChange callback handler
*/
onChange: PropTypes.func.isRequired,
/**
* Fires upon clearing all values (via custom renderers)
*/
onClearAll: PropTypes.func,
/**
* Fires upon creation of new item if create prop set to true
*/
onCreateNew: PropTypes.func,
/**
* Fires upon dropdown close
*/
onDropdownClose: PropTypes.func,
/**
* Fires upon dropdown closing state, stops the closing and provides own method close()
* @return undefined
*/
onDropdownCloseRequest: PropTypes.func,
/**
* Fires upon dropdown open
*/
onDropdownOpen: PropTypes.func,
/**
* Fires upon selecting all values (via custom renderers)
*/
onSelectAll: PropTypes.func,
/**
* Overrides internal option (the pillow with an "x") on the select content
*/
optionRenderer: PropTypes.func,
/**
* Available options, (option with key disabled: true will be disabled)
*/
options: PropTypes.array.isRequired,
/**
* If set, input type hidden would be added in the component with pattern prop as regex
*/
pattern: PropTypes.string,
/**
* Placeholder shown where there are no selected values
*/
placeholder: PropTypes.string,
/**
* If valid dom element specified - dropdown will break out to render inside the specified element
*/
portal: PropTypes.element,
/**
* If set, input type hidden would be added in the component with required prop as true/false
*/
required: PropTypes.bool,
/**
* Search by object property in values
*/
searchBy: PropTypes.string,
/**
* Overrides internal search function
*/
searchFn: PropTypes.func,
/**
* If true, select will have search input text
*/
searchable: PropTypes.bool,
/**
* Allow to select all (if select is multi select)
*/
selectAll: PropTypes.bool,
/**
* Label for "Select all"
*/
selectAllLabel: PropTypes.string,
/**
* Separator line between close all and dropdown handle
*/
separator: PropTypes.bool,
/**
* Overrides internal separator
*/
separatorRenderer: PropTypes.func,
/**
* Sort by object property in values
*/
sortBy: PropTypes.string,
/**
* Style object to pass to select
*/
style: PropTypes.object,
/**
* Field in data to use for value
*/
valueField: PropTypes.string,
/**
* Selected values
*/
values: PropTypes.array
};
static propTypes = SelectPropsModel;

constructor(props) {
super(props);
Expand Down
42 changes: 42 additions & 0 deletions src/models/SelectMethodsModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

import PropTypes from 'prop-types';

const SelectMethodsModel = PropTypes.objectOf({
activeCursorItem: PropTypes.func,

addItem: PropTypes.func.isRequired,

areAllSelected: PropTypes.func.isRequired,

clearAll: PropTypes.func.isRequired,

createNew: PropTypes.func.isRequired,

dropDown: PropTypes.func.isRequired.isRequired,

getInputSize: PropTypes.func.isRequired.isRequired,

getSelectBounds: PropTypes.func.isRequired,

getSelectRef: PropTypes.func.isRequired,

handleKeyDown: PropTypes.func.isRequired,

isSelected: PropTypes.func.isRequired,

removeItem: PropTypes.func.isRequired,

safeString: PropTypes.func.isRequired,

searchResults: PropTypes.func.isRequired,

selectAll: PropTypes.func.isRequired,

setSearch: PropTypes.func.isRequired,

sortBy: PropTypes.func.isRequired,

toggleSelectAll: PropTypes.func.isRequired
})

export default SelectMethodsModel;
Loading

0 comments on commit 62d6383

Please sign in to comment.