coding

React multi select component dengan fitur type to search

6 Syawal 1444 | 07 May 2022

Regga Rantai - Dapat meng-handle ribuan data dengan latency yg rendah synchronously..

Ada beberapa library yang keren-keren, namun terkadang kita memerlukan sesuatu yang tidak kita dapatkan dari library yang tersedia.. Saat tulisan ini dibuat, saya belum mendapatkan yang dapat meng-handle ribuan data tanpa nge-lag dan secara synchronous..

Memang bisa sih jika asynchronously, namun seperti kita ketahui tiap project memiliki requirements yang terkadang berbeda.. Oleh karena itu akhirnya saya buat sendiri dan sudah saya publish di npmjs.com/package/rr-multi-select.

1. Install

Jika kamu menggunakan yarn:
yarn add rr-multi-select

atau jika menggunakann npm:
npm install rr-multi-select

2. Cara penggunaan

Ini contoh penggunaan jika options-nya berupa simple array, dengan React Hook:

import React, {useState} from 'react'
import RRMultiSelect from 'rr-multi-select'

const options = [
  "Data 1",
  "Data 2",
  "Data 3"
]

const FormBlock = () => {

  const [value,setValue] = useState([])

  return (
    <RRMultiSelect
      options={options}
      value={value}
      onChange={setValue}
    />
  )
}
export default FormBlock

Jika ingin menggunakan label yang berbeda dengan value-nya, maka bisa menggunakan array of objects, dengan React Hook:

import React, {useState} from 'react'
import RRMultiSelect from 'rr-multi-select'

const options = [
  {value:"data1",label:"Data 1"},
  {value:"data2",label:"Data 2"},
  {value:"data3",label:"Data 3"}
]

const FormBlock = () => {

  const [value,setValue] = useState([])

  return (
    <RRMultiSelect
      options={options}
      isObject={["value","label"]}
      value={value}
      onChange={setValue}
    />
  )
}
export default FormBlock

Jika menggunakan React component class:

import React from 'react'
import RRMultiSelect from 'rr-multi-select'

export default class FormBlock extends React.Component {

  state = {
    options: [
      {value:"data1",label:"Data 1"},
      {value:"data2",label:"Data 2"},
      {value:"data3",label:"Data 3"}
    ],
    value: []
  }

  handleInputChange = d => {
    this.setState({value: d})
  }

  render() {
    return (
      <RRMultiSelect
        options={this.state.options}
        isObject={["value","label"]}
        value={this.state.value}
        onChange={this.handleInputChange}
      />
    )
  }
}
3. Props
NameDescription
optionsArray (required)
isObjectArray (required for array of objects options)
valueArray (required)
onChangeCallback function (required)
placeholderTextString, default: "Select..."
inputPlaceholderString, default: "Type to search..."

[1] options
Misal untuk simple array:

options={[
  'data1',
  'data2'
]}

atau untuk objects:

options={[
  {value:"data1",label:"Data 1"},
  {value:"data2",label:"Data 2"},
  {value:"data3",label:"Data 3"}
]}

isObject={["value","label"]}

“value” dan “label” bisa diganti, namun perlu disesuaikan dengan isObject

[2] isObject
Jika menggunakan array of objects, maka prop ini required.

index 0 adalah object prop name utk value
index 1 adalah object prop name utk label

misal:

isObject={["value","label"]}

jika kamu memiliki object prop name yang berbeda misal “nilai” dan “teks”:

options={[
  {nilai:"data1",teks:"Data 1"},
  {nilai:"data2",teks:"Data 2"},
  {nilai:"data3",teks:"Data 3"}
]}

isObject={["nilai","teks"]}

[3] value
Array kosong []

atau jika memiliki default value:

const options={[
  {value:"data1",label:"Data 1"},
  {value:"data2",label:"Data 2"},
  {value:"data3",label:"Data 3"}
]}

const [value,setValue] = useState([
  {value:"data2",label:"Data 2"}
])

return (
  <RRMultiSelect
    options={options}
    isObject={["value","label"]}
    value={value}
    onChange={setValue}
  />
)

[4] onChange
Function return selected value(s):

onChange={(v)=>{
  // v is selected value(s)
}}

[5] placeholderText
Jika kamu ingin menggantinya seperti “Pilih disini…” atau yang semisalnya..

placeholderText={"Pilih disini..."}

[6] inputPlaceholder
Jika kamu ingin menggantinya seperti “Ketik untuk memfilter…” atau yang semisalnya..

placeholderText={"Ketik untuk memfilter..."}
4. Styling

Untuk styling/css kamu bisa sesuaikan dengan kebutuhanmu menggunakan class name berikut ini:

.rrms {
  position:relative;
  font-size: 1em;
}
.rrms-field {
  display: table;
  width:100%;
  border: 1px solid #a3a3a3;
  min-height: 44px
}
.rrms-field > div {
  display: table-cell;
  vertical-align: middle;
  padding: 5px 10px;
  cursor: pointer;
}
.rrms-value > span {
  display: inline-block;
  background: linear-gradient(45deg, #6a7d5e, #3f6f26);
  padding: 2px 5px;
  margin: 2px;
  border-radius: 2px;
  color: #fff;
}
.rrms-icons {
  text-align: right;
  width: 15px;
}
ul.rrms-list {
  list-style: none;
  padding: 0;
  margin: 0;
  max-height:300px;
  overflow: auto
}
ul.rrms-list li {
  cursor: pointer;
  padding: 5px 10px;
  border-bottom: 1px solid rgb(0 0 0 / 10%)
}
ul.rrms-list li > div {
  position: relative;
  padding-left: 1.4em;
}
ul.rrms-list li > div::before {
  content: "";
  width: 0.73em;
  height: 0.73em;
  border: 1px solid;
  position: absolute;
  top: 0.125em;
  left: 0;
  font-size: 1.1em;
  border-radius: 2px;
}
ul.rrms-list li.a {
  background: linear-gradient(45deg, #6a7d5e, #3f6f26);
  color: #fff
}
ul.rrms-list li.a:hover {
  background: linear-gradient(45deg, #3f6f26, #6a7d5e);
  color: #ffffff;
}
ul.rrms-list li:hover {
  background: linear-gradient(45deg, #eeeeee, #aebda4)
}
ul.rrms-list li.a > div::before {
  background: #3e5731;
  border-color: #123102;
}
ul.rrms-list li.a > div::after {
  content: "✓";
  top: 0.02em;
  left: 0.07em;
  position: absolute;
  color: #fff;
  width: 0.73em;
  height: 0.73em;
  transform: scale(0.75);
}
.rrms-input {
  position:absolute;
  width:100%;
  top:0;
  left:0;
  border:1px solid #a3a3a3;
  background: #eee;
  box-shadow: 0 5px 20px -5px rgba(0,0,0,0.3);
  overflow:auto;
  z-index:9;
}
.rrms-input > input, .rrms-input > input:focus {
  padding: 5px 10px;
  width:100%;
  height: 30px;
  box-shadow: inset 0 0 10px rgb(0,0,0,0.25);
  border: 2px solid #4e9428;
  outline: none;
}
.rrms-caret {
  display: inline-block;
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 6px solid #a4a4a4;
  top: -2px;
  position: relative;
}

Untuk repository ada di:
https://github.com/reggarantai/rr-multi-select

Mudah-mudah ada manfaatnya ya..

Wassalaamu’alaikum..


Bagikan: WhatsApp

_ _ _

reggarantai

Posted by Regga | @reggarantai
Instagram  Facebook  Skype  Works

Post tags:
Post type:

Kutipan