diff --git a/apps/bottle/src/app/bottles/Bottles.tsx b/apps/bottle/src/app/bottles/Bottles.tsx index b84ab7b..40f0892 100644 --- a/apps/bottle/src/app/bottles/Bottles.tsx +++ b/apps/bottle/src/app/bottles/Bottles.tsx @@ -46,22 +46,15 @@ export function Bottles() { top={data => ( {name => ( - <> - - {type === 'random' - ? data.randomBottles?.length > 0 - ? `${name}님에게\n추천하는 분들이에요!` - : '아직 주변에 새로운\n보틀이 없어요' - : data.sentBottles?.length > 0 - ? `${name}님을 마음에\n들어한 분들이에요` - : '아직 받은 보틀이 없어요'} - - - {type === 'random' - ? '시간이 지나면 새로운 분들을 추천해 드려요' - : '시간 내에 보틀을 열지 않으면 사라져요'} - - + + {type === 'random' + ? data.randomBottles?.length > 0 + ? `${name}님에게\n추천하는 분들이에요!` + : '아직 주변에 새로운\n보틀이 없어요' + : data.sentBottles?.length > 0 + ? `${name}님을 마음에\n들어한 분들이에요` + : '아직 받은 보틀이 없어요'} + )} )} @@ -69,8 +62,18 @@ export function Bottles() { {data => { const bottles = type === 'random' ? data.randomBottles : data.sentBottles; return bottles.length === 0 ? ( -
- no bottle +
+
+ no bottle +
) : ( bottles?.map(bottle => ( diff --git a/apps/bottle/src/app/bottles/[...slug]/ActionButtons.tsx b/apps/bottle/src/app/bottles/[...slug]/ActionButtons.tsx index 465f2bb..3df67c4 100644 --- a/apps/bottle/src/app/bottles/[...slug]/ActionButtons.tsx +++ b/apps/bottle/src/app/bottles/[...slug]/ActionButtons.tsx @@ -1,9 +1,8 @@ 'use client'; -import { FixedButton } from '@/features/steps/StepContainer'; import { useAcceptBottleMutation } from '@/store/mutation/useAcceptBottleMutation'; import { useRefuseBottleMutation } from '@/store/mutation/useRefuseBottleMutation'; -import { CTAButton } from '@bottlesteam/ui'; +import { CTAButton, FixedBottomCTAButton } from '@bottlesteam/ui'; import { overlay } from 'overlay-kit'; import { BottleType } from '../Bottles'; import { ExpressInterestBottomSheet } from './ExpressInterestBottomSheet'; @@ -31,7 +30,7 @@ export function ActionButtons({ type, id }: Props) { : () => accept(null); return ( - refuse()}>떠내려 보내기} right={ diff --git a/apps/bottle/src/app/bottles/[...slug]/ExpressInterestBottomSheet.tsx b/apps/bottle/src/app/bottles/[...slug]/ExpressInterestBottomSheet.tsx index 2e394da..a796f1d 100644 --- a/apps/bottle/src/app/bottles/[...slug]/ExpressInterestBottomSheet.tsx +++ b/apps/bottle/src/app/bottles/[...slug]/ExpressInterestBottomSheet.tsx @@ -1,7 +1,7 @@ import { Control } from '@/components/control'; -import { BottomSheet, BottomSheetProps, Button, Paragraph, TextField, spacings } from '@bottlesteam/ui'; +import { Asset, BottomSheet, BottomSheetProps, Button, Paragraph, TextField, spacings } from '@bottlesteam/ui'; import { useEffect, useState } from 'react'; -import { emoticonsContainer } from './bottomSheetStyle.css'; +import { deleteButtonStyle, emoticonsContainer } from './bottomSheetStyle.css'; interface Props extends Omit { onExpress: (likeMessage: string) => void; @@ -32,7 +32,24 @@ export function ExpressInterestBottomSheet({ onExpress, ...bottomSheetProps }: P size="sm" body={ <> - setMessage(e.currentTarget.value)} error={isError} /> + setMessage(e.currentTarget.value)} + error={isError} + rightButton={ + message.length > 0 && ( + + ) + } + /> {isError && ERROR_CAPTION} 이모티콘으로 표현해보세요 diff --git a/apps/bottle/src/app/bottles/[...slug]/bottomSheetStyle.css.ts b/apps/bottle/src/app/bottles/[...slug]/bottomSheetStyle.css.ts index 3091bc1..11c8d5d 100644 --- a/apps/bottle/src/app/bottles/[...slug]/bottomSheetStyle.css.ts +++ b/apps/bottle/src/app/bottles/[...slug]/bottomSheetStyle.css.ts @@ -7,6 +7,10 @@ export const emoticonsContainer = style({ justifyContent: 'space-between', marginTop: spacings.sm, }); -// export const emoticonBox=style({ - -// }) +export const deleteButtonStyle = style({ + background: 'none', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + border: 'none', +}); diff --git a/apps/bottle/src/app/create-profile/_steps/interests/index.tsx b/apps/bottle/src/app/create-profile/_steps/interests/index.tsx index f2c6255..d173418 100644 --- a/apps/bottle/src/app/create-profile/_steps/interests/index.tsx +++ b/apps/bottle/src/app/create-profile/_steps/interests/index.tsx @@ -46,44 +46,42 @@ export function Interests() { return ( <> - - 푹 빠진 취미는 무엇인가요? - 최소 3개, 최대 10개까지 선택할 수 있어요 - 문화 예술 - -
- {culture.map((item, index) => ( - handleClick(item)}> - {item} - - ))} -
- 스포츠 -
- {sports.map((item, index) => ( - handleClick(item)}> - {item} - - ))} -
- 오락 -
- {entertainment.map((item, index) => ( - handleClick(item)}> - {item} - - ))} -
- 기타 -
- {etc.map((item, index) => ( - handleClick(item)}> - {item} - - ))} -
-
-
+ 푹 빠진 취미는 무엇인가요? + 최소 3개, 최대 10개까지 선택할 수 있어요 + 문화 예술 + +
+ {culture.map((item, index) => ( + handleClick(item)}> + {item} + + ))} +
+ 스포츠 +
+ {sports.map((item, index) => ( + handleClick(item)}> + {item} + + ))} +
+ 오락 +
+ {entertainment.map((item, index) => ( + handleClick(item)}> + {item} + + ))} +
+ 기타 +
+ {etc.map((item, index) => ( + handleClick(item)}> + {item} + + ))} +
+
{ diff --git a/apps/bottle/src/app/create-profile/_steps/kakao-id/index.tsx b/apps/bottle/src/app/create-profile/_steps/kakao-id/index.tsx index 8c3224a..d762333 100644 --- a/apps/bottle/src/app/create-profile/_steps/kakao-id/index.tsx +++ b/apps/bottle/src/app/create-profile/_steps/kakao-id/index.tsx @@ -41,7 +41,7 @@ export function KaKaoId() { send({ type: AppBridgeMessageType.CREATE_PROFILE_COMPLETE }); }} > - 다음 + 완료 ); diff --git a/apps/bottle/src/app/create-profile/_steps/region/bottom-sheet/RegionBottomSheet.tsx b/apps/bottle/src/app/create-profile/_steps/region/bottom-sheet/RegionBottomSheet.tsx index df06938..32cff91 100644 --- a/apps/bottle/src/app/create-profile/_steps/region/bottom-sheet/RegionBottomSheet.tsx +++ b/apps/bottle/src/app/create-profile/_steps/region/bottom-sheet/RegionBottomSheet.tsx @@ -1,6 +1,6 @@ import { Asset, Paragraph, colors, BottomSheet, BottomSheetProps, Chip } from '@bottlesteam/ui'; import { useEffect, useState } from 'react'; -import { itemStyle, listStyle, tabBarStyle } from './regionBottomSheetStyle.css'; +import { itemStyle, listStyle, tabBarStyle, tabItemsStyle } from './regionBottomSheetStyle.css'; interface Props extends Omit { items: string[]; @@ -25,7 +25,7 @@ export function RegionBottomSheet({ onSelect, selected, items, type, ...bottomSh {...bottomSheetProps} body={ <> - +
    {items.map(item => (
  • - 전체 지역 - - 상세 지역 +
    + 전체 지역 + + 상세 지역 +
    +
    + +
); } diff --git a/apps/bottle/src/app/create-profile/_steps/region/bottom-sheet/regionBottomSheetStyle.css.ts b/apps/bottle/src/app/create-profile/_steps/region/bottom-sheet/regionBottomSheetStyle.css.ts index f98846a..c79c584 100644 --- a/apps/bottle/src/app/create-profile/_steps/region/bottom-sheet/regionBottomSheetStyle.css.ts +++ b/apps/bottle/src/app/create-profile/_steps/region/bottom-sheet/regionBottomSheetStyle.css.ts @@ -5,10 +5,17 @@ export const tabBarStyle = style({ width: '100%', display: 'flex', alignItems: 'center', - gap: spacings.sm, + justifyContent: 'space-between', + marginBottom: spacings.xl, }); +export const tabItemsStyle = style({ + display: 'flex', + gap: spacings.xxs, + alignItems: 'center', +}); + export const listStyle = style({ width: '100%', height: '208px', @@ -16,9 +23,6 @@ export const listStyle = style({ display: 'flex', flexDirection: 'column', gap: spacings.sm, - '::-webkit-scrollbar': { - display: 'none', - }, }); export const itemStyle = style({ @@ -26,3 +30,5 @@ export const itemStyle = style({ display: 'flex', alignItems: 'center', }); + +export const closeIconStyle = style({}); diff --git a/apps/bottle/src/app/create-profile/_steps/region/index.tsx b/apps/bottle/src/app/create-profile/_steps/region/index.tsx index a90cf1b..3a839e2 100644 --- a/apps/bottle/src/app/create-profile/_steps/region/index.tsx +++ b/apps/bottle/src/app/create-profile/_steps/region/index.tsx @@ -31,32 +31,6 @@ export function Region() { const [city, setCity] = useState(selected != null ? selected.city : undefined); const [state, setState] = useState(selected != null ? selected.state : undefined); - const openRegionBottomSheet = (type: 'city' | 'state') => { - overlay.open(({ isOpen, unmount }) => { - return ( - <> - {regionsData && ( - { - type === 'city' ? setCity(item) : setState(item); - type === 'city' && city !== item && setState(undefined); - }} - isOpen={isOpen} - onClose={unmount} - items={ - type === 'city' - ? regionsData.regions.map(({ city }) => city) - : (regionsData.regions.find(region => region.city === city) as RegionData).state - } - /> - )} - - ); - }); - }; - return ( <> @@ -64,19 +38,46 @@ export function Region() { 전체 지역
openRegionBottomSheet('city')} + onClick={async () => { + if (regionsData == null) { + return; + } + const selectedCity = await openRegionBottomSheet( + 'city', + regionsData?.regions.map(({ city }) => city), + city + ); + if (selectedCity !== city) { + setCity(selectedCity); + setState(undefined); + } + + if (selectedCity != null) { + const selectedState = await openRegionBottomSheet( + 'state', + (regionsData?.regions.find(region => region.city === selectedCity) as RegionData).state, + state + ); + setState(selectedState); + } + }} placeholder={'전체 지역을 선택해 주세요'} value={city} /> 시 · 군 · 구
{ + onClick={async () => { if (city === undefined) { send({ type: AppBridgeMessageType.TOAST_OPEN, payload: { message: '전체 지역을 먼저 선택해주세요.' } }); return; } - openRegionBottomSheet('state'); + const selectedState = await openRegionBottomSheet( + 'state', + (regionsData?.regions.find(region => region.city === city) as RegionData).state, + state + ); + setState(selectedState); }} placeholder={'상세 지역을 선택해 주세요'} value={state} @@ -98,3 +99,23 @@ export function Region() { ); } + +const openRegionBottomSheet = async ( + type: 'city' | 'state', + items: string[], + selected: string | undefined +): Promise => + await overlay.openAsync(({ isOpen, close, unmount }) => { + return ( + <> + + + ); + }); diff --git a/apps/bottle/src/components/user-information/SelectedProfile.tsx b/apps/bottle/src/components/user-information/SelectedProfile.tsx index 6037ff2..89ee93e 100644 --- a/apps/bottle/src/components/user-information/SelectedProfile.tsx +++ b/apps/bottle/src/components/user-information/SelectedProfile.tsx @@ -19,7 +19,7 @@ export function SelectedProfile({ interest: { culture, sports, entertainment, etc }, }, }: Props) { - const basicInformation = [job, mbti, city, height, smoking, alcohol]; + const basicInformation = [job, mbti, city, `${height}cm`, smoking, alcohol]; const personalities = keyword; const hobbies = [ ...Object.values(culture), diff --git a/apps/bottle/src/features/steps/StepContainer.tsx b/apps/bottle/src/features/steps/StepContainer.tsx index 085b28b..dc6adb2 100644 --- a/apps/bottle/src/features/steps/StepContainer.tsx +++ b/apps/bottle/src/features/steps/StepContainer.tsx @@ -1,7 +1,7 @@ import { Stepper } from '@/components/stepper'; -import { CTAButton, Paragraph, ParagraphProps, VariantOneProps, VariantTwoProps } from '@bottlesteam/ui'; +import { FixedBottomCTAButton, Paragraph, ParagraphProps, VariantOneProps } from '@bottlesteam/ui'; import { ReactNode } from 'react'; -import { buttonContainer, buttonStyle, containerStyle } from './stepStyle.css'; +import { containerStyle } from './stepStyle.css'; interface Props { children: ReactNode; @@ -40,33 +40,8 @@ function Subtitle({ children, ...rest }: Omit -
- {isVariantOne(props) ? ( - - {props.children} - - ) : ( - - )} -
-
- ); +function FixedButton(props: VariantOneProps) { + return ; } export const Step = Object.assign(StepContainer, { diff --git a/packages/e2e/tests/create-profile.spec.ts b/packages/e2e/tests/create-profile.spec.ts index 098a046..867282b 100644 --- a/packages/e2e/tests/create-profile.spec.ts +++ b/packages/e2e/tests/create-profile.spec.ts @@ -111,7 +111,6 @@ test('Create Profile Funnel Basic Flow', async ({ page }) => { }); await test.step('Select region and move to step 10', async () => { const cityPlaceholder = page.getByText('전체 지역을 선택해 주세요'); - const statePlaceholder = page.getByText('상세 지역을 선택해 주세요'); await cityPlaceholder.click(); const city = page.getByRole('listitem').first(); @@ -119,7 +118,6 @@ test('Create Profile Funnel Basic Flow', async ({ page }) => { const citySelectButton = page.getByRole('button', { name: '완료', exact: true }); await citySelectButton.click(); - await statePlaceholder.click(); const state = page.getByRole('listitem').first(); await state.click(); const stateSelectButton = page.getByRole('button', { name: '완료', exact: true }); diff --git a/packages/ui/src/components/agreement/Agreement.tsx b/packages/ui/src/components/agreement/Agreement.tsx index 2c64aa5..64b209d 100644 --- a/packages/ui/src/components/agreement/Agreement.tsx +++ b/packages/ui/src/components/agreement/Agreement.tsx @@ -1,6 +1,6 @@ import { ComponentProps, ReactNode } from 'react'; -import { agreementListContainerStyle, containerStyle, separatorStyle } from './agreementStyle.css'; import { AgreementAgreeAllItem, AgreementItem } from './AgreementItem'; +import { agreementListContainerStyle, containerStyle, separatorStyle } from './agreementStyle.css'; export interface AgreementProps extends ComponentProps<'div'> { agreeAll: ReactNode; diff --git a/packages/ui/src/components/agreement/AgreementItem.tsx b/packages/ui/src/components/agreement/AgreementItem.tsx index 2a3d362..e8e130f 100644 --- a/packages/ui/src/components/agreement/AgreementItem.tsx +++ b/packages/ui/src/components/agreement/AgreementItem.tsx @@ -1,7 +1,7 @@ import { ChangeEvent, ReactNode, useId } from 'react'; -import { agreementItemStyle, checkboxStyle } from './agreementStyle.css'; import { Asset } from '../asset'; import { Paragraph } from '../paragraph'; +import { agreementItemStyle, checkboxStyle } from './agreementStyle.css'; export interface AgreementItemProps { checked: boolean; diff --git a/packages/ui/src/components/asset/Asset.tsx b/packages/ui/src/components/asset/Asset.tsx index e74554c..dbd664c 100644 --- a/packages/ui/src/components/asset/Asset.tsx +++ b/packages/ui/src/components/asset/Asset.tsx @@ -2,6 +2,8 @@ import { ComponentProps } from 'react'; import LeftArrowIcon from './icons/icon_arrow_left.svg'; import CheckIcon from './icons/icon_check.svg'; import CheckIconColored from './icons/icon_check_colored.svg'; +import IconClose from './icons/icon_close.svg'; +import DeleteIcon from './icons/icon_delete.svg'; import DownIcon from './icons/icon_down.svg'; import RightIcon from './icons/icon_right.svg'; import VerticalBarIcon from './icons/icon_vertical_bar.svg'; @@ -14,7 +16,9 @@ type Type = | 'icon-vertical-bar' | 'vector' | 'icon-check' - | 'icon-check-colored'; + | 'icon-check-colored' + | 'icon-close' + | 'icon-delete'; export interface AssetProps extends ComponentProps<'svg'> { type: Type; @@ -33,6 +37,10 @@ export function Asset({ type, ...rest }: AssetProps) { ) : type === 'icon-check-colored' ? ( + ) : type === 'icon-close' ? ( + + ) : type === 'icon-delete' ? ( + ) : ( ); diff --git a/packages/ui/src/components/asset/icons/icon_close.svg b/packages/ui/src/components/asset/icons/icon_close.svg new file mode 100644 index 0000000..bc112eb --- /dev/null +++ b/packages/ui/src/components/asset/icons/icon_close.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/ui/src/components/asset/icons/icon_delete.svg b/packages/ui/src/components/asset/icons/icon_delete.svg new file mode 100644 index 0000000..38782c2 --- /dev/null +++ b/packages/ui/src/components/asset/icons/icon_delete.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/ui/src/components/bubble/bubbleStyle.css.ts b/packages/ui/src/components/bubble/bubbleStyle.css.ts index d4e256f..09ce392 100644 --- a/packages/ui/src/components/bubble/bubbleStyle.css.ts +++ b/packages/ui/src/components/bubble/bubbleStyle.css.ts @@ -1,5 +1,5 @@ import { style } from '@vanilla-extract/css'; -import { colors, spacings } from '../../foundations'; +import { colors, spacings, typography } from '../../foundations'; export const wrapperStyle = style({ width: 'auto', @@ -18,6 +18,8 @@ export const messageContainerstyle = style({ alignItems: 'center', backgroundColor: colors.white100, borderRadius: '20px', + boxShadow: '0px 0px 8px 0px rgba(0, 0, 0, 0.04);', + ...typography.st2, }); export const vectorContainerStyle = style({ diff --git a/packages/ui/src/components/button/button.css.ts b/packages/ui/src/components/button/button.css.ts index 9ff3fe0..7562efd 100644 --- a/packages/ui/src/components/button/button.css.ts +++ b/packages/ui/src/components/button/button.css.ts @@ -150,7 +150,7 @@ export const buttonStyle = recipe({ style: { color: colors.white100, width: '328px', - height: '56px', + height: '64px', ...typography.st1, backgroundColor: colors.purple400, borderRadius: radius.sm, diff --git a/packages/ui/src/components/chip/chipStyle.css.ts b/packages/ui/src/components/chip/chipStyle.css.ts index d224e1a..560d54e 100644 --- a/packages/ui/src/components/chip/chipStyle.css.ts +++ b/packages/ui/src/components/chip/chipStyle.css.ts @@ -9,7 +9,7 @@ export const chipStyle = recipe({ justifyContent: 'center', alignItems: 'center', ...typography.bo, - borderRadius: radius.sm, + borderRadius: radius.xs, padding: `0 ${spacings.sm}`, }, variants: { diff --git a/packages/ui/src/components/cta-button/CTAButton.tsx b/packages/ui/src/components/cta-button/CTAButton.tsx index 7da4725..82001cc 100644 --- a/packages/ui/src/components/cta-button/CTAButton.tsx +++ b/packages/ui/src/components/cta-button/CTAButton.tsx @@ -3,6 +3,7 @@ import { VariantOne, VariantOneProps } from './VariantOne/VariantOne'; import { LeftButton } from './VariantTwo/LeftButton'; import { RightButton } from './VariantTwo/RightButton'; import { VariantTwo, VariantTwoProps } from './VariantTwo/VariantTwo'; +import { isVariantOne } from './utils'; export type CTAButtonProps = | ({ @@ -12,12 +13,6 @@ export type CTAButtonProps = variant: 'two'; } & VariantTwoProps); -export function isVariantOne(props: CTAButtonProps): props is { - variant: 'one'; -} & VariantOneProps { - return props.variant === 'one'; -} - const CTAButtonImpl = forwardRef, CTAButtonProps>((props: CTAButtonProps, ref) => { return isVariantOne(props) ? ( diff --git a/packages/ui/src/components/cta-button/index.ts b/packages/ui/src/components/cta-button/index.ts index 2050cbe..4f44c64 100644 --- a/packages/ui/src/components/cta-button/index.ts +++ b/packages/ui/src/components/cta-button/index.ts @@ -1,2 +1,3 @@ export { CTAButton } from './CTAButton'; export type { CTAButtonProps, VariantOneProps, VariantTwoProps } from './CTAButton'; +export { isVariantOne } from './utils'; diff --git a/packages/ui/src/components/cta-button/utils.ts b/packages/ui/src/components/cta-button/utils.ts new file mode 100644 index 0000000..411eb60 --- /dev/null +++ b/packages/ui/src/components/cta-button/utils.ts @@ -0,0 +1,7 @@ +import { CTAButtonProps, VariantOneProps } from './CTAButton'; + +export function isVariantOne(props: CTAButtonProps): props is { + variant: 'one'; +} & VariantOneProps { + return props.variant === 'one'; +} diff --git a/packages/ui/src/components/fixed-bottom-cta-button/FixedBottomCTAButton.tsx b/packages/ui/src/components/fixed-bottom-cta-button/FixedBottomCTAButton.tsx new file mode 100644 index 0000000..cefcb42 --- /dev/null +++ b/packages/ui/src/components/fixed-bottom-cta-button/FixedBottomCTAButton.tsx @@ -0,0 +1,21 @@ +import { MAX_WIDTH } from '../../constants'; +import { CTAButton, CTAButtonProps, isVariantOne } from '../cta-button'; +import { buttonStyle, buttonContainer } from './fixedBottomCTAButtonStyle.css'; + +export type FixedBottomCTAButtonProps = CTAButtonProps; + +export function FixedBottomCTAButton(props: FixedBottomCTAButtonProps) { + return ( +
+
+ {isVariantOne(props) ? ( + + {props.children} + + ) : ( + + )} +
+
+ ); +} diff --git a/packages/ui/src/components/fixed-bottom-cta-button/fixedBottomCTAButtonStyle.css.ts b/packages/ui/src/components/fixed-bottom-cta-button/fixedBottomCTAButtonStyle.css.ts new file mode 100644 index 0000000..cc5e383 --- /dev/null +++ b/packages/ui/src/components/fixed-bottom-cta-button/fixedBottomCTAButtonStyle.css.ts @@ -0,0 +1,24 @@ +import { style } from '@vanilla-extract/css'; +import { CTA_HEIGHT } from '../../constants'; +import { spacings } from '../../foundations'; + +export const buttonContainer = style({ + position: 'fixed', + bottom: 0, + left: 0, + width: '100%', + height: `${CTA_HEIGHT}px`, + paddingTop: spacings.xl, + display: 'flex', + justifyContent: 'center', + background: 'linear-gradient(180deg, rgba(251, 251, 251, 0) 0%, #FBFBFB 25%)', +}); + +export const buttonStyle = style({ + width: '100%', + '@media': { + 'screen and (min-width: 500px)': { + width: '360px', + }, + }, +}); diff --git a/packages/ui/src/components/fixed-bottom-cta-button/index.ts b/packages/ui/src/components/fixed-bottom-cta-button/index.ts new file mode 100644 index 0000000..3994911 --- /dev/null +++ b/packages/ui/src/components/fixed-bottom-cta-button/index.ts @@ -0,0 +1,2 @@ +export { FixedBottomCTAButton } from './FixedBottomCTAButton'; +export type { FixedBottomCTAButtonProps } from './FixedBottomCTAButton'; diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index a2e8794..7447a44 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -4,8 +4,10 @@ export { Bubble } from './bubble'; export type { BubbleProps } from './bubble'; export { ImageButton } from './image-button'; export type { ImageButtonProps } from './image-button'; -export { CTAButton } from './cta-button'; +export { CTAButton, isVariantOne } from './cta-button'; export type { CTAButtonProps, VariantOneProps, VariantTwoProps } from './cta-button'; +export { FixedBottomCTAButton } from './fixed-bottom-cta-button'; +export type { FixedBottomCTAButtonProps } from './fixed-bottom-cta-button'; export { Paragraph } from './paragraph'; export type { ParagraphProps } from './paragraph'; export { Asset } from './asset'; diff --git a/packages/ui/src/components/text-field/TextField.tsx b/packages/ui/src/components/text-field/TextField.tsx index 4a6ad45..0e8f72d 100644 --- a/packages/ui/src/components/text-field/TextField.tsx +++ b/packages/ui/src/components/text-field/TextField.tsx @@ -1,4 +1,4 @@ -import { ComponentPropsWithoutRef, ElementRef, ReactNode, forwardRef, useId } from 'react'; +import { ComponentPropsWithoutRef, ElementRef, ReactNode, forwardRef, useId, useState } from 'react'; import { Caption } from './Caption'; import { labelStyle, inputStyle, containerStyle } from './textFieldStyle.css'; @@ -11,14 +11,26 @@ export interface TextFieldProps extends ComponentPropsWithoutRef<'input'> { const TextFieldImpl = forwardRef, TextFieldProps>( ({ rightButton, caption, error = false, style, ...inputProps }, ref) => { const id = useId(); + const [focused, setFocused] = useState(false); const hasRightButton = rightButton !== undefined; const { disabled } = inputProps; return (
-