mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 04:50:36 +03:00
D: Add documentation to react components pt1
This commit is contained in:
parent
3e34414b85
commit
c18efc93e1
|
@ -143,11 +143,10 @@ This readme file is used mostly to document project dependencies and conventions
|
||||||
## 📝 Commit conventions
|
## 📝 Commit conventions
|
||||||
|
|
||||||
- 🚀 F: major feature implementation
|
- 🚀 F: major feature implementation
|
||||||
- 💄 D: UI design
|
|
||||||
- 🔥 B: bug fix
|
- 🔥 B: bug fix
|
||||||
- 🚑 M: Minor fixes
|
- 🚑 M: Minor fixes
|
||||||
- 🔧 R: refactoring and code improvement
|
- 🔧 R: refactoring and code improvement
|
||||||
- 📝 I: documentation
|
- 📝 D: documentation
|
||||||
|
|
||||||
## 🖥️ Local build (Windows 10+)
|
## 🖥️ Local build (Windows 10+)
|
||||||
|
|
||||||
|
|
97
rsconcept/frontend/src/components/props.d.ts
vendored
97
rsconcept/frontend/src/components/props.d.ts
vendored
|
@ -2,47 +2,112 @@
|
||||||
import { HTMLMotionProps } from 'framer-motion';
|
import { HTMLMotionProps } from 'framer-motion';
|
||||||
|
|
||||||
export namespace CProps {
|
export namespace CProps {
|
||||||
export interface Titled {
|
/**
|
||||||
title?: string;
|
* Represents an object that can have inline styles and CSS class names for styling.
|
||||||
titleHtml?: string;
|
*/
|
||||||
hideTitle?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Control = Titled & {
|
|
||||||
disabled?: boolean;
|
|
||||||
noBorder?: boolean;
|
|
||||||
noOutline?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface Styling {
|
export interface Styling {
|
||||||
|
/** Optional inline styles for the component. */
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
|
|
||||||
|
/** Optional CSS class name(s) for the component. */
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Editor = Control & {
|
/**
|
||||||
label?: string;
|
* Represents an object that can have a color or set of colors.
|
||||||
};
|
*/
|
||||||
|
|
||||||
export interface Colors {
|
export interface Colors {
|
||||||
|
/** Optional color or set of colors applied via classNames. */
|
||||||
colors?: string;
|
colors?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an object that can have a title with optional HTML rendering and a flag to hide the title.
|
||||||
|
*/
|
||||||
|
export interface Titled {
|
||||||
|
/** Tooltip: `plain text`. */
|
||||||
|
title?: string;
|
||||||
|
|
||||||
|
/** Tooltip: `HTML formatted`. */
|
||||||
|
titleHtml?: string;
|
||||||
|
|
||||||
|
/** Indicates whether the `title` should be hidden. */
|
||||||
|
hideTitle?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents `control` component with optional title and configuration options.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* This type extends the {@link Titled} interface, adding properties to control the visual and interactive behavior of a component.
|
||||||
|
*/
|
||||||
|
export type Control = Titled & {
|
||||||
|
/** Indicates whether the control is disabled. */
|
||||||
|
disabled?: boolean;
|
||||||
|
|
||||||
|
/** Indicates whether the control should render without a border. */
|
||||||
|
noBorder?: boolean;
|
||||||
|
|
||||||
|
/** Indicates whether the control should render without an outline. */
|
||||||
|
noOutline?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents `editor` component that includes a label, control features, and optional title properties.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* This type extends the {@link Control} type, inheriting title-related properties and additional configuration options, while also adding an optional label.
|
||||||
|
*/
|
||||||
|
export type Editor = Control & {
|
||||||
|
/** Text label. */
|
||||||
|
label?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents `div` component with all standard HTML attributes and React-specific properties.
|
||||||
|
*/
|
||||||
export type Div = React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
|
export type Div = React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents `button` component with optional title and HTML attributes.
|
||||||
|
*/
|
||||||
export type Button = Titled &
|
export type Button = Titled &
|
||||||
Omit<
|
Omit<
|
||||||
React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>,
|
React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>,
|
||||||
'children' | 'type'
|
'children' | 'type'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents `label` component with HTML attributes.
|
||||||
|
*/
|
||||||
export type Label = Omit<
|
export type Label = Omit<
|
||||||
React.DetailedHTMLProps<React.LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>,
|
React.DetailedHTMLProps<React.LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>,
|
||||||
'children'
|
'children'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents `textarea` component with optional title and HTML attributes.
|
||||||
|
*/
|
||||||
export type TextArea = Titled &
|
export type TextArea = Titled &
|
||||||
React.DetailedHTMLProps<React.TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>;
|
React.DetailedHTMLProps<React.TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents `input` component with optional title and HTML attributes.
|
||||||
|
*/
|
||||||
export type Input = Titled & React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
|
export type Input = Titled & React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents `button` component with optional title and animation properties.
|
||||||
|
*/
|
||||||
export type AnimatedButton = Titled & Omit<HTMLMotionProps<'button'>, 'type'>;
|
export type AnimatedButton = Titled & Omit<HTMLMotionProps<'button'>, 'type'>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents `div` component with animation properties.
|
||||||
|
*/
|
||||||
export type AnimatedDiv = HTMLMotionProps<'div'>;
|
export type AnimatedDiv = HTMLMotionProps<'div'>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents `mouse event` in React.
|
||||||
|
*/
|
||||||
export type EventMouse = React.MouseEvent<Element, MouseEvent>;
|
export type EventMouse = React.MouseEvent<Element, MouseEvent>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,25 @@ import { globals } from '@/utils/constants';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
interface ButtonProps extends CProps.Control, CProps.Colors, CProps.Button {
|
interface ButtonProps extends CProps.Control, CProps.Colors, CProps.Button {
|
||||||
text?: string;
|
/** Icon to display first. */
|
||||||
icon?: React.ReactNode;
|
icon?: React.ReactNode;
|
||||||
|
|
||||||
|
/** Text to display second. */
|
||||||
|
text?: string;
|
||||||
|
|
||||||
|
/** Indicates whether to render the button in a dense style. */
|
||||||
dense?: boolean;
|
dense?: boolean;
|
||||||
|
|
||||||
|
/** Indicates loading state to prevent interactions and change visual style. */
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Button component that provides a customizable `button` with text, icon, tooltips and various styles.
|
||||||
|
*/
|
||||||
function Button({
|
function Button({
|
||||||
text,
|
|
||||||
icon,
|
icon,
|
||||||
|
text,
|
||||||
title,
|
title,
|
||||||
titleHtml,
|
titleHtml,
|
||||||
hideTitle,
|
hideTitle,
|
||||||
|
|
|
@ -7,13 +7,22 @@ import { CheckboxChecked } from '../Icons';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
export interface CheckboxProps extends Omit<CProps.Button, 'value' | 'onClick'> {
|
export interface CheckboxProps extends Omit<CProps.Button, 'value' | 'onClick'> {
|
||||||
|
/** Label to display next to the checkbox. */
|
||||||
label?: string;
|
label?: string;
|
||||||
|
|
||||||
|
/** Indicates whether the checkbox is disabled. */
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
|
||||||
|
/** Current value - `true` or `false`. */
|
||||||
value: boolean;
|
value: boolean;
|
||||||
|
|
||||||
|
/** Callback to set the `value`. */
|
||||||
setValue?: (newValue: boolean) => void;
|
setValue?: (newValue: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checkbox component that allows users to toggle a boolean value.
|
||||||
|
*/
|
||||||
function Checkbox({
|
function Checkbox({
|
||||||
disabled,
|
disabled,
|
||||||
label,
|
label,
|
||||||
|
|
|
@ -8,10 +8,16 @@ import { CProps } from '../props';
|
||||||
import { CheckboxProps } from './Checkbox';
|
import { CheckboxProps } from './Checkbox';
|
||||||
|
|
||||||
export interface CheckboxTristateProps extends Omit<CheckboxProps, 'value' | 'setValue'> {
|
export interface CheckboxTristateProps extends Omit<CheckboxProps, 'value' | 'setValue'> {
|
||||||
|
/** Current value - `null`, `true` or `false`. */
|
||||||
value: boolean | null;
|
value: boolean | null;
|
||||||
|
|
||||||
|
/** Callback to set the `value`. */
|
||||||
setValue?: (newValue: boolean | null) => void;
|
setValue?: (newValue: boolean | null) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CheckboxTristate component that allows toggling among three states: `true`, `false`, and `null`.
|
||||||
|
*/
|
||||||
function CheckboxTristate({
|
function CheckboxTristate({
|
||||||
disabled,
|
disabled,
|
||||||
label,
|
label,
|
||||||
|
|
|
@ -2,11 +2,17 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import { CProps } from '@/components/props';
|
import { CProps } from '@/components/props';
|
||||||
|
|
||||||
interface DividerProps extends CProps.Styling {
|
export interface DividerProps extends CProps.Styling {
|
||||||
|
/** Indicates whether the divider is vertical. */
|
||||||
vertical?: boolean;
|
vertical?: boolean;
|
||||||
|
|
||||||
|
/** Margins to apply to the divider `classNames`. */
|
||||||
margins?: string;
|
margins?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divider component that renders a horizontal or vertical divider with customizable margins and styling.
|
||||||
|
*/
|
||||||
function Divider({ vertical, margins = 'mx-2', className, ...restProps }: DividerProps) {
|
function Divider({ vertical, margins = 'mx-2', className, ...restProps }: DividerProps) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -6,12 +6,22 @@ import { animateDropdown } from '@/styling/animations';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
interface DropdownProps extends CProps.Styling {
|
interface DropdownProps extends CProps.Styling {
|
||||||
|
/** Indicates whether the dropdown should stretch to the left. */
|
||||||
stretchLeft?: boolean;
|
stretchLeft?: boolean;
|
||||||
|
|
||||||
|
/** Indicates whether the dropdown should stretch to the top. */
|
||||||
stretchTop?: boolean;
|
stretchTop?: boolean;
|
||||||
|
|
||||||
|
/** Indicates whether the dropdown is open. */
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
|
||||||
|
/** Children to render inside the component. */
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dropdown animated component that displays a list of children with optional positioning and visibility control.
|
||||||
|
*/
|
||||||
function Dropdown({ isOpen, stretchLeft, stretchTop, className, children, ...restProps }: DropdownProps) {
|
function Dropdown({ isOpen, stretchLeft, stretchTop, className, children, ...restProps }: DropdownProps) {
|
||||||
return (
|
return (
|
||||||
<div className='relative'>
|
<div className='relative'>
|
||||||
|
|
|
@ -7,15 +7,23 @@ import { globals } from '@/utils/constants';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
interface DropdownButtonProps extends CProps.AnimatedButton {
|
interface DropdownButtonProps extends CProps.AnimatedButton {
|
||||||
text?: string;
|
/** Icon to display first (not used if children are provided). */
|
||||||
icon?: React.ReactNode;
|
icon?: React.ReactNode;
|
||||||
|
|
||||||
|
/** Text to display second (not used if children are provided). */
|
||||||
|
text?: string;
|
||||||
|
|
||||||
|
/** Custom children to display. */
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DropdownButton animated component that renders a `button` with optional text, icon, and click functionality.
|
||||||
|
* It supports optional children for custom content or the default text/icon display.
|
||||||
|
*/
|
||||||
function DropdownButton({
|
function DropdownButton({
|
||||||
text,
|
|
||||||
icon,
|
icon,
|
||||||
|
text,
|
||||||
className,
|
className,
|
||||||
title,
|
title,
|
||||||
titleHtml,
|
titleHtml,
|
||||||
|
|
|
@ -3,21 +3,13 @@ import { motion } from 'framer-motion';
|
||||||
|
|
||||||
import { animateDropdownItem } from '@/styling/animations';
|
import { animateDropdownItem } from '@/styling/animations';
|
||||||
|
|
||||||
import Checkbox from './Checkbox';
|
import Checkbox, { CheckboxProps } from './Checkbox';
|
||||||
|
|
||||||
interface DropdownCheckboxProps {
|
/** DropdownCheckbox animated component that renders a {@link Checkbox} inside a {@link Dropdown} item. */
|
||||||
value: boolean;
|
function DropdownCheckbox({ setValue, disabled, ...restProps }: CheckboxProps) {
|
||||||
label?: string;
|
|
||||||
title?: string;
|
|
||||||
disabled?: boolean;
|
|
||||||
setValue?: (newValue: boolean) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
function DropdownCheckbox({ title, setValue, disabled, ...restProps }: DropdownCheckboxProps) {
|
|
||||||
return (
|
return (
|
||||||
<motion.div
|
<motion.div
|
||||||
variants={animateDropdownItem}
|
variants={animateDropdownItem}
|
||||||
title={title}
|
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'px-3 py-1',
|
'px-3 py-1',
|
||||||
'text-left overflow-ellipsis whitespace-nowrap',
|
'text-left overflow-ellipsis whitespace-nowrap',
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
|
|
||||||
import { CProps } from '@/components/props';
|
|
||||||
import { animateDropdownItem } from '@/styling/animations';
|
import { animateDropdownItem } from '@/styling/animations';
|
||||||
|
|
||||||
interface DividerAnimatedProps extends CProps.Styling {
|
import { DividerProps } from './Divider';
|
||||||
vertical?: boolean;
|
|
||||||
margins?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
function DividerAnimated({ vertical, margins = 'mx-2', className, ...restProps }: DividerAnimatedProps) {
|
/**
|
||||||
|
* DropdownDivider component that renders {@link Divider} with animation inside {@link Dropdown}.
|
||||||
|
*/
|
||||||
|
function DropdownDivider({ vertical, margins = 'mx-2', className, ...restProps }: DividerProps) {
|
||||||
return (
|
return (
|
||||||
<motion.div
|
<motion.div
|
||||||
variants={animateDropdownItem}
|
variants={animateDropdownItem}
|
||||||
|
@ -26,4 +25,4 @@ function DividerAnimated({ vertical, margins = 'mx-2', className, ...restProps }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DividerAnimated;
|
export default DropdownDivider;
|
|
@ -1,9 +1,17 @@
|
||||||
interface EmbedYoutubeProps {
|
interface EmbedYoutubeProps {
|
||||||
|
/** Video ID to embed. */
|
||||||
videoID: string;
|
videoID: string;
|
||||||
|
|
||||||
|
/** Display height in pixels. */
|
||||||
pxHeight: number;
|
pxHeight: number;
|
||||||
|
|
||||||
|
/** Display width in pixels. */
|
||||||
pxWidth?: number;
|
pxWidth?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EmbedYoutube component that embeds a YouTube video into the page using the given video ID and dimensions.
|
||||||
|
*/
|
||||||
function EmbedYoutube({ videoID, pxHeight, pxWidth }: EmbedYoutubeProps) {
|
function EmbedYoutube({ videoID, pxHeight, pxWidth }: EmbedYoutubeProps) {
|
||||||
if (!pxWidth) {
|
if (!pxWidth) {
|
||||||
pxWidth = (pxHeight * 16) / 9;
|
pxWidth = (pxHeight * 16) / 9;
|
||||||
|
|
|
@ -9,12 +9,19 @@ import Button from './Button';
|
||||||
import Label from './Label';
|
import Label from './Label';
|
||||||
|
|
||||||
interface FileInputProps extends Omit<CProps.Input, 'accept' | 'type'> {
|
interface FileInputProps extends Omit<CProps.Input, 'accept' | 'type'> {
|
||||||
|
/** Label to display in file upload button. */
|
||||||
label: string;
|
label: string;
|
||||||
|
|
||||||
|
/** Filter: file types. */
|
||||||
acceptType?: string;
|
acceptType?: string;
|
||||||
|
|
||||||
|
/** Callback to set the `value`. Value is transmitted as `event.target.files[0]`. */
|
||||||
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FileInput component for selecting a `file`, displaying the selected file name.
|
||||||
|
*/
|
||||||
function FileInput({ id, label, acceptType, title, className, style, onChange, ...restProps }: FileInputProps) {
|
function FileInput({ id, label, acceptType, title, className, style, onChange, ...restProps }: FileInputProps) {
|
||||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||||
const [fileName, setFileName] = useState('');
|
const [fileName, setFileName] = useState('');
|
||||||
|
|
|
@ -2,6 +2,10 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FlexColumn component that renders a `flex` column container.
|
||||||
|
* This component is useful for creating vertical layouts with flexbox.
|
||||||
|
*/
|
||||||
function FlexColumn({ className, children, ...restProps }: CProps.Div) {
|
function FlexColumn({ className, children, ...restProps }: CProps.Div) {
|
||||||
return (
|
return (
|
||||||
<div className={clsx('cc-column', className)} {...restProps}>
|
<div className={clsx('cc-column', className)} {...restProps}>
|
||||||
|
|
|
@ -5,10 +5,16 @@ import { globals } from '@/utils/constants';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
interface IndicatorProps extends CProps.Titled, CProps.Styling {
|
interface IndicatorProps extends CProps.Titled, CProps.Styling {
|
||||||
|
/** Icon to display. */
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
|
|
||||||
|
/** Indicates whether the indicator should have no padding. */
|
||||||
noPadding?: boolean;
|
noPadding?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicator component that displays a status `icon` with a tooltip.
|
||||||
|
*/
|
||||||
function Indicator({ icon, title, titleHtml, hideTitle, noPadding, className, ...restProps }: IndicatorProps) {
|
function Indicator({ icon, title, titleHtml, hideTitle, noPadding, className, ...restProps }: IndicatorProps) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
IconShare
|
IconShare
|
||||||
} from '@/components/Icons';
|
} from '@/components/Icons';
|
||||||
import Button from '@/components/ui/Button';
|
import Button from '@/components/ui/Button';
|
||||||
import DividerAnimated from '@/components/ui/DividerAnimated';
|
import DropdownDivider from '@/components/ui/DropdownDivider';
|
||||||
import Dropdown from '@/components/ui/Dropdown';
|
import Dropdown from '@/components/ui/Dropdown';
|
||||||
import DropdownButton from '@/components/ui/DropdownButton';
|
import DropdownButton from '@/components/ui/DropdownButton';
|
||||||
import { useAccessMode } from '@/context/AccessModeContext';
|
import { useAccessMode } from '@/context/AccessModeContext';
|
||||||
|
@ -96,7 +96,7 @@ function MenuOssTabs({ onDestroy }: MenuOssTabsProps) {
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<DividerAnimated margins='mx-3 my-1' />
|
<DropdownDivider margins='mx-3 my-1' />
|
||||||
|
|
||||||
{user ? (
|
{user ? (
|
||||||
<DropdownButton
|
<DropdownButton
|
||||||
|
|
|
@ -27,7 +27,7 @@ import {
|
||||||
IconUpload
|
IconUpload
|
||||||
} from '@/components/Icons';
|
} from '@/components/Icons';
|
||||||
import Button from '@/components/ui/Button';
|
import Button from '@/components/ui/Button';
|
||||||
import DividerAnimated from '@/components/ui/DividerAnimated';
|
import DropdownDivider from '@/components/ui/DropdownDivider';
|
||||||
import Dropdown from '@/components/ui/Dropdown';
|
import Dropdown from '@/components/ui/Dropdown';
|
||||||
import DropdownButton from '@/components/ui/DropdownButton';
|
import DropdownButton from '@/components/ui/DropdownButton';
|
||||||
import { useAccessMode } from '@/context/AccessModeContext';
|
import { useAccessMode } from '@/context/AccessModeContext';
|
||||||
|
@ -186,7 +186,7 @@ function MenuRSTabs({ onDestroy }: MenuRSTabsProps) {
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<DividerAnimated margins='mx-3 my-1' />
|
<DropdownDivider margins='mx-3 my-1' />
|
||||||
|
|
||||||
{user ? (
|
{user ? (
|
||||||
<DropdownButton
|
<DropdownButton
|
||||||
|
@ -239,7 +239,7 @@ function MenuRSTabs({ onDestroy }: MenuRSTabsProps) {
|
||||||
onClick={handleInlineSynthesis}
|
onClick={handleInlineSynthesis}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DividerAnimated margins='mx-3 my-1' />
|
<DropdownDivider margins='mx-3 my-1' />
|
||||||
|
|
||||||
<DropdownButton
|
<DropdownButton
|
||||||
text='Упорядочить список'
|
text='Упорядочить список'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user