/* * Copyright (c) 2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause */ import React, { useState } from 'react'; import { type DropdownItem } from '../Dropdown/Dropdown'; import { type RangeOrValues } from '../Slider/range'; import classNames from '../utils/classNames'; import { useSynchronisationIfChangedFromOutside } from './InlineInput'; import NumberInlineInput from './NumberInlineInput'; import styles from '../Dropdown/Dropdown.module.scss'; export type NumberDropdownItem = DropdownItem; interface DropdownProps { id?: string; label?: React.ReactNode; items: NumberDropdownItem[]; value: number; onChange: (value: number) => void; range: RangeOrValues; numItemsBeforeScroll?: number; className?: string; disabled?: boolean; title?: string; } export default ({ id, label, items, value, onChange, range, numItemsBeforeScroll = 0, className = '', disabled = false, title, }: DropdownProps) => { const [isActive, setIsActive] = useState(false); const [inlineValue, setInlineValue] = useState(value); const [isValid, setIsValid] = useState(true); const setNewValue = (newValue: number) => { setInlineValue(newValue); onChange(newValue); setIsActive(false); }; const onClickItem = (item: NumberDropdownItem) => { if (item.value != null && typeof item.value === 'number') { setNewValue(item.value); } }; useSynchronisationIfChangedFromOutside(value, setInlineValue); return (
{ if (!event.currentTarget.contains(event.relatedTarget)) { setIsActive(false); } }} title={title} >
{label}
setInlineValue(val)} onChangeComplete={val => setNewValue(val)} className={`tw-x-2 tw-h-full tw-w-full tw-bg-gray-700 tw-text-white tw-underline tw-underline-offset-2 ${ isValid ? 'tw-decoration-white' : 'tw-decoration-red' }`} textAlignLeft onValidityChanged={setIsValid} preventDefaultInvalidStyle disabled={disabled} />
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions -- We need an interactive handler as described below */}
{ // To prevent the dropdown from closing when users click on the scrollbar of the items ev.preventDefault(); }} style={ numItemsBeforeScroll > 0 ? { maxHeight: `${numItemsBeforeScroll * 24}px`, } : {} } data-height={ numItemsBeforeScroll > 0 && items.length > numItemsBeforeScroll } className={`tw-text-while tw-absolute tw-right-0 tw-z-10 tw-w-full tw-bg-gray-700 tw-p-0 ${classNames( styles.content, !isActive && 'tw-hidden', )}`} > {items.map(item => ( ))}
); };