Update RaidCombobox and RaidItem
Also removes RaidSelect, which has been removed
This commit is contained in:
parent
8cb41bc82c
commit
a092a5b6ad
6 changed files with 208 additions and 316 deletions
|
|
@ -1,22 +0,0 @@
|
||||||
.Raid.Select {
|
|
||||||
min-width: 420px;
|
|
||||||
|
|
||||||
.Top {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: $unit;
|
|
||||||
padding: $unit 0;
|
|
||||||
|
|
||||||
.SegmentedControl {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Input.Bound {
|
|
||||||
background-color: var(--select-contained-bg);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--select-contained-bg-hover);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,170 +0,0 @@
|
||||||
import React, { useEffect, useState } from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
|
||||||
import * as RadixSelect from '@radix-ui/react-select'
|
|
||||||
import classNames from 'classnames'
|
|
||||||
|
|
||||||
import Overlay from '~components/common/Overlay'
|
|
||||||
|
|
||||||
import ChevronIcon from '~public/icons/Chevron.svg'
|
|
||||||
|
|
||||||
import styles from './index.module.scss'
|
|
||||||
import SegmentedControl from '~components/common/SegmentedControl'
|
|
||||||
import Segment from '~components/common/Segment'
|
|
||||||
import Input from '~components/common/Input'
|
|
||||||
|
|
||||||
// Props
|
|
||||||
interface Props
|
|
||||||
extends React.DetailedHTMLProps<
|
|
||||||
React.SelectHTMLAttributes<HTMLSelectElement>,
|
|
||||||
HTMLSelectElement
|
|
||||||
> {
|
|
||||||
altText?: string
|
|
||||||
currentSegment: number
|
|
||||||
iconSrc?: string
|
|
||||||
open: boolean
|
|
||||||
trigger?: React.ReactNode
|
|
||||||
children?: React.ReactNode
|
|
||||||
onOpenChange?: () => void
|
|
||||||
onValueChange?: (value: string) => void
|
|
||||||
onSegmentClick: (segment: number) => void
|
|
||||||
onClose?: () => void
|
|
||||||
triggerClass?: string
|
|
||||||
overlayVisible?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
const RaidSelect = React.forwardRef<HTMLButtonElement, Props>(function Select(
|
|
||||||
props: Props,
|
|
||||||
forwardedRef
|
|
||||||
) {
|
|
||||||
// Import translations
|
|
||||||
const { t } = useTranslation('common')
|
|
||||||
|
|
||||||
const searchInput = React.createRef<HTMLInputElement>()
|
|
||||||
|
|
||||||
const [open, setOpen] = useState(false)
|
|
||||||
const [value, setValue] = useState('')
|
|
||||||
const [query, setQuery] = useState('')
|
|
||||||
|
|
||||||
const triggerClasses = classNames(
|
|
||||||
{
|
|
||||||
SelectTrigger: true,
|
|
||||||
Disabled: props.disabled,
|
|
||||||
},
|
|
||||||
props.triggerClass
|
|
||||||
)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setOpen(props.open)
|
|
||||||
}, [props.open])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (props.value && props.value !== '') setValue(`${props.value}`)
|
|
||||||
else setValue('')
|
|
||||||
}, [props.value])
|
|
||||||
|
|
||||||
function onValueChange(newValue: string) {
|
|
||||||
setValue(`${newValue}`)
|
|
||||||
if (props.onValueChange) props.onValueChange(newValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCloseAutoFocus() {
|
|
||||||
setOpen(false)
|
|
||||||
if (props.onClose) props.onClose()
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEscapeKeyDown() {
|
|
||||||
setOpen(false)
|
|
||||||
if (props.onClose) props.onClose()
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPointerDownOutside() {
|
|
||||||
setOpen(false)
|
|
||||||
if (props.onClose) props.onClose()
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<RadixSelect.Root
|
|
||||||
open={open}
|
|
||||||
value={value !== '' ? value : undefined}
|
|
||||||
onValueChange={onValueChange}
|
|
||||||
onOpenChange={props.onOpenChange}
|
|
||||||
>
|
|
||||||
<RadixSelect.Trigger
|
|
||||||
className={triggerClasses}
|
|
||||||
placeholder={props.placeholder}
|
|
||||||
ref={forwardedRef}
|
|
||||||
>
|
|
||||||
{props.iconSrc ? <img alt={props.altText} src={props.iconSrc} /> : ''}
|
|
||||||
<RadixSelect.Value placeholder={props.placeholder} />
|
|
||||||
{!props.disabled ? (
|
|
||||||
<RadixSelect.Icon className="SelectIcon">
|
|
||||||
<ChevronIcon />
|
|
||||||
</RadixSelect.Icon>
|
|
||||||
) : (
|
|
||||||
''
|
|
||||||
)}
|
|
||||||
</RadixSelect.Trigger>
|
|
||||||
|
|
||||||
<RadixSelect.Portal className="Select">
|
|
||||||
<>
|
|
||||||
<Overlay
|
|
||||||
open={open}
|
|
||||||
visible={props.overlayVisible != null ? props.overlayVisible : true}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<RadixSelect.Content
|
|
||||||
className="Raid Select"
|
|
||||||
onCloseAutoFocus={onCloseAutoFocus}
|
|
||||||
onEscapeKeyDown={onEscapeKeyDown}
|
|
||||||
onPointerDownOutside={onPointerDownOutside}
|
|
||||||
>
|
|
||||||
<div className="Top">
|
|
||||||
<Input
|
|
||||||
autoComplete="off"
|
|
||||||
className="Search Bound"
|
|
||||||
name="query"
|
|
||||||
placeholder={t('search.placeholders.raid')}
|
|
||||||
ref={searchInput}
|
|
||||||
value={query}
|
|
||||||
onChange={() => {}}
|
|
||||||
/>
|
|
||||||
<SegmentedControl blended={true}>
|
|
||||||
<Segment
|
|
||||||
groupName="raid_section"
|
|
||||||
name="events"
|
|
||||||
selected={props.currentSegment === 1}
|
|
||||||
onClick={() => props.onSegmentClick(1)}
|
|
||||||
>
|
|
||||||
{t('raids.sections.events')}
|
|
||||||
</Segment>
|
|
||||||
<Segment
|
|
||||||
groupName="raid_section"
|
|
||||||
name="raids"
|
|
||||||
selected={props.currentSegment === 0}
|
|
||||||
onClick={() => props.onSegmentClick(0)}
|
|
||||||
>
|
|
||||||
{t('raids.sections.raids')}
|
|
||||||
</Segment>
|
|
||||||
<Segment
|
|
||||||
groupName="raid_section"
|
|
||||||
name="solo"
|
|
||||||
selected={props.currentSegment === 2}
|
|
||||||
onClick={() => props.onSegmentClick(2)}
|
|
||||||
>
|
|
||||||
{t('raids.sections.solo')}
|
|
||||||
</Segment>
|
|
||||||
</SegmentedControl>
|
|
||||||
</div>
|
|
||||||
<RadixSelect.Viewport>{props.children}</RadixSelect.Viewport>
|
|
||||||
</RadixSelect.Content>
|
|
||||||
</>
|
|
||||||
</RadixSelect.Portal>
|
|
||||||
</RadixSelect.Root>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
RaidSelect.defaultProps = {
|
|
||||||
overlayVisible: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
export default RaidSelect
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
.Combobox.Raid {
|
.combobox.raid {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
min-width: 440px;
|
min-width: 440px;
|
||||||
|
|
||||||
.Header {
|
.header {
|
||||||
background: var(--dialog-bg);
|
background: var(--dialog-bg);
|
||||||
border-top-left-radius: $card-corner;
|
border-top-left-radius: $card-corner;
|
||||||
border-top-right-radius: $card-corner;
|
border-top-right-radius: $card-corner;
|
||||||
|
|
@ -13,7 +13,64 @@
|
||||||
padding: $unit;
|
padding: $unit;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.Clear.Button {
|
.input {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
background-color: var(--input-bound-bg);
|
||||||
|
border: 2px solid transparent;
|
||||||
|
border-radius: $input-corner;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&:not(.wrapper) {
|
||||||
|
padding: $unit * 1.5 $unit-2x;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.wrapper {
|
||||||
|
$offset: 2px;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
background: var(--input-bg);
|
||||||
|
border-radius: $input-corner;
|
||||||
|
border: $offset solid transparent;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.counter {
|
||||||
|
color: var(--text-tertiary);
|
||||||
|
display: block;
|
||||||
|
font-weight: $bold;
|
||||||
|
line-height: 42px;
|
||||||
|
position: absolute;
|
||||||
|
right: $unit-2x;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
background: transparent;
|
||||||
|
border-radius: $input-corner;
|
||||||
|
border: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: $unit * 1.5 $unit-2x;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border: 2px solid $blue;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bound {
|
||||||
|
background-color: var(--input-bound-bg);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--input-bound-bg-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear.button {
|
||||||
background: none;
|
background: none;
|
||||||
padding: ($unit * 0.75) $unit-half $unit-half;
|
padding: ($unit * 0.75) $unit-half $unit-half;
|
||||||
display: none;
|
display: none;
|
||||||
|
|
@ -33,7 +90,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.Controls {
|
.controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: $unit;
|
gap: $unit;
|
||||||
|
|
||||||
|
|
@ -48,25 +105,13 @@
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.Flipped {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.SegmentedControlWrapper {
|
|
||||||
flex-grow: 1;
|
|
||||||
|
|
||||||
.SegmentedControl {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.Raids {
|
.raids {
|
||||||
border-bottom-left-radius: $card-corner;
|
border-bottom-left-radius: $card-corner;
|
||||||
border-bottom-right-radius: $card-corner;
|
border-bottom-right-radius: $card-corner;
|
||||||
height: 36vh;
|
height: 28vh;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
padding: 0 $unit;
|
padding: 0 $unit;
|
||||||
|
|
||||||
|
|
@ -75,30 +120,30 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.Searching {
|
&.Searching {
|
||||||
.CommandGroup {
|
.group {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
|
|
||||||
.Label {
|
.label {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.SelectItem {
|
.item {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.CommandGroup.Hidden {
|
.group.hidden {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.CommandGroup {
|
.group {
|
||||||
&.Hidden {
|
&.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Label {
|
.label {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: var(--text-tertiary);
|
color: var(--text-tertiary);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -109,7 +154,7 @@
|
||||||
gap: $unit;
|
gap: $unit;
|
||||||
padding: $unit $unit-2x $unit-half ($unit * 1.5);
|
padding: $unit $unit-2x $unit-half ($unit * 1.5);
|
||||||
|
|
||||||
.Separator {
|
.separator {
|
||||||
background: var(--select-separator);
|
background: var(--select-separator);
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
@ -121,26 +166,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.trigger {
|
.info {
|
||||||
background: var(--input-bound-bg);
|
|
||||||
display: flex;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 11px;
|
|
||||||
min-height: 51px;
|
|
||||||
|
|
||||||
.value {
|
|
||||||
display: flex;
|
|
||||||
gap: $unit-half;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.info {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: $unit-half;
|
gap: $unit-half;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extraIndicator {
|
.extraIndicator {
|
||||||
background: var(--extra-purple-secondary);
|
background: var(--extra-purple-secondary);
|
||||||
border-radius: $full-corner;
|
border-radius: $full-corner;
|
||||||
color: $grey-100;
|
color: $grey-100;
|
||||||
|
|
@ -151,37 +184,35 @@
|
||||||
height: $unit-3x;
|
height: $unit-3x;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Group,
|
.group,
|
||||||
.Separator {
|
.separator {
|
||||||
color: var(--text-tertiary);
|
color: var(--text-tertiary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Raid.wind {
|
.raid.wind {
|
||||||
color: var(--wind-text);
|
color: var(--wind-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Raid.fire {
|
.raid.fire {
|
||||||
color: var(--fire-text);
|
color: var(--fire-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Raid.water {
|
.raid.water {
|
||||||
color: var(--water-text);
|
color: var(--water-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Raid.earth {
|
.raid.earth {
|
||||||
color: var(--earth-text);
|
color: var(--earth-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Raid.dark {
|
.raid.dark {
|
||||||
color: var(--dark-text);
|
color: var(--dark-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Raid.light {
|
.raid.light {
|
||||||
color: var(--light-text);
|
color: var(--light-text);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.SelectTrigger.Raid:not(.Highlighted) .Value.Empty {
|
.SelectTrigger.Raid:not(.Highlighted) .Value.Empty {
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,17 @@ const RaidCombobox = (props: Props) => {
|
||||||
const inputRef = createRef<HTMLInputElement>()
|
const inputRef = createRef<HTMLInputElement>()
|
||||||
const sortButtonRef = createRef<HTMLButtonElement>()
|
const sortButtonRef = createRef<HTMLButtonElement>()
|
||||||
|
|
||||||
|
// Classes
|
||||||
|
const comboboxClasses = classNames({
|
||||||
|
[styles.combobox]: true,
|
||||||
|
[styles.raid]: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const raidsClasses = classNames({
|
||||||
|
[styles.raids]: true,
|
||||||
|
[styles.searching]: query !== '',
|
||||||
|
})
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
// Methods: Lifecycle Hooks
|
// Methods: Lifecycle Hooks
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
@ -313,14 +324,14 @@ const RaidCombobox = (props: Props) => {
|
||||||
const options = generateRaidItems(group.raids)
|
const options = generateRaidItems(group.raids)
|
||||||
|
|
||||||
const groupClassName = classNames({
|
const groupClassName = classNames({
|
||||||
CommandGroup: true,
|
[styles.group]: true,
|
||||||
Hidden: group.section !== currentSection,
|
[styles.hidden]: group.section !== currentSection,
|
||||||
})
|
})
|
||||||
|
|
||||||
const heading = (
|
const heading = (
|
||||||
<div className="Label">
|
<div className={styles.label}>
|
||||||
{group.name[locale]}
|
{group.name[locale]}
|
||||||
<div className="Separator" />
|
<div className={styles.separator} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -350,7 +361,7 @@ const RaidCombobox = (props: Props) => {
|
||||||
<CommandGroup
|
<CommandGroup
|
||||||
data-section={untitledGroup.section}
|
data-section={untitledGroup.section}
|
||||||
className={classNames({
|
className={classNames({
|
||||||
CommandGroup: true,
|
[styles.group]: true,
|
||||||
})}
|
})}
|
||||||
key="ungrouped-raids"
|
key="ungrouped-raids"
|
||||||
>
|
>
|
||||||
|
|
@ -379,7 +390,7 @@ const RaidCombobox = (props: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RaidItem
|
<RaidItem
|
||||||
className={isSelected ? 'Selected' : ''}
|
className={classNames({ [styles.selected]: isSelected })}
|
||||||
icon={{ alt: raid.name[locale], src: imageUrl }}
|
icon={{ alt: raid.name[locale], src: imageUrl }}
|
||||||
extra={raid.group.extra}
|
extra={raid.group.extra}
|
||||||
key={key}
|
key={key}
|
||||||
|
|
@ -400,7 +411,7 @@ const RaidCombobox = (props: Props) => {
|
||||||
// Renders a SegmentedControl component for selecting raid sections.
|
// Renders a SegmentedControl component for selecting raid sections.
|
||||||
function renderSegmentedControl() {
|
function renderSegmentedControl() {
|
||||||
return (
|
return (
|
||||||
<SegmentedControl blended={true}>
|
<SegmentedControl blended={true} className="raid" wrapperClassName="raid">
|
||||||
<Segment
|
<Segment
|
||||||
groupName="raid_section"
|
groupName="raid_section"
|
||||||
name="events"
|
name="events"
|
||||||
|
|
@ -444,9 +455,10 @@ const RaidCombobox = (props: Props) => {
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
blended={true}
|
blended={true}
|
||||||
buttonSize="small"
|
bound={true}
|
||||||
|
size="small"
|
||||||
leftAccessoryIcon={<ArrowIcon />}
|
leftAccessoryIcon={<ArrowIcon />}
|
||||||
leftAccessoryClassName={sort === Sort.DESCENDING ? 'Flipped' : ''}
|
leftAccessoryClassName={sort === Sort.DESCENDING ? 'flipped' : ''}
|
||||||
onClick={reverseSort}
|
onClick={reverseSort}
|
||||||
onKeyDown={handleSortButtonKeyDown}
|
onKeyDown={handleSortButtonKeyDown}
|
||||||
ref={sortButtonRef}
|
ref={sortButtonRef}
|
||||||
|
|
@ -462,10 +474,19 @@ const RaidCombobox = (props: Props) => {
|
||||||
const element = (
|
const element = (
|
||||||
<>
|
<>
|
||||||
{!props.minimal ? (
|
{!props.minimal ? (
|
||||||
<div className="Info">
|
<div className={styles.info}>
|
||||||
<span className="Group">{currentRaid.group.name[locale]}</span>
|
<span className={styles.group}>
|
||||||
<span className="Separator">/</span>
|
{currentRaid.group.name[locale]}
|
||||||
<span className={classNames({ Raid: true }, linkClass)}>
|
</span>
|
||||||
|
<span className={styles.separator}>/</span>
|
||||||
|
<span
|
||||||
|
className={classNames(
|
||||||
|
{
|
||||||
|
[styles.raid]: true,
|
||||||
|
},
|
||||||
|
linkClass?.split(' ').map((className) => styles[className])
|
||||||
|
)}
|
||||||
|
>
|
||||||
{currentRaid.name[locale]}
|
{currentRaid.name[locale]}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -476,7 +497,7 @@ const RaidCombobox = (props: Props) => {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{currentRaid.group.extra && !props.minimal && (
|
{currentRaid.group.extra && !props.minimal && (
|
||||||
<i className="ExtraIndicator">EX</i>
|
<i className={styles.extraIndicator}>EX</i>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
@ -493,9 +514,9 @@ const RaidCombobox = (props: Props) => {
|
||||||
// Renders the search input for the raid combobox
|
// Renders the search input for the raid combobox
|
||||||
function renderSearchInput() {
|
function renderSearchInput() {
|
||||||
return (
|
return (
|
||||||
<div className="Bound Joined">
|
<div className={styles.wrapper}>
|
||||||
<CommandInput
|
<CommandInput
|
||||||
className="Input"
|
className={styles.input}
|
||||||
placeholder={t('search.placeholders.raid')}
|
placeholder={t('search.placeholders.raid')}
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
|
|
@ -504,9 +525,9 @@ const RaidCombobox = (props: Props) => {
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={classNames({
|
className={classNames({
|
||||||
Button: true,
|
[styles.button]: true,
|
||||||
Clear: true,
|
[styles.clear]: true,
|
||||||
Visible: query.length > 0,
|
[styles.visible]: query.length > 0,
|
||||||
})}
|
})}
|
||||||
onClick={clearSearch}
|
onClick={clearSearch}
|
||||||
>
|
>
|
||||||
|
|
@ -540,7 +561,7 @@ const RaidCombobox = (props: Props) => {
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
return (
|
return (
|
||||||
<Popover
|
<Popover
|
||||||
className="Flush"
|
className="raid flush"
|
||||||
open={open}
|
open={open}
|
||||||
onOpenChange={toggleOpen}
|
onOpenChange={toggleOpen}
|
||||||
placeholder={
|
placeholder={
|
||||||
|
|
@ -549,26 +570,26 @@ const RaidCombobox = (props: Props) => {
|
||||||
trigger={{
|
trigger={{
|
||||||
bound: true,
|
bound: true,
|
||||||
className: classNames({
|
className: classNames({
|
||||||
Raid: true,
|
raid: true,
|
||||||
Highlighted: props.showAllRaidsOption,
|
highlighted: props.showAllRaidsOption,
|
||||||
}),
|
}),
|
||||||
size: props.size,
|
size: props.size,
|
||||||
}}
|
}}
|
||||||
triggerTabIndex={props.tabIndex}
|
triggerTabIndex={props.tabIndex}
|
||||||
value={renderTriggerContent()}
|
value={renderTriggerContent()}
|
||||||
>
|
>
|
||||||
<Command className="Raid Combobox">
|
<Command className={comboboxClasses}>
|
||||||
<div className="Header">
|
<div className={styles.header}>
|
||||||
{renderSearchInput()}
|
{renderSearchInput()}
|
||||||
{!query && (
|
{!query && (
|
||||||
<div className="Controls">
|
<div className={styles.controls}>
|
||||||
{renderSegmentedControl()}
|
{renderSegmentedControl()}
|
||||||
{renderSortButton()}
|
{renderSortButton()}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={classNames({ Raids: true, Searching: query !== '' })}
|
className={raidsClasses}
|
||||||
ref={listRef}
|
ref={listRef}
|
||||||
role="listbox"
|
role="listbox"
|
||||||
tabIndex={6}
|
tabIndex={6}
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,64 @@
|
||||||
.SelectItem.Raid {
|
.item {
|
||||||
padding-top: $unit;
|
align-items: center;
|
||||||
padding-bottom: $unit;
|
border-radius: $item-corner;
|
||||||
padding-left: $unit;
|
border: 2px solid transparent;
|
||||||
|
color: var(--text-tertiary);
|
||||||
|
display: flex;
|
||||||
|
gap: $unit;
|
||||||
|
font-size: $font-regular;
|
||||||
|
padding: $unit $unit-2x $unit $unit;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
background-color: var(--option-bg-hover);
|
||||||
|
color: var(--text-primary);
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border: 2px solid $blue;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-top: $unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: $unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: $unit-4x;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
.ExtraIndicator {
|
.extraIndicator {
|
||||||
background: var(--extra-purple-secondary);
|
background: var(--extra-purple-secondary);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Selected {
|
.selected {
|
||||||
background-color: var(--pill-bg-hover);
|
background-color: var(--pill-bg-hover);
|
||||||
color: var(--pill-text-hover);
|
color: var(--pill-text-hover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.Selected .ExtraIndicator {
|
&.selected .extraIndicator {
|
||||||
background: var(--extra-purple-secondary);
|
background: var(--extra-purple-secondary);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Text {
|
.text {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ExtraIndicator {
|
.extraIndicator {
|
||||||
background: var(--extra-purple-bg);
|
background: var(--extra-purple-bg);
|
||||||
border-radius: $full-corner;
|
border-radius: $full-corner;
|
||||||
color: var(--extra-purple-text);
|
color: var(--extra-purple-dark-text);
|
||||||
display: flex;
|
display: flex;
|
||||||
font-weight: $bold;
|
font-weight: $bold;
|
||||||
font-size: $font-tiny;
|
font-size: $font-tiny;
|
||||||
|
|
@ -37,7 +68,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Selected {
|
.selected {
|
||||||
background-color: var(--pill-bg);
|
background-color: var(--pill-bg);
|
||||||
color: var(--pill-text);
|
color: var(--pill-text);
|
||||||
border-radius: $full-corner;
|
border-radius: $full-corner;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { ComponentProps, PropsWithChildren } from 'react'
|
import React, { ComponentProps, PropsWithChildren } from 'react'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
import { CommandItem } from '~components/common/Command'
|
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
import { CommandItem } from '~components/common/Command'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
|
||||||
interface Props extends ComponentProps<'div'> {
|
interface Props extends ComponentProps<'div'> {
|
||||||
|
|
@ -35,10 +35,9 @@ const RaidItem = React.forwardRef<HTMLDivElement, PropsWithChildren<Props>>(
|
||||||
) {
|
) {
|
||||||
const { t } = useTranslation('common')
|
const { t } = useTranslation('common')
|
||||||
|
|
||||||
const classes = classNames(
|
const classes = classNames({
|
||||||
{ SelectItem: true, Raid: true },
|
[styles.item]: true,
|
||||||
props.className
|
})
|
||||||
)
|
|
||||||
|
|
||||||
const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
|
const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
|
||||||
if (event.key === 'Escape' && onEscapeKeyPressed) {
|
if (event.key === 'Escape' && onEscapeKeyPressed) {
|
||||||
|
|
@ -69,10 +68,12 @@ const RaidItem = React.forwardRef<HTMLDivElement, PropsWithChildren<Props>>(
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
ref={forwardedRef}
|
ref={forwardedRef}
|
||||||
>
|
>
|
||||||
{icon ? <img alt={icon.alt} src={icon.src} /> : ''}
|
{icon && <img alt={icon.alt} src={icon.src} />}
|
||||||
<span className="Text">{children}</span>
|
<span className={styles.text}>{children}</span>
|
||||||
{selected ? <i className="Selected">{t('combobox.selected')}</i> : ''}
|
{selected && (
|
||||||
{extra ? <i className="ExtraIndicator">EX</i> : ''}
|
<i className={styles.selected}>{t('combobox.selected')}</i>
|
||||||
|
)}
|
||||||
|
{extra && <i className={styles.extraIndicator}>EX</i>}
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue