diff --git a/services/web/frontend/js/features/settings/components/emails/add-email/country-input.tsx b/services/web/frontend/js/features/settings/components/emails/add-email/country-input.tsx index 2de138c3ab..c211121417 100644 --- a/services/web/frontend/js/features/settings/components/emails/add-email/country-input.tsx +++ b/services/web/frontend/js/features/settings/components/emails/add-email/country-input.tsx @@ -5,6 +5,8 @@ import classnames from 'classnames' import countries, { CountryCode } from '../../../data/countries-list' import { bsVersion } from '@/features/utils/bootstrap-5' import OLFormControl from '@/features/ui/components/ol/ol-form-control' +import { DropdownItem } from '@/features/ui/components/bootstrap-5/dropdown-menu' +import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher' type CountryInputProps = { setValue: React.Dispatch> @@ -46,16 +48,24 @@ function Downshift({ setValue, inputRef }: CountryInputProps) { }, }) + const shouldOpen = isOpen && inputItems.length + return (
-
+
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
+ } + bs5={ + + {item.name} + + } + /> ))} diff --git a/services/web/frontend/js/features/settings/components/emails/downshift-input.tsx b/services/web/frontend/js/features/settings/components/emails/downshift-input.tsx index bb9929e392..e34a1a9af7 100644 --- a/services/web/frontend/js/features/settings/components/emails/downshift-input.tsx +++ b/services/web/frontend/js/features/settings/components/emails/downshift-input.tsx @@ -4,6 +4,8 @@ import classnames from 'classnames' import { escapeRegExp } from 'lodash' import { bsVersion } from '@/features/utils/bootstrap-5' import OLFormControl from '@/features/ui/components/ol/ol-form-control' +import { DropdownItem } from '@/features/ui/components/bootstrap-5/dropdown-menu' +import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher' type DownshiftInputProps = { highlightMatches?: boolean @@ -77,13 +79,18 @@ function Downshift({ ) } + const shouldOpen = isOpen && inputItems.length + return (
@@ -116,28 +123,62 @@ function Downshift({
    {showSuggestedText && inputItems.length && ( -
  • {itemsTitle}
  • + {itemsTitle}} + bs5={ +
  • + + {itemsTitle} + +
  • + } + /> )} {inputItems.map((item, index) => ( + // eslint-disable-next-line jsx-a11y/role-supports-aria-props
  • -
    - - {highlightMatchedCharacters(item, inputValue)} - -
    + + + {highlightMatchedCharacters(item, inputValue)} + +
+ } + bs5={ + + {highlightMatchedCharacters(item, inputValue)} + + } + /> ))} diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/dropdown-menu.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/dropdown-menu.tsx index 3eec25d6f3..9202eb3492 100644 --- a/services/web/frontend/js/features/ui/components/bootstrap-5/dropdown-menu.tsx +++ b/services/web/frontend/js/features/ui/components/bootstrap-5/dropdown-menu.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { forwardRef } from 'react' import { Dropdown as BS5Dropdown, DropdownToggle as BS5DropdownToggle, @@ -18,22 +18,22 @@ export function Dropdown({ ...props }: DropdownProps) { return } -export function DropdownItem({ - active, - children, - description, - leadingIcon, - trailingIcon, - ...props -}: DropdownItemProps) { - const trailingIconType = active ? 'check' : trailingIcon - return ( -
  • +export const DropdownItem = forwardRef< + typeof BS5DropdownItem, + DropdownItemProps +>( + ( + { active, children, description, leadingIcon, trailingIcon, ...props }, + ref + ) => { + const trailingIconType = active ? 'check' : trailingIcon + return ( {leadingIcon && ( {description} )} -
  • - ) -} + ) + } +) +DropdownItem.displayName = 'DropdownItem' export function DropdownToggle({ ...props }: DropdownToggleProps) { return diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/split-button.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/split-button.tsx index 48e191b75f..8c80aafd44 100644 --- a/services/web/frontend/js/features/ui/components/bootstrap-5/split-button.tsx +++ b/services/web/frontend/js/features/ui/components/bootstrap-5/split-button.tsx @@ -40,9 +40,9 @@ export function SplitButton({ {items.map((item, index) => ( - - {item.label} - +
  • + {item.label} +
  • ))}
    diff --git a/services/web/frontend/js/features/ui/components/types/dropdown-menu-props.ts b/services/web/frontend/js/features/ui/components/types/dropdown-menu-props.ts index 01b3b16d8f..9084ea15d2 100644 --- a/services/web/frontend/js/features/ui/components/types/dropdown-menu-props.ts +++ b/services/web/frontend/js/features/ui/components/types/dropdown-menu-props.ts @@ -22,12 +22,14 @@ export type DropdownItemProps = PropsWithChildren<{ as?: ElementType description?: string disabled?: boolean - eventKey: string | number + eventKey?: string | number href?: string leadingIcon?: string onClick?: () => void trailingIcon?: string variant?: 'default' | 'danger' + className?: string + role?: string }> export type DropdownToggleProps = PropsWithChildren<{ diff --git a/services/web/frontend/stories/ui/dropdown-menu.stories.tsx b/services/web/frontend/stories/ui/dropdown-menu.stories.tsx index 8f747e4ba9..0062b15176 100644 --- a/services/web/frontend/stories/ui/dropdown-menu.stories.tsx +++ b/services/web/frontend/stories/ui/dropdown-menu.stories.tsx @@ -10,16 +10,22 @@ type Args = React.ComponentProps export const Default = (args: Args) => { return ( - - Example - - - Example - +
  • + + Example + +
  • +
  • + + Example + +
  • - - Example - +
  • + + Example + +
  • ) } @@ -27,16 +33,27 @@ export const Default = (args: Args) => { export const Active = (args: Args) => { return ( - - Example - - - Example - +
  • + + Example + +
  • +
  • + + Example + +
  • - - Example - +
  • + + Example + +
  • ) } @@ -44,16 +61,22 @@ export const Active = (args: Args) => { export const Danger = (args: Args) => { return ( - - Example - - - Example - +
  • + + Example + +
  • +
  • + + Example + +
  • - - Example - +
  • + + Example + +
  • ) } @@ -61,23 +84,27 @@ export const Danger = (args: Args) => { export const Description = (args: Args) => { return ( - - Example - - - Example - +
  • + + Example + +
  • +
  • + + Example + +
  • ) } @@ -85,28 +112,44 @@ export const Description = (args: Args) => { export const Icon = (args: Args) => { return ( - - Editor & PDF - - - Editor only - - - PDF only - - - PDF in separate tab - +
  • + + Editor & PDF + +
  • +
  • + + Editor only + +
  • +
  • + + PDF only + +
  • +
  • + + PDF in separate tab + +
  • ) } diff --git a/services/web/frontend/stylesheets/bootstrap-5/components/dropdown-menu.scss b/services/web/frontend/stylesheets/bootstrap-5/components/dropdown-menu.scss index db986fd1ee..bcdd3a5580 100644 --- a/services/web/frontend/stylesheets/bootstrap-5/components/dropdown-menu.scss +++ b/services/web/frontend/stylesheets/bootstrap-5/components/dropdown-menu.scss @@ -113,3 +113,16 @@ border-left: 1px solid var(--neutral-10); } } + +.select-dropdown-menu { + top: 100%; + margin-top: var(--spacing-04); + width: 100%; + max-height: 200px; + overflow: auto; + overflow-x: hidden; +} + +.dropdown-item--highlighted { + background-color: var(--bg-light-secondary); +}