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
|
||||
|
||||
- 🚀 F: major feature implementation
|
||||
- 💄 D: UI design
|
||||
- 🔥 B: bug fix
|
||||
- 🚑 M: Minor fixes
|
||||
- 🔧 R: refactoring and code improvement
|
||||
- 📝 I: documentation
|
||||
- 📝 D: documentation
|
||||
|
||||
## 🖥️ 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';
|
||||
|
||||
export namespace CProps {
|
||||
export interface Titled {
|
||||
title?: string;
|
||||
titleHtml?: string;
|
||||
hideTitle?: boolean;
|
||||
}
|
||||
|
||||
export type Control = Titled & {
|
||||
disabled?: boolean;
|
||||
noBorder?: boolean;
|
||||
noOutline?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents an object that can have inline styles and CSS class names for styling.
|
||||
*/
|
||||
export interface Styling {
|
||||
/** Optional inline styles for the component. */
|
||||
style?: React.CSSProperties;
|
||||
|
||||
/** Optional CSS class name(s) for the component. */
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export type Editor = Control & {
|
||||
label?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents an object that can have a color or set of colors.
|
||||
*/
|
||||
export interface Colors {
|
||||
/** Optional color or set of colors applied via classNames. */
|
||||
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>;
|
||||
|
||||
/**
|
||||
* Represents `button` component with optional title and HTML attributes.
|
||||
*/
|
||||
export type Button = Titled &
|
||||
Omit<
|
||||
React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>,
|
||||
'children' | 'type'
|
||||
>;
|
||||
|
||||
/**
|
||||
* Represents `label` component with HTML attributes.
|
||||
*/
|
||||
export type Label = Omit<
|
||||
React.DetailedHTMLProps<React.LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>,
|
||||
'children'
|
||||
>;
|
||||
|
||||
/**
|
||||
* Represents `textarea` component with optional title and HTML attributes.
|
||||
*/
|
||||
export type TextArea = Titled &
|
||||
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>;
|
||||
|
||||
/**
|
||||
* Represents `button` component with optional title and animation properties.
|
||||
*/
|
||||
export type AnimatedButton = Titled & Omit<HTMLMotionProps<'button'>, 'type'>;
|
||||
|
||||
/**
|
||||
* Represents `div` component with animation properties.
|
||||
*/
|
||||
export type AnimatedDiv = HTMLMotionProps<'div'>;
|
||||
|
||||
/**
|
||||
* Represents `mouse event` in React.
|
||||
*/
|
||||
export type EventMouse = React.MouseEvent<Element, MouseEvent>;
|
||||
}
|
||||
|
|
|
@ -5,16 +5,25 @@ import { globals } from '@/utils/constants';
|
|||
import { CProps } from '../props';
|
||||
|
||||
interface ButtonProps extends CProps.Control, CProps.Colors, CProps.Button {
|
||||
text?: string;
|
||||
/** Icon to display first. */
|
||||
icon?: React.ReactNode;
|
||||
|
||||
/** Text to display second. */
|
||||
text?: string;
|
||||
|
||||
/** Indicates whether to render the button in a dense style. */
|
||||
dense?: boolean;
|
||||
|
||||
/** Indicates loading state to prevent interactions and change visual style. */
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Button component that provides a customizable `button` with text, icon, tooltips and various styles.
|
||||
*/
|
||||
function Button({
|
||||
text,
|
||||
icon,
|
||||
text,
|
||||
title,
|
||||
titleHtml,
|
||||
hideTitle,
|
||||
|
|
|
@ -7,13 +7,22 @@ import { CheckboxChecked } from '../Icons';
|
|||
import { CProps } from '../props';
|
||||
|
||||
export interface CheckboxProps extends Omit<CProps.Button, 'value' | 'onClick'> {
|
||||
/** Label to display next to the checkbox. */
|
||||
label?: string;
|
||||
|
||||
/** Indicates whether the checkbox is disabled. */
|
||||
disabled?: boolean;
|
||||
|
||||
/** Current value - `true` or `false`. */
|
||||
value: boolean;
|
||||
|
||||
/** Callback to set the `value`. */
|
||||
setValue?: (newValue: boolean) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checkbox component that allows users to toggle a boolean value.
|
||||
*/
|
||||
function Checkbox({
|
||||
disabled,
|
||||
label,
|
||||
|
|
|
@ -8,10 +8,16 @@ import { CProps } from '../props';
|
|||
import { CheckboxProps } from './Checkbox';
|
||||
|
||||
export interface CheckboxTristateProps extends Omit<CheckboxProps, 'value' | 'setValue'> {
|
||||
/** Current value - `null`, `true` or `false`. */
|
||||
value: boolean | null;
|
||||
|
||||
/** Callback to set the `value`. */
|
||||
setValue?: (newValue: boolean | null) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckboxTristate component that allows toggling among three states: `true`, `false`, and `null`.
|
||||
*/
|
||||
function CheckboxTristate({
|
||||
disabled,
|
||||
label,
|
||||
|
|
|
@ -2,11 +2,17 @@ import clsx from 'clsx';
|
|||
|
||||
import { CProps } from '@/components/props';
|
||||
|
||||
interface DividerProps extends CProps.Styling {
|
||||
export interface DividerProps extends CProps.Styling {
|
||||
/** Indicates whether the divider is vertical. */
|
||||
vertical?: boolean;
|
||||
|
||||
/** Margins to apply to the divider `classNames`. */
|
||||
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) {
|
||||
return (
|
||||
<div
|
||||
|
|
|
@ -6,12 +6,22 @@ import { animateDropdown } from '@/styling/animations';
|
|||
import { CProps } from '../props';
|
||||
|
||||
interface DropdownProps extends CProps.Styling {
|
||||
/** Indicates whether the dropdown should stretch to the left. */
|
||||
stretchLeft?: boolean;
|
||||
|
||||
/** Indicates whether the dropdown should stretch to the top. */
|
||||
stretchTop?: boolean;
|
||||
|
||||
/** Indicates whether the dropdown is open. */
|
||||
isOpen: boolean;
|
||||
|
||||
/** Children to render inside the component. */
|
||||
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) {
|
||||
return (
|
||||
<div className='relative'>
|
||||
|
|
|
@ -7,15 +7,23 @@ import { globals } from '@/utils/constants';
|
|||
import { CProps } from '../props';
|
||||
|
||||
interface DropdownButtonProps extends CProps.AnimatedButton {
|
||||
text?: string;
|
||||
/** Icon to display first (not used if children are provided). */
|
||||
icon?: React.ReactNode;
|
||||
|
||||
/** Text to display second (not used if children are provided). */
|
||||
text?: string;
|
||||
|
||||
/** Custom children to display. */
|
||||
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({
|
||||
text,
|
||||
icon,
|
||||
text,
|
||||
className,
|
||||
title,
|
||||
titleHtml,
|
||||
|
|
|
@ -3,21 +3,13 @@ import { motion } from 'framer-motion';
|
|||
|
||||
import { animateDropdownItem } from '@/styling/animations';
|
||||
|
||||
import Checkbox from './Checkbox';
|
||||
import Checkbox, { CheckboxProps } from './Checkbox';
|
||||
|
||||
interface DropdownCheckboxProps {
|
||||
value: boolean;
|
||||
label?: string;
|
||||
title?: string;
|
||||
disabled?: boolean;
|
||||
setValue?: (newValue: boolean) => void;
|
||||
}
|
||||
|
||||
function DropdownCheckbox({ title, setValue, disabled, ...restProps }: DropdownCheckboxProps) {
|
||||
/** DropdownCheckbox animated component that renders a {@link Checkbox} inside a {@link Dropdown} item. */
|
||||
function DropdownCheckbox({ setValue, disabled, ...restProps }: CheckboxProps) {
|
||||
return (
|
||||
<motion.div
|
||||
variants={animateDropdownItem}
|
||||
title={title}
|
||||
className={clsx(
|
||||
'px-3 py-1',
|
||||
'text-left overflow-ellipsis whitespace-nowrap',
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import clsx from 'clsx';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
import { CProps } from '@/components/props';
|
||||
import { animateDropdownItem } from '@/styling/animations';
|
||||
|
||||
interface DividerAnimatedProps extends CProps.Styling {
|
||||
vertical?: boolean;
|
||||
margins?: string;
|
||||
}
|
||||
import { DividerProps } from './Divider';
|
||||
|
||||
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 (
|
||||
<motion.div
|
||||
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 {
|
||||
/** Video ID to embed. */
|
||||
videoID: string;
|
||||
|
||||
/** Display height in pixels. */
|
||||
pxHeight: number;
|
||||
|
||||
/** Display width in pixels. */
|
||||
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) {
|
||||
if (!pxWidth) {
|
||||
pxWidth = (pxHeight * 16) / 9;
|
||||
|
|
|
@ -9,12 +9,19 @@ import Button from './Button';
|
|||
import Label from './Label';
|
||||
|
||||
interface FileInputProps extends Omit<CProps.Input, 'accept' | 'type'> {
|
||||
/** Label to display in file upload button. */
|
||||
label: string;
|
||||
|
||||
/** Filter: file types. */
|
||||
acceptType?: string;
|
||||
|
||||
/** Callback to set the `value`. Value is transmitted as `event.target.files[0]`. */
|
||||
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) {
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
const [fileName, setFileName] = useState('');
|
||||
|
|
|
@ -2,6 +2,10 @@ import clsx from 'clsx';
|
|||
|
||||
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) {
|
||||
return (
|
||||
<div className={clsx('cc-column', className)} {...restProps}>
|
||||
|
|
|
@ -5,10 +5,16 @@ import { globals } from '@/utils/constants';
|
|||
import { CProps } from '../props';
|
||||
|
||||
interface IndicatorProps extends CProps.Titled, CProps.Styling {
|
||||
/** Icon to display. */
|
||||
icon: React.ReactNode;
|
||||
|
||||
/** Indicates whether the indicator should have no padding. */
|
||||
noPadding?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicator component that displays a status `icon` with a tooltip.
|
||||
*/
|
||||
function Indicator({ icon, title, titleHtml, hideTitle, noPadding, className, ...restProps }: IndicatorProps) {
|
||||
return (
|
||||
<div
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
IconShare
|
||||
} from '@/components/Icons';
|
||||
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 DropdownButton from '@/components/ui/DropdownButton';
|
||||
import { useAccessMode } from '@/context/AccessModeContext';
|
||||
|
@ -96,7 +96,7 @@ function MenuOssTabs({ onDestroy }: MenuOssTabsProps) {
|
|||
/>
|
||||
) : null}
|
||||
|
||||
<DividerAnimated margins='mx-3 my-1' />
|
||||
<DropdownDivider margins='mx-3 my-1' />
|
||||
|
||||
{user ? (
|
||||
<DropdownButton
|
||||
|
|
|
@ -27,7 +27,7 @@ import {
|
|||
IconUpload
|
||||
} from '@/components/Icons';
|
||||
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 DropdownButton from '@/components/ui/DropdownButton';
|
||||
import { useAccessMode } from '@/context/AccessModeContext';
|
||||
|
@ -186,7 +186,7 @@ function MenuRSTabs({ onDestroy }: MenuRSTabsProps) {
|
|||
/>
|
||||
) : null}
|
||||
|
||||
<DividerAnimated margins='mx-3 my-1' />
|
||||
<DropdownDivider margins='mx-3 my-1' />
|
||||
|
||||
{user ? (
|
||||
<DropdownButton
|
||||
|
@ -239,7 +239,7 @@ function MenuRSTabs({ onDestroy }: MenuRSTabsProps) {
|
|||
onClick={handleInlineSynthesis}
|
||||
/>
|
||||
|
||||
<DividerAnimated margins='mx-3 my-1' />
|
||||
<DropdownDivider margins='mx-3 my-1' />
|
||||
|
||||
<DropdownButton
|
||||
text='Упорядочить список'
|
||||
|
|
Loading…
Reference in New Issue
Block a user