chore: Update aria-controls and aria-expanded for components (#42961)

## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

- React Doctor fixes for aria controls and aria expanded
- Updated eslint to include the role
This commit is contained in:
Ali Waseem authored and GitHub committed 2026-02-18 16:41:10 +00:00
1 parent 3ae6cd7b1f
commit 2dd75cbfdd
13 files changed
+128 -63

No files matched your search

@@ -1,19 +1,19 @@
import { Check, ChevronsUpDown } from 'lucide-react'
import { useState } from 'react'
import { useId, useState } from 'react'
import {
Button,
cn,
Command_Shadcn_,
CommandEmpty_Shadcn_,
CommandGroup_Shadcn_,
CommandInput_Shadcn_,
CommandItem_Shadcn_,
CommandList_Shadcn_,
Command_Shadcn_,
FormControl_Shadcn_,
Popover_Shadcn_,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
Popover_Shadcn_,
ScrollArea,
cn,
} from 'ui'
// copied from https://docs.aws.amazon.com/general/latest/gr/cognito_identity.html
@@ -56,6 +56,7 @@ export const AwsRegionSelector = ({
onChange: (value: string) => void
}) => {
const [open, setOpen] = useState(false)
const listboxId = useId()
return (
<Popover_Shadcn_ open={open} onOpenChange={setOpen}>
@@ -64,6 +65,8 @@ export const AwsRegionSelector = ({
<Button
type="default"
role="combobox"
aria-expanded={open}
aria-controls={listboxId}
className={cn('w-full justify-between', !value && 'text-muted-foreground')}
size="small"
iconRight={
@@ -74,7 +77,7 @@ export const AwsRegionSelector = ({
</Button>
</FormControl_Shadcn_>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ className="p-0" sameWidthAsTrigger>
<PopoverContent_Shadcn_ id={listboxId} className="p-0" sameWidthAsTrigger>
<Command_Shadcn_>
<CommandInput_Shadcn_ placeholder="Search AWS regions..." />
<CommandList_Shadcn_>
@@ -11,16 +11,14 @@ import {
StripeAddressElementOptions,
type SetupIntent,
} from '@stripe/stripe-js'
import { Check, ChevronsUpDown } from 'lucide-react'
import { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react'
import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import { z } from 'zod'
import { Form } from '@ui/components/shadcn/ui/form'
import { TAX_IDS } from 'components/interfaces/Organization/BillingSettings/BillingCustomerData/TaxID.constants'
import type { CustomerAddress, CustomerTaxId } from 'data/organizations/types'
import { getURL } from 'lib/helpers'
import { Check, ChevronsUpDown } from 'lucide-react'
import { forwardRef, useEffect, useId, useImperativeHandle, useMemo, useState } from 'react'
import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
Button,
Checkbox_Shadcn_,
@@ -41,6 +39,7 @@ import {
PopoverTrigger_Shadcn_ as PopoverTrigger,
} from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { z } from 'zod'
export const BillingCustomerDataSchema = z.object({
tax_id_type: z.string(),
@@ -111,6 +110,7 @@ export const NewPaymentMethodElement = forwardRef(
const [fullyLoaded, setFullyLoaded] = useState(false)
const [showTaxIDsPopover, setShowTaxIDsPopover] = useState(false)
const taxIdListboxId = useId()
const onSelectTaxIdType = (name: string) => {
const selectedTaxIdOption = TAX_IDS.find((option) => option.name === name)
@@ -288,6 +288,8 @@ export const NewPaymentMethodElement = forwardRef(
type="default"
role="combobox"
size="medium"
aria-expanded={showTaxIDsPopover}
aria-controls={taxIdListboxId}
className={cn(
'w-full justify-between h-[34px]',
!selectedTaxId && 'text-muted'
@@ -305,7 +307,12 @@ export const NewPaymentMethodElement = forwardRef(
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent sameWidthAsTrigger className="p-0" align="start">
<PopoverContent
id={taxIdListboxId}
sameWidthAsTrigger
className="p-0"
align="start"
>
<Command>
<CommandInput placeholder="Search tax ID..." />
<CommandList>
@@ -1,18 +1,18 @@
import { CheckIcon, ChevronsUpDown, Globe } from 'lucide-react'
import { useState } from 'react'
import { useId, useState } from 'react'
import {
Button,
cn,
Command_Shadcn_,
CommandEmpty_Shadcn_,
CommandGroup_Shadcn_,
CommandInput_Shadcn_,
CommandItem_Shadcn_,
CommandList_Shadcn_,
Command_Shadcn_,
Popover_Shadcn_,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
Popover_Shadcn_,
ScrollArea,
cn,
} from 'ui'
import { ALL_TIMEZONES } from './PITR.constants'
@@ -28,6 +28,7 @@ export const TimezoneSelection = ({
onSelectTimezone,
}: TimezoneSelectionProps) => {
const [open, setOpen] = useState(false)
const listboxId = useId()
const timezoneOptions = ALL_TIMEZONES.map((option) => option.text)
@@ -38,6 +39,7 @@ export const TimezoneSelection = ({
<Button
role="combobox"
aria-expanded={open}
aria-controls={listboxId}
className="w-[350px] justify-between"
size="small"
icon={<Globe />}
@@ -48,7 +50,7 @@ export const TimezoneSelection = ({
: 'Select timezone...'}
</Button>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ className="w-[350px] p-0">
<PopoverContent_Shadcn_ id={listboxId} className="w-[350px] p-0">
<Command_Shadcn_>
<CommandInput_Shadcn_ placeholder="Search timezone..." className="h-9" />
<CommandList_Shadcn_>
@@ -1,9 +1,8 @@
import { Check, ChevronsUpDown, Database, Plus } from 'lucide-react'
import { useEffect, useState } from 'react'
import { ActionBar } from 'components/interfaces/TableGridEditor/SidePanelEditor/ActionBar'
import { useSchemasQuery } from 'data/database/schemas-query'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { Check, ChevronsUpDown, Database, Plus } from 'lucide-react'
import { useEffect, useId, useState } from 'react'
import {
Button,
cn,
@@ -25,6 +24,7 @@ import {
SidePanel,
} from 'ui'
import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
import WrapperDynamicColumns from './WrapperDynamicColumns'
import type { Table, TableOption } from './Wrappers.types'
import { makeValidateRequired } from './Wrappers.utils'
@@ -48,6 +48,7 @@ const WrapperTableEditor = ({
initialData,
}: WrapperTableEditorProps) => {
const [open, setOpen] = useState(false)
const listboxId = useId()
const [selectedTableIndex, setSelectedTableIndex] = useState<string>('')
useEffect(() => {
@@ -101,6 +102,8 @@ const WrapperTableEditor = ({
<Button
type="default"
role="combobox"
aria-expanded={open}
aria-controls={listboxId}
className={cn(
'w-full justify-between',
!selectedTableIndex && 'text-muted-foreground'
@@ -113,7 +116,7 @@ const WrapperTableEditor = ({
{!!selectedTableIndex ? tables[Number(selectedTableIndex)].label : '---'}
</Button>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ className="p-0" sameWidthAsTrigger>
<PopoverContent_Shadcn_ id={listboxId} className="p-0" sameWidthAsTrigger>
<Command_Shadcn_>
<CommandInput_Shadcn_ placeholder="Find a table..." />
<CommandList_Shadcn_>
@@ -1,8 +1,6 @@
import { Check, ChevronsUpDown, X } from 'lucide-react'
import { useId, useMemo, useState } from 'react'
import { UseFormReturn } from 'react-hook-form'
import { z } from 'zod'
import { useMemo, useState } from 'react'
import {
Button,
cn,
@@ -21,6 +19,8 @@ import {
PopoverTrigger_Shadcn_ as PopoverTrigger,
} from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { z } from 'zod'
import { COUNTRIES } from './BillingAddress.constants'
import { TAX_IDS } from './TaxID.constants'
@@ -53,6 +53,8 @@ export const BillingCustomerDataForm = ({
}: BillingCustomerDataFormProps) => {
const [showCountriesPopover, setShowCountriesPopover] = useState(false)
const [showTaxIDsPopover, setShowTaxIDsPopover] = useState(false)
const countryListboxId = useId()
const taxIdListboxId = useId()
const onSelectTaxIdType = (name: string) => {
const selectedTaxIdOption = TAX_IDS.find((option) => option.name === name)
@@ -136,6 +138,8 @@ export const BillingCustomerDataForm = ({
role="combobox"
size="medium"
disabled={disabled}
aria-expanded={showCountriesPopover}
aria-controls={countryListboxId}
className={cn(
'w-full justify-between h-[34px]',
!field.value && 'text-muted'
@@ -154,7 +158,12 @@ export const BillingCustomerDataForm = ({
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent sameWidthAsTrigger className="p-0" align="start">
<PopoverContent
id={countryListboxId}
sameWidthAsTrigger
className="p-0"
align="start"
>
<Command>
<CommandInput placeholder="Search country..." />
<CommandList>
@@ -246,6 +255,8 @@ export const BillingCustomerDataForm = ({
role="combobox"
size="medium"
disabled={disabled}
aria-expanded={showTaxIDsPopover}
aria-controls={taxIdListboxId}
className={cn(
'w-full justify-between h-[34px] pr-2',
!selectedTaxId && 'text-muted'
@@ -260,7 +271,12 @@ export const BillingCustomerDataForm = ({
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent sameWidthAsTrigger className="p-0" align="start">
<PopoverContent
id={taxIdListboxId}
sameWidthAsTrigger
className="p-0"
align="start"
>
<Command>
<CommandInput placeholder="Search tax ID..." />
<CommandList>
@@ -1,8 +1,4 @@
import { PermissionAction } from '@supabase/shared-types/out/constants'
import dayjs from 'dayjs'
import Link from 'next/link'
import { useMemo, useState } from 'react'
import { useParams } from 'common'
import {
ScaffoldContainer,
@@ -17,13 +13,17 @@ import { OrganizationProjectSelector } from 'components/ui/OrganizationProjectSe
import { useOrgDailyStatsQuery } from 'data/analytics/org-daily-stats-query'
import { useProjectDetailQuery } from 'data/projects/project-detail-query'
import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query'
import dayjs from 'dayjs'
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { TIME_PERIODS_BILLING, TIME_PERIODS_REPORTS } from 'lib/constants/metrics'
import { Check, ChevronDown } from 'lucide-react'
import Link from 'next/link'
import { useQueryState } from 'nuqs'
import { useMemo, useState } from 'react'
import { Button, cn, CommandGroup_Shadcn_, CommandItem_Shadcn_ } from 'ui'
import { Admonition } from 'ui-patterns'
import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
import { Restriction } from '../BillingSettings/Restriction'
import ActiveCompute from './ActiveCompute'
import Activity from './Activity'
@@ -163,13 +163,15 @@ export const Usage = () => {
onSelect={(project) => {
setSelectedProjectRef(project.ref)
}}
renderTrigger={() => {
renderTrigger={({ listboxId, open }) => {
return (
<Button
block
type="default"
role="combobox"
size="tiny"
aria-expanded={open}
aria-controls={listboxId}
className="justify-between w-[180px]"
iconRight={<ChevronDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />}
>
@@ -1,17 +1,17 @@
import { AnimatePresence, motion } from 'framer-motion'
import { Check, ChevronsUpDown, ExternalLink } from 'lucide-react'
import Link from 'next/link'
import type { UseFormReturn } from 'react-hook-form'
import { toast } from 'sonner'
// End of third-party imports
import { useParams } from 'common'
import CopyButton from 'components/ui/CopyButton'
import { OrganizationProjectSelector } from 'components/ui/OrganizationProjectSelector'
import { AnimatePresence, motion } from 'framer-motion'
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
import { Check, ChevronsUpDown, ExternalLink } from 'lucide-react'
import Link from 'next/link'
import type { UseFormReturn } from 'react-hook-form'
import { toast } from 'sonner'
import {
cn,
Button,
cn,
CommandGroup_Shadcn_,
CommandItem_Shadcn_,
FormControl_Shadcn_,
@@ -20,6 +20,7 @@ import {
import { Admonition } from 'ui-patterns'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import ShimmeringLoader from 'ui-patterns/ShimmeringLoader'
import type { ExtendedSupportCategories } from './Support.constants'
import type { SupportFormValues } from './SupportForm.schema'
import { NO_ORG_MARKER, NO_PROJECT_MARKER } from './SupportForm.utils'
@@ -89,13 +90,15 @@ function ProjectSelector({ form, orgSlug, projectRef }: ProjectSelectorProps) {
field.onChange(projects[0]?.ref ?? NO_PROJECT_MARKER)
}}
onSelect={(project) => field.onChange(project.ref)}
renderTrigger={({ isLoading, project }) => {
renderTrigger={({ isLoading, project, listboxId, open }) => {
return (
<Button
block
type="default"
role="combobox"
aria-label="Select a project"
aria-expanded={open}
aria-controls={listboxId}
size="small"
className="justify-between"
iconRight={<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />}
@@ -11,35 +11,35 @@ import {
Type,
} from 'lucide-react'
import Link from 'next/link'
import { ReactNode, useState } from 'react'
import { ReactNode, useId, useState } from 'react'
import {
Alert_Shadcn_,
AlertDescription_Shadcn_,
AlertTitle_Shadcn_,
Alert_Shadcn_,
Button,
cn,
Command_Shadcn_,
CommandEmpty_Shadcn_,
CommandGroup_Shadcn_,
CommandInput_Shadcn_,
CommandItem_Shadcn_,
CommandList_Shadcn_,
CommandSeparator_Shadcn_,
Command_Shadcn_,
CriticalIcon,
Input,
Label_Shadcn_,
Popover_Shadcn_,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
Popover_Shadcn_,
ScrollArea,
Tooltip,
TooltipContent,
TooltipTrigger,
cn,
} from 'ui'
import {
POSTGRES_DATA_TYPES,
POSTGRES_DATA_TYPE_OPTIONS,
POSTGRES_DATA_TYPES,
RECOMMENDED_ALTERNATIVE_DATA_TYPE,
} from '../SidePanelEditor.constants'
import type { PostgresDataTypeOption } from '../SidePanelEditor.types'
@@ -70,6 +70,7 @@ const ColumnType = ({
error,
}: ColumnTypeProps) => {
const [open, setOpen] = useState(false)
const listboxId = useId()
const availableTypes = POSTGRES_DATA_TYPES.concat(
enumTypes.map((type) => type.format.replaceAll('"', ''))
)
@@ -173,6 +174,7 @@ const ColumnType = ({
role="combobox"
size={'small'}
aria-expanded={open}
aria-controls={listboxId}
className={cn('w-full justify-between', !value && 'text-foreground-lighter')}
iconRight={<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />}
>
@@ -186,7 +188,12 @@ const ColumnType = ({
)}
</Button>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ className="w-[460px] p-0" side="bottom" align="center">
<PopoverContent_Shadcn_
id={listboxId}
className="w-[460px] p-0"
side="bottom"
align="center"
>
<Command_Shadcn_>
<CommandInput_Shadcn_
placeholder="Search types..."
@@ -1,6 +1,5 @@
import { GripVertical, Settings2 } from 'lucide-react'
import { useMemo, useState } from 'react'
import { useId, useMemo, useState } from 'react'
import {
Checkbox_Shadcn_,
Command_Shadcn_ as Command,
@@ -13,6 +12,7 @@ import {
PopoverContent_Shadcn_ as PopoverContent,
PopoverTrigger_Shadcn_ as PopoverTrigger,
} from 'ui'
import { ButtonTooltip } from '../ButtonTooltip'
import { Sortable, SortableDragHandle, SortableItem } from './primitives/Sortable'
import { useDataTable } from './providers/DataTableProvider'
@@ -22,6 +22,7 @@ export function DataTableViewOptions() {
const [open, setOpen] = useState(false)
const [drag, setDrag] = useState(false)
const [search, setSearch] = useState('')
const listboxId = useId()
const columnOrder = table.getState().columnOrder
@@ -41,12 +42,13 @@ export function DataTableViewOptions() {
size="tiny"
role="combobox"
aria-expanded={open}
aria-controls={listboxId}
className="w-[26px]"
icon={<Settings2 className="text-foreground" />}
tooltip={{ content: { side: 'bottom', text: 'Toggle column visibility' } }}
/>
</PopoverTrigger>
<PopoverContent side="bottom" align="end" className="w-[200px] p-0">
<PopoverContent id={listboxId} side="bottom" align="end" className="w-[200px] p-0">
<Command>
<CommandInput value={search} onValueChange={setSearch} placeholder="Search columns..." />
<CommandList>
@@ -16,7 +16,7 @@ import { BASE_PATH } from 'lib/constants'
import { useProfile } from 'lib/profile'
import { Book, Maximize2, X } from 'lucide-react'
import { useRouter } from 'next/router'
import { useState } from 'react'
import { useId, useState } from 'react'
import { useEditorPanelStateSnapshot } from 'state/editor-panel-state'
import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state'
import { useSqlEditorV2StateSnapshot } from 'state/sql-editor-v2'
@@ -83,6 +83,7 @@ export const EditorPanel = () => {
const [showWarning, setShowWarning] = useState<'hasWriteOperation' | 'hasUnknownFunctions'>()
const [showResults, setShowResults] = useState(true)
const [isTemplatesOpen, setIsTemplatesOpen] = useState(false)
const templatesListboxId = useId()
const errorHeader = error?.formattedError?.split('\n')?.filter((x: string) => x.length > 0)?.[0]
const errorContent =
@@ -167,12 +168,13 @@ export const EditorPanel = () => {
role="combobox"
className="mr-2"
aria-expanded={isTemplatesOpen}
aria-controls={templatesListboxId}
icon={<Book size={14} />}
>
Templates
</Button>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ align="end" className="w-[300px] p-0">
<PopoverContent_Shadcn_ id={templatesListboxId} align="end" className="w-[300px] p-0">
<Command_Shadcn_>
<CommandInput_Shadcn_ placeholder="Search templates..." />
<CommandList_Shadcn_>
@@ -3,7 +3,7 @@ import { useDebounce, useIntersectionObserver } from '@uidotdev/usehooks'
import { OrgProject, useOrgProjectsInfiniteQuery } from 'data/projects/org-projects-infinite-query'
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
import { Check, ChevronsUpDown, HelpCircle } from 'lucide-react'
import { ReactNode, useEffect, useMemo, useRef, useState } from 'react'
import { ReactNode, useEffect, useId, useMemo, useRef, useState } from 'react'
import {
Button,
cn,
@@ -34,9 +34,13 @@ interface OrganizationProjectSelectorSelectorProps {
renderTrigger?: ({
isLoading,
project,
listboxId,
open,
}: {
isLoading: boolean
project?: OrgProject
listboxId: string
open: boolean
}) => ReactNode
renderActions?: (setOpen: (value: boolean) => void) => ReactNode
onSelect?: (project: OrgProject) => void
@@ -69,6 +73,7 @@ export const OrganizationProjectSelector = ({
const [openInternal, setOpenInternal] = useState(false)
const open = _open ?? openInternal
const setOpen = _setOpen ?? setOpenInternal
const listboxId = useId()
const [search, setSearch] = useState('')
const debouncedSearch = useDebounce(search, 500)
@@ -130,13 +135,20 @@ export const OrganizationProjectSelector = ({
<Popover_Shadcn_ open={open} onOpenChange={setOpen} modal={modal}>
<PopoverTrigger_Shadcn_ asChild>
{renderTrigger ? (
renderTrigger({ isLoading: isLoadingProjects || isFetching, project: selectedProject })
renderTrigger({
isLoading: isLoadingProjects || isFetching,
project: selectedProject,
listboxId,
open,
})
) : (
<Button
block
type="default"
role="combobox"
size="small"
aria-expanded={open}
aria-controls={listboxId}
className="justify-between"
iconRight={<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />}
>
@@ -149,6 +161,7 @@ export const OrganizationProjectSelector = ({
)}
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_
id={listboxId}
sameWidthAsTrigger={sameWidthAsTrigger}
className="p-0"
side="bottom"
+3
View File
@@ -1,5 +1,6 @@
const { defineConfig } = require('eslint/config')
const barrelFiles = require('eslint-plugin-barrel-files')
const jsxA11y = require('eslint-plugin-jsx-a11y')
const supabaseConfig = require('eslint-config-supabase/next')
module.exports = defineConfig([
@@ -8,6 +9,7 @@ module.exports = defineConfig([
{
plugins: {
'barrel-files': barrelFiles,
'jsx-a11y': jsxA11y,
},
rules: {
'@next/next/no-img-element': 'off',
@@ -15,6 +17,7 @@ module.exports = defineConfig([
'react/display-name': 'warn',
'react/jsx-key': 'error',
'barrel-files/avoid-re-export-all': 'error',
'jsx-a11y/role-has-required-aria-props': 'error',
},
},
])
@@ -1,14 +1,4 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { isEqual } from 'lodash'
import { AlertCircle, Book, Check } from 'lucide-react'
import { useRouter } from 'next/router'
import { useEffect, useMemo, useState } from 'react'
import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import * as z from 'zod'
import { FileData } from '@/components/ui/FileExplorerAndEditor/FileExplorerAndEditor.types'
import { useLatest } from '@/hooks/misc/useLatest'
import { useParams } from 'common'
import { EDGE_FUNCTION_TEMPLATES } from 'components/interfaces/Functions/Functions.templates'
import { DefaultLayout } from 'components/layouts/DefaultLayout'
@@ -22,6 +12,12 @@ import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { BASE_PATH } from 'lib/constants'
import { isEqual } from 'lodash'
import { AlertCircle, Book, Check } from 'lucide-react'
import { useRouter } from 'next/router'
import { useEffect, useId, useMemo, useState } from 'react'
import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import { useAiAssistantStateSnapshot } from 'state/ai-assistant-state'
import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state'
import {
@@ -47,6 +43,10 @@ import {
TooltipContent,
TooltipTrigger,
} from 'ui'
import * as z from 'zod'
import { FileData } from '@/components/ui/FileExplorerAndEditor/FileExplorerAndEditor.types'
import { useLatest } from '@/hooks/misc/useLatest'
// Array of adjectives and nouns for random function name generation
const ADJECTIVES = [
@@ -123,6 +123,7 @@ const NewFunctionPage = () => {
const [files, setFiles] = useState<FileData[]>(INITIAL_FILES)
const [selectedFileId, setSelectedFileId] = useState<number>(INITIAL_FILES[0].id)
const [open, setOpen] = useState(false)
const templatesListboxId = useId()
const [isPreviewingTemplate, setIsPreviewingTemplate] = useState(false)
const [savedCode, setSavedCode] = useState<string>('')
@@ -311,12 +312,13 @@ const NewFunctionPage = () => {
type="default"
role="combobox"
aria-expanded={open}
aria-controls={templatesListboxId}
icon={<Book size={14} />}
>
Templates
</Button>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ className="w-[300px] p-0" align="end">
<PopoverContent_Shadcn_ id={templatesListboxId} className="w-[300px] p-0" align="end">
<Command_Shadcn_>
<CommandInput_Shadcn_ placeholder="Search templates..." />
<CommandList_Shadcn_>