mirror of
https://gitee.com/ineo6/homebrew-install.git
synced 2025-06-25 05:49:15 +08:00
feat: 添加app模块
This commit is contained in:
parent
39ff6f1b8d
commit
5f112390b5
331
.dumi/theme/builtins/AppDetail.tsx
Normal file
331
.dumi/theme/builtins/AppDetail.tsx
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { Select, Input, Table } from 'antd';
|
||||||
|
import queryString from 'query-string';
|
||||||
|
// @ts-ignore
|
||||||
|
import SourceCode from 'dumi-theme-default/src/builtins/SourceCode';
|
||||||
|
// @ts-ignore
|
||||||
|
import Alert from 'dumi-theme-default/src/builtins/Alert';
|
||||||
|
import { ColumnsType } from 'antd/es/table';
|
||||||
|
import './CaskAndFormula/app-detail.less';
|
||||||
|
|
||||||
|
const Option = Select.Option;
|
||||||
|
const { Search } = Input;
|
||||||
|
|
||||||
|
const getQuery = () => {
|
||||||
|
return queryString.parse(window.location.search);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface DataType {
|
||||||
|
arch: string;
|
||||||
|
os: string;
|
||||||
|
version: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns: ColumnsType<DataType> = [
|
||||||
|
{
|
||||||
|
title: 'arch',
|
||||||
|
dataIndex: 'arch',
|
||||||
|
width: 200,
|
||||||
|
onCell: (_, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
return { rowSpan: 10 };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { rowSpan: 0 };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'os',
|
||||||
|
dataIndex: 'os',
|
||||||
|
width: 300,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'version',
|
||||||
|
dataIndex: 'version',
|
||||||
|
render: (text, row) => {
|
||||||
|
return (
|
||||||
|
<a href={row.url} target="_blank" rel="noopener noreferrer">
|
||||||
|
{row.version}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const AppDetail = ({}) => {
|
||||||
|
const [caskDetail, setCaskDetail] = useState({});
|
||||||
|
const [formulaDetail, setFormulaDetail] = useState({});
|
||||||
|
const [isCask, setIsCask] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const query = getQuery();
|
||||||
|
|
||||||
|
if (query.cid) {
|
||||||
|
getCaskDetail(query.cid);
|
||||||
|
setIsCask(true);
|
||||||
|
} else if (query.fid) {
|
||||||
|
getFormulaDetail(query.fid);
|
||||||
|
setIsCask(false);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const getCaskDetail = id => {
|
||||||
|
fetch(
|
||||||
|
'http://localhost:8000/homebrew/cask-detail?' +
|
||||||
|
queryString.stringify({
|
||||||
|
id,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === 0 && res.result) {
|
||||||
|
const result = res.result;
|
||||||
|
|
||||||
|
result.variations = JSON.parse(result.variations);
|
||||||
|
result.depends_on = JSON.parse(result.depends_on);
|
||||||
|
|
||||||
|
setCaskDetail(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFormulaDetail = id => {
|
||||||
|
fetch(
|
||||||
|
'http://localhost:8000/homebrew/formula-detail?' +
|
||||||
|
queryString.stringify({
|
||||||
|
id,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === 0 && res.result) {
|
||||||
|
const result = res.result;
|
||||||
|
|
||||||
|
// result.versions = JSON.parse(result.versions);
|
||||||
|
// result.versioned_formulae = JSON.parse(result.versioned_formulae);
|
||||||
|
// result.dependencies = JSON.parse(result.dependencies);
|
||||||
|
// result.build_dependencies = JSON.parse(result.build_dependencies);
|
||||||
|
|
||||||
|
console.log(result);
|
||||||
|
setFormulaDetail(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderObjectJson = obj => {
|
||||||
|
if (!obj) return;
|
||||||
|
|
||||||
|
const list: any = [];
|
||||||
|
|
||||||
|
for (const key in obj) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||||
|
const element = obj[key];
|
||||||
|
|
||||||
|
for (const condition in element) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(element, condition)) {
|
||||||
|
const version = element[condition];
|
||||||
|
|
||||||
|
list.push(
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{key}
|
||||||
|
{condition}
|
||||||
|
{version}
|
||||||
|
</p>
|
||||||
|
</div>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.length === 0) return;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h3 className="app-detail-content-title">系统要求</h3>
|
||||||
|
{list}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderVariations = variations => {
|
||||||
|
console.log(variations);
|
||||||
|
if (!variations) return;
|
||||||
|
|
||||||
|
const keys = Object.keys(variations);
|
||||||
|
|
||||||
|
if (keys.length === 0) return;
|
||||||
|
|
||||||
|
const intelDataArray: DataType[] = [];
|
||||||
|
const appleSiliconDataArray: any = [];
|
||||||
|
|
||||||
|
keys.forEach(key => {
|
||||||
|
const value = variations[key];
|
||||||
|
if (key.includes('arm64_')) {
|
||||||
|
appleSiliconDataArray.push({
|
||||||
|
arch: 'Apple Silicon',
|
||||||
|
os: key.replace('arm64_', ''),
|
||||||
|
url: value.url,
|
||||||
|
version: value.version || caskDetail.version,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
intelDataArray.push({
|
||||||
|
arch: 'Intel',
|
||||||
|
os: key,
|
||||||
|
url: value.url,
|
||||||
|
version: value.version || caskDetail.version,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h3 className="app-detail-content-title">软件版本</h3>
|
||||||
|
<div className="variations-content">
|
||||||
|
{intelDataArray.length > 0 && (
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
dataSource={intelDataArray}
|
||||||
|
showHeader={false}
|
||||||
|
pagination={false}
|
||||||
|
bordered
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{appleSiliconDataArray.length > 0 && (
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
dataSource={appleSiliconDataArray}
|
||||||
|
showHeader={false}
|
||||||
|
pagination={false}
|
||||||
|
bordered
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderCask = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="app-img">
|
||||||
|
<span>
|
||||||
|
<h1>
|
||||||
|
{caskDetail.token} {caskDetail.version}
|
||||||
|
</h1>
|
||||||
|
<h2>{caskDetail.desc}</h2>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h3 className="app-detail-content-title">安装命令</h3>
|
||||||
|
|
||||||
|
<SourceCode
|
||||||
|
code={`brew install --cask ${caskDetail.token}`}
|
||||||
|
lang="bash"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div>{renderObjectJson(caskDetail.depends_on)}</div>
|
||||||
|
|
||||||
|
{caskDetail.caveats && <Alert type="info">{caskDetail.caveats}</Alert>}
|
||||||
|
|
||||||
|
{renderVariations(caskDetail.variations)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderVersionedFormulae = versionedFormulae => {
|
||||||
|
if (!versionedFormulae) return;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h3 className="app-detail-content-title">其他版本</h3>
|
||||||
|
<Table
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
dataIndex: 'name',
|
||||||
|
render: (text, row) => {
|
||||||
|
return <div>{text}</div>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'versions',
|
||||||
|
render: (text, row) => {
|
||||||
|
return <div>{text.stable}</div>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
dataSource={versionedFormulae}
|
||||||
|
showHeader={false}
|
||||||
|
pagination={false}
|
||||||
|
bordered
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderDep = (deps, title) => {
|
||||||
|
if (!deps) return;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h3 className="app-detail-content-title">{title}</h3>
|
||||||
|
<Table
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
dataIndex: 'name',
|
||||||
|
render: (text, row) => {
|
||||||
|
return <div>{text}</div>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'versions',
|
||||||
|
render: (text) => {
|
||||||
|
return <div>{text.stable}</div>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
dataSource={deps}
|
||||||
|
showHeader={false}
|
||||||
|
pagination={false}
|
||||||
|
bordered
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderFormula = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="app-img">
|
||||||
|
<span>
|
||||||
|
<h1>
|
||||||
|
{formulaDetail.name} {formulaDetail.versions?.stable}
|
||||||
|
</h1>
|
||||||
|
<h2>{formulaDetail.desc}</h2>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h3 className="app-detail-content-title">安装命令</h3>
|
||||||
|
|
||||||
|
<SourceCode code={`brew install ${formulaDetail.name}`} lang="bash" />
|
||||||
|
|
||||||
|
{renderVersionedFormulae(formulaDetail.versioned_formulae)}
|
||||||
|
|
||||||
|
{renderDep(formulaDetail.dependencies, '依赖')}
|
||||||
|
|
||||||
|
{renderDep(formulaDetail.build_dependencies, '构建依赖')}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="__dumi-default-app-detail">
|
||||||
|
<div className="app-detail-content">
|
||||||
|
{isCask ? renderCask() : renderFormula()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppDetail;
|
205
.dumi/theme/builtins/CaskAndFormula.tsx
Normal file
205
.dumi/theme/builtins/CaskAndFormula.tsx
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { Select, Tooltip, Checkbox } from 'antd';
|
||||||
|
import { QuestionCircleOutlined } from '@ant-design/icons';
|
||||||
|
// @ts-ignore
|
||||||
|
import SourceCode from 'dumi-theme-default/src/builtins/SourceCode';
|
||||||
|
|
||||||
|
import './SourceGenerate.less';
|
||||||
|
import CaskCard from './CaskAndFormula/Cask';
|
||||||
|
import { Card, List, Input, Tabs } from 'antd';
|
||||||
|
import queryString from 'query-string';
|
||||||
|
|
||||||
|
const Option = Select.Option;
|
||||||
|
const { Search } = Input;
|
||||||
|
|
||||||
|
const CaskAndFormula = ({}) => {
|
||||||
|
const [listParams, setListParams] = useState({
|
||||||
|
page: 1,
|
||||||
|
pageSize: 12,
|
||||||
|
});
|
||||||
|
const [activeKey, setActiveKey] = useState('cask');
|
||||||
|
|
||||||
|
const [caskPageData, setCaskPageData] = useState({
|
||||||
|
data: [],
|
||||||
|
total: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [formulaPageData, setFormulaPageData] = useState({
|
||||||
|
data: [],
|
||||||
|
total: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getList();
|
||||||
|
}, [activeKey, listParams]);
|
||||||
|
|
||||||
|
const getList = () => {
|
||||||
|
if (activeKey === 'cask') {
|
||||||
|
getCaskList();
|
||||||
|
} else {
|
||||||
|
getFormula();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChange = (key: string) => {
|
||||||
|
setActiveKey(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCaskList = () => {
|
||||||
|
fetch(
|
||||||
|
'http://localhost:8000/homebrew/cask-list?' +
|
||||||
|
queryString.stringify(listParams),
|
||||||
|
)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === 0 && res.result) {
|
||||||
|
setCaskPageData(res.result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFormula = () => {
|
||||||
|
fetch(
|
||||||
|
'http://localhost:8000/homebrew/formula-list?' +
|
||||||
|
queryString.stringify(listParams),
|
||||||
|
)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === 0 && res.result) {
|
||||||
|
const result = res.result
|
||||||
|
|
||||||
|
if (result && result.data) {
|
||||||
|
result.data.forEach(item => {
|
||||||
|
if (item.versions) {
|
||||||
|
item.versions = JSON.parse(item.versions)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
setFormulaPageData(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const openCaskDetail = item => {
|
||||||
|
window.open('/app-detail?cid=' + item.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openFormulaDetail = item => {
|
||||||
|
window.open('/app-detail?fid=' + item.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSearch = value => {
|
||||||
|
setListParams({
|
||||||
|
...listParams,
|
||||||
|
page: 1,
|
||||||
|
search: value,
|
||||||
|
});
|
||||||
|
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderCask = () => {
|
||||||
|
return (
|
||||||
|
<List
|
||||||
|
grid={{ gutter: 16, column: 4 }}
|
||||||
|
dataSource={caskPageData.data}
|
||||||
|
pagination={{
|
||||||
|
onChange: page => {
|
||||||
|
console.log(page);
|
||||||
|
setListParams({
|
||||||
|
...listParams,
|
||||||
|
page,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
pageSize: listParams.pageSize,
|
||||||
|
total: caskPageData.total,
|
||||||
|
}}
|
||||||
|
renderItem={item => (
|
||||||
|
<List.Item>
|
||||||
|
<Card
|
||||||
|
title={item.token}
|
||||||
|
extra={<a onClick={openCaskDetail.bind(this, item)}>查看</a>}
|
||||||
|
>
|
||||||
|
<div>{item.desc}</div>
|
||||||
|
<div>
|
||||||
|
<div style={{ marginTop: '10px', color: '#999' }}>
|
||||||
|
{item.version}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</List.Item>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderFormula = () => {
|
||||||
|
return (
|
||||||
|
<List
|
||||||
|
grid={{ gutter: 16, column: 4 }}
|
||||||
|
dataSource={formulaPageData.data}
|
||||||
|
pagination={{
|
||||||
|
onChange: page => {
|
||||||
|
setListParams({
|
||||||
|
...listParams,
|
||||||
|
page,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
pageSize: listParams.pageSize,
|
||||||
|
total: formulaPageData.total,
|
||||||
|
}}
|
||||||
|
renderItem={item => (
|
||||||
|
<List.Item>
|
||||||
|
<Card
|
||||||
|
title={item.name}
|
||||||
|
extra={<a onClick={openFormulaDetail.bind(this, item)}>查看</a>}
|
||||||
|
>
|
||||||
|
<div>{item.desc}</div>
|
||||||
|
<div>
|
||||||
|
<div style={{ marginTop: '10px', color: '#999' }}>
|
||||||
|
{item.versions.stable}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</List.Item>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="__dumi-default-cask-and-formula">
|
||||||
|
<Tabs
|
||||||
|
defaultActiveKey={activeKey}
|
||||||
|
onChange={onChange}
|
||||||
|
size="large"
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
key: 'cask',
|
||||||
|
label: 'Cask',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'formula',
|
||||||
|
label: 'Formula',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Search
|
||||||
|
placeholder="搜索..."
|
||||||
|
allowClear
|
||||||
|
enterButton="Search"
|
||||||
|
size="large"
|
||||||
|
onSearch={onSearch}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ marginTop: '10px' }}>
|
||||||
|
{activeKey === 'cask' ? renderCask() : renderFormula()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CaskAndFormula;
|
17
.dumi/theme/builtins/CaskAndFormula/Cask.tsx
Normal file
17
.dumi/theme/builtins/CaskAndFormula/Cask.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Select, Tooltip, Checkbox } from 'antd';
|
||||||
|
|
||||||
|
const Option = Select.Option;
|
||||||
|
|
||||||
|
const CaskCard = ({ data }) => {
|
||||||
|
const [terminalType, setTerminalType] = useState<string>('zsh');
|
||||||
|
const [isJsonApi, setJsonApi] = useState<boolean>(true);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="__dumi-default-cask-card">
|
||||||
|
{data.token}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CaskCard;
|
38
.dumi/theme/builtins/CaskAndFormula/app-detail.less
Normal file
38
.dumi/theme/builtins/CaskAndFormula/app-detail.less
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
.__dumi-default-app-detail {
|
||||||
|
.app-detail-content {
|
||||||
|
background: #fff;
|
||||||
|
max-width: 780px;
|
||||||
|
margin: 20px 0 0;
|
||||||
|
padding: 20px 30px 25px;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.app-img {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
margin-right: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #999;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.variations-content {
|
||||||
|
.ant-table-wrapper + .ant-table-wrapper {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
137
.dumi/theme/style/flex.less
Normal file
137
.dumi/theme/style/flex.less
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
//from tailwindcss
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-row {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-col {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-wrap {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-nowrap {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-start {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-end {
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-baseline {
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-stretch {
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-center {
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-start {
|
||||||
|
align-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-end {
|
||||||
|
align-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-between {
|
||||||
|
align-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-around {
|
||||||
|
align-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.self-auto {
|
||||||
|
align-self: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.self-start {
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.self-end {
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.self-center {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.self-stretch {
|
||||||
|
align-self: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-start {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-end {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-center {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-between {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-around {
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-evenly {
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-1 {
|
||||||
|
flex: 1 1 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-auto {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-initial {
|
||||||
|
flex: 0 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-none {
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-grow-0 {
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-grow {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-shrink-0 {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-shrink {
|
||||||
|
flex-shrink: 1;
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
@import './markdown.less';
|
@import './markdown.less';
|
||||||
@import './variables.less';
|
@import './variables.less';
|
||||||
|
@import './flex.less';
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
8
docs/app-detail.md
Normal file
8
docs/app-detail.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
nav:
|
||||||
|
hide: true
|
||||||
|
toc: false
|
||||||
|
sidemenu: false
|
||||||
|
---
|
||||||
|
|
||||||
|
<AppDetail></AppDetail>
|
12
docs/homebrew.md
Normal file
12
docs/homebrew.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
nav:
|
||||||
|
title: 应用
|
||||||
|
toc: false
|
||||||
|
sidemenu: false
|
||||||
|
---
|
||||||
|
|
||||||
|
# Cask && Formula
|
||||||
|
|
||||||
|
如果我的工作帮助到你,您可以考虑请我喝杯咖啡。
|
||||||
|
|
||||||
|
<CaskAndFormula></CaskAndFormula>
|
@ -47,7 +47,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^4.5.0",
|
"@ant-design/icons": "^4.5.0",
|
||||||
"antd": "^4.13.1"
|
"antd": "^4.24.16",
|
||||||
|
"query-string": "^9.1.1"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"patchedDependencies": {
|
"patchedDependencies": {
|
||||||
|
Binary file not shown.
653
pnpm-lock.yaml
generated
653
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user