Skip to content

Commit cc0eb78

Browse files
committed
FlashList working but not fully accurate
1 parent ffb38b7 commit cc0eb78

1 file changed

Lines changed: 226 additions & 16 deletions

File tree

src/design-system/components/Select.tsx

Lines changed: 226 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useTheme } from '@baca/hooks'
22
import { BottomSheetModal } from '@gorhom/bottom-sheet'
33
import { useCallback, useMemo, useRef } from 'react'
4-
import { Keyboard, StyleSheet, Dimensions } from 'react-native'
4+
import { Keyboard, StyleSheet, Dimensions, Platform, useWindowDimensions } from 'react-native'
55
import { TouchableOpacity } from 'react-native-gesture-handler'
66

77
import { Box } from './Box'
@@ -13,7 +13,6 @@ import { SelectKey, SelectItemProps, SelectProps } from './types'
1313
import { BottomSheet } from '../bottomSheets/BottomSheet'
1414
import { BottomSheetFlashList } from '../bottomSheets/BottomSheetFlashList'
1515

16-
// const ITEM_HEIGHT = 56
1716
const BOTTOM_SHEET_CONTENT_HEIGHT = Dimensions.get('screen').height / 1.5
1817

1918
const SelectItem = <T extends SelectKey>({
@@ -100,6 +99,7 @@ export const Select = <T extends SelectKey>({
10099
}: SelectProps<T>) => {
101100
const ref = useRef<BottomSheetModal>(null)
102101
const { colors } = useTheme()
102+
const { width: windowWidth } = useWindowDimensions()
103103

104104
const showDropdown = useCallback(() => {
105105
onOpen && onOpen()
@@ -148,17 +148,12 @@ export const Select = <T extends SelectKey>({
148148

149149
const keyExtractor = useCallback((item: SelectItemProps<T>) => item.value.toString(), [])
150150

151-
// const getItemLayout = useCallback(
152-
// (_data: ArrayLike<SelectItemProps<T>> | null | undefined, index: number) => {
153-
// return { length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index }
154-
// },
155-
// []
156-
// )
157-
158151
const inputColor = useMemo(() => {
159152
return isError ? 'text.error.primary' : dropdownDisabled ? 'utility.gray.500' : 'text.primary'
160153
}, [dropdownDisabled, isError])
161154

155+
const contentWidth = Platform.OS === 'web' ? Math.min(windowWidth * 0.4, 400) : 'auto'
156+
162157
return (
163158
<>
164159
<Touchable disabled={dropdownDisabled} onPress={showDropdown} justifyContent="center">
@@ -177,14 +172,20 @@ export const Select = <T extends SelectKey>({
177172
<Icon color={inputColor} size={22} name="arrow-down-s-line" style={styles.icon} />
178173
</Touchable>
179174
<BottomSheet title={label} bottomSheetRef={ref}>
180-
<Box pb={6} px={4} style={{ height: BOTTOM_SHEET_CONTENT_HEIGHT }}>
175+
<Box
176+
pb={6}
177+
px={4}
178+
style={{
179+
height: BOTTOM_SHEET_CONTENT_HEIGHT,
180+
width: contentWidth,
181+
}}
182+
>
181183
<BottomSheetFlashList
182-
style={styles.bottomSheetFlashList}
183184
data={items}
184185
keyExtractor={keyExtractor}
185186
renderItem={renderItem}
186-
estimatedItemSize={50} // Added
187-
initialScrollIndex={0} // Added
187+
estimatedItemSize={51}
188+
showsVerticalScrollIndicator={windowWidth > 400}
188189
/>
189190
</Box>
190191
</BottomSheet>
@@ -193,9 +194,6 @@ export const Select = <T extends SelectKey>({
193194
}
194195

195196
const styles = StyleSheet.create({
196-
bottomSheetFlashList: {
197-
maxHeight: BOTTOM_SHEET_CONTENT_HEIGHT,
198-
},
199197
icon: {
200198
position: 'absolute',
201199
right: 8,
@@ -214,3 +212,215 @@ const styles = StyleSheet.create({
214212
paddingVertical: 12,
215213
},
216214
})
215+
216+
// import { useTheme } from '@baca/hooks'
217+
// import { BottomSheetModal } from '@gorhom/bottom-sheet'
218+
// import { useCallback, useMemo, useRef } from 'react'
219+
// import { Keyboard, StyleSheet, Dimensions, Platform } from 'react-native'
220+
// import { TouchableOpacity } from 'react-native-gesture-handler'
221+
222+
// import { Box } from './Box'
223+
// import { Icon } from './Icon'
224+
// import { Row } from './Row'
225+
// import { Text } from './Text'
226+
// import { Touchable } from './Touchables/Touchable'
227+
// import { SelectKey, SelectItemProps, SelectProps } from './types'
228+
// import { BottomSheet } from '../bottomSheets/BottomSheet'
229+
// import { BottomSheetFlashList } from '../bottomSheets/BottomSheetFlashList'
230+
231+
// const BOTTOM_SHEET_CONTENT_HEIGHT = Dimensions.get('screen').height / 1.5
232+
// const BOTTOM_SHEET_CONTENT_WIDTH = Dimensions.get('screen').width / 3
233+
234+
// const SelectItem = <T extends SelectKey>({
235+
// item,
236+
// setValue,
237+
// maxSelectedItems,
238+
// closeDropdown,
239+
// value,
240+
// disabled,
241+
// }: {
242+
// item: SelectItemProps<T>
243+
// setValue: (newValue: T[]) => void
244+
// maxSelectedItems: number
245+
// closeDropdown: () => void
246+
// value: T[]
247+
// disabled: boolean
248+
// }) => {
249+
// const selected = value?.includes(item.value)
250+
// const { colors } = useTheme()
251+
252+
// const onItemSelect = useCallback(() => {
253+
// if (maxSelectedItems === 1) {
254+
// setValue([item.value])
255+
// closeDropdown()
256+
// return
257+
// }
258+
// const newValue = [...value].filter((el) => el)
259+
// if (value?.includes(item.value)) {
260+
// const index = newValue.indexOf(item.value)
261+
// newValue.splice(index, 1)
262+
// setValue(newValue)
263+
// return
264+
// }
265+
// if (value?.length < maxSelectedItems) {
266+
// newValue.push(item.value)
267+
// setValue(newValue)
268+
// }
269+
// }, [closeDropdown, item.value, maxSelectedItems, setValue, value])
270+
271+
// const color = useMemo(
272+
// () => (disabled && !selected ? colors.bg.brand.primary : colors.bg.active),
273+
// [disabled, selected, colors]
274+
// )
275+
276+
// return (
277+
// <TouchableOpacity style={styles.itemWrapper} onPress={onItemSelect}>
278+
// {maxSelectedItems === 1 ? (
279+
// <Row my={2} flex={1} alignItems="center">
280+
// <Text>{item.labelInDropdown ?? item.label}</Text>
281+
// </Row>
282+
// ) : null}
283+
// {maxSelectedItems > 1 ? (
284+
// <Row mb={4}>
285+
// <Box
286+
// borderRadius={5}
287+
// borderColor={disabled && !selected ? 'border.disabled' : 'border.brand'}
288+
// borderWidth={1}
289+
// width={5}
290+
// height={5}
291+
// mr={4}
292+
// justifyContent="center"
293+
// alignItems="center"
294+
// >
295+
// {selected ? <Icon color="icon.fg.brand" name="check-fill" size={18} /> : null}
296+
// </Box>
297+
// <Row flex={1} alignItems="center">
298+
// <Text style={{ color }}>{item.labelInDropdown ?? item.label}</Text>
299+
// </Row>
300+
// </Row>
301+
// ) : null}
302+
// </TouchableOpacity>
303+
// )
304+
// }
305+
306+
// export const Select = <T extends SelectKey>({
307+
// placeholder,
308+
// disabled: dropdownDisabled = false,
309+
// items,
310+
// value,
311+
// setValue,
312+
// maxSelectedItems = 1,
313+
// onOpen,
314+
// isError = false,
315+
// }: SelectProps<T>) => {
316+
// const ref = useRef<BottomSheetModal>(null)
317+
// const { colors } = useTheme()
318+
319+
// const showDropdown = useCallback(() => {
320+
// onOpen && onOpen()
321+
// Keyboard.dismiss()
322+
// ref?.current?.present?.()
323+
// }, [onOpen])
324+
325+
// const closeDropdown = useCallback(() => {
326+
// ref.current?.snapToPosition(-1)
327+
// }, [])
328+
329+
// const disabled = useMemo(
330+
// () => value?.length === maxSelectedItems,
331+
// [maxSelectedItems, value?.length]
332+
// )
333+
334+
// const label = useMemo(() => {
335+
// let retVal = ''
336+
// const selectedItems = items?.filter((item) => value.includes(item.value)) ?? []
337+
// if (selectedItems?.length === 0) {
338+
// return placeholder ?? ''
339+
// }
340+
// for (const item of selectedItems) {
341+
// retVal += `${item.label}, `
342+
// }
343+
// retVal = retVal.slice(0, -2)
344+
// return retVal
345+
// }, [items, placeholder, value])
346+
347+
// const renderItem = useCallback(
348+
// ({ item }: { item: SelectItemProps<T> }) => {
349+
// return (
350+
// <SelectItem
351+
// key={item.label}
352+
// item={item}
353+
// setValue={setValue}
354+
// maxSelectedItems={maxSelectedItems}
355+
// closeDropdown={closeDropdown}
356+
// value={value}
357+
// disabled={disabled}
358+
// />
359+
// )
360+
// },
361+
// [closeDropdown, disabled, maxSelectedItems, setValue, value]
362+
// )
363+
364+
// const keyExtractor = useCallback((item: SelectItemProps<T>) => item.value.toString(), [])
365+
366+
// const inputColor = useMemo(() => {
367+
// return isError ? 'text.error.primary' : dropdownDisabled ? 'utility.gray.500' : 'text.primary'
368+
// }, [dropdownDisabled, isError])
369+
370+
// return (
371+
// <>
372+
// <Touchable disabled={dropdownDisabled} onPress={showDropdown} justifyContent="center">
373+
// <Text
374+
// numberOfLines={1}
375+
// style={[
376+
// styles.textInput,
377+
// isError
378+
// ? { borderColor: colors.text.error.primary }
379+
// : { borderColor: colors.border.primary },
380+
// ]}
381+
// color={inputColor}
382+
// >
383+
// {label}
384+
// </Text>
385+
// <Icon color={inputColor} size={22} name="arrow-down-s-line" style={styles.icon} />
386+
// </Touchable>
387+
// <BottomSheet title={label} bottomSheetRef={ref}>
388+
// <Box
389+
// pb={6}
390+
// px={4}
391+
// style={{
392+
// height: BOTTOM_SHEET_CONTENT_HEIGHT,
393+
// maxWidth: Platform.OS === 'web' ? BOTTOM_SHEET_CONTENT_WIDTH : 'auto',
394+
// }}
395+
// >
396+
// <BottomSheetFlashList
397+
// data={items}
398+
// keyExtractor={keyExtractor}
399+
// renderItem={renderItem}
400+
// estimatedItemSize={51}
401+
// />
402+
// </Box>
403+
// </BottomSheet>
404+
// </>
405+
// )
406+
// }
407+
408+
// const styles = StyleSheet.create({
409+
// icon: {
410+
// position: 'absolute',
411+
// right: 8,
412+
// },
413+
// itemWrapper: {
414+
// paddingVertical: 8,
415+
// },
416+
// textInput: {
417+
// alignItems: 'center',
418+
// borderRadius: 8,
419+
// borderWidth: 1,
420+
// flex: 1,
421+
// fontSize: 16,
422+
// paddingHorizontal: 10,
423+
// paddingRight: 28,
424+
// paddingVertical: 12,
425+
// },
426+
// })

0 commit comments

Comments
 (0)