Skip to content

Commit b77ea88

Browse files
authored
Merge pull request #30 from solved-ac/feature/fix-select-type
Fix Select component
2 parents 8f4d041 + ef94966 commit b77ea88

File tree

2 files changed

+55
-52
lines changed

2 files changed

+55
-52
lines changed

example/src/stories/Select.stories.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,35 @@ CustomRender.args = {
7070
</>
7171
),
7272
}
73+
74+
export const CustomTypes = Template.bind({})
75+
CustomTypes.args = {
76+
value: 'Select',
77+
items: [
78+
{
79+
value: 'kr',
80+
icon: 'https://flagicons.lipis.dev/flags/4x3/kr.svg',
81+
label: 'Korea',
82+
},
83+
{
84+
value: 'gb',
85+
icon: 'https://flagicons.lipis.dev/flags/4x3/gb.svg',
86+
label: 'United Kingdom',
87+
},
88+
{
89+
value: 'us',
90+
icon: 'https://flagicons.lipis.dev/flags/4x3/us.svg',
91+
label: 'United States',
92+
},
93+
{
94+
value: 'jp',
95+
icon: 'https://flagicons.lipis.dev/flags/4x3/jp.svg',
96+
label: 'Japan',
97+
},
98+
],
99+
render: (s: { value: string; icon: string; label: string }) => (
100+
<>
101+
<img src={s.icon} alt={s.label} style={{ height: '1em' }} /> {s.label}
102+
</>
103+
),
104+
}

src/components/Select.tsx

Lines changed: 23 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,12 @@ import {
66
FloatingFocusManager,
77
FloatingOverlay,
88
FloatingPortal,
9-
inner,
109
offset,
1110
shift,
12-
SideObject,
1311
size,
1412
useClick,
1513
useDismiss,
1614
useFloating,
17-
useInnerOffset,
1815
useInteractions,
1916
useListNavigation,
2017
useRole,
@@ -32,7 +29,7 @@ import React, {
3229
useState
3330
} from 'react'
3431
import { IoChevronDown } from 'react-icons/io5'
35-
import { PC, PP, PR } from '../types/PolymorphicElementProps'
32+
import { PP, PR } from '../types/PolymorphicElementProps'
3633
import { cssClickable, cssDisablable } from '../utils/styles'
3734
import { ListItem, ListItemProps } from './$List'
3835
import { Centering } from './Centering'
@@ -87,7 +84,7 @@ const SelectInputAdornment = styled(Centering)`
8784

8885
type SelectItemNode = string | { value: string }
8986

90-
export interface SelectProps<T extends SelectItemNode = string> {
87+
export interface SelectProps<T extends SelectItemNode> {
9188
fullWidth?: boolean
9289
disableEllipsis?: boolean
9390
items?: T[]
@@ -97,7 +94,7 @@ export interface SelectProps<T extends SelectItemNode = string> {
9794
ListItemProps?: Partial<PP<'div', ListItemProps>>
9895
}
9996

100-
export const Select: PC<'button', SelectProps> = React.forwardRef(
97+
export const Select = React.forwardRef(
10198
<T extends ElementType, E extends SelectItemNode>(
10299
props: PP<T, SelectProps<E>>,
103100
ref?: PR<T>
@@ -117,16 +114,13 @@ export const Select: PC<'button', SelectProps> = React.forwardRef(
117114

118115
const listRef = useRef<Array<HTMLElement | null>>([])
119116
const listContentRef = useRef<Array<string | null>>([])
120-
const overflowRef = useRef<null | SideObject>(null)
121117
const allowSelectRef = useRef(false)
122118
const allowMouseUpRef = useRef(true)
123119
const selectTimeoutRef = useRef<any>()
124120

125121
const [open, setOpen] = useState(false)
126122
const [selectedIndex, setSelectedIndex] = useState(0)
127123
const [activeIndex, setActiveIndex] = useState<number | null>(null)
128-
const [fallback, setFallback] = useState(false)
129-
const [innerOffset, setInnerOffset] = useState(0)
130124
const [controlledScrolling, setControlledScrolling] = useState(false)
131125
const [touch, setTouch] = useState(false)
132126

@@ -151,38 +145,22 @@ export const Select: PC<'button', SelectProps> = React.forwardRef(
151145
autoUpdate(reference, floating, update, {
152146
animationFrame: true,
153147
}),
154-
middleware: fallback
155-
? [
156-
offset(8),
157-
...[
158-
touch
159-
? shift({ crossAxis: true, padding: 8 })
160-
: flip({ padding: 8 }),
161-
],
162-
size({
163-
apply({ elements, availableHeight, availableWidth, rects }) {
164-
Object.assign(elements.floating.style, {
165-
maxHeight: `${availableHeight}px`,
166-
minWidth: `${rects.reference.width}px`,
167-
maxWidth: `${availableWidth}px`,
168-
})
169-
},
170-
padding: 8,
171-
}),
172-
]
173-
: [
174-
inner({
175-
listRef,
176-
overflowRef,
177-
index: selectedIndex,
178-
offset: innerOffset,
179-
onFallbackChange: setFallback,
180-
padding: 8,
181-
minItemsVisible: touch ? 10 : 4,
182-
referenceOverflowThreshold: 20,
183-
}),
184-
offset({ crossAxis: -4 }),
185-
],
148+
middleware: [
149+
offset(8),
150+
...[
151+
touch ? shift({ crossAxis: true, padding: 8 }) : flip({ padding: 8 }),
152+
],
153+
size({
154+
apply({ elements, availableHeight, availableWidth, rects }) {
155+
Object.assign(elements.floating.style, {
156+
maxHeight: `${availableHeight}px`,
157+
minWidth: `${rects.reference.width}px`,
158+
maxWidth: `${availableWidth}px`,
159+
})
160+
},
161+
padding: 8,
162+
}),
163+
],
186164
})
187165

188166
useImperativeHandle(ref, () => reference)
@@ -192,11 +170,6 @@ export const Select: PC<'button', SelectProps> = React.forwardRef(
192170
useClick(context),
193171
useDismiss(context),
194172
useRole(context, { role: 'listbox' }),
195-
useInnerOffset(context, {
196-
enabled: !fallback,
197-
onChange: setInnerOffset,
198-
overflowRef,
199-
}),
200173
useListNavigation(context, {
201174
listRef,
202175
activeIndex,
@@ -222,8 +195,6 @@ export const Select: PC<'button', SelectProps> = React.forwardRef(
222195
}
223196
allowSelectRef.current = false
224197
allowMouseUpRef.current = true
225-
setInnerOffset(0)
226-
setFallback(false)
227198
return undefined
228199
}, [open])
229200

@@ -255,20 +226,20 @@ export const Select: PC<'button', SelectProps> = React.forwardRef(
255226
}, [open, refs, controlledScrolling, activeIndex])
256227

257228
useLayoutEffect(() => {
258-
if (open && fallback) {
229+
if (open) {
259230
requestAnimationFrame(() => {
260231
if (selectedIndex != null) {
261232
listRef.current[selectedIndex]?.scrollIntoView({ block: 'nearest' })
262233
}
263234
})
264235
}
265-
}, [open, fallback, selectedIndex])
236+
}, [open, selectedIndex])
266237

267238
useLayoutEffect(() => {
268-
if (refs.floating.current && fallback) {
239+
if (refs.floating.current) {
269240
refs.floating.current.style.maxHeight = ''
270241
}
271-
}, [refs, fallback])
242+
}, [refs])
272243

273244
const selected = selectedIndex < items.length ? items[selectedIndex] : null
274245

0 commit comments

Comments
 (0)