Skip to content

Commit

Permalink
feat(component): searchfield component with icons and center eye icon…
Browse files Browse the repository at this point in the history
… in passwordfield
  • Loading branch information
Lahuen Garcia committed Sep 26, 2024
1 parent 055430a commit 4010e1a
Show file tree
Hide file tree
Showing 16 changed files with 332 additions and 138 deletions.
2 changes: 1 addition & 1 deletion packages/components/assets/icons/cross-close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 1 addition & 14 deletions packages/components/assets/icons/eye.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72 changes: 49 additions & 23 deletions packages/components/src/FieldInput/FieldInput.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState } from 'react'
import { Flex, Input, Text } from 'theme-ui'
import { Box, Flex, Input, Text } from 'theme-ui'

import { CharacterCount } from '../CharacterCount/CharacterCount'

Expand All @@ -14,6 +14,7 @@ export interface Props extends FieldProps {
showCharacterCount?: boolean
'data-cy'?: string
customOnBlur?: (event: any) => void
endAdornment?: any
}

type InputModifiers = {
Expand Down Expand Up @@ -44,37 +45,62 @@ export const FieldInput = ({
showCharacterCount,
minLength,
maxLength,
endAdornment,
...rest
}: Props) => {
const [curLength, setLength] = useState<number>(input?.value?.length ?? 0)

const InputElement = (
<Input
disabled={disabled}
variant={meta?.error && meta?.touched ? 'textareaError' : 'textarea'}
{...input}
{...rest}
minLength={minLength}
maxLength={maxLength}
onBlur={(e) => {
if (modifiers) {
e.target.value = processInputModifiers(e.target.value, modifiers)
input.onChange(e)
}
if (customOnBlur) {
customOnBlur(e)
}
input.onBlur()
}}
onChange={(ev) => {
showCharacterCount && setLength(ev.target.value.length)
input.onChange(ev)
}}
/>
)

return (
<Flex sx={{ flexDirection: 'column', flex: 1, gap: 1 }}>
{meta.error && meta.touched && (
<Text sx={{ fontSize: 1, color: 'error' }}>{meta.error}</Text>
)}
<Input
disabled={disabled}
variant={meta?.error && meta?.touched ? 'textareaError' : 'textarea'}
{...input}
{...rest}
minLength={minLength}
maxLength={maxLength}
onBlur={(e) => {
if (modifiers) {
e.target.value = processInputModifiers(e.target.value, modifiers)
input.onChange(e)
}
if (customOnBlur) {
customOnBlur(e)
}
input.onBlur()
}}
onChange={(ev) => {
showCharacterCount && setLength(ev.target.value.length)
input.onChange(ev)
}}
/>
{endAdornment ? (
<Box
style={{
display: 'flex',
alignItems: 'center',
position: 'relative',
}}
>
{InputElement}
<Box
sx={{
position: 'absolute',
right: 2,
}}
>
{endAdornment}
</Box>
</Box>
) : (
InputElement
)}
{showCharacterCount && maxLength && (
<CharacterCount
currentSize={curLength}
Expand Down
1 change: 1 addition & 0 deletions packages/components/src/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export const glyphs: IGlyphs = {
view: iconMap.view,
volunteer: iconMap.volunteer,
website: iconMap.website,
search: iconMap.search,
}

export type Props = IProps & VerticalAlignProps & SpaceProps
Expand Down
2 changes: 2 additions & 0 deletions packages/components/src/Icon/svgs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import bazarSVG from '../../assets/icons/icon-bazar.svg'
import commentSVG from '../../assets/icons/icon-comment.svg'
import discordSVG from '../../assets/icons/icon-discord.svg'
import emailOutlineSVG from '../../assets/icons/icon-email.svg'
import searchSVG from '../../assets/icons/icon-search.svg'
import socialMediaSVG from '../../assets/icons/icon-social-media.svg'
import starActiveSVG from '../../assets/icons/icon-star-active.svg'
import starSVG from '../../assets/icons/icon-star-default.svg'
Expand Down Expand Up @@ -89,4 +90,5 @@ export const iconMap = {
view: <ImageIcon src={viewSVG} />,
volunteer: <ImageIcon src={volunteerSVG} />,
website: <ImageIcon src={websiteSVG} />,
search: <ImageIcon src={searchSVG} />,
}
1 change: 1 addition & 0 deletions packages/components/src/Icon/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,6 @@ export type availableGlyphs =
| 'view'
| 'volunteer'
| 'website'
| 'search'

export type IGlyphs = { [k in availableGlyphs]: JSX.Element }
29 changes: 17 additions & 12 deletions packages/components/src/OsmGeocoding/OsmGeocoding.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect, useRef, useState } from 'react'
import { Input } from 'theme-ui'
import { useDebouncedCallback } from 'use-debounce'

import { SearchField } from '../SearchField/SearchField'
import { OsmGeocodingLoader } from './OsmGeocodingLoader'
import { OsmGeocodingResultsList } from './OsmGeocodingResultsList'

Expand Down Expand Up @@ -94,16 +94,26 @@ export const OsmGeocoding = ({
ref={mainContainerRef}
style={{ width: '100%' }}
>
<Input
<SearchField
autoComplete="off"
type="search"
name="geocoding"
id="geocoding"
data-cy="osm-geocoding-input"
placeholder={placeholder}
dataCy="howtos-search-box"
placeHolder={placeholder}
value={searchValue}
style={{
width: '100%',
onChange={(value: string) => {
setQueryLocationService(true)
setSearchValue(value)
}}
onClickDelete={() => {
setSearchValue('')
setQueryLocationService(false)
}}
onClickSearch={() => {
setQueryLocationService(true)
setSearchValue(searchValue)
}}
additionalStyle={{
background: 'white',
fontFamily: 'Varela Round',
fontSize: '14px',
Expand All @@ -114,11 +124,6 @@ export const OsmGeocoding = ({
showResultsListing || showLoader ? '5px 5px 0 0' : '5px',
marginBottom: 0,
}}
onClick={() => setShowResults(true)}
onChange={(event) => {
setQueryLocationService(true)
setSearchValue(event.target.value)
}}
/>
{showLoader && <OsmGeocodingLoader />}
{showResultsListing && (
Expand Down
25 changes: 25 additions & 0 deletions packages/components/src/SearchField/SearchField.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useState } from 'react'

import { SearchField } from './SearchField'

import type { Meta, StoryFn } from '@storybook/react'

export default {
title: 'Forms/SearchField',
component: SearchField,
} as Meta<typeof SearchField>

export const Default: StoryFn<typeof SearchField> = () => {
const [searchValue, setSearchValue] = useState<string>('')

return (
<SearchField
dataCy="default-search-box"
placeHolder="Default search"
value={searchValue}
onChange={(value: string) => setSearchValue(value)}
onClickDelete={() => setSearchValue('')}
onClickSearch={() => {}}
/>
)
}
96 changes: 96 additions & 0 deletions packages/components/src/SearchField/SearchField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Box, Input } from 'theme-ui'

import { Icon } from '../Icon/Icon'

import type { ThemeUIStyleObject } from 'theme-ui'

export type Props = {
autoComplete?: string
name?: string
id?: string
dataCy: string
placeHolder: string
value: string
onChange: (value: string) => void
onClickDelete: () => void
onClickSearch: () => void
additionalStyle?: ThemeUIStyleObject
}

export const SearchField = (props: Props) => {
const {
autoComplete = 'on',
name = 'rand-name',
id = 'rand-id',
dataCy,
placeHolder,
value,
onChange,
onClickDelete,
onClickSearch,
additionalStyle = {},
} = props

return (
<Box
sx={{
position: 'relative',
width: '100%',
display: 'flex',
alignItems: 'center',
}}
>
<Input
autoComplete={autoComplete}
name={name}
id={id}
variant="inputOutline"
type="search"
data-cy={dataCy}
placeholder={placeHolder}
value={value}
onChange={(e) => onChange(e.target.value)}
sx={{
paddingRight: 11,
'::-webkit-search-cancel-button': {
display: 'none',
},
'::-ms-clear': {
display: 'none',
},
...additionalStyle,
}}
/>
<Box
sx={{
right: 2,
position: 'absolute',
display: 'flex',
alignItems: 'center',
}}
>
{value && (
<Icon
sx={{
display: 'flex',
alignItems: 'center',
marginRight: 1,
}}
glyph="close"
onClick={onClickDelete}
size="17"
/>
)}
<Icon
sx={{
display: 'flex',
alignItems: 'center',
}}
glyph="search"
onClick={onClickSearch}
size="19"
/>
</Box>
</Box>
)
}
3 changes: 1 addition & 2 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export { OsmGeocoding } from './OsmGeocoding/OsmGeocoding'
export { PinProfile } from './PinProfile/PinProfile'
export { ProfileLink } from './ProfileLink/ProfileLink'
export { ResearchEditorOverview } from './ResearchEditorOverview/ResearchEditorOverview'
export { SearchField } from './SearchField/SearchField'
export { Select } from './Select/Select'
export { SettingsFormWrapper } from './SettingsFormWrapper/SettingsFormWrapper'
export { SiteFooter } from './SiteFooter/SiteFooter'
Expand All @@ -69,7 +70,5 @@ export { UserEngagementWrapper } from './UserEngagementWrapper/UserEngagementWra
export { Username } from './Username/Username'
export { UserStatistics } from './UserStatistics/UserStatistics'
export { VideoPlayer } from './VideoPlayer/VideoPlayer'

// export { IImageGalleryItem } from './ImageGallery/ImageGallery'
export type { availableGlyphs } from './Icon/types'
export type { ITab } from './SettingsFormWrapper/SettingsFormTab'
5 changes: 4 additions & 1 deletion src/assets/icons/cross-close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 10 additions & 1 deletion src/assets/icons/icon-search.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 4010e1a

Please sign in to comment.