From 49e42eb2314cef6a10fa1dd708c39d2c0c9b8ed9 Mon Sep 17 00:00:00 2001 From: Neil Arya Date: Sat, 14 Oct 2023 14:50:54 +0530 Subject: [PATCH] Placeholder added in select & props structure set to standard --- package.json | 2 +- src/lib/components/select/index.tsx | 34 +++++++++++---- src/lib/components/select/multi.tsx | 62 ++++++++++++++++++---------- src/pages/docs/multiSelect/index.tsx | 2 +- src/pages/docs/select/index.tsx | 9 +--- src/pages/home/showcases.tsx | 4 +- 6 files changed, 73 insertions(+), 40 deletions(-) diff --git a/package.json b/package.json index d2f3fa6b..6a28cda6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "mumpui", "description": "A light-weight flexible & elegant design system for developers.", - "version": "1.3.0", + "version": "1.4.0", "main": "dist/index.js", "author": "neilveil", "repository": "neilveil/mumpui", diff --git a/src/lib/components/select/index.tsx b/src/lib/components/select/index.tsx index 3fcb4f65..ae74cee5 100644 --- a/src/lib/components/select/index.tsx +++ b/src/lib/components/select/index.tsx @@ -3,6 +3,7 @@ import React, { useEffect, useRef, useState } from 'react' import { default as Multi } from './multi' import { default as Native } from './native' import { default as search } from './search' +import Placeholder from '../placeholder' export type option = { key: string @@ -12,8 +13,8 @@ export type option = { type props = Omit, 'onChange' | 'value'> & { options?: option[] - value?: option - onChange?: (value?: option) => void + value?: string + onChange?: (value: string) => void onSearch?: (search: string) => void simpleSearch?: boolean placeholder?: any @@ -50,14 +51,22 @@ export default function Main({ if (ref.current && !ref.current.contains(e.target)) setOptionsVisible(false) } + const keyListener = (e: any) => { + if (e.key === 'Escape') setOptionsVisible(false) + } + useEffect(() => { window.addEventListener('click', clickListener) - return () => window.removeEventListener('click', clickListener) + window.addEventListener('keyup', keyListener) + return () => { + window.removeEventListener('click', clickListener) + window.removeEventListener('keyup', keyListener) + } }, []) const _onSelect = (selected: option) => { if (onSearch) onSearch('') - if (onChange) onChange(selected) + if (onChange) onChange(selected.key) setOptionsVisible(false) _setSearch('') } @@ -67,7 +76,9 @@ export default function Main({ if (simpleSearch) _setSearch(search) } - if (value) options = options.filter(x => value.key !== x.key) + const selectedOptions = options.find(x => x.key === value) + + if (value) options = options.filter(x => value !== x.key) if (_search) options = search(_search, options) @@ -79,9 +90,9 @@ export default function Main({ className={className} onClick={() => !disabled && setOptionsVisible(!optionsVisible)} > -
{value ? valueHOC(value) : placeholder}
+
{selectedOptions ? valueHOC(selectedOptions) : placeholder}
- {optionsVisible && !!(options.length || onSearch || simpleSearch) && ( + {optionsVisible && (
{!!(onSearch || simpleSearch || clearable) && (
_setSearch('')} + value={_search} autoFocus /> ) : ( @@ -109,7 +121,7 @@ export default function Main({ )} {!!clearable && ( -
!!onChange && onChange()}> +
!!onChange && onChange('')}> Clear
)} @@ -128,6 +140,12 @@ export default function Main({ {optionHOC(x)}
))} + + {!options.length && ( +
_setSearch('')} style={{ display: 'flex', justifyContent: 'center' }}> + +
+ )}
)}
diff --git a/src/lib/components/select/multi.tsx b/src/lib/components/select/multi.tsx index fe128ba9..2a4ead97 100644 --- a/src/lib/components/select/multi.tsx +++ b/src/lib/components/select/multi.tsx @@ -1,11 +1,12 @@ import React, { useEffect, useRef, useState } from 'react' import { type option } from '.' import search from './search' +import Placeholder from '../placeholder' type multiple = Omit, 'onChange' | 'value'> & { options?: option[] - value?: option[] - onChange?: (value: option[]) => void + value?: string[] + onChange?: (value: string[]) => void onSearch?: (search: string) => void simpleSearch?: boolean placeholder?: any @@ -41,14 +42,22 @@ export default function Main({ if (ref.current && !ref.current.contains(e.target)) setOptionsVisible(false) } + const keyListener = (e: any) => { + if (e.key === 'Escape') setOptionsVisible(false) + } + useEffect(() => { window.addEventListener('click', clickListener) - return () => window.removeEventListener('click', clickListener) + window.addEventListener('keyup', keyListener) + return () => { + window.removeEventListener('click', clickListener) + window.removeEventListener('keyup', keyListener) + } }, []) const _onChange = (selected: option) => { if (onSearch) onSearch('') - if (onChange) onChange(value.concat(selected)) + if (onChange) onChange(value.concat(selected.key)) _setSearch('') const inputEl = ref.current.querySelector('input') @@ -63,23 +72,27 @@ export default function Main({ if (simpleSearch) _setSearch(search) } - const selectedKey = value.map(x => x.key) - - const valueEl = value.map((x, i) => ( -
- {x.label} - { - if (disabled) return - e.stopPropagation() - if (onChange) onChange(value.filter(y => y.key !== x.key)) - }} - /> -
- )) + const valueEl = value.map((x, i) => { + const option = options.find(y => y.key === x) + + if (!option) return null - options = options.filter(x => !selectedKey.includes(x.key)) + return ( +
+ {option.label} + { + if (disabled) return + e.stopPropagation() + if (onChange) onChange(value.filter(y => y !== x)) + }} + /> +
+ ) + }) + + options = options.filter(x => !value.includes(x.key)) if (_search) options = search(_search, options) @@ -93,7 +106,7 @@ export default function Main({ >
{value.length ? valueEl : placeholder}
- {optionsVisible && !!(options.length || onSearch || simpleSearch) && ( + {optionsVisible && (
{!!(onSearch || simpleSearch || clearable) && (
_setSearch('')} className='mp-select-search' + value={_search} autoFocus /> ) : ( @@ -140,6 +154,12 @@ export default function Main({ {optionHOC(x)}
))} + + {!options.length && ( +
_setSearch('')} style={{ display: 'flex', justifyContent: 'center' }}> + +
+ )}
)} diff --git a/src/pages/docs/multiSelect/index.tsx b/src/pages/docs/multiSelect/index.tsx index e0042d68..f5c52577 100644 --- a/src/pages/docs/multiSelect/index.tsx +++ b/src/pages/docs/multiSelect/index.tsx @@ -5,7 +5,7 @@ import * as snippets from './snippets' import data from 'data' export default function Main() { - const [value, setValue] = useState([data.countries[0]]) + const [value, setValue] = useState([data.countries[0].key]) return ( diff --git a/src/pages/docs/select/index.tsx b/src/pages/docs/select/index.tsx index d46507e5..364f4eb1 100644 --- a/src/pages/docs/select/index.tsx +++ b/src/pages/docs/select/index.tsx @@ -5,8 +5,7 @@ import * as snippets from './snippets' import data from 'data' export default function Main() { - const [value, setValue] = useState<(typeof data.countries)[0] | undefined>(data.countries[0]) - const [valueNative, setValueNative] = useState('india') + const [value, setValue] = useState('india') return ( @@ -53,11 +52,7 @@ export default function Main() { - setValueNative(valueNative)} - /> + setValue(valueNative)} /> diff --git a/src/pages/home/showcases.tsx b/src/pages/home/showcases.tsx index 66439da9..67563c50 100644 --- a/src/pages/home/showcases.tsx +++ b/src/pages/home/showcases.tsx @@ -103,7 +103,7 @@ export default { select: { ...metagraph.select, Component() { - const [value, setValue] = useState<(typeof data.countries)[0] | undefined>(data.countries[0]) + const [value, setValue] = useState(data.countries[0].key) return