nicolium: give id to more components

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2026-02-21 15:41:55 +01:00
parent dafec66d90
commit fb3d6d1388
6 changed files with 51 additions and 37 deletions

View File

@ -5,6 +5,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
import { getPointerPosition } from '@/features/video';
interface ISlider {
id?: string;
/** Value between 0 and 1. */
value: number;
/** Callback when the value changes. */
@ -12,7 +13,7 @@ interface ISlider {
}
/** Draggable slider component. */
const Slider: React.FC<ISlider> = ({ value, onChange }) => {
const Slider: React.FC<ISlider> = ({ id, value, onChange }) => {
const node = useRef<HTMLDivElement>(null);
const keyboardAnimationTimeout = useRef<number | null>(null);
const [animateKeyboardInput, setAnimateKeyboardInput] = useState<boolean>(false);
@ -141,6 +142,7 @@ const Slider: React.FC<ISlider> = ({ value, onChange }) => {
style={{ width: `${value * 100}%` }}
/>
<span
id={id}
className={clsx(
'absolute top-1/2 z-10 -ml-1.5 size-3 -translate-y-1/2 rounded-full bg-accent-500 shadow transition-[left] ease-in-out',
animateKeyboardInput ? 'duration-150' : 'duration-0',

View File

@ -4,6 +4,7 @@ import React, { useCallback, useRef } from 'react';
import { getPointerPosition } from '@/features/video';
interface IStepSlider {
id?: string;
/** Value between 0 and the amount of steps minus one. */
value: number;
/** Steps available in the slider. */
@ -13,7 +14,7 @@ interface IStepSlider {
}
/** Slider allowing selecting integers in a given range. */
const StepSlider: React.FC<IStepSlider> = ({ value, steps, onChange }) => {
const StepSlider: React.FC<IStepSlider> = ({ id, value, steps, onChange }) => {
const node = useRef<HTMLDivElement>(null);
const handleMouseDown: React.MouseEventHandler = (e) => {
@ -112,6 +113,7 @@ const StepSlider: React.FC<IStepSlider> = ({ value, steps, onChange }) => {
/>
))}
<span
id={id}
className='absolute top-1/2 z-10 -ml-1.5 size-3 -translate-y-1/2 rounded-full bg-accent-500 shadow transition-[left] duration-100 ease-in-out'
tabIndex={0}
role='slider'

View File

@ -14,6 +14,7 @@ interface ColorGroup {
}
interface IPalette {
id?: string;
palette: ColorGroup;
onChange: (palette: ColorGroup) => void;
resetKey?: string;
@ -21,7 +22,13 @@ interface IPalette {
}
/** Editable color palette. */
const Palette: React.FC<IPalette> = ({ palette, onChange, resetKey, allowTintChange = true }) => {
const Palette: React.FC<IPalette> = ({
id,
palette,
onChange,
resetKey,
allowTintChange = true,
}) => {
const tints = Object.keys(palette).sort(compareId);
const [hue, setHue] = useState(0);
@ -61,7 +68,7 @@ const Palette: React.FC<IPalette> = ({ palette, onChange, resetKey, allowTintCha
))}
</HStack>
<Slider value={hue} onChange={setHue} />
<Slider id={id} value={hue} onChange={setHue} />
</Stack>
);
};

View File

@ -134,11 +134,11 @@ const MenuItem: React.FC<MenuItemProps> = ({ className, menuItem }) => {
if (menuItem.toggle) {
return (
<div className='flex flex-row items-center justify-between space-x-4 px-4 py-1 text-sm text-gray-700 dark:text-gray-400'>
<label className='flex flex-row items-center justify-between space-x-4 px-4 py-1 text-sm text-gray-700 dark:text-gray-400'>
<span>{menuItem.text}</span>
{menuItem.toggle}
</div>
</label>
);
} else if (!menuItem.text) {
return (

View File

@ -5,12 +5,13 @@ import Icon from '@/components/ui/icon';
import Select from '@/components/ui/select';
interface IThemeSelector {
id?: string;
value: string;
onChange: (value: 'system' | 'light' | 'dark' | 'black') => void;
}
/** Pure theme selector. */
const ThemeSelector: React.FC<IThemeSelector> = ({ value, onChange }) => {
const ThemeSelector: React.FC<IThemeSelector> = ({ id, value, onChange }) => {
const themeIconSrc = useMemo(() => {
switch (value) {
case 'system':
@ -31,35 +32,33 @@ const ThemeSelector: React.FC<IThemeSelector> = ({ value, onChange }) => {
};
return (
<label>
<div className='relative rounded-md shadow-sm'>
<div className='pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3'>
<Icon src={themeIconSrc} className='size-4 text-gray-600 dark:text-gray-700' />
</div>
<Select onChange={handleChange} defaultValue={value} className='!pl-10'>
<option value='system'>
<FormattedMessage id='theme_toggle.system' defaultMessage='System' />
</option>
<option value='light'>
<FormattedMessage id='theme_toggle.light' defaultMessage='Light' />
</option>
<option value='dark'>
<FormattedMessage id='theme_toggle.dark' defaultMessage='Dark' />
</option>
<option value='black'>
<FormattedMessage id='theme_toggle.black' defaultMessage='Black' />
</option>
</Select>
<div className='pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3'>
<Icon
src={require('@phosphor-icons/core/regular/caret-down.svg')}
className='size-4 text-gray-600 dark:text-gray-700'
/>
</div>
<div className='relative rounded-md shadow-sm'>
<div className='pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3'>
<Icon src={themeIconSrc} className='size-4 text-gray-600 dark:text-gray-700' />
</div>
</label>
<Select id={id} onChange={handleChange} defaultValue={value} className='!pl-10'>
<option value='system'>
<FormattedMessage id='theme_toggle.system' defaultMessage='System' />
</option>
<option value='light'>
<FormattedMessage id='theme_toggle.light' defaultMessage='Light' />
</option>
<option value='dark'>
<FormattedMessage id='theme_toggle.dark' defaultMessage='Dark' />
</option>
<option value='black'>
<FormattedMessage id='theme_toggle.black' defaultMessage='Black' />
</option>
</Select>
<div className='pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3'>
<Icon
src={require('@phosphor-icons/core/regular/caret-down.svg')}
className='size-4 text-gray-600 dark:text-gray-700'
/>
</div>
</div>
);
};

View File

@ -6,8 +6,12 @@ import { useSettings } from '@/stores/settings';
import ThemeSelector from './theme-selector';
interface IThemeToggle {
id?: string;
}
/** Stateful theme selector. */
const ThemeToggle: React.FC = () => {
const ThemeToggle: React.FC<IThemeToggle> = ({ id }) => {
const dispatch = useAppDispatch();
const { themeMode } = useSettings();
@ -15,7 +19,7 @@ const ThemeToggle: React.FC = () => {
dispatch(changeSetting(['themeMode'], themeMode));
};
return <ThemeSelector value={themeMode} onChange={handleChange} />;
return <ThemeSelector id={id} value={themeMode} onChange={handleChange} />;
};
export { ThemeToggle as default };