diff --git a/.changeset/metal-moles-invent.md b/.changeset/metal-moles-invent.md new file mode 100644 index 00000000..a88ff667 --- /dev/null +++ b/.changeset/metal-moles-invent.md @@ -0,0 +1,5 @@ +--- +'@sopt-makers/ui': minor +--- + +bottom sheet component diff --git a/apps/docs/src/App.tsx b/apps/docs/src/App.tsx index 8f62c614..81e712d8 100644 --- a/apps/docs/src/App.tsx +++ b/apps/docs/src/App.tsx @@ -5,7 +5,19 @@ import { ChangeEvent, useState } from 'react'; import '@sopt-makers/ui/dist/index.css'; import { colors } from '@sopt-makers/colors'; -import { FieldBox, SearchField, Test, TextArea, TextField, SelectV2, Tooltip } from '@sopt-makers/ui'; +import { + FieldBox, + SearchField, + Test, + TextArea, + TextField, + SelectV2, + BottomSheetRoot, + BottomSheetTrigger, + BottomSheetContent, + BottomSheetActionButton, + BottomSheetBody, +} from '@sopt-makers/ui'; interface Option { label: string; @@ -161,10 +173,24 @@ function App() { ))} - - 툴팁 트리거 - 콘텐츠 - + +
+ + 열기 + + +

+ 커뮤니티 이용규칙은 누구나 기분 좋게 참여할 수 있는 커뮤니티를 만들기 위해 제정되었습니다. 서비스 내의 + 모든 커뮤니티는 커뮤니티 이용규칙에 의해 운영되므로, 이용자는 커뮤니티 이용 전 반드시 모든 내용을 + 숙지하여야 합니다. 방송통신심의위원회의 정보통신에 관한 심의규정, 현행 법률, 서비스 이용약관 및 커뮤니티 + 이용규칙을 위반하거나, 사회 통념 및 관련 법령을 기준으로 타 이용자에게 악영향을 끼치는 경우, 게시물이 + 삭제되고 서비스 이용이 일정 기간 제한될 수 있습니다. 커뮤니티 이용규칙은 누구나 기분 좋게 참여할 수 있는 + 커뮤니티를 만들기 위해 제정되었습니다. 서비스 내의 모든 커뮤니티는 커뮤니티 이용규칙에 의해 운영되므로, +

+
+ Button +
+
); diff --git a/apps/docs/src/stories/BottomSheet.stories.tsx b/apps/docs/src/stories/BottomSheet.stories.tsx new file mode 100644 index 00000000..da3b2d0e --- /dev/null +++ b/apps/docs/src/stories/BottomSheet.stories.tsx @@ -0,0 +1,155 @@ +import { + BottomSheetActionButton, + BottomSheetBody, + BottomSheetContent, + BottomSheetRoot, + BottomSheetTrigger, +} from '@sopt-makers/ui'; +import type { Meta, StoryObj } from '@storybook/react'; + +type SampleProps = { + open?: boolean; + onOpenChange?: (open: boolean) => void; + defaultOpen?: boolean; + title?: string; + backIcon?: boolean; +}; + +const meta: Meta = { + title: 'Components/BottomSheet', + tags: ['autodocs'], + parameters: { + docs: { + codePanel: true, + }, + }, + args: { + defaultOpen: false, + title: 'Title', + backIcon: false, + }, + argTypes: { + open: { type: 'boolean', control: { type: 'boolean' }, description: '`boolean`' }, + onOpenChange: { + type: 'function', + control: { type: 'function' }, + description: '`(open:boolean) => void`', + }, + defaultOpen: { + type: 'boolean', + control: { type: 'boolean' }, + description: '`boolean`', + }, + title: { type: 'string', control: { type: 'string' }, description: '`string`' }, + backIcon: { type: 'boolean', control: { type: 'boolean' }, description: '`boolean`' }, + }, +}; +export default meta; + +export const BottomSheetDefault: StoryObj = { + name: 'BottomSheet - Default', + render: (args) => { + return ( + + + + + + +

+ 커뮤니티 이용규칙은 누구나 기분 좋게 참여할 수 있는 커뮤니티를 만들기 위해 제정되었습니다. 서비스 내의 + 모든 커뮤니티는 커뮤니티 이용규칙에 의해 운영되므로, 이용자는 커뮤니티 이용 전 반드시 모든 내용을 + 숙지하여야 합니다. 방송통신심의위원회의 정보통신에 관한 심의규정, 현행 법률, 서비스 이용약관 및 커뮤니티 + 이용규칙을 위반하거나, 사회 통념 및 관련 법령을 기준으로 타 이용자에게 악영향을 끼치는 경우, 게시물이 + 삭제되고 서비스 이용이 일정 기간 제한될 수 있습니다. +

+
+
+
+ ); + }, +}; + +export const BottomSheetBackIcon: StoryObj = { + name: 'BottomSheet - Back Icon', + render: (args) => ( + + + + + + +

+ 커뮤니티 이용규칙은 누구나 기분 좋게 참여할 수 있는 커뮤니티를 만들기 위해 제정되었습니다. 서비스 내의 모든 + 커뮤니티는 커뮤니티 이용규칙에 의해 운영되므로, 이용자는 커뮤니티 이용 전 반드시 모든 내용을 숙지하여야 + 합니다. 방송통신심의위원회의 정보통신에 관한 심의규정, 현행 법률, 서비스 이용약관 및 커뮤니티 이용규칙을 + 위반하거나, 사회 통념 및 관련 법령을 기준으로 타 이용자에게 악영향을 끼치는 경우, 게시물이 삭제되고 서비스 + 이용이 일정 기간 제한될 수 있습니다. +

+
+
+
+ ), + args: { + backIcon: true, + }, +}; + +export const BottomSheetWithActionButton: StoryObj = { + name: 'BottomSheet - Action Button', + render: (args) => ( + + + + + + +

+ 커뮤니티 이용규칙은 누구나 기분 좋게 참여할 수 있는 커뮤니티를 만들기 위해 제정되었습니다. 서비스 내의 모든 + 커뮤니티는 커뮤니티 이용규칙에 의해 운영되므로, 이용자는 커뮤니티 이용 전 반드시 모든 내용을 숙지하여야 + 합니다. 방송통신심의위원회의 정보통신에 관한 심의규정, 현행 법률, 서비스 이용약관 및 커뮤니티 이용규칙을 + 위반하거나, 사회 통념 및 관련 법령을 기준으로 타 이용자에게 악영향을 끼치는 경우, 게시물이 삭제되고 서비스 + 이용이 일정 기간 제한될 수 있습니다. +

+
+ Button +
+
+ ), +}; + +export const BottomSheetBodyScrolled: StoryObj = { + name: 'BottomSheet - Body Scrolled', + render: (args) => ( + + + + + + +

+ 커뮤니티 이용규칙은 누구나 기분 좋게 참여할 수 있는 커뮤니티를 만들기 위해 제정되었습니다. 서비스 내의 모든 + 커뮤니티는 커뮤니티 이용규칙에 의해 운영되므로, 이용자는 커뮤니티 이용 전 반드시 모든 내용을 숙지하여야 + 합니다. 방송통신심의위원회의 정보통신에 관한 심의규정, 현행 법률, 서비스 이용약관 및 커뮤니티 이용규칙을 + 위반하거나, 사회 통념 및 관련 법령을 기준으로 타 이용자에게 악영향을 끼치는 경우, 게시물이 삭제되고 서비스 + 이용이 일정 기간 제한될 수 있습니다. 커뮤니티 이용규칙은 누구나 기분 좋게 참여할 수 있는 커뮤니티를 만들기 + 위해 제정되었습니다. 서비스 내의 모든 커뮤니티는 커뮤니티 이용규칙에 의해 운영되므로, 이용자는 커뮤니티 이용 + 전 반드시 모든 내용을 숙지하여야 합니다. 방송통신심의위원회의 정보통신에 관한 심의규정, 현행 법률, 서비스 + 이용약관 및 커뮤니티 이용규칙을 위반하거나, 사회 통념 및 관련 법령을 기준으로 타 이용자에게 악영향을 끼치는 + 경우, 게시물이 삭제되고 서비스 이용이 일정 기간 제한될 수 있습니다. 커뮤니티 이용규칙은 누구나 기분 좋게 + 참여할 수 있는 커뮤니티를 만들기 위해 제정되었습니다. 서비스 내의 모든 커뮤니티는 커뮤니티 이용규칙에 의해 + 운영되므로, 이용자는 커뮤니티 이용 전 반드시 모든 내용을 숙지하여야 합니다. 방송통신심의위원회의 정보통신에 + 관한 심의규정, 현행 법률, 서비스 이용약관 및 커뮤니티 이용규칙을 위반하거나, 사회 통념 및 관련 법령을 + 기준으로 타 이용자에게 악영향을 끼치는 경우, 게시물이 삭제되고 서비스 이용이 일정 기간 제한될 수 있습니다. + 커뮤니티 이용규칙은 누구나 기분 좋게 참여할 수 있는 커뮤니티를 만들기 위해 제정되었습니다. 서비스 내의 모든 + 커뮤니티는 커뮤니티 이용규칙에 의해 운영되므로, 이용자는 커뮤니티 이용 전 반드시 모든 내용을 숙지하여야 + 합니다. 방송통신심의위원회의 정보통신에 관한 심의규정, 현행 법률, 서비스 이용약관 및 커뮤니티 이용규칙을 + 위반하거나, 사회 통념 및 관련 법령을 기준으로 타 이용자에게 악영향을 끼치는 경우, 게시물이 삭제되고 서비스 + 이용이 일정 기간 제한될 수 있습니다. +

+
+ Button +
+
+ ), +}; diff --git a/packages/eslint-config-custom/react-internal.js b/packages/eslint-config-custom/react-internal.js index ae6523a0..93a7452d 100644 --- a/packages/eslint-config-custom/react-internal.js +++ b/packages/eslint-config-custom/react-internal.js @@ -34,6 +34,7 @@ module.exports = { ignorePatterns: ['node_modules/', 'dist/', '.eslintrc.js'], rules: { + 'import/no-extraneous-dependencies': 'off', 'import/no-default-export': 'off', 'import/prefer-default-export': 'warn', '@typescript-eslint/explicit-function-return-type': 'off', diff --git a/packages/ui/BottomSheet/context.tsx b/packages/ui/BottomSheet/context.tsx new file mode 100644 index 00000000..d7017e44 --- /dev/null +++ b/packages/ui/BottomSheet/context.tsx @@ -0,0 +1,31 @@ +import { createContext, PropsWithChildren, useContext } from 'react'; + +interface ContextProps { + open: boolean; + onOpenChange: (open: boolean) => void; +} + +export const BottomSheetContext = createContext(null); + +export function BottomSheetProvider({ open, onOpenChange, children }: PropsWithChildren) { + return ( + + {children} + + ); +} + +export function useBottomSheetContext() { + const context = useContext(BottomSheetContext); + + if (context === null) { + throw new Error('this hook must be used within a BottomSheetProvider'); + } + + return context; +} diff --git a/packages/ui/BottomSheet/index.tsx b/packages/ui/BottomSheet/index.tsx new file mode 100644 index 00000000..ad067112 --- /dev/null +++ b/packages/ui/BottomSheet/index.tsx @@ -0,0 +1,150 @@ +/* eslint-disable -- able to click dim sesction jsx-a11y/click-events-have-key-events */ +/* eslint-disable -- able to click dim sesction jsx-a11y/no-static-element-interactions */ + +import { HTMLAttributes, PropsWithChildren, ReactNode, useEffect } from 'react'; +import { BottomSheetProvider, useBottomSheetContext } from './context'; +import { useBooleanState } from '@toss/react'; +import { IconChevronLeft } from '@sopt-makers/icons'; +import { + actionButtonStyle, + bodyWrapperStyle, + buttonWrapperStyle, + contentWrapperStyle, + dimStyle, + iconStyle, + overlayStyle, + titleTextStyle, + titleWrapperStyle, +} from './style.css'; +import Button from '../Button'; +import { createPortal } from 'react-dom'; + +export function BottomSheetTrigger({ children }: HTMLAttributes) { + const { open, onOpenChange } = useBottomSheetContext(); + + const handleOpenChange = () => { + onOpenChange(!open); + }; + + return
{children}
; +} + +BottomSheetTrigger.displayName = 'BottomSheetTrigger'; + +interface RootProps { + open?: boolean; + defaultOpen?: boolean; + onOpenChange?: (open: boolean) => void; +} + +export function BottomSheetRoot({ + open: _open, + defaultOpen = false, + onOpenChange, + children, +}: PropsWithChildren) { + const [internalOpenValue, internalOpen, internalClose] = useBooleanState(defaultOpen); + + const isUncontrolled = _open === undefined; + + const open = isUncontrolled ? internalOpenValue : _open; + const handleOpenChange = (value: boolean) => { + if (isUncontrolled) { + if (value) { + internalOpen(); + } else { + internalClose(); + } + } else { + onOpenChange?.(value); + } + }; + + return ( + + {children} + + ); +} + +BottomSheetRoot.displayName = 'BottomSheetRoot'; + +interface ContentProps { + title?: string; + backIcon?: boolean; +} + +export function BottomSheetContent({ title, backIcon, children }: PropsWithChildren) { + const { open, onOpenChange } = useBottomSheetContext(); + + useEffect(() => { + if (window === undefined) return; + + const getScrollbarWidth = () => { + return window.innerWidth - document.documentElement.clientWidth; + }; + + /** overflow hidden 시 스크롤바 사라짐으로 layout shift 방지를 위한 padding-right를 추가 */ + const originPaddingRight = document.body.style.paddingRight; + if (open) { + const scrollbarWidth = getScrollbarWidth(); + document.body.style.overflow = 'hidden'; + document.body.style.paddingRight = `${scrollbarWidth}px`; + } + + return () => { + document.body.style.overflow = 'auto'; + document.body.style.paddingRight = originPaddingRight; + }; + }, [open]); + + return createPortal( + open && ( + <> +
onOpenChange(false)} /> +
+ {title && ( +
+ {backIcon && onOpenChange(false)} className={iconStyle} />} +

{title}

+
+ )} + {children} +
+ + ), + document.body, + ); +} + +BottomSheetContent.displayName = 'BottomSheetContent'; + +interface BodyProps extends HTMLAttributes { + maxHeight?: string; +} + +export const BottomSheetBody = ({ children, ...props }: PropsWithChildren) => { + const { maxHeight = '400px', ...restProps } = props; + + return ( +
+
+ {children} +
+
+ ); +}; + +BottomSheetBody.displayName = 'BottomSheetBody'; + +export function BottomSheetActionButton({ children }: PropsWithChildren) { + return ( +
+ +
+ ); +} + +BottomSheetActionButton.displayName = 'BottomSheetActionButton'; diff --git a/packages/ui/BottomSheet/style.css.ts b/packages/ui/BottomSheet/style.css.ts new file mode 100644 index 00000000..837906b2 --- /dev/null +++ b/packages/ui/BottomSheet/style.css.ts @@ -0,0 +1,64 @@ +import { style } from '@vanilla-extract/css'; +import theme from '../theme.css'; + +export const iconStyle = style({ + width: '24px', + height: '24px', + color: theme.colors.gray10, + cursor: 'pointer', +}); + +export const overlayStyle = style({ + position: 'fixed', + bottom: 0, + left: 0, + + zIndex: 999, + width: 'calc(100% - 32px)', + padding: '12px 8px', + margin: '0px 16px', + + backgroundColor: theme.colors.gray800, + borderRadius: '16px', +}); + +export const buttonWrapperStyle = style({ + padding: '8px 8px 0px 8px', +}); + +export const actionButtonStyle = style({ + width: '100%', +}); + +export const titleWrapperStyle = style({ + display: 'flex', + alignItems: 'center', + paddingTop: '8px', +}); + +export const titleTextStyle = style({ + padding: '0 8px', + color: theme.colors.gray10, + ...theme.fontsObject.TITLE_4_20_SB, +}); + +export const bodyWrapperStyle = style({ + padding: '12px 8px', +}); + +export const contentWrapperStyle = style({ + overflowY: 'auto', +}); + +export const dimStyle = style({ + position: 'fixed', + left: 0, + top: 0, + + zIndex: 999, + width: '100%', + height: '100%', + backgroundColor: theme.colors.backgroundDimmed, + overflowY: 'hidden', + touchAction: 'none', +}); diff --git a/packages/ui/index.ts b/packages/ui/index.ts index 9f4a2314..85175c3a 100644 --- a/packages/ui/index.ts +++ b/packages/ui/index.ts @@ -15,5 +15,6 @@ export { Tooltip } from './Tooltip'; export * from './Skeleton'; export * from './FieldBox'; export * from './Tag'; +export * from './BottomSheet'; // test component export { default as Test } from './Test'; diff --git a/packages/ui/package.json b/packages/ui/package.json index 28dbad8a..4a17ea27 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -27,6 +27,7 @@ "@sopt-makers/colors": "workspace:^", "@sopt-makers/fonts": "workspace:^", "@sopt-makers/icons": "workspace:^", + "@toss/react": "^1.8.1", "@vanilla-extract/css": "^1.14.0", "@vanilla-extract/sprinkles": "^1.6.1", "clsx": "^2.1.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 69d34725..f91296e1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,7 +29,7 @@ importers: version: link:packages/tsconfig turbo: specifier: latest - version: 2.5.4 + version: 2.7.3 apps/docs: dependencies: @@ -184,6 +184,9 @@ importers: '@sopt-makers/icons': specifier: workspace:^ version: link:../icons + '@toss/react': + specifier: ^1.8.1 + version: 1.8.1(react@18.3.1) '@vanilla-extract/css': specifier: ^1.14.0 version: 1.16.0 @@ -2766,6 +2769,21 @@ packages: '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + '@toss/react@1.8.1': + resolution: {integrity: sha512-jH3oo/7yctexuutj/YgQrddaK1bU2s5659dkJIXOe23bEjkY+lbhvEz2FLEhRjSo6k6ktPagpxO4AcdhCi5k5A==} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18 + + '@toss/storage@1.4.1': + resolution: {integrity: sha512-jvnBXAQ/Fqqdt+gqYKeHYk7SzR2LX/FC50JIoVI0RldG1mDh1tebOqD7XkrZ89q77t/RwTuh60+8fjZDgend/g==} + + '@toss/utility-types@1.2.1': + resolution: {integrity: sha512-1y8s1bvmuhuMX/d6qR9mmvcgFZIKYIQqJbAIshlGArXkjk/ec67gXc5uByEV1Y7in9ZhrGNRmjD8DTH0988vpQ==} + + '@toss/utils@1.6.1': + resolution: {integrity: sha512-x6m8jLKWtAmCbxTLXbgTzJ5wZyRSUQPLpR/oLJP1ZK9ytXcRf03oA46W/+78kErUkEw/yQz2L+t2xFDHSeZ6IQ==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + '@trysound/sax@0.2.0': resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} @@ -3587,6 +3605,9 @@ packages: citty@0.1.6: resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + clean-regexp@1.0.0: resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} engines: {node: '>=4'} @@ -3814,6 +3835,10 @@ packages: resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} engines: {node: '>= 0.4'} + date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -5272,6 +5297,9 @@ packages: lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + lodash.throttle@4.1.1: + resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -6406,6 +6434,7 @@ packages: source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} + deprecated: The work that was done in this beta branch won't be included in future versions space-separated-tokens@1.1.5: resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} @@ -6796,38 +6825,38 @@ packages: peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - turbo-darwin-64@2.5.4: - resolution: {integrity: sha512-ah6YnH2dErojhFooxEzmvsoZQTMImaruZhFPfMKPBq8sb+hALRdvBNLqfc8NWlZq576FkfRZ/MSi4SHvVFT9PQ==} + turbo-darwin-64@2.7.3: + resolution: {integrity: sha512-aZHhvRiRHXbJw1EcEAq4aws1hsVVUZ9DPuSFaq9VVFAKCup7niIEwc22glxb7240yYEr1vLafdQ2U294Vcwz+w==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.5.4: - resolution: {integrity: sha512-2+Nx6LAyuXw2MdXb7pxqle3MYignLvS7OwtsP9SgtSBaMlnNlxl9BovzqdYAgkUW3AsYiQMJ/wBRb7d+xemM5A==} + turbo-darwin-arm64@2.7.3: + resolution: {integrity: sha512-CkVrHSq+Bnhl9sX2LQgqQYVfLTWC2gvI74C4758OmU0djfrssDKU9d4YQF0AYXXhIIRZipSXfxClQziIMD+EAg==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.5.4: - resolution: {integrity: sha512-5May2kjWbc8w4XxswGAl74GZ5eM4Gr6IiroqdLhXeXyfvWEdm2mFYCSWOzz0/z5cAgqyGidF1jt1qzUR8hTmOA==} + turbo-linux-64@2.7.3: + resolution: {integrity: sha512-GqDsCNnzzr89kMaLGpRALyigUklzgxIrSy2pHZVXyifgczvYPnLglex78Aj3T2gu+T3trPPH2iJ+pWucVOCC2Q==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.5.4: - resolution: {integrity: sha512-/2yqFaS3TbfxV3P5yG2JUI79P7OUQKOUvAnx4MV9Bdz6jqHsHwc9WZPpO4QseQm+NvmgY6ICORnoVPODxGUiJg==} + turbo-linux-arm64@2.7.3: + resolution: {integrity: sha512-NdCDTfIcIo3dWjsiaAHlxu5gW61Ed/8maah1IAF/9E3EtX0aAHNiBMbuYLZaR4vRJ7BeVkYB6xKWRtdFLZ0y3g==} cpu: [arm64] os: [linux] - turbo-windows-64@2.5.4: - resolution: {integrity: sha512-EQUO4SmaCDhO6zYohxIjJpOKRN3wlfU7jMAj3CgcyTPvQR/UFLEKAYHqJOnJtymbQmiiM/ihX6c6W6Uq0yC7mA==} + turbo-windows-64@2.7.3: + resolution: {integrity: sha512-7bVvO987daXGSJVYBoG8R4Q+csT1pKIgLJYZevXRQ0Hqw0Vv4mKme/TOjYXs9Qb1xMKh51Tb3bXKDbd8/4G08g==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.5.4: - resolution: {integrity: sha512-oQ8RrK1VS8lrxkLriotFq+PiF7iiGgkZtfLKF4DDKsmdbPo0O9R2mQxm7jHLuXraRCuIQDWMIw6dpcr7Iykf4A==} + turbo-windows-arm64@2.7.3: + resolution: {integrity: sha512-nTodweTbPmkvwMu/a55XvjMsPtuyUSC+sV7f/SR57K36rB2I0YG21qNETN+00LOTUW9B3omd8XkiXJkt4kx/cw==} cpu: [arm64] os: [win32] - turbo@2.5.4: - resolution: {integrity: sha512-kc8ZibdRcuWUG1pbYSBFWqmIjynlD8Lp7IB6U3vIzvOv9VG+6Sp8bzyeBWE3Oi8XV5KsQrznyRTBPvrf99E4mA==} + turbo@2.7.3: + resolution: {integrity: sha512-+HjKlP4OfYk+qzvWNETA3cUO5UuK6b5MSc2UJOKyvBceKucQoQGb2g7HlC2H1GHdkfKrk4YF1VPvROkhVZDDLQ==} hasBin: true tween-functions@1.2.0: @@ -8803,14 +8832,14 @@ snapshots: '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.25.6 + '@babel/runtime': 7.25.9 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 '@manypkg/get-packages@1.1.3': dependencies: - '@babel/runtime': 7.25.6 + '@babel/runtime': 7.25.9 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -10221,6 +10250,28 @@ snapshots: '@tootallnate/quickjs-emscripten@0.23.0': {} + '@toss/react@1.8.1(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.9 + '@toss/storage': 1.4.1 + '@toss/utils': 1.6.1 + classnames: 2.5.1 + lodash.debounce: 4.0.8 + lodash.throttle: 4.1.1 + react: 18.3.1 + + '@toss/storage@1.4.1': + dependencies: + '@babel/runtime': 7.25.9 + + '@toss/utility-types@1.2.1': {} + + '@toss/utils@1.6.1': + dependencies: + '@babel/runtime': 7.25.9 + '@toss/utility-types': 1.2.1 + date-fns: 2.30.0 + '@trysound/sax@0.2.0': {} '@tsconfig/node10@1.0.11': {} @@ -11381,6 +11432,8 @@ snapshots: dependencies: consola: 3.2.3 + classnames@2.5.1: {} + clean-regexp@1.0.0: dependencies: escape-string-regexp: 1.0.5 @@ -11594,6 +11647,10 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.1 + date-fns@2.30.0: + dependencies: + '@babel/runtime': 7.25.9 + debug@2.6.9: dependencies: ms: 2.0.0 @@ -13445,6 +13502,8 @@ snapshots: lodash.startcase@4.4.0: {} + lodash.throttle@4.1.1: {} + lodash@4.17.21: {} log-symbols@3.0.0: @@ -13544,7 +13603,7 @@ snapshots: media-query-parser@2.0.2: dependencies: - '@babel/runtime': 7.25.6 + '@babel/runtime': 7.25.9 media-typer@0.3.0: {} @@ -15114,32 +15173,32 @@ snapshots: tslib: 1.14.1 typescript: 5.6.3 - turbo-darwin-64@2.5.4: + turbo-darwin-64@2.7.3: optional: true - turbo-darwin-arm64@2.5.4: + turbo-darwin-arm64@2.7.3: optional: true - turbo-linux-64@2.5.4: + turbo-linux-64@2.7.3: optional: true - turbo-linux-arm64@2.5.4: + turbo-linux-arm64@2.7.3: optional: true - turbo-windows-64@2.5.4: + turbo-windows-64@2.7.3: optional: true - turbo-windows-arm64@2.5.4: + turbo-windows-arm64@2.7.3: optional: true - turbo@2.5.4: + turbo@2.7.3: optionalDependencies: - turbo-darwin-64: 2.5.4 - turbo-darwin-arm64: 2.5.4 - turbo-linux-64: 2.5.4 - turbo-linux-arm64: 2.5.4 - turbo-windows-64: 2.5.4 - turbo-windows-arm64: 2.5.4 + turbo-darwin-64: 2.7.3 + turbo-darwin-arm64: 2.7.3 + turbo-linux-64: 2.7.3 + turbo-linux-arm64: 2.7.3 + turbo-windows-64: 2.7.3 + turbo-windows-arm64: 2.7.3 tween-functions@1.2.0: {}