- {/*
+
+ {/*
We can only style forward elements based on input state (with ~ or +), has() is not supported yet.
That's why we need to explicitly pass error/checked/disabled classes to the wrapper element.
*/}
@@ -94,6 +96,7 @@ export const Checkbox: FC = (props) => {
ref={inputRef}
id={id}
name={name}
+ aria-label={ariaLabel}
checked={!!checked}
onChange={onChange}
onBlur={onBlur}
@@ -115,4 +118,6 @@ export const Checkbox: FC = (props) => {
)
-}
+})
+
+Checkbox.displayName = 'Checkbox'
diff --git a/packages/ui/src/Select/CheckableSelectField.module.scss b/packages/ui/src/Select/CheckableSelectField.module.scss
index ab4b81472..e187adb17 100644
--- a/packages/ui/src/Select/CheckableSelectField.module.scss
+++ b/packages/ui/src/Select/CheckableSelectField.module.scss
@@ -35,7 +35,14 @@
}
.search {
+ display: flex;
+ align-items: center;
+ gap: c.$grid * 2;
margin-bottom: c.$grid * 2;
+
+ &Field {
+ flex-grow: 1;
+ }
}
.option {
diff --git a/packages/ui/src/Select/CheckableSelectField.tsx b/packages/ui/src/Select/CheckableSelectField.tsx
index dd27501f3..2fd307aa0 100644
--- a/packages/ui/src/Select/CheckableSelectField.tsx
+++ b/packages/ui/src/Select/CheckableSelectField.tsx
@@ -8,10 +8,12 @@ import { Link } from '../Link'
import { SelectFieldOption } from './helpers'
import { TextField } from '../TextField'
import { HelpProps } from '../Help'
+import { Tooltip } from '../Tooltip'
+import { Checkbox } from '../Checkbox'
import { useOpenCloseState } from '../hooks'
+import { TruncatedText } from '../TruncatedText'
import styles from './CheckableSelectField.module.scss'
-import { TruncatedText } from '../TruncatedText'
export type CheckableSelectFieldCoreStaticProps
= {
name: string
@@ -40,6 +42,8 @@ export type CheckableSelectFieldExtraProps = {
noOptionsMessage?: string
defaultOpen?: boolean
id?: string
+ filterOptionsLabel?: string
+ filterOptions?: (candidate: SelectFieldOption, input: string) => boolean
}
export type CheckableSelectProps = CheckableSelectFieldCoreStaticProps & CheckableSelectFieldExtraProps
@@ -77,9 +81,12 @@ export const CheckableSelectField = (props:
noneSelectedLabel = 'None selected',
noOptionsMessage = 'No options',
id: rootId,
+ filterOptions,
+ filterOptionsLabel,
} = props
const id = useUID()
const { isOpen, toggle, close } = useOpenCloseState(defaultOpen)
+ const { isOpen: isCustomSearchEnabled, toggle: toggleCustomSearch } = useOpenCloseState(false)
const [searchValue, setSearchValue] = useState('')
const [forceUpdateToken, setForceUpdateToken] = useState(1)
const [anchorElement, setAnchorElement] = useState(null)
@@ -97,8 +104,14 @@ export const CheckableSelectField = (props:
const filteredOptions = useMemo(() => {
const value = searchValue.toLowerCase()
- return options.filter(({ label }) => label.toLowerCase().includes(value))
- }, [options, searchValue])
+ return options.filter((option) => {
+ if (isCustomSearchEnabled && filterOptions) {
+ return filterOptions(option, value)
+ }
+
+ return option.label.toLowerCase().includes(value)
+ })
+ }, [options, searchValue, isCustomSearchEnabled, filterOptions])
const getValueLabel = () => {
if (placeholderMode === 'permanent') {
@@ -150,18 +163,34 @@ export const CheckableSelectField = (props:
onUpdateLayout={() => setForceUpdateToken((token) => token + 1)}
>
-
setSearchValue(e.target.value)}
- value={searchValue}
- label=""
- disabled={disabled}
- placeholder={placeholder}
- />
+
+ setSearchValue(e.target.value)}
+ value={searchValue}
+ label=""
+ disabled={disabled}
+ placeholder={placeholder}
+ />
+ {filterOptions && (
+
+ {(tooltipRef) => (
+
+ )}
+
+ )}
+
{filteredOptions.length > 0 ? (
filteredOptions.map((option) => {
diff --git a/packages/ui/src/Tooltip.tsx b/packages/ui/src/Tooltip.tsx
index 3dca0254d..1a8ece82e 100644
--- a/packages/ui/src/Tooltip.tsx
+++ b/packages/ui/src/Tooltip.tsx
@@ -25,8 +25,6 @@ import { getPortalContainer, PortalContainer } from './utils/portal'
import styles from './Tooltip.module.scss'
-const tooltipZIndex = 20
-
const TooltipContext = createContext<{
hide: () => void
clearHideTimeout: () => void
@@ -47,14 +45,15 @@ export type TooltipProps = {
hoverAbleTooltip?: boolean
children: (
ref: React.Dispatch
>,
- onMouseEnter?: MouseEventHandler,
- onMouseLeave?: MouseEventHandler,
+ onMouseEnter?: MouseEventHandler,
+ onMouseLeave?: MouseEventHandler,
) => ReactNode
popperRef?: MutableRefObject
updateToken?: ReactText | boolean
tooltipContainer?: PortalContainer
wordBreak?: CSSProperties['wordBreak']
disabled?: boolean
+ zIndex?: number
}
/**
@@ -88,6 +87,7 @@ export const Tooltip: FC = ({
tooltipContainer = 'body',
hoverAbleTooltip = true,
disabled = false,
+ zIndex = 20,
}) => {
const [isShown, setShown] = useState(false)
const timeoutRef = useRef(null)
@@ -225,7 +225,7 @@ export const Tooltip: FC = ({
className={cn(styles.overlay, {
[styles.hidden]: !isTooltipVisible,
})}
- style={{ ...popper.styles.popper, ...{ zIndex: context ? tooltipZIndex + 1 : tooltipZIndex }, wordBreak }}
+ style={{ ...popper.styles.popper, ...{ zIndex: context ? zIndex + 1 : zIndex }, wordBreak }}
data-test="tooltip-overlay"
aria-hidden
{...popper.attributes.popper}