diff --git a/packages/ui/src/Bento/animation/microinteractions/NumberSlider.tsx b/packages/ui/src/Bento/animation/microinteractions/NumberSlider.tsx index 5eea4cab8..9b65165a6 100644 --- a/packages/ui/src/Bento/animation/microinteractions/NumberSlider.tsx +++ b/packages/ui/src/Bento/animation/microinteractions/NumberSlider.tsx @@ -97,4 +97,4 @@ const AnimatedNumber = styled(Text, { '$group-window-xs': { fontSize: '$8', }, -}); +} as any); diff --git a/packages/ui/src/Bento/ecommerce/cart/Fullpage.tsx b/packages/ui/src/Bento/ecommerce/cart/Fullpage.tsx index 15cdd5f7d..2fade6837 100644 --- a/packages/ui/src/Bento/ecommerce/cart/Fullpage.tsx +++ b/packages/ui/src/Bento/ecommerce/cart/Fullpage.tsx @@ -233,7 +233,8 @@ const Item = ({ item }: { item: Items[number] }) => { borderRadius="$12" theme="green" > - Remove + {/* Remove */} + Remove diff --git a/packages/ui/src/Bento/ecommerce/product_list/ProductList.tsx b/packages/ui/src/Bento/ecommerce/product_list/ProductList.tsx index 02b28cd6e..955e35cd5 100644 --- a/packages/ui/src/Bento/ecommerce/product_list/ProductList.tsx +++ b/packages/ui/src/Bento/ecommerce/product_list/ProductList.tsx @@ -21,7 +21,8 @@ const StyledText = styled(Text, { lineHeight: '$4', }); -function Item({ item }: { item: Product }) { +function Item({ item }: { item: Product | null }) { + if (!item) return null; return ( // Note: you can also use `Link` from solito/link - {products.map((item, index) => ( - - ))} + {products.map( + (item, index) => item && , + )} {someSpacers} ); diff --git a/packages/ui/src/Bento/ecommerce/product_list/ProductListBestItems.tsx b/packages/ui/src/Bento/ecommerce/product_list/ProductListBestItems.tsx index e84a10278..aa18c3a93 100644 --- a/packages/ui/src/Bento/ecommerce/product_list/ProductListBestItems.tsx +++ b/packages/ui/src/Bento/ecommerce/product_list/ProductListBestItems.tsx @@ -24,7 +24,8 @@ const StyledText = styled(Text, { type Product = ReturnType[0]; -function Item({ item }: { item: Product }) { +function Item({ item }: { item: Product | null }) { + if (!item) return null; return ( // Note: you can also use `Link` from solito/link - {products.map((item, index) => ( - - ))} + {products.map( + (item, index) => item && , + )} ); } diff --git a/packages/ui/src/Bento/ecommerce/product_list/ProductListGridThumbs.tsx b/packages/ui/src/Bento/ecommerce/product_list/ProductListGridThumbs.tsx index a4bf1adc7..3ddad0828 100644 --- a/packages/ui/src/Bento/ecommerce/product_list/ProductListGridThumbs.tsx +++ b/packages/ui/src/Bento/ecommerce/product_list/ProductListGridThumbs.tsx @@ -12,7 +12,8 @@ const StyledText = styled(Text, { lineHeight: '$4', }); -function Item({ item }: { item: Product }) { +function Item({ item }: { item: Product | null }) { + if (!item) return null; return ( // Note: you can also use `Link` from solito/link - {products.map((item, index) => ( - - ))} + {products.map( + (item, index) => item && , + )} {someSpacers} ); diff --git a/packages/ui/src/Bento/ecommerce/product_list/ProductListWithFeatures.tsx b/packages/ui/src/Bento/ecommerce/product_list/ProductListWithFeatures.tsx index 90bf23143..1dfa81dc2 100644 --- a/packages/ui/src/Bento/ecommerce/product_list/ProductListWithFeatures.tsx +++ b/packages/ui/src/Bento/ecommerce/product_list/ProductListWithFeatures.tsx @@ -23,7 +23,8 @@ const StyledText = styled(Text, { lineHeight: '$4', }); -function Item({ item }: { item: Product }) { +function Item({ item }: { item: Product | null }) { + if (!item) return null; return ( - {products.map((item, index) => ( - - ))} + {products.map( + (item, index) => item && , + )} {someSpacers} ); diff --git a/packages/ui/src/Bento/ecommerce/product_list/ProductListWithLabel.tsx b/packages/ui/src/Bento/ecommerce/product_list/ProductListWithLabel.tsx index 2c96234c6..3c0489570 100644 --- a/packages/ui/src/Bento/ecommerce/product_list/ProductListWithLabel.tsx +++ b/packages/ui/src/Bento/ecommerce/product_list/ProductListWithLabel.tsx @@ -18,7 +18,8 @@ type Product = ReturnType[0]; const premiums = [3, 6, 12, 15, 20, 25]; const bestSellers = [1, 5, 10, 13, 18, 23]; -function Item({ item, index }: { item: Product; index: number }) { +function Item({ item, index }: { item: Product | null; index: number }) { + if (!item) return null; const isPremium = premiums.includes(index); const isBestSeller = bestSellers.includes(index); const showLabel = isPremium || isBestSeller; @@ -121,9 +122,10 @@ export function ProductListWithLabel() { paddingHorizontal: '$3', }} > - {products.map((item, index) => ( - - ))} + {products.map( + (item, index) => + item && , + )} {someSpacers} ); diff --git a/packages/ui/src/Bento/ecommerce/product_list/data/products.tsx b/packages/ui/src/Bento/ecommerce/product_list/data/products.tsx index a5210986e..49083e9af 100644 --- a/packages/ui/src/Bento/ecommerce/product_list/data/products.tsx +++ b/packages/ui/src/Bento/ecommerce/product_list/data/products.tsx @@ -56,8 +56,9 @@ export const getProducts = () => { .fill(0) .map((_, i) => { const category = allImages[i % allImages.length]; - const name = Object.keys(category)[i % 10]; - const image = category[name]; + if (!category) return null; + const name = Object.keys(category ?? {})[i % 10]; + const image = name ? category[name] : ''; return { id: i, name, diff --git a/packages/ui/src/Bento/ecommerce/product_page/ProductHorizontalGallery.tsx b/packages/ui/src/Bento/ecommerce/product_page/ProductHorizontalGallery.tsx index b960863f0..2b08533ca 100644 --- a/packages/ui/src/Bento/ecommerce/product_page/ProductHorizontalGallery.tsx +++ b/packages/ui/src/Bento/ecommerce/product_page/ProductHorizontalGallery.tsx @@ -89,7 +89,7 @@ export const SizableText = styled(Text, { /** ------ EXAMPLE ------ */ export function ProductHorizontalGallery() { const [selectedPicture, setSelectedPicture] = useState( - product.pictures[0].picture, + product.pictures?.[0]?.picture || '', ); const [tempPicture, setTempPicture] = useState(null); const setDebounceTempPicture = debounce(setTempPicture, 100); diff --git a/packages/ui/src/Bento/ecommerce/product_page/ProductWithReview.tsx b/packages/ui/src/Bento/ecommerce/product_page/ProductWithReview.tsx index fa06bf8b0..5147128d4 100644 --- a/packages/ui/src/Bento/ecommerce/product_page/ProductWithReview.tsx +++ b/packages/ui/src/Bento/ecommerce/product_page/ProductWithReview.tsx @@ -86,7 +86,7 @@ export const SizableText = styled(Text, { /** ------ EXAMPLE ------ */ export function ProductWithReview() { const [selectedPicture, setSelectedPicture] = useState( - product.pictures[0].picture, + product.pictures?.[0]?.picture || '', ); const [tempPicture, setTempPicture] = useState(null); const setDebounceTempPicture = debounce(setTempPicture, 100); diff --git a/packages/ui/src/Bento/elements/datepickers/DatePicker.tsx b/packages/ui/src/Bento/elements/datepickers/DatePicker.tsx index 007fb7a07..38a6831e0 100644 --- a/packages/ui/src/Bento/elements/datepickers/DatePicker.tsx +++ b/packages/ui/src/Bento/elements/datepickers/DatePicker.tsx @@ -1,4 +1,7 @@ -import { useDatePickerContext } from '@rehookify/datepicker'; +import { + useDatePickerContext, + DatePickerProvider as _DatePickerProvider, +} from '@rehookify/datepicker'; import type { DPDay } from '@rehookify/datepicker'; import { ChevronLeft, ChevronRight } from '@tamagui/lucide-icons'; import { useEffect, useMemo, useState } from 'react'; @@ -21,7 +24,9 @@ function CalendarHeader() { propGetters: { subtractOffset }, } = useDatePickerContext(); const { type: header, setHeader } = useHeaderType(); - const { year, month } = calendars[0]; + const calendar = calendars[0]; + if (!calendar) return null; + const { year, month } = calendar; if (header === 'year') { return ; @@ -125,21 +130,29 @@ export function useDateAnimation({ useEffect(() => { if (listenTo === 'month') { - if (currentMonth !== calendars[0].month) { - setCurrentMonth(calendars[0].month); + const calendar = calendars[0]; + if (!calendar) return; + if (currentMonth !== calendar.month) { + setCurrentMonth(calendar.month); } } - }, [calendars[0][listenTo], currentMonth]); + }, [calendars[0]?.[listenTo], currentMonth]); useEffect(() => { if (listenTo === 'year') { - if (currentYear !== calendars[0].year) { - setCurrentYear(calendars[0].year); + const calendar = calendars[0]; + if (!calendar) return; + if (currentYear !== calendar.year) { + setCurrentYear(calendar.year); } } - }, [calendars[0][listenTo], currentYear]); + }, [calendars[0]?.[listenTo], currentYear]); const prevNextAnimation = () => { + const c0 = calendars[0]; + if (!c0) { + return { enterStyle: { opacity: 0 } }; + } if (listenTo === 'years') { if (currentYearsSum === null) return { enterStyle: { opacity: 0 } }; @@ -149,19 +162,19 @@ export function useDateAnimation({ }; } if (listenTo === 'month') { - if (currentMonth === null) return { enterStyle: { opacity: 0 } }; - const newDate = new Date( - `${calendars[0][listenTo]} 1, ${calendars[0].year}`, + if (!c0 || currentMonth === null) return { enterStyle: { opacity: 0 } }; + const newDate = new Date(`${c0.month} 1, ${c0.year}`); + const currentDate = new Date( + `${currentMonth ?? c0.month} 1, ${currentYear ?? c0.year}`, ); - const currentDate = new Date(`${currentMonth} 1, ${calendars[0].year}`); - if (currentMonth === 'December' && calendars[0].month === 'January') { + if (currentMonth === 'December' && c0.month === 'January') { return { enterStyle: { opacity: 0, x: 15 }, exitStyle: { opacity: 0, x: 15 }, }; } - if (currentMonth === 'January' && calendars[0].month === 'December') { + if (currentMonth === 'January' && c0.month === 'December') { return { enterStyle: { opacity: 0, x: -15 }, exitStyle: { opacity: 0, x: -15 }, @@ -174,8 +187,8 @@ export function useDateAnimation({ } if (listenTo === 'year') { if (currentYear === null) return { enterStyle: { opacity: 0 } }; - const newDate = new Date(`${calendars[0].month} 1, ${calendars[0].year}`); - const currentDate = new Date(`${calendars[0].month} 1, ${currentYear}`); + const newDate = new Date(`${c0.month} 1, ${c0.year}`); + const currentDate = new Date(`${c0.month} 1, ${currentYear ?? c0.year}`); return { enterStyle: { opacity: 0, x: newDate < currentDate ? -15 : 15 }, @@ -186,7 +199,7 @@ export function useDateAnimation({ return { prevNextAnimation, prevNextAnimationKey: - listenTo === 'years' ? sumYears() : calendars[0][listenTo], + listenTo === 'years' ? sumYears() : calendars[0]?.[listenTo], }; } @@ -196,7 +209,7 @@ function DayPicker() { propGetters: { dayButton }, } = useDatePickerContext(); - const { days } = calendars[0]; + const { days = [] } = calendars[0] || {}; const { prevNextAnimation, prevNextAnimationKey } = useDateAnimation({ listenTo: 'month', @@ -205,14 +218,14 @@ function DayPicker() { // divide days array into sub arrays that each has 7 days, for better stylings const subDays = useMemo( () => - days.reduce((acc, day, i) => { + calendars[0]?.days?.reduce((acc, day, i) => { if (i % 7 === 0) { acc.push([]); } - acc[acc.length - 1].push(day); + acc[acc.length - 1]?.push(day); return acc; - }, [] as DPDay[][]), - [days], + }, [] as DPDay[][]) ?? [], + [calendars], ); return ( @@ -228,7 +241,11 @@ function DayPicker() { {subDays.map((days) => { return ( - + {days.map((d) => ( - ); - })} - - ); - })} + {d.day} + + + ); + })} + + ))} diff --git a/packages/ui/src/Bento/elements/datepickers/YearPicker.tsx b/packages/ui/src/Bento/elements/datepickers/YearPicker.tsx index 6838b0cae..b81916ad8 100644 --- a/packages/ui/src/Bento/elements/datepickers/YearPicker.tsx +++ b/packages/ui/src/Bento/elements/datepickers/YearPicker.tsx @@ -32,27 +32,7 @@ export function YearPickerInput() { }, [offsetDate]); return ( - { - if (offset) { - offset.setMonth(0); - } - setOffsetDate(offset); - }, - calendar: { - startDay: 1, - }, - }} - > + - + <_DatePickerProvider + config={{ + onDatesChange, + selectedDates, + offsetDate, + onOffsetChange: (offset) => { + if (offset) { + offset.setMonth(0); + } + setOffsetDate(offset); + }, + calendar: { + startDay: 1, + }, + }} + > + + ); diff --git a/packages/ui/src/Bento/elements/datepickers/common/dateParts.tsx b/packages/ui/src/Bento/elements/datepickers/common/dateParts.tsx index 7dda725a7..13a7dfc0e 100644 --- a/packages/ui/src/Bento/elements/datepickers/common/dateParts.tsx +++ b/packages/ui/src/Bento/elements/datepickers/common/dateParts.tsx @@ -206,7 +206,7 @@ export function YearPicker({ data: { years, calendars }, propGetters: { yearButton }, } = useDatePickerContext(); - const selectedYear = calendars[0].year; + const selectedYear = calendars?.[0]?.year; const { prevNextAnimation, prevNextAnimationKey } = useDateAnimation({ listenTo: 'years', @@ -273,7 +273,7 @@ export function YearRangeSlider() { - {`${years[0].year} - ${years[years.length - 1].year}`} + {`${years?.[0]?.year} - ${years?.[years.length - 1]?.year}`} )} - + {menuItems.map(({ label, onSelect = () => {} }) => ( {label} diff --git a/packages/ui/src/form/components/ImageUpload/ImageUpload.tsx b/packages/ui/src/form/components/ImageUpload/ImageUpload.tsx index cafee6784..62d57b3ab 100644 --- a/packages/ui/src/form/components/ImageUpload/ImageUpload.tsx +++ b/packages/ui/src/form/components/ImageUpload/ImageUpload.tsx @@ -12,7 +12,12 @@ const RButton: any = OriginalRButton; const RStack: any = OriginalRStack; const RH5: any = OriginalRH5; -export const ImageUpload = ({ hasProfileImage, previewElement, name, label }) => { +export const ImageUpload = ({ + hasProfileImage, + previewElement, + name, + label, +}) => { const { pickImage, removeImage, src } = useImageUpload(name); const [hasImage, setHasImage] = useState(hasProfileImage); @@ -36,13 +41,19 @@ export const ImageUpload = ({ hasProfileImage, previewElement, name, label }) => padding="$4" borderRadius="$3" space - style={{ flexDirection: 'column', alignItems: "center", justifyContent: "center" }} + style={{ + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + }} > {cloneElement(previewElement, { src })} - + {label} } color="white" - size="$3" style={{ backgroundColor: '#232323', color: 'white', - textAlign: 'center' + textAlign: 'center', }} onPress={handlePickImage} > @@ -81,7 +91,7 @@ export const ImageUpload = ({ hasProfileImage, previewElement, name, label }) => style={{ backgroundColor: '#232323', color: 'white', - textAlign: 'center' + textAlign: 'center', }} onPress={handleRemoveImage} > diff --git a/packages/ui/src/form/components/SubmitButton.tsx b/packages/ui/src/form/components/SubmitButton.tsx index 055ccaec0..8f46ee8fa 100644 --- a/packages/ui/src/form/components/SubmitButton.tsx +++ b/packages/ui/src/form/components/SubmitButton.tsx @@ -11,12 +11,15 @@ export const SubmitButton = ({ const safeStyle = typeof style === 'object' && style !== null ? style : {}; return ( i.value !== item.value) ?? [] + ? ((selection as Option[])?.filter((i) => i.value !== item.value) ?? []) : [...((selection as Option[]) ?? []), item]; } else { newVal = isSelected(item) ? null : item; @@ -139,7 +139,7 @@ export function LmAutocomplete({ helperText={helperText} helperTextProps={helperTextProps} size={size} - {...containerProps} + {...(containerProps as any)} > diff --git a/packages/ui/src/form/lib/LmInput.tsx b/packages/ui/src/form/lib/LmInput.tsx index 675040826..43ee3a2ce 100644 --- a/packages/ui/src/form/lib/LmInput.tsx +++ b/packages/ui/src/form/lib/LmInput.tsx @@ -69,7 +69,7 @@ export const LmInput = forwardRef(function LmInputEl( labelInline={labelInline} helperText={helperText} helperTextProps={helperTextProps} - {...containerProps} + {...(containerProps as any)} > {multiline ? (