From 0aaa86df343c5e01cb5db0311d18d6b44b166282 Mon Sep 17 00:00:00 2001 From: ajay-sentry <159853603+ajay-sentry@users.noreply.github.com> Date: Tue, 30 Apr 2024 16:06:10 -0700 Subject: [PATCH 1/3] ref: 1548 Part 1: Convert all Header files to TS (#2821) * ref all header files to TS * remove prop types and rebase --- ...{AdminLink.spec.jsx => AdminLink.spec.tsx} | 34 ++++++++----- .../Header/{AdminLink.jsx => AdminLink.tsx} | 7 ++- ...ktopMenu.spec.jsx => DesktopMenu.spec.tsx} | 30 ++++++------ .../{DesktopMenu.jsx => DesktopMenu.tsx} | 49 ++++++++++++++++--- .../{Dropdown.spec.jsx => Dropdown.spec.tsx} | 29 ++++++----- .../Header/{Dropdown.jsx => Dropdown.tsx} | 41 ++++++++++------ .../{Header.spec.jsx => Header.spec.tsx} | 26 +++++----- src/layouts/Header/{Header.jsx => Header.tsx} | 0 ...tDetails.spec.jsx => SeatDetails.spec.tsx} | 38 ++++++++------ .../{SeatDetails.jsx => SeatDetails.tsx} | 0 src/layouts/Header/{index.js => index.ts} | 0 11 files changed, 168 insertions(+), 86 deletions(-) rename src/layouts/Header/{AdminLink.spec.jsx => AdminLink.spec.tsx} (72%) rename src/layouts/Header/{AdminLink.jsx => AdminLink.tsx} (74%) rename src/layouts/Header/{DesktopMenu.spec.jsx => DesktopMenu.spec.tsx} (95%) rename src/layouts/Header/{DesktopMenu.jsx => DesktopMenu.tsx} (66%) rename src/layouts/Header/{Dropdown.spec.jsx => Dropdown.spec.tsx} (89%) rename src/layouts/Header/{Dropdown.jsx => Dropdown.tsx} (83%) rename src/layouts/Header/{Header.spec.jsx => Header.spec.tsx} (60%) rename src/layouts/Header/{Header.jsx => Header.tsx} (100%) rename src/layouts/Header/{SeatDetails.spec.jsx => SeatDetails.spec.tsx} (75%) rename src/layouts/Header/{SeatDetails.jsx => SeatDetails.tsx} (100%) rename src/layouts/Header/{index.js => index.ts} (100%) diff --git a/src/layouts/Header/AdminLink.spec.jsx b/src/layouts/Header/AdminLink.spec.tsx similarity index 72% rename from src/layouts/Header/AdminLink.spec.jsx rename to src/layouts/Header/AdminLink.spec.tsx index f00926ac19..3853086dcd 100644 --- a/src/layouts/Header/AdminLink.spec.jsx +++ b/src/layouts/Header/AdminLink.spec.tsx @@ -6,6 +6,23 @@ import { MemoryRouter, Route } from 'react-router-dom' import AdminLink from './AdminLink' +const wrapper: ({ + initialEntries, +}: { + initialEntries?: string +}) => React.FC = + ({ initialEntries = '/gh' }) => + ({ children }) => + ( + + + + {children} + + + + ) + const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } }, }) @@ -19,24 +36,12 @@ beforeEach(() => { afterAll(() => server.close()) describe('AdminLink', () => { - let renderData - function setup(data = {}) { server.use( rest.get('/internal/users/current', (req, res, ctx) => res(ctx.status(200), ctx.json(data)) ) ) - - renderData = render( - - - - - - - - ) } describe('user is an admin', () => { @@ -52,6 +57,7 @@ describe('AdminLink', () => { }) it('renders link to access page', async () => { + render(, { wrapper: wrapper({}) }) const link = await screen.findByText(/Admin/) expect(link).toBeInTheDocument() @@ -71,8 +77,10 @@ describe('AdminLink', () => { }) }) + const { container } = render(, { wrapper: wrapper({}) }) + it('renders nothing', () => { - expect(renderData.container).toBeEmptyDOMElement() + expect(container).toBeEmptyDOMElement() }) }) }) diff --git a/src/layouts/Header/AdminLink.jsx b/src/layouts/Header/AdminLink.tsx similarity index 74% rename from src/layouts/Header/AdminLink.jsx rename to src/layouts/Header/AdminLink.tsx index f042e0ae6f..1cd4345254 100644 --- a/src/layouts/Header/AdminLink.jsx +++ b/src/layouts/Header/AdminLink.tsx @@ -10,7 +10,12 @@ function AdminLink() { } return ( - + Admin ) diff --git a/src/layouts/Header/DesktopMenu.spec.jsx b/src/layouts/Header/DesktopMenu.spec.tsx similarity index 95% rename from src/layouts/Header/DesktopMenu.spec.jsx rename to src/layouts/Header/DesktopMenu.spec.tsx index 4e587e1533..95daea968e 100644 --- a/src/layouts/Header/DesktopMenu.spec.jsx +++ b/src/layouts/Header/DesktopMenu.spec.tsx @@ -2,6 +2,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen, waitFor, within } from '@testing-library/react' import { graphql, rest } from 'msw' import { setupServer } from 'msw/node' +import React from 'react' import { MemoryRouter, Route } from 'react-router-dom' import config from 'config' @@ -13,7 +14,7 @@ jest.mock('config') const loggedInUser = { me: { owner: { - defaultOrgUsername: 'codecov', + defaultOrgUsername: 'codecov' as string | null, }, user: { username: 'p', @@ -46,7 +47,13 @@ const queryClient = new QueryClient({ }) const server = setupServer() -const wrapper = +const wrapper: ({ + initialEntries, + path, +}: { + initialEntries?: string + path?: string +}) => React.FC = ( { initialEntries = '/gh', path = '/:provider' } = { initialEntries: '/gh', @@ -72,12 +79,7 @@ beforeEach(() => { afterAll(() => server.close()) describe('DesktopMenu', () => { - function setup( - { hasLoggedInUser = true, user = loggedInUser } = { - hasLoggedInUser: true, - user: loggedInUser, - } - ) { + function setup({ hasLoggedInUser = true, user = loggedInUser }) { server.use( graphql.query('Seats', (req, res, ctx) => res(ctx.status(200), ctx.data(mockSeatData)) @@ -97,7 +99,7 @@ describe('DesktopMenu', () => { describe('rendering logo button', () => { describe('when default org does not exist', () => { it('directs user to about codecov io', async () => { - setup() + setup({}) render(, { wrapper: wrapper({ @@ -184,7 +186,7 @@ describe('DesktopMenu', () => { }) it('renders static links', async () => { - setup() + setup({}) render(, { wrapper: wrapper({ @@ -218,7 +220,7 @@ describe('DesktopMenu', () => { }) it('renders the dropdown when user is logged in', async () => { - setup() + setup({}) render(, { wrapper: wrapper({ @@ -268,7 +270,7 @@ describe('DesktopMenu', () => { describe('when running in self hosted mode', () => { it('renders the seat count when user is logged in', async () => { config.IS_SELF_HOSTED = true - setup() + setup({}) render(, { wrapper: wrapper({ @@ -283,7 +285,7 @@ describe('DesktopMenu', () => { it('renders the admin link when user is logged in', async () => { config.IS_SELF_HOSTED = true - setup() + setup({}) render(, { wrapper: wrapper({ @@ -301,7 +303,7 @@ describe('DesktopMenu', () => { describe('LoginPrompt', () => { describe('with a provider available', () => { it('renders a login button and a sign up button', () => { - render(, { wrapper: wrapper() }) + render(, { wrapper: wrapper({}) }) const loginPrompt = screen.getByTestId('login-prompt') diff --git a/src/layouts/Header/DesktopMenu.jsx b/src/layouts/Header/DesktopMenu.tsx similarity index 66% rename from src/layouts/Header/DesktopMenu.jsx rename to src/layouts/Header/DesktopMenu.tsx index 8ac9a5a92f..b4ce3bf386 100644 --- a/src/layouts/Header/DesktopMenu.jsx +++ b/src/layouts/Header/DesktopMenu.tsx @@ -12,8 +12,12 @@ import AdminLink from './AdminLink' import Dropdown from './Dropdown' import SeatDetails from './SeatDetails' +interface URLParams { + provider: string +} + export function LoginPrompt() { - const { provider } = useParams() + const { provider } = useParams() const to = window.location.href const { pathname } = useLocation() @@ -25,7 +29,12 @@ export function LoginPrompt() { return (
New to Codecov?{' '} - + Learn more
@@ -36,17 +45,27 @@ export function LoginPrompt() { data-testid="login-prompt" className="mx-2 flex items-center justify-between gap-4 md:mx-0" > - + Log in - ) } -const LogoButton = ({ defaultOrg }) => { +const LogoButton = ({ defaultOrg }: { defaultOrg: string }) => { let pageName = 'root' if (defaultOrg) { pageName = 'owner' @@ -60,6 +79,8 @@ const LogoButton = ({ defaultOrg }) => { }} variant="header" data-testid="homepage-link" + isExternal={pageName === 'root' ? true : false} + hook="desktop-menu-homepage-link" > Link to Homepage @@ -82,17 +103,31 @@ function DesktopMenu() { <> diff --git a/src/layouts/Header/Dropdown.spec.jsx b/src/layouts/Header/Dropdown.spec.tsx similarity index 89% rename from src/layouts/Header/Dropdown.spec.jsx rename to src/layouts/Header/Dropdown.spec.tsx index 8be803ccc8..55badccb38 100644 --- a/src/layouts/Header/Dropdown.spec.jsx +++ b/src/layouts/Header/Dropdown.spec.tsx @@ -20,11 +20,11 @@ const currentUser = { jest.mock('services/image') jest.mock('config') -const Wrapper = - ({ provider }) => +const wrapper: (initialEntries?: string) => React.FC = + (initialEntries = '/gh') => ({ children }) => ( - + {children} @@ -35,7 +35,12 @@ const Wrapper = describe('Dropdown', () => { function setup({ selfHosted } = { selfHosted: false }) { - useImage.mockReturnValue({ src: 'imageUrl', isLoading: false, error: null }) + const mockUseImage = useImage as jest.Mock + mockUseImage.mockReturnValue({ + src: 'imageUrl', + isLoading: false, + error: null, + }) config.IS_SELF_HOSTED = selfHosted const mockRemoveItem = jest.spyOn( window.localStorage.__proto__, @@ -53,7 +58,7 @@ describe('Dropdown', () => { it('renders the users avatar', () => { render(, { - wrapper: Wrapper({ provider: 'gh' }), + wrapper: wrapper(), }) const img = screen.getByRole('img') @@ -69,7 +74,7 @@ describe('Dropdown', () => { it('shows settings link', async () => { const { user } = setup() render(, { - wrapper: Wrapper({ provider: 'gh' }), + wrapper: wrapper(), }) expect(screen.queryByText('Settings')).not.toBeInTheDocument() @@ -85,7 +90,7 @@ describe('Dropdown', () => { it('shows sign out link', async () => { const { user } = setup() render(, { - wrapper: Wrapper({ provider: 'gh' }), + wrapper: wrapper(), }) expect(screen.queryByText('Sign Out')).not.toBeInTheDocument() @@ -103,7 +108,7 @@ describe('Dropdown', () => { jest.spyOn(console, 'error').mockImplementation() render(, { - wrapper: Wrapper({ provider: 'gh' }), + wrapper: wrapper(), }) const openSelect = screen.getByRole('combobox') @@ -121,7 +126,7 @@ describe('Dropdown', () => { it('shows manage app access link', async () => { const { user } = setup() render(, { - wrapper: Wrapper({ provider: 'gh' }), + wrapper: wrapper(), }) expect( @@ -145,7 +150,7 @@ describe('Dropdown', () => { it('shows settings link', async () => { const { user } = setup() render(, { - wrapper: Wrapper({ provider: 'gl' }), + wrapper: wrapper('/gl'), }) expect(screen.queryByText('Settings')).not.toBeInTheDocument() @@ -161,7 +166,7 @@ describe('Dropdown', () => { it('shows sign out link', async () => { const { user } = setup() render(, { - wrapper: Wrapper({ provider: 'gl' }), + wrapper: wrapper('/gl'), }) expect(screen.queryByText('Sign Out')).not.toBeInTheDocument() @@ -177,7 +182,7 @@ describe('Dropdown', () => { it('does not show manage app access link', async () => { const { user } = setup() render(, { - wrapper: Wrapper({ provider: 'gl' }), + wrapper: wrapper('/gl'), }) expect( diff --git a/src/layouts/Header/Dropdown.jsx b/src/layouts/Header/Dropdown.tsx similarity index 83% rename from src/layouts/Header/Dropdown.jsx rename to src/layouts/Header/Dropdown.tsx index 03f9510e4b..ce1e9f9d0a 100644 --- a/src/layouts/Header/Dropdown.jsx +++ b/src/layouts/Header/Dropdown.tsx @@ -1,6 +1,5 @@ import cs from 'classnames' import { useSelect } from 'downshift' -import PropTypes from 'prop-types' import { useParams } from 'react-router-dom' import config from 'config' @@ -12,8 +11,30 @@ import Icon from 'ui/Icon' const LOCAL_STORAGE_SESSION_TRACKING_KEY = 'tracking-session-expiry' -function Dropdown({ currentUser }) { - const { provider } = useParams() +interface URLParams { + provider: string +} + +type CurrentUser = { + user: { + avatarUrl: string + username: string + } +} + +type itemProps = { + to: toProps + onClick?: () => void +} + +type toProps = { + pageName: string + options?: object +} + +// TODO: get types for free after converting useUser hook +function Dropdown({ currentUser }: { currentUser: CurrentUser }) { + const { provider } = useParams() const isGh = providerToName(provider) === 'Github' const to = `${window.location.protocol}//${window.location.host}/login` @@ -22,7 +43,7 @@ function Dropdown({ currentUser }) { !config.IS_SELF_HOSTED && isGh ? [ { - props: { to: { pageName: 'codecovAppInstallation' } }, + props: { to: { pageName: 'codecovAppInstallation' } } as itemProps, children: 'Install Codecov app', }, ] @@ -84,7 +105,7 @@ function Dropdown({ currentUser }) { 'rotate-0': !isOpen, })} > - +
    + {/* @ts-expect-error props might be overloaded with stuff */} @@ -112,13 +134,4 @@ function Dropdown({ currentUser }) { ) } -Dropdown.propTypes = { - currentUser: PropTypes.shape({ - user: PropTypes.shape({ - avatarUrl: PropTypes.string.isRequired, - username: PropTypes.string.isRequired, - }).isRequired, - }), -} - export default Dropdown diff --git a/src/layouts/Header/Header.spec.jsx b/src/layouts/Header/Header.spec.tsx similarity index 60% rename from src/layouts/Header/Header.spec.jsx rename to src/layouts/Header/Header.spec.tsx index b9d675e4fa..01729e99ad 100644 --- a/src/layouts/Header/Header.spec.jsx +++ b/src/layouts/Header/Header.spec.tsx @@ -1,12 +1,10 @@ import { render, screen } from '@testing-library/react' import { MemoryRouter, Route, Switch } from 'react-router-dom' -import { useImage } from 'services/image' import { useUser } from 'services/user' import Header from './Header' -jest.mock('services/image') jest.mock('services/user') const loggedInUser = { @@ -16,24 +14,30 @@ const loggedInUser = { }, } -describe('Header', () => { - function setup({ provider }) { - useUser.mockReturnValue({ data: loggedInUser }) - useImage.mockReturnValue({ src: 'imageUrl', isLoading: false, error: null }) - - render( - +const wrapper: (initialEntries?: string) => React.FC = + (initialEntries = '/gh') => + ({ children }) => + ( + -
    + {children} ) + +describe('Header', () => { + function setup() { + const mockedUseUser = useUser as jest.Mock + + mockedUseUser.mockReturnValue({ data: loggedInUser }) } it('renders the DesktopMenu', () => { - setup({ provider: 'gh' }) + setup() + + render(
    , { wrapper: wrapper() }) const menu = screen.getByTestId('desktop-menu') expect(menu).toBeInTheDocument() }) diff --git a/src/layouts/Header/Header.jsx b/src/layouts/Header/Header.tsx similarity index 100% rename from src/layouts/Header/Header.jsx rename to src/layouts/Header/Header.tsx diff --git a/src/layouts/Header/SeatDetails.spec.jsx b/src/layouts/Header/SeatDetails.spec.tsx similarity index 75% rename from src/layouts/Header/SeatDetails.spec.jsx rename to src/layouts/Header/SeatDetails.spec.tsx index f44af74b40..cb3aab807d 100644 --- a/src/layouts/Header/SeatDetails.spec.jsx +++ b/src/layouts/Header/SeatDetails.spec.tsx @@ -17,6 +17,23 @@ const mockUndefinedSeats = { config: {}, } +const wrapper: ({ + initialEntries, +}: { + initialEntries?: string +}) => React.FC = + ({ initialEntries = '/gh' }) => + ({ children }) => + ( + + + + {children} + + + + ) + const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } }, }) @@ -30,24 +47,12 @@ beforeEach(() => { afterAll(() => server.close()) describe('SeatDetails', () => { - let renderData - - function setup({ data = mockData }) { + function setup({ data = mockData }: { data?: any }) { server.use( graphql.query('Seats', (req, res, ctx) => res(ctx.status(200), ctx.data(data)) ) ) - - renderData = render( - - - - - - - - ) } describe('renders component', () => { @@ -57,6 +62,7 @@ describe('SeatDetails', () => { }) it('displays the number of active seats', async () => { + render(, { wrapper: wrapper({}) }) const number = await screen.findByText('5') expect(number).toBeInTheDocument() @@ -65,6 +71,8 @@ describe('SeatDetails', () => { }) it('displays the number of total seats', async () => { + render(, { wrapper: wrapper({}) }) + const number = await screen.findByText('10') expect(number).toBeInTheDocument() @@ -78,8 +86,10 @@ describe('SeatDetails', () => { setup({ data: mockUndefinedSeats }) }) + const { container } = render(, { wrapper: wrapper({}) }) + it('renders nothing', () => { - expect(renderData.container).toBeEmptyDOMElement() + expect(container).toBeEmptyDOMElement() }) }) }) diff --git a/src/layouts/Header/SeatDetails.jsx b/src/layouts/Header/SeatDetails.tsx similarity index 100% rename from src/layouts/Header/SeatDetails.jsx rename to src/layouts/Header/SeatDetails.tsx diff --git a/src/layouts/Header/index.js b/src/layouts/Header/index.ts similarity index 100% rename from src/layouts/Header/index.js rename to src/layouts/Header/index.ts From c4f8899aa52ce415642b00805575529bc7f0449a Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Wed, 1 May 2024 14:31:24 -0300 Subject: [PATCH 2/3] fix: Remove repository from GUT settings page header (#2823) Small tweak removing `repository` from the GUT settings page. --- .../AccountSettings/tabs/OrgUploadToken/OrgUploadToken.jsx | 4 +--- .../tabs/OrgUploadToken/OrgUploadToken.spec.jsx | 4 ++-- .../tabs/OrgUploadToken/useGenerateOrgUploadToken.js | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/pages/AccountSettings/tabs/OrgUploadToken/OrgUploadToken.jsx b/src/pages/AccountSettings/tabs/OrgUploadToken/OrgUploadToken.jsx index f5343a2815..8bd2a3a79c 100644 --- a/src/pages/AccountSettings/tabs/OrgUploadToken/OrgUploadToken.jsx +++ b/src/pages/AccountSettings/tabs/OrgUploadToken/OrgUploadToken.jsx @@ -14,9 +14,7 @@ function OrgUploadToken() { return (
    -

    - Global repository upload token -

    +

    Global upload token

    diff --git a/src/pages/AccountSettings/tabs/OrgUploadToken/OrgUploadToken.spec.jsx b/src/pages/AccountSettings/tabs/OrgUploadToken/OrgUploadToken.spec.jsx index b32ab75b8b..1870e1c6d4 100644 --- a/src/pages/AccountSettings/tabs/OrgUploadToken/OrgUploadToken.spec.jsx +++ b/src/pages/AccountSettings/tabs/OrgUploadToken/OrgUploadToken.spec.jsx @@ -113,7 +113,7 @@ describe('OrgUploadToken', () => { it('renders title', async () => { render(, { wrapper }) - const title = await screen.findByText(/Global repository upload token/) + const title = await screen.findByText(/Global upload token/) expect(title).toBeInTheDocument() }) @@ -237,7 +237,7 @@ describe('OrgUploadToken', () => { await waitFor(() => expect(addNotification).toHaveBeenCalledWith({ type: 'success', - text: 'Global repository upload token generated.', + text: 'Global upload token generated.', }) ) }) diff --git a/src/pages/AccountSettings/tabs/OrgUploadToken/useGenerateOrgUploadToken.js b/src/pages/AccountSettings/tabs/OrgUploadToken/useGenerateOrgUploadToken.js index 6178fdcfd5..0c10733dbd 100644 --- a/src/pages/AccountSettings/tabs/OrgUploadToken/useGenerateOrgUploadToken.js +++ b/src/pages/AccountSettings/tabs/OrgUploadToken/useGenerateOrgUploadToken.js @@ -19,7 +19,7 @@ export default function useGenerateOrgUploadToken() { } else { addToast({ type: 'success', - text: 'Global repository upload token generated.', + text: 'Global upload token generated.', }) } }, From 44246b9011d2d6a1c535f2c587f2021ad17f2d0a Mon Sep 17 00:00:00 2001 From: Spencer Murray <159931558+spalmurray-codecov@users.noreply.github.com> Date: Wed, 1 May 2024 16:12:56 -0400 Subject: [PATCH 3/3] Install radix-ui react radio group (#2825) --- package-lock.json | 55 +++++++++++++++++++++++++++++++++++++++++++---- package.json | 1 + 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index f3078a410d..b53a113fd8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@hookform/resolvers": "^2.8.5", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-popover": "^1.0.6", + "@radix-ui/react-radio-group": "^1.1.3", "@sentry/react": "^8.0.0-beta.4", "@stripe/react-stripe-js": "^1.7.2", "@stripe/stripe-js": "^1.52.1", @@ -4980,11 +4981,42 @@ } } }, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.1.3.tgz", + "integrity": "sha512-x+yELayyefNeKeTx4fjK6j99Fs6c4qKm3aY38G3swQVTN6xMpsrbigC0uHs2L//g8q4qR7qOcww8430jJmi2ag==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-use-size": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-roving-focus": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz", "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==", - "dev": true, "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.1", @@ -5369,7 +5401,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz", "integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==", - "dev": true, "dependencies": { "@babel/runtime": "^7.13.10" }, @@ -37479,11 +37510,28 @@ "@radix-ui/react-slot": "1.0.2" } }, + "@radix-ui/react-radio-group": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.1.3.tgz", + "integrity": "sha512-x+yELayyefNeKeTx4fjK6j99Fs6c4qKm3aY38G3swQVTN6xMpsrbigC0uHs2L//g8q4qR7qOcww8430jJmi2ag==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-use-size": "1.0.1" + } + }, "@radix-ui/react-roving-focus": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz", "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==", - "dev": true, "requires": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.1", @@ -37685,7 +37733,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz", "integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==", - "dev": true, "requires": { "@babel/runtime": "^7.13.10" } diff --git a/package.json b/package.json index acba823e24..dfc019947e 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@hookform/resolvers": "^2.8.5", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-popover": "^1.0.6", + "@radix-ui/react-radio-group": "^1.1.3", "@sentry/react": "^8.0.0-beta.4", "@stripe/react-stripe-js": "^1.7.2", "@stripe/stripe-js": "^1.52.1",