nicolium: give id to more components
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
@ -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',
|
||||
|
||||
@ -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'
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -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 (
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -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 };
|
||||
|
||||
Reference in New Issue
Block a user