/
gsam
/
ui-kit-ce
Обзор
Документация
Войти
/
gsam
/
ui-kit-ce
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
docs/showroom/components/Code/Code.tsx
213 строк
5 KB
Denis Svyatovets
chore: правки prettier
27 июн 2025, 14:46
27 июн 2025, 14:46
e9e0fb5
Код
Авторство
О чём код?
import * as React from 'react' import { createUseStyles, useValue, clsx, Labelled, useCopy } from '@v-uik/base' import { Source, SourceProps } from './components' import { ContextButtons, ContextButtonsProps } from '../_components' import { getBackgroundByKind } from '../utils' const GRADIENT_HIDDEN_MAX_HEIGHT = 130 export const ShowCodeKind = { default: 'default', gradient: 'gradient', } as const export type ShowCodeKindType = (typeof ShowCodeKind)[keyof typeof ShowCodeKind] export type CodeProps = SourceProps & Omit<ContextButtonsProps, 'gutters'> & { /** * * @inner */ //eslint-disable-next-line @typescript-eslint/no-explicit-any data?: any /** * * @inner */ showCodeKind?: ShowCodeKindType /** * * @inner */ disableScrollOnClose?: boolean /** * * @inner */ width?: number | string /** * * @inner */ className?: string /** * * @inner */ label?: string } const useStyles = createUseStyles({ root: { position: 'relative', }, buttonContainer: { zIndex: 1, position: 'absolute', bottom: 1, right: 1, display: 'flex', flexDirection: 'row', '& button:last-child:not(:first-child)': { borderTopLeftRadius: 0, }, }, buttonContainerGutters: { marginRight: -20, }, sourceWrapper: { position: 'relative', }, sourceWrapperGradient: { height: GRADIENT_HIDDEN_MAX_HEIGHT, }, sourceWrapperGradientOpen: { height: 'auto', }, sourceWrapperGradientOverlay: { height: 150, width: 'calc(100% - 2px)', position: 'absolute', bottom: 0, zIndex: 1, left: 1, }, }) const getHeight = ( isGradient: boolean, isShowCode: boolean, fallbackValue: React.CSSProperties['height'] ): React.CSSProperties['height'] => (isGradient && (isShowCode ? fallbackValue : GRADIENT_HIDDEN_MAX_HEIGHT - 1)) || fallbackValue export const Code: React.FC<CodeProps> = ({ data: dataProp, code: codeProp, height = 'auto', gutters, withClear: withClearProp, onClear, withShowCode, noCopy, isShowCode: isShowCodeProp, onShowCode, showCodeKind = ShowCodeKind.default, disableScrollOnClose, kind, width, className, label, ...rest }) => { //eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment const [data, setData] = React.useState<any>([]) const [code, setCode] = React.useState('') const [isShowCode, setIsShowCode] = useValue(!!isShowCodeProp, { useInnerState: isShowCodeProp === undefined, }) const ref = React.useRef<HTMLDivElement>(null) const isGradient = showCodeKind === 'gradient' const classes = useStyles() const handleClear = () => { setData([]) setCode('') onClear?.() } const toggleShow = (value: boolean) => { onShowCode?.(value) if (isShowCodeProp === undefined) { setIsShowCode((s: boolean) => !s) } if (!disableScrollOnClose && value) { ref.current?.scrollIntoView() } } const { isCopied, copyToClipboard } = useCopy({ text: (data || code) as string, copiedDuration: 1000, }) const showCode = (withShowCode && isShowCode) || !withShowCode || showCodeKind === 'gradient' const withClear = withClearProp && (!!code || ((data || []) as [])?.length > 0) const sourceWrapperClassName = clsx(classes.sourceWrapper, { [classes.sourceWrapperGradient]: isGradient, [classes.sourceWrapperGradientOpen]: isGradient && isShowCode, }) React.useEffect(() => { setData(dataProp) }, [dataProp]) React.useEffect(() => { setCode(codeProp ?? '') }, [codeProp]) if (!showCode) { return null } return ( <Labelled label={label}> <div className={clsx(classes.root, className)}> <div ref={ref} className={sourceWrapperClassName} style={{ width: width }} > <Source height={getHeight(isGradient, isShowCode as boolean, height)} code={code ? code : JSON.stringify(data, null, 1)} gutters={gutters} overflowHidden={isGradient && !isShowCode} kind={kind} {...rest} /> {isGradient && !isShowCode && ( <div className={classes.sourceWrapperGradientOverlay} style={{ backgroundImage: `linear-gradient(180deg, rgba(255,255,255,0) 0, ${getBackgroundByKind( kind )} 100%)`, }} /> )} </div> <ContextButtons kind={kind} noCopy={noCopy} withShowCode={withShowCode} withClear={withClear} gutters={gutters} isCopied={isCopied} isShowCode={isShowCode as boolean} onShowCode={toggleShow} onClear={handleClear} onCopy={copyToClipboard} /> </div> </Labelled> ) }