Refactor(css): Change all less to module mode

This commit is contained in:
2024-10-17 20:26:06 +08:00
parent 3d77dc793b
commit b7c3fb8524
111 changed files with 962 additions and 858 deletions

View File

@@ -14,11 +14,11 @@
}
}
[data-component=playground-code-editor-editor] {
.root {
position: relative;
height: 0;
.monaco-editor-light {
:global .monaco-editor-light {
height: 100%;
overflow: hidden;
background-color: var(--border);
@@ -40,7 +40,7 @@
}
}
.monaco-editor-vs-dark {
:global .monaco-editor-vs-dark {
height: 100%;
overflow: hidden;
background-color: var(--border);
@@ -62,7 +62,7 @@
}
}
.playground-code-editor-loading {
.playgroundCodeEditorLoading {
position: absolute;
top: 0;
right: 0;

View File

@@ -1,6 +1,6 @@
import { editor, Selection } from 'monaco-editor'
import MonacoEditor, { Monaco } from '@monaco-editor/react'
import '@/components/Playground/CodeEditor/Editor/editor.less'
import styles from '@/components/Playground/CodeEditor/Editor/index.module.less'
import '@/components/Playground/CodeEditor/Editor/loader'
import { IEditorOptions, IFiles, ITheme, ITsconfig } from '@/components/Playground/shared'
import { fileNameToLanguage, tsconfigJsonDiagnosticsOptions } from '@/components/Playground/files'
@@ -112,7 +112,7 @@ const Editor = ({
return (
<>
<div data-component={'playground-code-editor-editor'}>
<div className={styles.root}>
<MonacoEditor
theme={theme}
path={file.name}
@@ -129,7 +129,7 @@ const Editor = ({
readOnly: readonly
}}
/>
{total > 0 && !finished && <div className={'playground-code-editor-loading'} />}
{total > 0 && !finished && <div className={styles.playgroundCodeEditorLoading} />}
</div>
</>
)

View File

@@ -1,4 +1,5 @@
import { Dispatch, SetStateAction, KeyboardEvent, ChangeEvent, MouseEvent } from 'react'
import styles from '@/components/Playground/CodeEditor/FileSelector/item.module.less'
interface ItemProps {
className?: string
@@ -109,11 +110,11 @@ const Item = ({
return (
<div
className={`tab-item${active ? ' active' : ''}${className ? ` ${className}` : ''}`}
className={`${styles.root}${active ? ` ${styles.active}` : ''}${className ? ` ${className}` : ''}`}
onClick={handleOnClick}
>
{isCreating ? (
<div className={'tab-item-input'}>
<div className={styles.tabItemInput}>
<input
ref={inputRef}
value={fileName}
@@ -122,13 +123,13 @@ const Item = ({
onKeyDown={handleKeyDown}
spellCheck={'false'}
/>
<span className={'tab-item-input-mask'}>{fileName}</span>
<span className={styles.tabItemInputMask}>{fileName}</span>
</div>
) : (
<>
<div onDoubleClick={handleOnDoubleClick}>{value}</div>
{!readonly && (
<div className={'tab-item-close'} onClick={handleOnDelete}>
<div className={styles.tabItemClose} onClick={handleOnDelete}>
<IconOxygenClose />
</div>
)}

View File

@@ -1,86 +0,0 @@
[data-component=playground-file-selector].tab{
display: flex;
flex: 0 0 auto;
height: 40px;
.multiple {
flex: 1;
width: 0;
.tab-content {
height: 40px;
align-items: flex-end;
gap: 2px;
margin-left: 10px;
.tab-item-add {
padding: 0 12px;
}
.tabs-margin-right {
height: 100%;
> * {
height: 100%;
width: 10px;
}
}
}
}
.sticky {
display: flex;
flex: 0 0 auto;
align-items: flex-end;
margin-right: 10px;
}
.tab-item {
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 auto;
height: 30px;
padding: 0 20px;
border: 1px solid #f0f0f0;
background-color: rgba(0, 0, 0, 0.04);
border-radius: 6px 6px 0 0;
cursor: pointer;
.tab-item-input {
position: relative;
min-width: 40px;
transform: translateY(1px);
.tab-item-input-mask {
display: inline-block;
color: transparent;
}
input {
position: absolute;
background-color: transparent;
width: 100%;
font-size: 1em;
}
}
.tab-item-close {
transform: translateX(10px);
:hover {
fill: #888;
}
svg {
height: 8px;
fill: #666;
}
}
&.active {
background-color: white;
border-bottom: none;
}
}
}

View File

@@ -0,0 +1,37 @@
.root{
display: flex;
flex: 0 0 auto;
height: 40px;
.multiple {
flex: 1;
width: 0;
.tabContent {
height: 40px;
align-items: flex-end;
gap: 2px;
margin-left: 10px;
.tabItemAdd {
padding: 0 12px;
}
.tabsMarginRight {
height: 100%;
> * {
height: 100%;
width: 10px;
}
}
}
}
.sticky {
display: flex;
flex: 0 0 auto;
align-items: flex-end;
margin-right: 10px;
}
}

View File

@@ -1,4 +1,4 @@
import '@/components/Playground/CodeEditor/FileSelector/file-selector.less'
import styles from '@/components/Playground/CodeEditor/FileSelector/index.module.less'
import HideScrollbar, { HideScrollbarElement } from '@/components/common/HideScrollbar'
import FlexBox from '@/components/common/FlexBox'
import { IFiles } from '@/components/Playground/shared'
@@ -164,8 +164,8 @@ const FileSelector = ({
return (
<>
<div data-component={'playground-file-selector'} className={'tab'}>
<div className={'multiple'}>
<div className={styles.root}>
<div className={styles.multiple}>
<HideScrollbar
ref={hideScrollbarRef}
autoHideWaitingTime={800}
@@ -173,7 +173,7 @@ const FileSelector = ({
scrollbarAsidePadding={0}
scrollbarEdgePadding={0}
>
<FlexBox direction={'horizontal'} className={'tab-content'}>
<FlexBox direction={'horizontal'} className={styles.tabContent}>
{tabs.map((item, index) => (
<Item
key={index + item}
@@ -192,20 +192,20 @@ const FileSelector = ({
))}
{!readonly && (
<Item
className={'tab-item-add'}
className={styles.tabItemAdd}
value={'+'}
onClick={addTab}
readonly
/>
)}
<div className={'tabs-margin-right'}>
<div className={styles.tabsMarginRight}>
<div />
</div>
</FlexBox>
</HideScrollbar>
</div>
{(files[IMPORT_MAP_FILE_NAME] || files[TS_CONFIG_FILE_NAME]) && (
<div className={'sticky'}>
<div className={styles.sticky}>
{files[TS_CONFIG_FILE_NAME] && (
<Item
value={'tsconfig.json'}

View File

@@ -0,0 +1,47 @@
.root {
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 auto;
height: 30px;
padding: 0 20px;
border: 1px solid #f0f0f0;
background-color: rgba(0, 0, 0, 0.04);
border-radius: 6px 6px 0 0;
cursor: pointer;
.tabItemInput {
position: relative;
min-width: 40px;
transform: translateY(1px);
.tabItemInputMask {
display: inline-block;
color: transparent;
}
input {
position: absolute;
background-color: transparent;
width: 100%;
font-size: 1em;
}
}
.tabItemClose {
transform: translateX(10px);
:hover {
fill: #888;
}
svg {
height: 8px;
fill: #666;
}
}
&.active {
background-color: white;
border-bottom: none;
}
}

View File

@@ -1,5 +0,0 @@
[data-component=playground-code-editor] {
position: relative;
width: 100%;
height: 100%;
}

View File

@@ -0,0 +1,15 @@
.root {
position: relative;
width: 100%;
height: 100%;
.errorMessage {
position: absolute;
bottom: 0;
width: 100%;
color: white;
background-color: #FF4D4FAA;
padding: 5px 10px;
font-size: 1.2em;
}
}

View File

@@ -1,5 +1,5 @@
import _ from 'lodash'
import '@/components/Playground/CodeEditor/code-editor.less'
import styles from '@/components/Playground/CodeEditor/index.module.less'
import FlexBox from '@/components/common/FlexBox'
import { IEditorOptions, IFiles, ITheme, ITsconfig } from '@/components/Playground/shared'
import {
@@ -122,7 +122,7 @@ const CodeEditor = ({
return (
<>
<FlexBox data-component={'playground-code-editor'}>
<FlexBox className={styles.root}>
{showFileSelector && (
<FileSelector
files={files}
@@ -157,7 +157,7 @@ const CodeEditor = ({
onJumpFile={handleOnChangeSelectedFile}
extraLibs={extraLibs}
/>
{errorMsg && <div className={'playground-error-message'}>{errorMsg}</div>}
{errorMsg && <div className={styles.errorMessage}>{errorMsg}</div>}
</FlexBox>
</>
)

View File

@@ -1,5 +1,5 @@
import { ChangeEvent } from 'react'
import '@/components/Playground/Output/Preview/render.less'
import styles from '@/components/Playground/Output/Preview/render.module.less'
import { COLOR_FONT_MAIN } from '@/constants/common.constants'
import iframeRaw from '@/components/Playground/Output/Preview/iframe.html?raw'
import HideScrollbar from '@/components/common/HideScrollbar'
@@ -174,16 +174,18 @@ const Render = ({ iframeKey, compiledCode, mobileMode = false }: RenderProps) =>
return mobileMode ? (
<>
<HideScrollbar
className={'mobile-mode-background'}
className={styles.mobileModeRoot}
isShowVerticalScrollbar
isShowHorizontalScrollbar
autoHideWaitingTime={1000}
>
<div className={'mobile-mode-content'} style={{ zoom }}>
<div className={`device${isRotate ? ' rotate' : ''}`}>
<div className={`device-header${isRotate ? ' rotate' : ''}`} />
<div className={styles.mobileModeContent} style={{ zoom }}>
<div className={`${styles.device}${isRotate ? ` ${styles.rotate}` : ''}`}>
<div
className={`device-content${isRotate ? ' rotate' : ''}`}
className={`${styles.deviceHeader}${isRotate ? ` ${styles.rotate}` : ''}`}
/>
<div
className={`${styles.deviceContent}${isRotate ? ` ${styles.rotate}` : ''}`}
style={{
width: isRotate
? (devices.find((value) => value.name === selectedDevice)
@@ -198,7 +200,7 @@ const Render = ({ iframeKey, compiledCode, mobileMode = false }: RenderProps) =>
}}
>
<iframe
data-component={'playground-output-preview-render'}
className={styles.renderRoot}
key={iframeKey}
ref={iframeRef}
src={iframeUrl}
@@ -207,19 +209,21 @@ const Render = ({ iframeKey, compiledCode, mobileMode = false }: RenderProps) =>
allow={'clipboard-read; clipboard-write'}
/>
</div>
<div className={`device-footer${isRotate ? ' rotate' : ''}`} />
<div
className={`${styles.deviceFooter}${isRotate ? ` ${styles.rotate}` : ''}`}
/>
</div>
</div>
</HideScrollbar>
<div className={'switch-device'}>
<div className={styles.switchDevice}>
<IconOxygenMobile fill={COLOR_FONT_MAIN} />
<select value={selectedDevice} onChange={handleOnChangeDevice}>
{devices.map((value) => (
<option value={value.name}>{value.name}</option>
))}
</select>
<div className={'rotate-device'} title={'旋转屏幕'} onClick={handleOnRotateDevice}>
<div title={'旋转屏幕'} onClick={handleOnRotateDevice}>
{isRotate ? (
<IconOxygenRotateRight fill={COLOR_FONT_MAIN} />
) : (
@@ -227,7 +231,7 @@ const Render = ({ iframeKey, compiledCode, mobileMode = false }: RenderProps) =>
)}
</div>
</div>
<div className={'switch-zoom'}>
<div className={styles.switchZoom}>
<IconOxygenZoom fill={COLOR_FONT_MAIN} />
<input
type={'range'}
@@ -241,7 +245,7 @@ const Render = ({ iframeKey, compiledCode, mobileMode = false }: RenderProps) =>
</>
) : (
<iframe
data-component={'playground-output-preview-render'}
className={styles.renderRoot}
key={iframeKey}
ref={iframeRef}
src={iframeUrl}

View File

@@ -1,9 +1,9 @@
[data-component=playground-preview] {
.root {
display: flex;
position: relative;
height: 0;
.playground-error-message {
.errorMessage {
position: absolute;
bottom: 0;
width: 100%;

View File

@@ -1,4 +1,4 @@
import '@/components/Playground/Output/Preview/preview.less'
import styles from '@/components/Playground/Output/Preview/index.module.less'
import { IFiles, IImportMap } from '@/components/Playground/shared'
import Compiler from '@/components/Playground/compiler'
import Render from '@/components/Playground/Output/Preview/Render'
@@ -42,9 +42,9 @@ const Preview = ({
}, [files, Compiler, importMap, entryPoint])
return (
<div data-component={'playground-preview'}>
<div className={styles.root}>
<Render iframeKey={iframeKey} compiledCode={compiledCode} mobileMode={mobileMode} />
{errorMsg && <div className={'playground-error-message'}>{errorMsg}</div>}
{errorMsg && <div className={styles.errorMessage}>{errorMsg}</div>}
</div>
)
}

View File

@@ -1,14 +1,14 @@
[data-component=playground-output-preview-render] {
.renderRoot {
border: none;
height: 100%;
width: 100%;
flex: 1;
}
.mobile-mode-background {
.mobileModeRoot {
background-color: rgba(204, 204, 204, 0.66);
.mobile-mode-content {
.mobileModeContent {
padding: 80px;
}
@@ -24,7 +24,7 @@
flex-direction: row;
}
.device-header {
.deviceHeader {
margin: 20px auto;
width: 60px;
height: 10px;
@@ -38,7 +38,7 @@
}
}
.device-content {
.deviceContent {
margin: 0 10px;
background-color: white;
@@ -47,7 +47,7 @@
}
}
.device-footer {
.deviceFooter {
margin: 20px auto;
width: 40px;
height: 40px;
@@ -61,7 +61,7 @@
}
}
.switch-device, .switch-zoom {
.switchDevice, .switchZoom {
display: flex;
position: absolute;
top: 10px;
@@ -69,10 +69,10 @@
gap: 4px;
}
.switch-device {
.switchDevice {
left: 10px;
}
.switch-zoom {
.switchZoom {
right: 10px;
}

View File

@@ -0,0 +1,13 @@
.root {
position: relative;
.errorMessage {
position: absolute;
bottom: 0;
width: 100%;
color: white;
background-color: #FF4D4FAA;
padding: 5px 10px;
font-size: 1.2em;
}
}

View File

@@ -1,6 +1,6 @@
import MonacoEditor from '@monaco-editor/react'
import { Loader } from 'esbuild-wasm'
import '@/components/Playground/Output/Transform/transform.less'
import styles from '@/components/Playground/Output/Transform/index.module.less'
import { IFile, ITheme } from '@/components/Playground/shared'
import { cssToJsFromFile, jsonToJsFromFile } from '@/components/Playground/files'
import Compiler from '@/components/Playground/compiler'
@@ -57,14 +57,14 @@ const Transform = ({ file, theme }: OutputProps) => {
}, [file, Compiler])
return (
<div data-component={'playground-transform'}>
<div className={styles.root}>
<MonacoEditor
theme={theme}
language={'javascript'}
value={compiledCode}
options={{ ...MonacoEditorConfig, readOnly: true }}
/>
{errorMsg && <div className={'playground-error-message'}>{errorMsg}</div>}
{errorMsg && <div className={styles.errorMessage}>{errorMsg}</div>}
</div>
)
}

View File

@@ -1,3 +0,0 @@
[data-component=playground-transform] {
position: relative;
}

View File

@@ -26,7 +26,7 @@ const Output = ({
const [selectedTab, setSelectedTab] = useState('Preview')
return (
<FlexBox data-component={'playground-code-output'}>
<FlexBox>
<Playground.CodeEditor.FileSelector
files={{
Preview: { name: 'Preview', language: 'json', value: '' },

View File

@@ -1,4 +1,4 @@
[data-component=playground] {
.root {
width: 100%;
height: 100%;

View File

@@ -1,4 +1,4 @@
import '@/components/Playground/playground.less'
import styles from '@/components/Playground/index.module.less'
import { IFiles, IImportMap, ITsconfig } from '@/components/Playground/shared'
import {
ENTRY_FILE_NAME,
@@ -77,7 +77,7 @@ const Playground = ({
}, [tsconfigRaw])
return (
<FlexBox data-component={'playground'} direction={'horizontal'}>
<FlexBox className={styles.root} direction={'horizontal'}>
<CodeEditor
tsconfig={tsconfig}
files={{

View File

@@ -1,10 +1,16 @@
import { DetailedHTMLProps, HTMLAttributes } from 'react'
import '@/assets/css/components/common/card.less'
import styles from '@/assets/css/components/common/card.module.less'
type CardProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
const Card = forwardRef<HTMLDivElement, CardProps>(({ className, ...props }, ref) => {
return <div className={`card-box${className ? ` ${className}` : ''}`} {...props} ref={ref} />
return (
<div
className={`${styles.cardBox}${className ? ` ${className}` : ''}`}
{...props}
ref={ref}
/>
)
})
export default Card

View File

@@ -1,5 +1,5 @@
import { DetailedHTMLProps, HTMLAttributes } from 'react'
import '@/assets/css/components/common/fit-center.less'
import styles from '@/assets/css/components/common/fit-center.module.less'
interface FitCenterProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
vertical?: boolean
@@ -8,7 +8,7 @@ interface FitCenterProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement
const FitCenter = ({ className, vertical, ...props }: FitCenterProps) => {
return (
<div
className={`fit-center${className ? ` ${className}` : ''}${
className={`${styles.fitCenter}${className ? ` ${className}` : ''}${
vertical ? ' flex-vertical' : ' flex-horizontal'
}`}
{...props}

View File

@@ -1,5 +1,5 @@
import { DetailedHTMLProps, HTMLAttributes } from 'react'
import '@/assets/css/components/common/fit-fullscreen.less'
import styles from '@/assets/css/components/common/fit-fullscreen.module.less'
interface FitFullscreenProps
extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
@@ -11,7 +11,7 @@ const FitFullscreen = forwardRef<HTMLDivElement, FitFullscreenProps>(
({ zIndex, backgroundColor, className, style, ...props }, ref) => {
return (
<div
className={`fit-fullscreen${className ? ` ${className}` : ''}`}
className={`${styles.fitFullscreen}${className ? ` ${className}` : ''}`}
style={{
zIndex,
backgroundColor,

View File

@@ -1,5 +1,5 @@
import { DetailedHTMLProps, HTMLAttributes } from 'react'
import '@/assets/css/components/common/flex-box.less'
import styles from '@/assets/css/components/common/flex-box.module.less'
interface FlexBoxProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
direction?: 'horizontal' | 'vertical'
@@ -10,7 +10,7 @@ const FlexBox = forwardRef<HTMLDivElement, FlexBoxProps>(
({ className, direction, gap, style, ...props }, ref) => {
return (
<div
className={`flex-box ${
className={`${styles.flexBox} ${
direction === 'horizontal' ? 'flex-horizontal' : 'flex-vertical'
}${className ? ` ${className}` : ''}`}
style={{ gap, ...style }}

View File

@@ -1,5 +1,5 @@
import Icon from '@ant-design/icons'
import '@/assets/css/components/common/fullscreen-loading-mask.less'
import styles from '@/assets/css/components/common/fullscreen-loading-mask.module.less'
import { COLOR_FONT_MAIN } from '@/constants/common.constants'
import FitFullscreen from '@/components/common/FitFullscreen'
@@ -16,7 +16,7 @@ const FullscreenLoadingMask = () => {
return (
<>
<FitFullscreen>
<div className={'fullscreen-loading-mask'}>
<div className={styles.fullscreenLoadingMask}>
<AntdSpin indicator={loadingIcon} />
</div>
</FitFullscreen>

View File

@@ -6,7 +6,7 @@ import {
HTMLAttributes,
UIEvent
} from 'react'
import '@/assets/css/components/common/hide-scrollbar.less'
import styles from '@/assets/css/components/common/hide-scrollbar.module.less'
interface HideScrollbarProps
extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
@@ -515,7 +515,7 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
return (
<>
<div
className={'hide-scrollbar-mask'}
className={styles.hideScrollbarMask}
ref={maskRef}
onMouseMove={
!isPreventScroll ? handleScrollbarMouseEvent('move', 'all') : undefined
@@ -538,7 +538,7 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
>
<div
ref={rootRef}
className={`hide-scrollbar-selection${className ? ` ${className}` : ''}`}
className={`${styles.hideScrollbarSelection}${className ? ` ${className}` : ''}`}
tabIndex={0}
style={{
width: `calc(${maskRef.current?.clientWidth}px + ${verticalScrollbarWidth}px)`,
@@ -555,7 +555,7 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
onScroll={handleDefaultScroll}
>
<div
className={'hide-scrollbar-content'}
className={styles.hideScrollbarContent}
ref={contentRef}
style={{ minWidth, minHeight }}
data-refresh={refreshTime}
@@ -566,8 +566,8 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
{isShowVerticalScrollbar &&
(!isHiddenVerticalScrollbarWhenFull || verticalScrollbarLength < 100) && (
<div
className={`scrollbar vertical-scrollbar${
isVerticalScrollbarAutoHide ? ' hide' : ''
className={`${styles.scrollbar} ${styles.verticalScrollbar}${
isVerticalScrollbarAutoHide ? ` ${styles.hide}` : ''
}`}
style={{
height: maskRef.current
@@ -582,9 +582,9 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
padding: `${scrollbarAsidePadding}px ${scrollbarEdgePadding}px`
}}
>
<div className={'box'} style={{ width: scrollbarWidth }}>
<div className={styles.box} style={{ width: scrollbarWidth }}>
<div
className={'block'}
className={styles.block}
style={{
height: `${verticalScrollbarLength}%`,
top: `clamp(0px, ${verticalScrollbarPosition}%, ${
@@ -609,8 +609,8 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
(!isHiddenHorizontalScrollbarWhenFull ||
horizontalScrollbarLength < 100) && (
<div
className={`scrollbar horizontal-scrollbar${
isHorizontalScrollbarAutoHide ? ' hide' : ''
className={`${styles.scrollbar} ${styles.horizontalScrollbar}${
isHorizontalScrollbarAutoHide ? ` ${styles.hide}` : ''
}`}
style={{
width: maskRef.current
@@ -625,9 +625,9 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
padding: `${scrollbarEdgePadding}px ${scrollbarAsidePadding}px`
}}
>
<div className={'box'} style={{ height: scrollbarWidth }}>
<div className={styles.box} style={{ height: scrollbarWidth }}>
<div
className={'block'}
className={styles.block}
style={{
width: `${horizontalScrollbarLength}%`,
left: `clamp(0px, ${horizontalScrollbarPosition}%, ${

View File

@@ -1,5 +1,5 @@
import _ from 'lodash'
import '@/assets/css/components/common/indicator.less'
import styles from '@/assets/css/components/common/indicator.module.less'
interface IndicatorProps {
total: number
@@ -16,15 +16,15 @@ const Indicator = ({ total, current, onSwitch }: IndicatorProps) => {
return (
<>
<ul className={'dot-list flex-vertical'}>
<ul className={`${styles.dotList} flex-vertical`}>
{_.range(0, total).map((_value, index) => {
return (
<li
key={index}
className={`item center-box${index === current ? ' active' : ''}`}
className={`${styles.item} center-box${index === current ? ` ${styles.active}` : ''}`}
onClick={handleClick(index)}
>
<div className={'dot'} />
<div className={styles.dot} />
</li>
)
})}

View File

@@ -1,6 +1,6 @@
import { PropsWithChildren, ReactNode } from 'react'
import Icon from '@ant-design/icons'
import '@/assets/css/components/common/loading-mask.less'
import styles from '@/assets/css/components/common/loading-mask.module.less'
import { COLOR_FONT_MAIN } from '@/constants/common.constants'
interface LoadingMaskProps extends PropsWithChildren {
@@ -22,7 +22,7 @@ const LoadingMask = (props: LoadingMaskProps) => {
props.children
) : (
<>
<div className={'loading-mask'}>
<div className={styles.loadingMask}>
{props.maskContent || <AntdSpin indicator={loadingIcon} />}
</div>
</>

View File

@@ -1,4 +1,5 @@
import Icon from '@ant-design/icons'
import styles from '@/assets/css/components/common/sidebar.module.less'
import { COLOR_ERROR } from '@/constants/common.constants'
import { getRedirectUrl } from '@/util/route'
import { getAvatar, getLoginStatus, getNickname, removeToken } from '@/util/auth'
@@ -55,9 +56,9 @@ const Footer = () => {
}, [loginStatus])
return (
<div className={'footer'}>
<div className={styles.footer}>
<span
className={'icon-user'}
className={styles.iconUser}
onClick={handleClickAvatar}
title={getLoginStatus() ? '个人中心' : '登录'}
>
@@ -67,21 +68,25 @@ const Footer = () => {
<Icon viewBox={'-20 0 1024 1024'} component={IconOxygenUser} />
)}
</span>
<span hidden={getLoginStatus()} className={'text'}>
<span hidden={getLoginStatus()} className={styles.text}>
<NavLink to={getRedirectUrl('/login', `${lastMatch.pathname}${location.search}`)}>
</NavLink>
</span>
<span hidden={!getLoginStatus()} className={'text'} title={nickname}>
<span hidden={!getLoginStatus()} className={styles.text} title={nickname}>
{nickname}
</span>
<div
hidden={!getLoginStatus()}
className={`submenu-exit${!getLoginStatus() ? ' hide' : ''}`}
className={`${styles.submenuExit}${!getLoginStatus() ? ` ${styles.hide}` : ''}`}
>
<div className={'content'}>
<span hidden={!getLoginStatus()} className={'icon-exit'} onClick={handleLogout}>
<div className={styles.content}>
<span
hidden={!getLoginStatus()}
className={styles.iconExit}
onClick={handleLogout}
>
<Icon
component={isExiting ? IconOxygenLoading : IconOxygenExit}
spin={isExiting}

View File

@@ -1,5 +1,6 @@
import { ReactNode, MouseEvent } from 'react'
import Icon from '@ant-design/icons'
import styles from '@/assets/css/components/common/sidebar.module.less'
import Submenu from '@/components/common/Sidebar/Submenu'
type ItemProps = {
@@ -33,30 +34,26 @@ const Item = (props: ItemProps) => {
}
return (
<li className={'item'}>
<div className={'menu-bt'} onMouseEnter={showSubmenu}>
<li className={styles.item}>
<div className={styles.menuBt} onMouseEnter={showSubmenu}>
<NavLink
end={props.end}
to={props.path}
className={({ isActive, isPending }) =>
isPending ? 'pending' : isActive ? 'active' : ''
isPending ? 'pending' : isActive ? `${styles.active}` : ''
}
>
{props.icon && (
<div className={'icon-box'}>
<div className={styles.iconBox}>
{typeof props.icon === 'string' ? (
<img
className={'icon'}
src={`data:image/svg+xml;base64,${props.icon}`}
alt={'icon'}
/>
<img src={`data:image/svg+xml;base64,${props.icon}`} alt={'icon'} />
) : (
<Icon className={'icon'} component={props.icon} />
<Icon component={props.icon} />
)}
</div>
)}
<span className={'text'}>{props.text}</span>
<div className={'extend'}>{props.extend}</div>
<span className={styles.text}>{props.text}</span>
<div className={styles.extend}>{props.extend}</div>
</NavLink>
</div>
{props.children && (

View File

@@ -1,9 +1,10 @@
import { PropsWithChildren } from 'react'
import styles from '@/assets/css/components/common/sidebar.module.less'
import HideScrollbar from '@/components/common/HideScrollbar'
const Scroll = (props: PropsWithChildren) => {
return (
<div className={'scroll'}>
<div className={styles.scroll}>
<HideScrollbar
isShowVerticalScrollbar={true}
scrollbarWidth={2}

View File

@@ -1,10 +1,11 @@
import { DetailedHTMLProps, HTMLAttributes } from 'react'
import styles from '@/assets/css/components/common/sidebar.module.less'
const Separate = ({
className,
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) => {
return <div className={`separate${className ? ` ${className}` : ''}`} {...props} />
return <div className={`${styles.separate}${className ? ` ${className}` : ''}`} {...props} />
}
export default Separate

View File

@@ -1,4 +1,5 @@
import { PropsWithChildren } from 'react'
import styles from '@/assets/css/components/common/sidebar.module.less'
interface SidebarSubmenuProps extends PropsWithChildren {
submenuTop: number
@@ -8,13 +9,13 @@ interface SidebarSubmenuProps extends PropsWithChildren {
const Submenu = (props: SidebarSubmenuProps) => {
return (
<ul
className={'submenu'}
className={styles.submenu}
style={{
top: props.submenuTop,
left: props.submenuLeft
}}
>
<div className={'content'}>{props.children}</div>
<div className={styles.content}>{props.children}</div>
</ul>
)
}

View File

@@ -1,6 +1,6 @@
import { PropsWithChildren, ReactNode } from 'react'
import Icon from '@ant-design/icons'
import '@/assets/css/components/common/sidebar.less'
import styles from '@/assets/css/components/common/sidebar.module.less'
import { getLocalStorage, setLocalStorage } from '@/util/browser'
import Item from '@/components/common/Sidebar/Item'
import ItemList from '@/components/common/Sidebar/ItemList'
@@ -28,18 +28,18 @@ const Sidebar = (props: SidebarProps) => {
return (
<>
<div
className={`sidebar${isHideSidebar ? ' hide' : ''}`}
className={`${styles.sidebar}${isHideSidebar ? ` ${styles.hide}` : ''}`}
style={{ width: props.width ?? 'clamp(180px, 20vw, 240px)' }}
>
<div className={'title'}>
<span className={'icon-box'} onClick={switchSidebar}>
<div className={styles.title}>
<span className={styles.iconBox} onClick={switchSidebar}>
<Icon component={IconOxygenExpand} />
</span>
<span className={'text'}>{props.title}</span>
<span className={styles.text}>{props.title}</span>
</div>
<Separate style={{ marginTop: 0 }} />
<div className={'content'}>{props.children}</div>
<div className={'bottom-fixed'} style={{ flex: 'none' }}>
<div className={styles.content}>{props.children}</div>
<div className={styles.bottomFixed} style={{ flex: 'none' }}>
{props.bottomFixed}
</div>
<Separate style={{ marginTop: 0, marginBottom: 0 }} />

View File

@@ -1,7 +1,7 @@
import { DetailedHTMLProps, HTMLAttributes, ReactNode } from 'react'
import Icon from '@ant-design/icons'
import VanillaTilt, { TiltOptions } from 'vanilla-tilt'
import '@/assets/css/components/common/url-card.less'
import styles from '@/assets/css/components/common/url-card.module.less'
import Card from '@/components/common/Card'
import FlexBox from '@/components/common/FlexBox'
@@ -39,16 +39,16 @@ const UrlCard = ({
return (
<Card
data-component={'component-url-card'}
className={styles.root}
style={{ overflow: 'visible', ...style }}
{...props}
ref={cardRef}
onClick={handleCardOnClick}
>
<FlexBox className={'url-card'}>
<Icon component={icon} className={'icon'} />
<div className={'text'}>{children}</div>
<div className={'description'}>{description}</div>
<FlexBox className={styles.urlCard}>
<Icon component={icon} className={styles.icon} />
<div className={styles.text}>{children}</div>
<div>{description}</div>
</FlexBox>
</Card>
)

View File

@@ -1,6 +1,6 @@
import { HandleContextInst } from '@/components/dnd/HandleContext'
import Icon from '@ant-design/icons'
import '@/assets/css/components/dnd/drag-handle.less'
import styles from '@/assets/css/components/dnd/drag-handle.module.less'
interface DragHandleProps {
padding?: string | number
@@ -11,10 +11,9 @@ const DragHandle = ({ padding }: DragHandleProps) => {
return (
<button
data-component={'component-drag-handle'}
className={styles.root}
style={{ padding }}
ref={ref}
className={'drag-handle'}
{...attributes}
{...listeners}
>

View File

@@ -1,10 +1,10 @@
import '@/assets/css/components/dnd/drop-mask.less'
import Icon from '@ant-design/icons'
import styles from '@/assets/css/components/dnd/drop-mask.module.less'
const DropMask = () => {
return (
<div data-component={'component-drop-mask'}>
<div className={'drop-mask-border'}>
<div className={styles.root}>
<div className={styles.dropMaskBorder}>
<Icon component={IconOxygenReceive} />
</div>
</div>

View File

@@ -1,6 +1,6 @@
import { PropsWithChildren, ReactNode } from 'react'
import Icon from '@ant-design/icons'
import '@/assets/css/components/system/setting-card.less'
import styles from '@/assets/css/components/system/setting-card.module.less'
import Card from '@/components/common/Card'
import FlexBox from '@/components/common/FlexBox'
import Permission from '@/components/common/Permission'
@@ -17,18 +17,22 @@ interface SettingsCardProps extends PropsWithChildren {
}
export const SettingsCard = (props: SettingsCardProps) => {
return (
<Card data-component={'component-setting-card'}>
<FlexBox className={'settings-card'}>
<FlexBox direction={'horizontal'} className={'head'}>
<Icon component={props.icon} className={'icon'} />
<div className={'title'}>{props.title}</div>
<Card className={styles.root}>
<FlexBox className={styles.settingsCard}>
<FlexBox direction={'horizontal'} className={styles.head}>
<Icon component={props.icon} className={styles.icon} />
<div className={styles.title}>{props.title}</div>
{!props.loading && (
<Permission operationCode={props.modifyOperationCode}>
{props.expand}
<AntdButton onClick={props.onReset} title={'重置'}>
<Icon component={IconOxygenBack} />
</AntdButton>
<AntdButton className={'bt-save'} onClick={props.onSave} title={'保存'}>
<AntdButton
className={styles.btSave}
onClick={props.onSave}
title={'保存'}
>
<Icon component={IconOxygenSave} />
</AntdButton>
</Permission>

View File

@@ -1,6 +1,6 @@
import { PropsWithChildren, ReactNode } from 'react'
import Icon from '@ant-design/icons'
import '@/assets/css/components/system/statistics-card.less'
import styles from '@/assets/css/components/system/statistics-card.module.less'
import Card from '@/components/common/Card'
import FlexBox from '@/components/common/FlexBox'
import LoadingMask from '@/components/common/LoadingMask'
@@ -14,11 +14,11 @@ interface StatisticsCardProps extends PropsWithChildren {
export const StatisticsCard = (props: StatisticsCardProps) => {
return (
<Card data-component={'component-statistics-card'} style={{ overflow: 'visible' }}>
<FlexBox className={'statistics-card'}>
<FlexBox direction={'horizontal'} className={'head'}>
<Icon component={props.icon} className={'icon'} />
<div className={'title'}>{props.title}</div>
<Card className={styles.root} style={{ overflow: 'visible' }}>
<FlexBox className={styles.statisticsCard}>
<FlexBox direction={'horizontal'} className={styles.head}>
<Icon component={props.icon} className={styles.icon} />
<div className={styles.title}>{props.title}</div>
{props.expand}
</FlexBox>
<LoadingMask

View File

@@ -1,6 +1,6 @@
import VanillaTilt from 'vanilla-tilt'
import Icon from '@ant-design/icons'
import '@/assets/css/components/tools/load-more-card.less'
import styles from '@/assets/css/components/tools/load-more-card.module.less'
import FlexBox from '@/components/common/FlexBox'
import Card from '@/components/common/Card'
@@ -24,16 +24,16 @@ const LoadMoreCard = ({ onClick }: LoadMoreCardProps) => {
return (
<Card
data-component={'component-load-more-card'}
className={styles.root}
style={{ overflow: 'visible' }}
ref={cardRef}
onClick={onClick}
>
<FlexBox className={'load-more-card'}>
<div className={'icon'}>
<FlexBox className={styles.loadMoreCard}>
<div className={styles.icon}>
<Icon component={IconOxygenMore} />{' '}
</div>
<div className={'text'}></div>
<div className={styles.text}></div>
</FlexBox>
</Card>
)

View File

@@ -1,6 +1,6 @@
import { DetailedHTMLProps, HTMLAttributes } from 'react'
import VanillaTilt, { TiltOptions } from 'vanilla-tilt'
import '@/assets/css/components/tools/repository-card.less'
import styles from '@/assets/css/components/tools/repository-card.module.less'
import Card from '@/components/common/Card'
import FlexBox from '@/components/common/FlexBox'
import Draggable from '@/components/dnd/Draggable'
@@ -58,31 +58,31 @@ const RepositoryCard = ({
data={{ icon, toolName, toolId, authorUsername: '!', ver, platform }}
>
<Card
data-component={'component-repository-card'}
className={styles.root}
style={{ overflow: 'visible', ...style }}
ref={cardRef}
{...props}
>
<FlexBox className={'repository-card'}>
<div className={'header'}>
<FlexBox className={styles.repositoryCard}>
<div className={styles.header}>
{children}
<DragHandle />
</div>
<div className={'icon'}>
<div className={styles.icon}>
<img src={`data:image/svg+xml;base64,${icon}`} alt={'Icon'} />
</div>
<div className={'info'}>
<div className={'tool-name'}>{toolName}</div>
<div className={'tool-id'}>{`ID: ${toolId}`}</div>
<div className={styles.info}>
<div className={styles.toolName}>{toolName}</div>
<div>{`ID: ${toolId}`}</div>
</div>
<div className={'operation'}>
<div className={styles.operation}>
{onOpen && (
<AntdButton onClick={onOpen} size={'small'} type={'primary'}>
</AntdButton>
)}
{onEdit && onPublish && (
<div className={'edit'}>
<div className={styles.edit}>
<AntdButton.Group size={'small'}>
<AntdButton onClick={onEdit}></AntdButton>
<AntdButton onClick={onPublish}></AntdButton>

View File

@@ -2,7 +2,7 @@ import { DetailedHTMLProps, HTMLAttributes, MouseEvent } from 'react'
import VanillaTilt, { TiltOptions } from 'vanilla-tilt'
import protocolCheck from 'custom-protocol-check'
import Icon from '@ant-design/icons'
import '@/assets/css/components/tools/store-card.less'
import styles from '@/assets/css/components/tools/store-card.module.less'
import { COLOR_BACKGROUND, COLOR_MAIN, COLOR_PRODUCTION } from '@/constants/common.constants'
import { checkDesktop, omitText } from '@/util/common'
import { getLoginStatus, getUserId } from '@/util/auth'
@@ -80,9 +80,9 @@ const StoreCard = ({
icon: <Icon style={{ color: COLOR_MAIN }} component={IconOxygenInfo} />,
title: 'Android 端',
content: (
<FlexBox className={'android-qrcode'}>
<FlexBox className={styles.androidQrcode}>
<AntdQRCode value={getAndroidUrl(author.username, toolId)} size={300} />
<AntdTag className={'tag'}>使</AntdTag>
<AntdTag>使</AntdTag>
</FlexBox>
),
okText: '确定',
@@ -148,9 +148,9 @@ const StoreCard = ({
icon: <Icon style={{ color: COLOR_MAIN }} component={IconOxygenInfo} />,
title: 'Android 端',
content: (
<FlexBox className={'android-qrcode'}>
<FlexBox className={styles.androidQrcode}>
<AntdQRCode value={getAndroidUrl(author.username, toolId)} size={300} />
<AntdTag className={'tag'}>使</AntdTag>
<AntdTag>使</AntdTag>
</FlexBox>
),
okText: '确定',
@@ -204,20 +204,20 @@ const StoreCard = ({
}}
>
<Card
data-component={'component-store-card'}
className={styles.root}
style={{ overflow: 'visible', ...style }}
ref={cardRef}
{...props}
onClick={handleCardOnClick}
>
<FlexBox className={'store-card'}>
<div className={'header'}>
<div className={'version'}>
<FlexBox className={styles.storeCard}>
<div className={styles.header}>
<div className={styles.version}>
<AntdTag>
{platform.slice(0, 1)}-{ver}
</AntdTag>
</div>
<div className={'operation'}>
<div className={styles.operation}>
{platform !== 'ANDROID' && supportPlatform.includes('ANDROID') && (
<AntdTooltip title={'Android 端'}>
<Icon
@@ -264,22 +264,22 @@ const StoreCard = ({
<DragHandle />
</div>
</div>
<div className={'icon'}>
<div className={styles.icon}>
<img src={`data:image/svg+xml;base64,${icon}`} alt={'Icon'} />
</div>
<div className={'info'}>
<div className={'tool-name'}>{toolName}</div>
<div className={'tool-id'}>{`ID: ${toolId}`}</div>
<div className={styles.info}>
<div className={styles.toolName}>{toolName}</div>
<div>{`ID: ${toolId}`}</div>
{toolDesc && (
<div
className={'tool-desc'}
className={styles.toolDesc}
title={toolDesc}
>{`简介:${omitText(toolDesc, 18)}`}</div>
)}
</div>
{showAuthor && (
<div className={'author'} onClick={handleOnClickAuthor}>
<div className={'avatar'}>
<div className={styles.author} onClick={handleOnClickAuthor}>
<div className={styles.avatar}>
<AntdAvatar
src={
<AntdImage
@@ -291,7 +291,7 @@ const StoreCard = ({
style={{ background: COLOR_BACKGROUND }}
/>
</div>
<div className={'author-name'}>{author.userInfo.nickname}</div>
<div className={styles.authorName}>{author.userInfo.nickname}</div>
</div>
)}
</FlexBox>