-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add react-select #305
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
48dcbb7
feat: add react-select
Ariaspect c4211eb
feat(icon): add small close icon
Ariaspect 06e555f
feat: dropdown ui rework
Ariaspect 4ca3f66
refactor: move select to seperate file
Ariaspect 78710f8
refactor: mark label as legacy
Ariaspect 98bcf30
feat: tag selection onchange update
Ariaspect 0c5adfe
feat(select): no overlap and proper onchange
Ariaspect c77cac6
fix: minor import issue
Ariaspect 12a3480
feat(select): wrap tag select
Ariaspect fde3e42
chore(pnpm): update lockfile
Ariaspect 9a952c2
fix: onchange consistency on all modals
Ariaspect e19c5ff
fix: icon naming
Ariaspect 4fd2509
feat(css): select style tokenize
Ariaspect 01bb31a
fix: remove only old select
Ariaspect b2cce26
feat(css): custom component css tokenize
Ariaspect b5e4341
feat: cursor style
Ariaspect d0f5b77
Merge branch 'main' into feat/tag-multiselect-dropdown
SnowSuno File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import React from "react"; | ||
import { css } from "@emotion/react"; | ||
import { | ||
bg, | ||
round, | ||
row, | ||
justify, | ||
padding, | ||
text, | ||
w, | ||
h, | ||
align, | ||
border, | ||
} from "@/styles"; | ||
|
||
interface Tag { | ||
id: number; | ||
title: string; | ||
description: string; | ||
} | ||
|
||
interface Props { | ||
tag: Tag; | ||
selected: boolean; | ||
} | ||
|
||
const cursorPointer = css` | ||
cursor: pointer; | ||
`; | ||
|
||
export const PresetOption: React.FC<Props> = ({ tag, selected }) => ( | ||
<div | ||
css={[ | ||
row, | ||
justify.between, | ||
align.center, | ||
selected ? bg.blue100 : bg.white, | ||
w("fill"), | ||
h(30), | ||
round.md, | ||
padding.horizontal(10), | ||
cursorPointer, | ||
]} | ||
> | ||
<div | ||
css={[ | ||
align.center, | ||
border.gray200, | ||
round.md, | ||
padding.horizontal(6), | ||
padding.vertical(3), | ||
]} | ||
> | ||
<p css={[text.option2, text.gray500]}>{tag.title}</p> | ||
</div> | ||
<p css={[text.option1, selected ? text.gray600 : text.gray500]}> | ||
{tag.description} | ||
</p> | ||
</div> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,15 @@ | ||
import React from "react"; | ||
import { useUserTag } from "@/services/user-tag"; | ||
import { PositionedDownArrowIcon, SelectWrapper, TagSelect } from "./Label"; | ||
import { TagSelect } from "./TagSelect"; | ||
|
||
interface Props { | ||
selected: string[]; | ||
onChange: React.ChangeEventHandler<HTMLSelectElement>; | ||
onChange: (selection: string[]) => void; | ||
} | ||
|
||
export const SelectTagBox: React.FC<Props> = ({ selected, onChange }) => { | ||
export const SelectTagBox: React.FC<Props> = ({ onChange }) => { | ||
const { tags } = useUserTag(state => ({ | ||
tags: state.userTags, | ||
})); | ||
|
||
return ( | ||
<> | ||
<SelectWrapper> | ||
<TagSelect defaultValue={[]} onChange={onChange}> | ||
<option value="" disabled> | ||
태그를 선택하세요 | ||
</option> | ||
{tags.map(tag => ( | ||
<option key={tag.id} value={tag.title}> | ||
{tag.title} | ||
</option> | ||
))} | ||
</TagSelect> | ||
<PositionedDownArrowIcon /> | ||
</SelectWrapper> | ||
{selected.map(tag => ( | ||
<>{tag}</> | ||
))} | ||
</> | ||
); | ||
return <TagSelect tags={tags} onChange={onChange} />; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import React from "react"; | ||
import { css } from "@emotion/react"; | ||
import { CloseSmallIcon } from "@/assets"; | ||
|
||
import Select, { components } from "react-select"; | ||
import type { | ||
OptionProps, | ||
DropdownIndicatorProps, | ||
MultiValueGenericProps, | ||
MultiValueRemoveProps, | ||
} from "react-select"; | ||
|
||
import { | ||
bg, | ||
border, | ||
round, | ||
center, | ||
column, | ||
row, | ||
justify, | ||
margin, | ||
padding, | ||
gap, | ||
text, | ||
w, | ||
h, | ||
align, | ||
} from "@/styles"; | ||
|
||
import { PositionedDownArrowIcon } from "./Label"; | ||
import { PresetOption } from "./PresetOption"; | ||
|
||
interface Props { | ||
tags: Tag[]; | ||
onChange: (selection: string[]) => void; | ||
} | ||
|
||
interface Tag { | ||
id: number; | ||
title: string; | ||
description: string; | ||
} | ||
|
||
const cursorInitial = css` | ||
cursor: initial; | ||
`; | ||
const cursorPointer = css` | ||
cursor: pointer; | ||
`; | ||
const boxShadow = css` | ||
box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.06); | ||
`; | ||
|
||
const controlStyles = css([ | ||
center, | ||
w(300), | ||
h(38), | ||
padding.horizontal(10), | ||
justify.between, | ||
border.gray200, | ||
round.md, | ||
bg.gray100, | ||
text.subtitle, | ||
]); | ||
const placeholderStyles = css([text.subtitle, text.gray300, padding.left(5)]); | ||
const valueContainerStyles = css([row, gap(5)]); | ||
const menuListStyles = css([ | ||
column, | ||
gap(5), | ||
margin.top(5), | ||
padding(5), | ||
round.md, | ||
bg.white, | ||
boxShadow, | ||
]); | ||
const multiValueRemoveStyles = css(center); | ||
|
||
const selectStyles = { | ||
control: () => ({ ...controlStyles }), | ||
placeholder: () => ({ ...placeholderStyles }), | ||
valueContainer: () => ({ ...valueContainerStyles }), | ||
menuList: () => ({ ...menuListStyles }), | ||
multiValueRemove: () => ({ ...multiValueRemoveStyles }), | ||
}; | ||
|
||
const Option = (props: OptionProps<Tag>) => { | ||
const { data, isSelected } = props; | ||
return ( | ||
<components.Option {...props}> | ||
<PresetOption tag={data} selected={isSelected} /> | ||
</components.Option> | ||
); | ||
}; | ||
const DropdownIndicator = (props: DropdownIndicatorProps<Tag>) => ( | ||
<components.DropdownIndicator {...props}> | ||
<PositionedDownArrowIcon /> | ||
</components.DropdownIndicator> | ||
); | ||
const MultiValueContainer = (props: MultiValueGenericProps<Tag>) => { | ||
const { data } = props; | ||
return ( | ||
<components.MultiValueContainer {...props}> | ||
<div | ||
css={[ | ||
row, | ||
align.center, | ||
border.gray200, | ||
round.md, | ||
bg.white, | ||
padding.horizontal(8), | ||
padding.vertical(5), | ||
gap(6), | ||
cursorInitial, | ||
]} | ||
> | ||
<p css={[text.option1, text.gray500]}>{data.title}</p> | ||
<components.MultiValueRemove {...props} /> | ||
</div> | ||
</components.MultiValueContainer> | ||
); | ||
}; | ||
const MultiValueRemove = (props: MultiValueRemoveProps<Tag>) => ( | ||
<components.MultiValueRemove {...props}> | ||
<CloseSmallIcon css={cursorPointer} /> | ||
</components.MultiValueRemove> | ||
); | ||
|
||
export const TagSelect: React.FC<Props> = ({ tags, onChange }) => ( | ||
<Select | ||
css={cursorPointer} | ||
styles={selectStyles} | ||
components={{ | ||
Option, | ||
DropdownIndicator, | ||
IndicatorSeparator: () => null, | ||
MultiValueRemove, | ||
MultiValueLabel: () => null, | ||
MultiValueContainer, | ||
}} | ||
hideSelectedOptions={false} | ||
closeMenuOnSelect={false} | ||
isSearchable={false} | ||
isClearable={false} | ||
menuPortalTarget={document.body} | ||
unstyled | ||
// menuIsOpen | ||
options={tags} | ||
placeholder="태그를 선택하세요" | ||
onChange={selection => onChange(selection.map(t => t.title))} | ||
getOptionValue={tag => tag.id.toString()} | ||
isMulti | ||
/> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://sparcs.slack.com/archives/C01RC6QMSL8/p1694580896447669
요 슬랙 스레드에 관련 논의가 있는 것 같은데 여기도 useCallback을 적용할 수 있지 않을까? (잘 모름, 확신 없음)