feat: yaml editor

This commit is contained in:
jialin
2025-10-13 14:40:26 +08:00
parent e863b84016
commit 54703c67c1
48 changed files with 2062 additions and 246 deletions
@@ -0,0 +1,55 @@
import IconFont from '@/components/icon-font';
import { Collapse, CollapseProps } from 'antd';
import React from 'react';
import styled from 'styled-components';
const CollapseInner = styled(Collapse)`
.ant-collapse-header {
display: flex;
align-items: center;
margin-bottom: 10px !important;
padding-inline: 5px !important;
padding-block: 8px !important;
border-radius: var(--border-radius-base) !important;
font-size: 14px !important;
font-weight: 600 !important;
&:hover {
background-color: var(--ant-color-fill-tertiary) !important;
}
}
.ant-collapse-content-box {
padding-inline: 0 !important;
padding-block: 0 !important;
}
.ant-collapse-header-text {
display: flex;
align-items: center;
height: 24px;
}
`;
const CollapsePanel: React.FC<{ items: CollapseProps['items'] }> = ({
items
}) => {
return (
<CollapseInner
expandIconPosition="start"
bordered={false}
ghost
accordion
destroyOnHidden={false}
expandIcon={({ isActive }) => (
<IconFont
type="icon-down"
rotate={isActive ? 0 : -90}
style={{ fontSize: '14px' }}
></IconFont>
)}
items={items}
></CollapseInner>
);
};
export default CollapsePanel;
@@ -0,0 +1,51 @@
import useOverlayScroller from '@/hooks/use-overlay-scroller';
import React from 'react';
import './style.less';
const ColumnWrapper: React.FC<any> = ({
children,
footer,
maxHeight,
paddingBottom = 50
}) => {
const scroller = React.useRef<any>(null);
const { initialize } = useOverlayScroller({
options: {
scrollbars: {
autoHide: 'move'
}
}
});
React.useEffect(() => {
if (scroller.current) {
initialize(scroller.current);
}
}, []);
return (
<>
<div
className="column-wrapper-footer"
style={{ height: maxHeight || '100%' }}
>
<div
className="column-wrapper"
ref={scroller}
style={{ padding: '16px 24px' }}
>
<div
style={{
paddingBottom: footer ? paddingBottom : 0
}}
>
{children}
</div>
</div>
{footer && <div className="footer">{footer}</div>}
</div>
</>
);
};
export default ColumnWrapper;
@@ -0,0 +1,31 @@
.column-wrapper {
flex: 1;
position: relative;
height: 100%;
overflow-y: auto;
}
.simplebar-scrollbar::before {
width: var(--scrollbar-size);
background: var(--scrollbar-handle-bg);
}
.column-wrapper-footer {
flex: 1;
display: flex;
position: relative;
.column-wrapper {
border-left: none;
}
.footer {
position: absolute;
bottom: 0;
left: 0;
right: 0;
z-index: 100;
padding-block: 0;
background-color: var(--ant-color-bg-elevated);
}
}
@@ -0,0 +1,79 @@
import CopyButton from '@/components/copy-button';
import EditorWrap from '@/components/editor-wrap';
import HighlightCode from '@/components/highlight-code';
import SegmentLine from '@/components/segment-line';
import React from 'react';
import styled from 'styled-components';
interface ViewerProps {
code: string;
copyText?: string;
options?: Global.BaseOption<string>[];
defaultValue?: string;
headerHeight?: number;
lang?: string;
onChange?: (value: string | number) => void;
}
const Header = styled.div`
width: 100%;
padding-inline: 12px 10px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: var(--color-editor-header-bg);
`;
const CommandViewer: React.FC<ViewerProps> = (props) => {
const {
code,
copyText = '',
defaultValue,
options = [],
headerHeight = 40,
lang,
onChange
} = props || {};
const [value, setValue] = React.useState<string>(defaultValue || '');
const handlOnChange = (value: string | number) => {
setValue(value as string);
onChange?.(value);
};
return (
<EditorWrap
header={
<Header>
<SegmentLine
height={headerHeight}
defaultValue={defaultValue}
value={value}
size="small"
options={options}
onChange={handlOnChange}
></SegmentLine>
<CopyButton
text={copyText || code}
size="small"
style={{
color: 'rgba(255,255,255,.7)'
}}
/>
</Header>
}
>
<HighlightCode
height={380}
theme="dark"
code={code}
lang={lang || value}
copyable={false}
></HighlightCode>
</EditorWrap>
);
};
export default CommandViewer;