mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-16 14:22:28 +08:00
Compare commits
15 Commits
feature
...
typography
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a4cc2cbd3 | ||
|
|
e790b66a1e | ||
|
|
a052a5d2be | ||
|
|
3314988e39 | ||
|
|
36b916d8e0 | ||
|
|
1d4c4dd188 | ||
|
|
a2d889fb17 | ||
|
|
1c8eb5f00b | ||
|
|
a97fa60d90 | ||
|
|
5d2020f5cb | ||
|
|
a192155765 | ||
|
|
1edaa53a76 | ||
|
|
38f32d5cf7 | ||
|
|
065ff3d2ad | ||
|
|
08a0e26973 |
@@ -31,7 +31,7 @@ export const useIssueCount = (options: UseIssueCountOptions) => {
|
||||
|
||||
// Note: current query only filters by title keywords. Filtering by component name can be added later if needed.
|
||||
const searchUrl = useMemo(() => {
|
||||
const tokens = (titleKeywords || []).filter(Boolean).map<string>(encodeURIComponent);
|
||||
const tokens = (titleKeywords || []).filter(Boolean).map((k) => encodeURIComponent(String(k)));
|
||||
const orExpr = tokens.length > 0 ? tokens.join('%20OR%20') : '';
|
||||
const titlePart = orExpr ? `in:title+(${orExpr})` : 'in:title';
|
||||
const q = `repo:${repo}+is:issue+is:open+${titlePart}`;
|
||||
@@ -45,7 +45,7 @@ export const useIssueCount = (options: UseIssueCountOptions) => {
|
||||
const issueNewUrl = `https://github.com/${repo}/issues/new/choose`;
|
||||
|
||||
const issueSearchUrl = useMemo(() => {
|
||||
const keywords = (titleKeywords || []).filter(Boolean).map<string>(String);
|
||||
const keywords = (titleKeywords || []).filter(Boolean).map((k) => String(k));
|
||||
const groupExpr =
|
||||
keywords.length > 0 ? `(${keywords.map((k) => `is:issue in:title ${k}`).join(' OR ')})` : '';
|
||||
const qRaw = `is:open ${groupExpr}`.trim();
|
||||
|
||||
@@ -113,10 +113,8 @@ const RecommendItem: React.FC<RecommendItemProps> = (props) => {
|
||||
const [mousePosition, setMousePosition] = React.useState<[number, number]>([0, 0]);
|
||||
const [transMousePosition, setTransMousePosition] = React.useState<[number, number]>([0, 0]);
|
||||
|
||||
const onMouseMove: React.MouseEventHandler<HTMLAnchorElement> = (e) => {
|
||||
if (!cardRef.current) {
|
||||
return;
|
||||
}
|
||||
const onMouseMove = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
if (!cardRef.current) return;
|
||||
|
||||
const rect = cardRef.current.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
|
||||
@@ -29,13 +29,13 @@ const VersionUpgradeModal = () => {
|
||||
const [locale, lang] = useLocale(locales);
|
||||
const { pathname } = useLocation();
|
||||
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [open, updateOpen] = React.useState(false);
|
||||
|
||||
const isCN = lang === 'cn' || utils.isZhCN(pathname);
|
||||
|
||||
function handleClose() {
|
||||
localStorage.setItem(STORAGE_KEY, Date.now().toString());
|
||||
setOpen(false);
|
||||
updateOpen(false);
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
@@ -48,7 +48,7 @@ const VersionUpgradeModal = () => {
|
||||
|
||||
if (!lastTime) {
|
||||
const timer = setTimeout(() => {
|
||||
setOpen(true);
|
||||
updateOpen(true);
|
||||
}, 1000);
|
||||
|
||||
return () => {
|
||||
|
||||
@@ -101,9 +101,7 @@ let TOKEN_CACHE: { meta: TokenMeta; data: TokenData } | null | undefined;
|
||||
*/
|
||||
function readJsonIfExists<T>(abs: string): T | null {
|
||||
try {
|
||||
if (!fs.existsSync(abs)) {
|
||||
return null;
|
||||
}
|
||||
if (!fs.existsSync(abs)) return null;
|
||||
return JSON.parse(fs.readFileSync(abs, 'utf-8')) as T;
|
||||
} catch {
|
||||
return null;
|
||||
@@ -146,9 +144,7 @@ function replaceSemanticDomSection(md: string, context: ContentFilterContext) {
|
||||
// 从文档路径推断组件路径(用于生成链接)
|
||||
// 例如:components/card/index.en-US.md -> components/card/semantic.md
|
||||
const componentPathMatch = context.file.match(/components\/([^/]+)\//);
|
||||
if (!componentPathMatch) {
|
||||
return md;
|
||||
}
|
||||
if (!componentPathMatch) return md;
|
||||
|
||||
const componentName = componentPathMatch[1];
|
||||
const isZhCN = /-cn\.md$/i.test(context.file) || /\.zh-CN\.md$/i.test(context.file);
|
||||
@@ -158,14 +154,10 @@ function replaceSemanticDomSection(md: string, context: ContentFilterContext) {
|
||||
return md.replace(/<code[^>]*_semantic[^>]*>.*?<\/code>/g, (match) => {
|
||||
// 从匹配的标签中提取文件名
|
||||
const demoIndex = match.indexOf('./demo/');
|
||||
if (demoIndex === -1) {
|
||||
return match;
|
||||
}
|
||||
if (demoIndex === -1) return match;
|
||||
const start = demoIndex + './demo/'.length;
|
||||
const end = match.indexOf('"', start);
|
||||
if (end === -1) {
|
||||
return match;
|
||||
}
|
||||
if (end === -1) return match;
|
||||
const semanticFile = match.substring(start, end);
|
||||
// 生成对应的 semantic.md 文件名:_semantic.tsx -> semantic.md, _semantic_meta.tsx -> semantic_meta.md
|
||||
const semanticMdFileName = semanticFile
|
||||
@@ -188,9 +180,7 @@ function getMaxBacktickRun(text: string) {
|
||||
let m: RegExpExecArray | null = re.exec(text);
|
||||
|
||||
while (m) {
|
||||
if (m[0].length > max) {
|
||||
max = m[0].length;
|
||||
}
|
||||
if (m[0].length > max) max = m[0].length;
|
||||
m = re.exec(text);
|
||||
}
|
||||
return max;
|
||||
@@ -254,9 +244,7 @@ function antdCodeAppend(docFileAbs: string, src: string): string {
|
||||
'i',
|
||||
);
|
||||
const match = demoMd.match(re);
|
||||
if (!match) {
|
||||
return demoMd.trim();
|
||||
}
|
||||
if (!match) return demoMd.trim();
|
||||
return (match[2] ?? '').trim();
|
||||
}
|
||||
|
||||
@@ -267,7 +255,7 @@ function antdCodeAppend(docFileAbs: string, src: string): string {
|
||||
*
|
||||
* @param md - 原始 markdown 内容
|
||||
* @param docFileAbs - 文档文件的绝对路径,用于解析相对路径和检测语言
|
||||
* @param codeAppend - 代码追加函数:在替换 <code src> 标签时,用于追加额外的内容(如 demo 描述信息)
|
||||
* @param enablePickLocaleBlock - 是否启用多语言块提取,可以是布尔值或函数,默认为 true
|
||||
* @returns 替换后的 markdown 内容
|
||||
*/
|
||||
function replaceCodeSrcToMarkdown(
|
||||
@@ -317,9 +305,8 @@ function replaceCodeSrcToMarkdown(
|
||||
* @returns token 元数据和数据对象,如果文件不存在则返回 null
|
||||
*/
|
||||
function loadTokenFromRepo(api: IApi) {
|
||||
if (TOKEN_CACHE !== undefined) {
|
||||
return TOKEN_CACHE;
|
||||
}
|
||||
if (TOKEN_CACHE !== undefined) return TOKEN_CACHE;
|
||||
|
||||
const cwd = api.paths.cwd;
|
||||
const metaPath = path.join(cwd, 'components', 'version', 'token-meta.json');
|
||||
const dataPath = path.join(cwd, 'components', 'version', 'token.json');
|
||||
@@ -358,15 +345,9 @@ function escapeMdCell(v: unknown) {
|
||||
* @returns 规范化后的字符串,null/undefined 返回空字符串
|
||||
*/
|
||||
function normalizeValue(v: unknown) {
|
||||
if (v === undefined || v === null) {
|
||||
return '';
|
||||
}
|
||||
if (typeof v === 'string') {
|
||||
return v.trim();
|
||||
}
|
||||
if (typeof v === 'number' || typeof v === 'boolean') {
|
||||
return String(v);
|
||||
}
|
||||
if (v === undefined || v === null) return '';
|
||||
if (typeof v === 'string') return v.trim();
|
||||
if (typeof v === 'number' || typeof v === 'boolean') return String(v);
|
||||
try {
|
||||
return JSON.stringify(v);
|
||||
} catch {
|
||||
@@ -388,9 +369,7 @@ function normalizeValue(v: unknown) {
|
||||
*/
|
||||
function replaceComponentTokenTable(md: string, context: ContentFilterContext) {
|
||||
const tokens = loadTokenFromRepo(context.api);
|
||||
if (!tokens) {
|
||||
return md;
|
||||
}
|
||||
if (!tokens) return md;
|
||||
|
||||
const { meta: tokenMeta, data: tokenData } = tokens;
|
||||
const locale = detectDocLocale(context.file);
|
||||
@@ -419,9 +398,7 @@ function replaceComponentTokenTable(md: string, context: ContentFilterContext) {
|
||||
|
||||
return md.replace(re, (full, componentProp) => {
|
||||
const comp = String(componentProp || '').trim();
|
||||
if (!comp) {
|
||||
return full;
|
||||
}
|
||||
if (!comp) return full;
|
||||
|
||||
const comps = comp
|
||||
.split(',')
|
||||
@@ -497,9 +474,7 @@ function replaceComponentTokenTable(md: string, context: ContentFilterContext) {
|
||||
}
|
||||
|
||||
// 如果没有生成任何内容,则保留原标签
|
||||
if (!out.length) {
|
||||
return full;
|
||||
}
|
||||
if (!out.length) return full;
|
||||
// 返回生成的 markdown 表格,前后添加换行确保格式正确
|
||||
return `\n\n${out.join('\n').trim()}\n\n`;
|
||||
});
|
||||
@@ -514,12 +489,8 @@ function replaceComponentTokenTable(md: string, context: ContentFilterContext) {
|
||||
* @param api - Dumi API 实例,用于获取输出路径等配置
|
||||
*/
|
||||
function emitRawMd(api: IApi) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
return;
|
||||
}
|
||||
if (RAW_MD_EMITTED) {
|
||||
return;
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production') return;
|
||||
if (RAW_MD_EMITTED) return;
|
||||
RAW_MD_EMITTED = true;
|
||||
|
||||
const outRoot = api.paths.absOutputPath;
|
||||
@@ -528,9 +499,7 @@ function emitRawMd(api: IApi) {
|
||||
try {
|
||||
const { absPath, file } = route;
|
||||
const relPath = absPath.replace(/^\//, '');
|
||||
if (!relPath || !fs.existsSync(file)) {
|
||||
return;
|
||||
}
|
||||
if (!relPath || !fs.existsSync(file)) return;
|
||||
|
||||
// 应用路由过滤器
|
||||
if (PLUGIN_OPTIONS.routeFilter && !PLUGIN_OPTIONS.routeFilter(route)) {
|
||||
@@ -587,6 +556,7 @@ function emitRawMd(api: IApi) {
|
||||
* 2. 在 HTML 文件导出阶段输出处理后的 raw markdown 文件
|
||||
*
|
||||
* @param api - Dumi API 实例
|
||||
* @param options - 插件配置选项
|
||||
*/
|
||||
export default function rawMdPlugin(api: IApi) {
|
||||
// 注册配置键,允许用户在配置中使用 rawMd 键
|
||||
|
||||
@@ -19,8 +19,8 @@ function extractSemantics(objContent: string): Record<string, string> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 _semantic*.tsx 文件内容中提取语义信息
|
||||
* @param content - _semantic*.tsx 文件的文件内容字符串
|
||||
* 从 _semantic*.tsx 文件中提取语义信息
|
||||
* @param semanticFile - _semantic*.tsx 文件的绝对路径
|
||||
* @returns 包含中文和英文语义描述的对象,失败返回 null
|
||||
*/
|
||||
function extractLocaleInfoFromContent(content: string): {
|
||||
@@ -29,20 +29,14 @@ function extractLocaleInfoFromContent(content: string): {
|
||||
} | null {
|
||||
// 匹配 locales 对象定义
|
||||
const localesMatch = content.match(/const locales = \{([\s\S]*?)\};/);
|
||||
if (!localesMatch) {
|
||||
return null;
|
||||
}
|
||||
if (!localesMatch) return null;
|
||||
|
||||
// 提取中文和英文的语义描述
|
||||
const cnMatch = content.match(/cn:\s*\{([\s\S]*?)\},?\s*en:/);
|
||||
if (!cnMatch) {
|
||||
return null;
|
||||
}
|
||||
if (!cnMatch) return null;
|
||||
|
||||
const enMatch = content.match(/en:\s*\{([\s\S]*?)\}\s*[,;]/);
|
||||
if (!enMatch) {
|
||||
return null;
|
||||
}
|
||||
if (!enMatch) return null;
|
||||
|
||||
const cnContent = cnMatch[1];
|
||||
const enContent = enMatch[1];
|
||||
@@ -50,9 +44,7 @@ function extractLocaleInfoFromContent(content: string): {
|
||||
const cnSemantics = extractSemantics(cnContent);
|
||||
const enSemantics = extractSemantics(enContent);
|
||||
|
||||
if (Object.keys(cnSemantics).length === 0) {
|
||||
return null;
|
||||
}
|
||||
if (Object.keys(cnSemantics).length === 0) return null;
|
||||
|
||||
return { cn: cnSemantics, en: enSemantics };
|
||||
}
|
||||
@@ -68,9 +60,7 @@ function resolveTemplateFilePath(semanticFile: string, importPath: string): stri
|
||||
path.join(basePath, 'index.ts'),
|
||||
];
|
||||
for (const candidate of candidates) {
|
||||
if (fs.existsSync(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
if (fs.existsSync(candidate)) return candidate;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -82,9 +72,7 @@ function parseTemplateUsage(content: string): Array<{ componentName: string; imp
|
||||
for (const match of content.matchAll(importRegex)) {
|
||||
const importClause = match[1].trim();
|
||||
const importPath = match[2].trim();
|
||||
if (!importPath.startsWith('.')) {
|
||||
continue;
|
||||
}
|
||||
if (!importPath.startsWith('.')) continue;
|
||||
|
||||
const componentNames: string[] = [];
|
||||
if (importClause.startsWith('{')) {
|
||||
@@ -131,9 +119,7 @@ function parseTemplateUsage(content: string): Array<{ componentName: string; imp
|
||||
// 解析 ignoreSemantics 属性值
|
||||
function parseIgnoreSemantics(propsString: string): string[] {
|
||||
const ignoreMatch = propsString.match(/ignoreSemantics\s*=\s*\{([\s\S]*?)\}/);
|
||||
if (!ignoreMatch) {
|
||||
return [];
|
||||
}
|
||||
if (!ignoreMatch) return [];
|
||||
const ignoreContent = ignoreMatch[1];
|
||||
return Array.from(ignoreContent.matchAll(/['"]([^'"]+)['"]/g)).map((match) => match[1]);
|
||||
}
|
||||
@@ -141,12 +127,8 @@ function parseIgnoreSemantics(propsString: string): string[] {
|
||||
// 解析 singleOnly 属性值
|
||||
function parseSingleOnly(propsString: string): boolean {
|
||||
const singleOnlyMatch = propsString.match(/singleOnly(\s*=\s*\{?([^}\s]+)\}?)?/);
|
||||
if (!singleOnlyMatch) {
|
||||
return false;
|
||||
}
|
||||
if (!singleOnlyMatch[1]) {
|
||||
return true;
|
||||
}
|
||||
if (!singleOnlyMatch) return false;
|
||||
if (!singleOnlyMatch[1]) return true;
|
||||
const value = singleOnlyMatch[2];
|
||||
return value !== 'false';
|
||||
}
|
||||
@@ -154,9 +136,7 @@ function parseSingleOnly(propsString: string): boolean {
|
||||
// 抽取模板组件 JSX 的属性字符串
|
||||
function extractTemplateProps(content: string, componentName: string): string {
|
||||
const start = content.indexOf(`<${componentName}`);
|
||||
if (start === -1) {
|
||||
return '';
|
||||
}
|
||||
if (start === -1) return '';
|
||||
let index = start + componentName.length + 1;
|
||||
const propsStart = index;
|
||||
let braceDepth = 0;
|
||||
@@ -184,9 +164,7 @@ function extractTemplateProps(content: string, componentName: string): string {
|
||||
}
|
||||
|
||||
if (ch === '}') {
|
||||
if (braceDepth > 0) {
|
||||
braceDepth -= 1;
|
||||
}
|
||||
if (braceDepth > 0) braceDepth -= 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -220,21 +198,15 @@ function extractSemanticInfoFromTemplate(
|
||||
content: string,
|
||||
): { cn: Record<string, string>; en: Record<string, string> } | null {
|
||||
const templates = parseTemplateUsage(content);
|
||||
if (templates.length === 0) {
|
||||
return null;
|
||||
}
|
||||
if (templates.length === 0) return null;
|
||||
|
||||
for (const template of templates) {
|
||||
const templatePath = resolveTemplateFilePath(semanticFile, template.importPath);
|
||||
if (!templatePath) {
|
||||
continue;
|
||||
}
|
||||
if (!templatePath) continue;
|
||||
|
||||
const templateContent = fs.readFileSync(templatePath, 'utf-8');
|
||||
const templateLocales = extractLocaleInfoFromContent(templateContent);
|
||||
if (!templateLocales) {
|
||||
continue;
|
||||
}
|
||||
if (!templateLocales) continue;
|
||||
|
||||
const propsString = extractTemplateProps(content, template.componentName);
|
||||
const ignoreSemantics = parseIgnoreSemantics(propsString);
|
||||
@@ -263,15 +235,11 @@ function extractSemanticInfo(semanticFile: string): {
|
||||
en: Record<string, string>;
|
||||
} | null {
|
||||
try {
|
||||
if (!fs.existsSync(semanticFile)) {
|
||||
return null;
|
||||
}
|
||||
if (!fs.existsSync(semanticFile)) return null;
|
||||
|
||||
const content = fs.readFileSync(semanticFile, 'utf-8');
|
||||
const localeInfo = extractLocaleInfoFromContent(content);
|
||||
if (localeInfo) {
|
||||
return localeInfo;
|
||||
}
|
||||
if (localeInfo) return localeInfo;
|
||||
|
||||
return extractSemanticInfoFromTemplate(semanticFile, content);
|
||||
} catch (error) {
|
||||
@@ -356,12 +324,9 @@ function getComponentHTMLSnapshot(semanticFile: string, cwd: string): string | n
|
||||
try {
|
||||
const relativePath = path.relative(cwd, semanticFile);
|
||||
const pathMatch = relativePath.match(/^components\/([^/]+)\/demo\/([^/]+)\.tsx$/);
|
||||
if (!pathMatch) {
|
||||
return null;
|
||||
}
|
||||
if (!pathMatch) return null;
|
||||
|
||||
const [, componentName, fileName] = pathMatch;
|
||||
|
||||
const snapshotPath = path.join(
|
||||
cwd,
|
||||
'components',
|
||||
@@ -371,9 +336,7 @@ function getComponentHTMLSnapshot(semanticFile: string, cwd: string): string | n
|
||||
'demo-semantic.test.tsx.snap',
|
||||
);
|
||||
|
||||
if (!fs.existsSync(snapshotPath)) {
|
||||
return null;
|
||||
}
|
||||
if (!fs.existsSync(snapshotPath)) return null;
|
||||
|
||||
const snapshotContent = fs.readFileSync(snapshotPath, 'utf-8');
|
||||
// 匹配快照 key:exports[`renders components/button/demo/_semantic.tsx correctly 1`] = `...`;
|
||||
@@ -382,9 +345,7 @@ function getComponentHTMLSnapshot(semanticFile: string, cwd: string): string | n
|
||||
`exports\\[\\\`[^\\\`]*${snapshotKeyPattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[^\\\`]*\\\`\\]\\s*=\\s*\\\`([\\s\\S]*?)\\\`;`,
|
||||
);
|
||||
const snapshotMatch = snapshotContent.match(regex);
|
||||
if (!snapshotMatch) {
|
||||
return null;
|
||||
}
|
||||
if (!snapshotMatch) return null;
|
||||
|
||||
let html = snapshotMatch[1].trim();
|
||||
|
||||
@@ -454,12 +415,8 @@ function getComponentHTMLSnapshot(semanticFile: string, cwd: string): string | n
|
||||
* @param api - Dumi API 实例
|
||||
*/
|
||||
function emitSemanticMd(api: IApi) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
return;
|
||||
}
|
||||
if (SEMANTIC_MD_EMITTED) {
|
||||
return;
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production') return;
|
||||
if (SEMANTIC_MD_EMITTED) return;
|
||||
SEMANTIC_MD_EMITTED = true;
|
||||
|
||||
const outRoot = api.paths.absOutputPath;
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* Search for the first non-undefined value in the arguments and return it.
|
||||
*
|
||||
* ```js
|
||||
* const mergedIcon = fallbackProp(propIcon, contextIcon, defaultIcon);
|
||||
* ```
|
||||
*
|
||||
* Note: it is different from `??` operator which skips null
|
||||
*/
|
||||
export default function fallbackProp<T>(...args: T[]): T | undefined {
|
||||
return args.find((arg) => arg !== undefined);
|
||||
}
|
||||
@@ -34,7 +34,7 @@ const WaveEffect: React.FC<WaveEffectProps> = (props) => {
|
||||
const [varName] = genCssVar(rootPrefixCls, 'wave');
|
||||
|
||||
// ===================== Effect =====================
|
||||
const [waveColor, setWaveColor] = React.useState<string | null>(null);
|
||||
const [color, setWaveColor] = React.useState<string | null>(null);
|
||||
const [borderRadius, setBorderRadius] = React.useState<number[]>([]);
|
||||
const [left, setLeft] = React.useState(0);
|
||||
const [top, setTop] = React.useState(0);
|
||||
@@ -50,8 +50,8 @@ const WaveEffect: React.FC<WaveEffectProps> = (props) => {
|
||||
borderRadius: borderRadius.map((radius) => `${radius}px`).join(' '),
|
||||
};
|
||||
|
||||
if (waveColor) {
|
||||
waveStyle[varName('color')] = waveColor;
|
||||
if (color) {
|
||||
waveStyle[varName('color')] = color;
|
||||
}
|
||||
|
||||
function syncPos() {
|
||||
|
||||
@@ -225,7 +225,7 @@ const InternalCompoundedButton = React.forwardRef<
|
||||
|
||||
const loadingOrDelay = useMemo<LoadingConfigType>(() => getLoadingConfig(loading), [loading]);
|
||||
|
||||
const [innerLoading, setInnerLoading] = useState<boolean>(loadingOrDelay.loading);
|
||||
const [innerLoading, setLoading] = useState<boolean>(loadingOrDelay.loading);
|
||||
|
||||
const [hasTwoCNChar, setHasTwoCNChar] = useState<boolean>(false);
|
||||
|
||||
@@ -255,10 +255,10 @@ const InternalCompoundedButton = React.forwardRef<
|
||||
if (loadingOrDelay.delay > 0) {
|
||||
delayTimer = setTimeout(() => {
|
||||
delayTimer = null;
|
||||
setInnerLoading(true);
|
||||
setLoading(true);
|
||||
}, loadingOrDelay.delay);
|
||||
} else {
|
||||
setInnerLoading(loadingOrDelay.loading);
|
||||
setLoading(loadingOrDelay.loading);
|
||||
}
|
||||
|
||||
function cleanupTimer() {
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
|
||||
import { unit } from '@ant-design/cssinjs';
|
||||
|
||||
import { genFocusStyle, resetIcon } from '../../style';
|
||||
import { genNoMotionStyle } from '../../style/motion';
|
||||
import type { GenerateStyle } from '../../theme/internal';
|
||||
import { genStyleHooks, mergeToken } from '../../theme/internal';
|
||||
import genGroupStyle from './group';
|
||||
@@ -41,7 +40,7 @@ const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSS
|
||||
transition: `all ${token.motionDurationMid} ${token.motionEaseInOut}`,
|
||||
userSelect: 'none',
|
||||
touchAction: 'manipulation',
|
||||
...genNoMotionStyle(),
|
||||
|
||||
'&:disabled > *': {
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
@@ -81,7 +80,7 @@ const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSS
|
||||
|
||||
[`${componentCls}-loading-icon`]: {
|
||||
transition: ['width', 'opacity', 'margin']
|
||||
.map((prop) => `${prop} ${motionDurationSlow} ${motionEaseInOut}`)
|
||||
.map((transition) => `${transition} ${motionDurationSlow} ${motionEaseInOut}`)
|
||||
.join(','),
|
||||
},
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ const App: React.FC = () => {
|
||||
const { styles } = useStyle({ test: true });
|
||||
|
||||
const [selectDate, setSelectDate] = React.useState<Dayjs>(() => dayjs());
|
||||
const [panelDate, setPanelDate] = React.useState<Dayjs>(() => dayjs());
|
||||
const [panelDateDate, setPanelDate] = React.useState<Dayjs>(() => dayjs());
|
||||
|
||||
const onPanelChange = (value: Dayjs, mode: CalendarProps<Dayjs>['mode']) => {
|
||||
console.log(value.format('YYYY-MM-DD'), mode);
|
||||
@@ -131,7 +131,7 @@ const App: React.FC = () => {
|
||||
<span
|
||||
className={clsx({
|
||||
[styles.weekend]: isWeekend,
|
||||
gray: !panelDate.isSame(date, 'month'),
|
||||
gray: !panelDateDate.isSame(date, 'month'),
|
||||
})}
|
||||
>
|
||||
{date.get('date')}
|
||||
|
||||
@@ -907,115 +907,4 @@ describe('Cascader', () => {
|
||||
expect(screen.getAllByText('bamboo').length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('clearIcon', () => {
|
||||
it('should support custom clearIcon', () => {
|
||||
render(
|
||||
<Cascader
|
||||
open
|
||||
allowClear={{ clearIcon: <div>bamboo</div> }}
|
||||
options={options}
|
||||
defaultValue={['zhejiang', 'hangzhou']}
|
||||
/>,
|
||||
);
|
||||
expect(screen.getAllByText('bamboo').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should support ConfigProvider clearIcon', () => {
|
||||
render(
|
||||
<ConfigProvider cascader={{ clearIcon: <div>foobar</div> }}>
|
||||
<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} allowClear />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(screen.getAllByText('foobar').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should prefer prop clearIcon over ConfigProvider clearIcon', () => {
|
||||
render(
|
||||
<ConfigProvider cascader={{ clearIcon: <div>foobar</div> }}>
|
||||
<Cascader
|
||||
allowClear={{ clearIcon: <div>bamboo</div> }}
|
||||
options={options}
|
||||
defaultValue={['zhejiang', 'hangzhou']}
|
||||
/>
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(screen.getAllByText('bamboo').length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeIcon', () => {
|
||||
it('should support custom removeIcon', () => {
|
||||
render(
|
||||
<Cascader
|
||||
multiple
|
||||
removeIcon={<div>bamboo</div>}
|
||||
options={options}
|
||||
defaultValue={[
|
||||
['zhejiang', 'hangzhou'],
|
||||
['jiangsu', 'nanjing'],
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
expect(screen.getAllByText('bamboo').length).toBe(2);
|
||||
});
|
||||
|
||||
it('should support ConfigProvider removeIcon', () => {
|
||||
render(
|
||||
<ConfigProvider cascader={{ removeIcon: <div>foobar</div> }}>
|
||||
<Cascader
|
||||
multiple
|
||||
options={options}
|
||||
defaultValue={[
|
||||
['zhejiang', 'hangzhou'],
|
||||
['jiangsu', 'nanjing'],
|
||||
]}
|
||||
/>
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(screen.getAllByText('foobar').length).toBe(2);
|
||||
});
|
||||
|
||||
it('should prefer prop removeIcon over ConfigProvider removeIcon', () => {
|
||||
render(
|
||||
<ConfigProvider cascader={{ removeIcon: <div>foobar</div> }}>
|
||||
<Cascader
|
||||
multiple
|
||||
options={options}
|
||||
defaultValue={[
|
||||
['zhejiang', 'hangzhou'],
|
||||
['jiangsu', 'nanjing'],
|
||||
]}
|
||||
removeIcon={<div>bamboo</div>}
|
||||
/>
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(screen.getAllByText('bamboo').length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('searchIcon', () => {
|
||||
it('should support custom searchIcon', () => {
|
||||
render(<Cascader open showSearch={{ searchIcon: <div>bamboo</div> }} options={options} />);
|
||||
expect(screen.getAllByText('bamboo').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should support ConfigProvider searchIcon', () => {
|
||||
render(
|
||||
<ConfigProvider cascader={{ searchIcon: <div>foobar</div> }}>
|
||||
<Cascader open options={options} showSearch />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(screen.getAllByText('foobar').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should prefer prop searchIcon over ConfigProvider searchIcon', () => {
|
||||
render(
|
||||
<ConfigProvider cascader={{ searchIcon: <div>foobar</div> }}>
|
||||
<Cascader open showSearch={{ searchIcon: <div>bamboo</div> }} options={options} />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(screen.getAllByText('bamboo').length).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -44,12 +44,12 @@ const options: Option[] = [
|
||||
];
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [placement, setPlacement] = useState<'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight'>(
|
||||
const [placement, SetPlacement] = useState<'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight'>(
|
||||
'topLeft',
|
||||
);
|
||||
|
||||
const placementChange = (e: RadioChangeEvent) => {
|
||||
setPlacement(e.target.value);
|
||||
SetPlacement(e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -111,7 +111,6 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
| sort | Used to sort filtered options | function(a, b, inputValue) | - | |
|
||||
| searchValue | Set search value, Need work with `showSearch` | string | - | 4.17.0 |
|
||||
| onSearch | The callback function triggered when input changed | (search: string) => void | - | 4.17.0 |
|
||||
| searchIcon | Customize the search icon | ReactNode | - | 6.3.0 |
|
||||
|
||||
### Option
|
||||
|
||||
|
||||
@@ -166,9 +166,6 @@ export interface CascaderProps<
|
||||
bordered?: boolean;
|
||||
placement?: SelectCommonPlacement;
|
||||
suffixIcon?: React.ReactNode;
|
||||
showSearch?:
|
||||
| boolean
|
||||
| (SearchConfig<OptionType, keyof OptionType> & { searchIcon?: React.ReactNode });
|
||||
options?: OptionType[];
|
||||
status?: InputStatus;
|
||||
|
||||
@@ -247,12 +244,11 @@ const Cascader = React.forwardRef<CascaderRef, CascaderProps<any>>((props, ref)
|
||||
styles,
|
||||
classNames,
|
||||
loadingIcon,
|
||||
clearIcon,
|
||||
removeIcon,
|
||||
suffixIcon,
|
||||
...restProps
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const restProps = omit(rest, ['suffixIcon']);
|
||||
|
||||
const {
|
||||
getPrefixCls,
|
||||
getPopupContainer: getContextPopupContainer,
|
||||
@@ -262,10 +258,6 @@ const Cascader = React.forwardRef<CascaderRef, CascaderProps<any>>((props, ref)
|
||||
styles: contextStyles,
|
||||
expandIcon: contextExpandIcon,
|
||||
loadingIcon: contextLoadingIcon,
|
||||
clearIcon: contextClearIcon,
|
||||
removeIcon: contextRemoveIcon,
|
||||
suffixIcon: contextSuffixIcon,
|
||||
searchIcon: contextSearchIcon,
|
||||
} = useComponentConfig('cascader');
|
||||
|
||||
const { popupOverflow } = React.useContext(ConfigContext);
|
||||
@@ -375,21 +367,9 @@ const Cascader = React.forwardRef<CascaderRef, CascaderProps<any>>((props, ref)
|
||||
|
||||
// ===================== Icons =====================
|
||||
const showSuffixIcon = useShowArrow(props.suffixIcon, showArrow);
|
||||
const {
|
||||
suffixIcon: mergedSuffixIcon,
|
||||
removeIcon: mergedRemoveIcon,
|
||||
clearIcon: mergedClearIcon,
|
||||
} = useSelectIcons({
|
||||
const { suffixIcon, removeIcon, clearIcon } = useSelectIcons({
|
||||
...props,
|
||||
clearIcon,
|
||||
contextClearIcon,
|
||||
removeIcon,
|
||||
contextRemoveIcon,
|
||||
loadingIcon: mergedLoadingIcon,
|
||||
suffixIcon,
|
||||
contextSuffixIcon,
|
||||
searchIcon: typeof showSearch === 'object' && showSearch ? showSearch.searchIcon : undefined,
|
||||
contextSearchIcon,
|
||||
hasFeedback,
|
||||
feedbackIcon,
|
||||
showSuffixIcon,
|
||||
@@ -406,7 +386,7 @@ const Cascader = React.forwardRef<CascaderRef, CascaderProps<any>>((props, ref)
|
||||
return isRtl ? 'bottomRight' : 'bottomLeft';
|
||||
}, [placement, isRtl]);
|
||||
|
||||
const mergedAllowClear = allowClear === true ? { clearIcon: mergedClearIcon } : allowClear;
|
||||
const mergedAllowClear = allowClear === true ? { clearIcon } : allowClear;
|
||||
|
||||
// =========== Merged Props for Semantic ==========
|
||||
const mergedProps: CascaderProps<any> = {
|
||||
@@ -488,8 +468,8 @@ const Cascader = React.forwardRef<CascaderRef, CascaderProps<any>>((props, ref)
|
||||
allowClear={mergedAllowClear}
|
||||
showSearch={mergedShowSearch}
|
||||
expandIcon={mergedExpandIcon}
|
||||
suffixIcon={mergedSuffixIcon}
|
||||
removeIcon={mergedRemoveIcon}
|
||||
suffixIcon={suffixIcon}
|
||||
removeIcon={removeIcon}
|
||||
loadingIcon={mergedLoadingIcon}
|
||||
checkable={checkable}
|
||||
popupClassName={mergedPopupClassName}
|
||||
|
||||
@@ -114,7 +114,6 @@ demo:
|
||||
| sort | 用于排序 filter 后的选项 | function(a, b, inputValue) | - | |
|
||||
| searchValue | 设置搜索的值,需要与 `showSearch` 配合使用 | string | - | 4.17.0 |
|
||||
| onSearch | 监听搜索,返回输入的值 | (search: string) => void | - | 4.17.0 |
|
||||
| searchIcon | 自定义的搜索图标 | ReactNode | - | 6.3.0 |
|
||||
|
||||
### Option
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { unit } from '@ant-design/cssinjs';
|
||||
|
||||
import { genFocusOutline, resetComponent } from '../../style';
|
||||
import { genNoMotionStyle } from '../../style/motion';
|
||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import { genStyleHooks, mergeToken } from '../../theme/internal';
|
||||
|
||||
@@ -100,7 +99,6 @@ export const genCheckboxStyle: GenerateStyle<CheckboxToken> = (token) => {
|
||||
borderRadius: token.borderRadiusSM,
|
||||
borderCollapse: 'separate',
|
||||
transition: `all ${token.motionDurationSlow}`,
|
||||
...genNoMotionStyle(),
|
||||
|
||||
// Checkmark
|
||||
'&:after': {
|
||||
@@ -118,7 +116,6 @@ export const genCheckboxStyle: GenerateStyle<CheckboxToken> = (token) => {
|
||||
opacity: 0,
|
||||
content: '""',
|
||||
transition: `all ${token.motionDurationFast} ${token.motionEaseInBack}, opacity ${token.motionDurationFast}`,
|
||||
...genNoMotionStyle(),
|
||||
},
|
||||
|
||||
// Wrapper > Checkbox > input
|
||||
@@ -176,7 +173,6 @@ export const genCheckboxStyle: GenerateStyle<CheckboxToken> = (token) => {
|
||||
opacity: 1,
|
||||
transform: 'rotate(45deg) scale(1) translate(-50%,-50%)',
|
||||
transition: `all ${token.motionDurationMid} ${token.motionEaseOutBack} ${token.motionDurationFast}`,
|
||||
...genNoMotionStyle(),
|
||||
},
|
||||
|
||||
// Hover on checked checkbox directly
|
||||
|
||||
@@ -229,34 +229,6 @@ describe('ConfigProvider.Form', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('form labelAlign', () => {
|
||||
it('set labelAlign left', () => {
|
||||
const { container } = render(
|
||||
<ConfigProvider form={{ labelAlign: 'left' }}>
|
||||
<Form>
|
||||
<Form.Item label="姓名">
|
||||
<input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(container.querySelector('.ant-form-item-label-left')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('form labelAlign should override ConfigProvider labelAlign', () => {
|
||||
const { container } = render(
|
||||
<ConfigProvider form={{ labelAlign: 'left' }}>
|
||||
<Form labelAlign="right">
|
||||
<Form.Item label="姓名">
|
||||
<input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(container.querySelector('.ant-form-item-label-left')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('form disabled', () => {
|
||||
it('set Input enabled', () => {
|
||||
const { container } = render(
|
||||
|
||||
@@ -65,6 +65,7 @@ import type { TourProps } from '../tour/interface';
|
||||
import type { TransferProps } from '../transfer';
|
||||
import type { TreeProps } from '../tree';
|
||||
import type { TreeSelectProps } from '../tree-select';
|
||||
import type { TypographyClassNamesType, TypographyStylesType } from '../typography/Base';
|
||||
import type { UploadProps } from '../upload';
|
||||
import type { RenderEmptyHandler } from './defaultRenderEmpty';
|
||||
|
||||
@@ -242,6 +243,11 @@ export type AlertConfig = ComponentStyleConfig &
|
||||
|
||||
export type BadgeConfig = ComponentStyleConfig & Pick<BadgeProps, 'classNames' | 'styles'>;
|
||||
|
||||
export type TypographyConfig = ComponentStyleConfig & {
|
||||
classNames?: TypographyClassNamesType;
|
||||
styles?: TypographyStylesType;
|
||||
};
|
||||
|
||||
export type BreadcrumbConfig = ComponentStyleConfig &
|
||||
Pick<BreadcrumbProps, 'classNames' | 'styles' | 'separator' | 'dropdownIcon'>;
|
||||
|
||||
@@ -302,7 +308,6 @@ export type FormConfig = ComponentStyleConfig &
|
||||
| 'classNames'
|
||||
| 'styles'
|
||||
| 'tooltip'
|
||||
| 'labelAlign'
|
||||
>;
|
||||
|
||||
export type FloatButtonConfig = ComponentStyleConfig &
|
||||
@@ -373,10 +378,7 @@ export type InputNumberConfig = ComponentStyleConfig &
|
||||
Pick<InputNumberProps, 'variant' | 'classNames' | 'styles'>;
|
||||
|
||||
export type CascaderConfig = ComponentStyleConfig &
|
||||
Pick<
|
||||
CascaderProps,
|
||||
'variant' | 'styles' | 'classNames' | 'expandIcon' | 'loadingIcon' | 'removeIcon' | 'suffixIcon'
|
||||
> & { clearIcon?: React.ReactNode; searchIcon?: React.ReactNode };
|
||||
Pick<CascaderProps, 'variant' | 'styles' | 'classNames' | 'expandIcon' | 'loadingIcon'>;
|
||||
|
||||
export type TreeSelectConfig = ComponentStyleConfig &
|
||||
Pick<TreeSelectProps, 'variant' | 'classNames' | 'styles' | 'switcherIcon'>;
|
||||
@@ -451,7 +453,7 @@ export interface ConfigComponentProps {
|
||||
collapse?: CollapseConfig;
|
||||
floatButton?: FloatButtonConfig;
|
||||
floatButtonGroup?: FloatButtonGroupConfig;
|
||||
typography?: ComponentStyleConfig;
|
||||
typography?: TypographyConfig;
|
||||
skeleton?: SkeletonConfig;
|
||||
spin?: SpinConfig;
|
||||
segmented?: SegmentedConfig;
|
||||
|
||||
@@ -225,11 +225,11 @@ const Page: React.FC = () => {
|
||||
};
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [locale, setLocale] = useState<Locale>(enUS);
|
||||
const [locale, setLocal] = useState<Locale>(enUS);
|
||||
|
||||
const changeLocale = (e: RadioChangeEvent) => {
|
||||
const localeValue = e.target.value;
|
||||
setLocale(localeValue);
|
||||
setLocal(localeValue);
|
||||
if (!localeValue) {
|
||||
dayjs.locale('en');
|
||||
} else {
|
||||
|
||||
@@ -119,7 +119,7 @@ const {
|
||||
| cardMeta | Set Card.Meta common props | { className?: string, style?: React.CSSProperties, classNames?: [CardMetaProps\["classNames"\]](/components/card#semantic-dom), styles?: [CardMetaProps\["styles"\]](/components/card#semantic-dom) } | - | 6.0.0 |
|
||||
| calendar | Set Calendar common props | { className?: string, style?: React.CSSProperties, classNames?: [CalendarConfig\["classNames"\]](/components/calendar#semantic-dom), styles?: [CalendarConfig\["styles"\]](/components/calendar#semantic-dom) } | - | 5.7.0, `classNames` and `styles`: 6.0.0 |
|
||||
| carousel | Set Carousel common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
|
||||
| cascader | Set Cascader common props | { className?: string, style?: React.CSSProperties, classNames?: [CascaderConfig\["classNames"\]](/components/cascader#semantic-dom), styles?: [CascaderConfig\["styles"\]](/components/cascader#semantic-dom), expandIcon?: React.ReactNode, loadingIcon?: React.ReactNode, searchIcon?: React.ReactNode, clearIcon?: React.ReactNode, removeIcon?: React.ReactNode, suffixIcon?: React.ReactNode } | - | 5.7.0, `classNames` and `styles`: 6.0.0, `expandIcon`, `loadingIcon`, `searchIcon`, `clearIcon`, `removeIcon`, `suffixIcon`: 6.4.0 |
|
||||
| cascader | Set Cascader common props | { className?: string, style?: React.CSSProperties, classNames?: [CascaderConfig\["classNames"\]](/components/cascader#semantic-dom), styles?: [CascaderConfig\["styles"\]](/components/cascader#semantic-dom), expandIcon?: React.ReactNode, loadingIcon?: React.ReactNode } | - | 5.7.0, `classNames` and `styles`: 6.0.0, `expandIcon` and `loadingIcon`: 6.3.0 |
|
||||
| checkbox | Set Checkbox common props | { className?: string, style?: React.CSSProperties, classNames?: [CheckboxConfig\["classNames"\]](/components/checkbox#semantic-dom), styles?: [CheckboxConfig\["styles"\]](/components/checkbox#semantic-dom) } | - | 5.7.0, `classNames` and `styles`: 6.0.0 |
|
||||
| collapse | Set Collapse common props | { className?: string, style?: React.CSSProperties, expandIcon?: (props) => ReactNode, classNames?: [CollapseProps\["classNames"\]](/components/collapse#semantic-dom), styles?: [CollapseProps\["styles"\]](/components/collapse#semantic-dom) } | - | 5.7.0, `expandIcon`: 5.15.0, `classNames` and `styles`: 6.0.0 |
|
||||
| colorPicker | Set ColorPicker common props | { className?: string, style?: React.CSSProperties, classNames?: [ColorPickerConfig\["classNames"\]](/components/color-picker#semantic-dom), styles?: [ColorPickerConfig\["styles"\]](/components/color-picker#semantic-dom) } | - | 5.7.0 |
|
||||
@@ -133,7 +133,7 @@ const {
|
||||
| flex | Set Flex common props | { className?: string, style?: React.CSSProperties, vertical?: boolean } | - | 5.10.0 |
|
||||
| floatButton | Set FloatButton common props | { className?: string, style?: React.CSSProperties, classNames?: [FloatButtonProps\["classNames"\]](/components/float-button#semantic-dom), styles?: [FloatButtonProps\["styles"\]](/components/float-button#semantic-dom), backTopIcon?: React.ReactNode } | - | |
|
||||
| floatButtonGroup | Set FloatButton.Group common props | { closeIcon?: React.ReactNode, className?: string, style?: React.CSSProperties, classNames?: [FloatButtonProps\["classNames"\]](/components/float-button#semantic-dom), styles?: [FloatButtonProps\["styles"\]](/components/float-button#semantic-dom) } | - | |
|
||||
| form | Set Form common props | { className?: string, style?: React.CSSProperties, validateMessages?: [ValidateMessages](/components/form/#validatemessages), requiredMark?: boolean \| `optional`, scrollToFirstError?: boolean \| [Options](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options), classNames?:[FormConfig\["classNames"\]](/components/form#semantic-dom), styles?: [FormConfig\["styles"\]](/components/form#semantic-dom), tooltip?: [TooltipProps](/components/tooltip#api) & { icon?: ReactNode }, labelAlign?: `left` \| `right` } | - | `requiredMark`: 4.8.0; `colon`: 4.18.0; `scrollToFirstError`: 5.2.0; `className` and `style`: 5.7.0; `tooltip`: 6.3.0; `labelAlign`: 6.4.0 |
|
||||
| form | Set Form common props | { className?: string, style?: React.CSSProperties, validateMessages?: [ValidateMessages](/components/form/#validatemessages), requiredMark?: boolean \| `optional`, scrollToFirstError?: boolean \| [Options](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options), classNames?:[FormConfig\["classNames"\]](/components/form#semantic-dom), styles?: [FormConfig\["styles"\]](/components/form#semantic-dom), tooltip?: [TooltipProps](/components/tooltip#api) & { icon?: ReactNode } } | - | `requiredMark`: 4.8.0; `colon`: 4.18.0; `scrollToFirstError`: 5.2.0; `className` and `style`: 5.7.0; `tooltip`: 6.3.0 |
|
||||
| image | Set Image common props | { className?: string, style?: React.CSSProperties, preview?: { closeIcon?: React.ReactNode, classNames?:[ImageConfig\["classNames"\]](/components/image#semantic-dom), styles?: [ImageConfig\["styles"\]](/components/image#semantic-dom) }, fallback?: string } | - | 5.7.0, `closeIcon`: 5.14.0, `classNames` and `styles`: 6.0.0 |
|
||||
| input | Set Input common props | { autoComplete?: string, className?: string, style?: React.CSSProperties, allowClear?: boolean \| { clearIcon?: ReactNode } } | - | 4.2.0, `allowClear`: 5.15.0 |
|
||||
| inputNumber | Set InputNumber common props | { className?: string, style?: React.CSSProperties, classNames?: [InputNumberConfig\["classNames"\]](/components/input-number#semantic-dom), styles?: [InputNumberConfig\["styles"\]](/components/input-number#semantic-dom) } | - | |
|
||||
|
||||
@@ -74,6 +74,7 @@ import type {
|
||||
TourConfig,
|
||||
TransferConfig,
|
||||
TreeSelectConfig,
|
||||
TypographyConfig,
|
||||
UploadConfig,
|
||||
Variant,
|
||||
WaveConfig,
|
||||
@@ -225,7 +226,7 @@ export interface ConfigProviderProps {
|
||||
collapse?: CollapseConfig;
|
||||
divider?: ComponentStyleConfig;
|
||||
drawer?: DrawerConfig;
|
||||
typography?: ComponentStyleConfig;
|
||||
typography?: TypographyConfig;
|
||||
skeleton?: SkeletonConfig;
|
||||
spin?: SpinConfig;
|
||||
segmented?: ComponentStyleConfig;
|
||||
|
||||
@@ -121,7 +121,7 @@ const {
|
||||
| card | 设置 Card 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [CardProps\["classNames"\]](/components/card-cn#semantic-dom), styles?: [CardProps\["styles"\]](/components/card-cn#semantic-dom) } | - | 5.7.0, `classNames` 和 `styles`: 5.14.0 |
|
||||
| cardMeta | 设置 Card.Meta 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [CardMetaProps\["classNames"\]](/components/card-cn#semantic-dom), styles?: [CardMetaProps\["styles"\]](/components/card-cn#semantic-dom) } | - | 6.0.0 |
|
||||
| carousel | 设置 Carousel 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
|
||||
| cascader | 设置 Cascader 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [CascaderConfig\["classNames"\]](/components/cascader#semantic-dom), styles?: [CascaderConfig\["styles"\]](/components/cascader#semantic-dom), expandIcon?: React.ReactNode, loadingIcon?: React.ReactNode, searchIcon?: React.ReactNode, clearIcon?: React.ReactNode, removeIcon?: React.ReactNode, suffixIcon?: React.ReactNode } | - | 5.7.0, `classNames` 和 `styles`: 6.0.0, `expandIcon`, `loadingIcon`, `searchIcon`, `clearIcon`, `removeIcon`, `suffixIcon`: 6.4.0 |
|
||||
| cascader | 设置 Cascader 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [CascaderConfig\["classNames"\]](/components/cascader#semantic-dom), styles?: [CascaderConfig\["styles"\]](/components/cascader#semantic-dom), expandIcon?: React.ReactNode, loadingIcon?: React.ReactNode } | - | 5.7.0, `classNames` 和 `styles`: 6.0.0, `expandIcon` 和 `loadingIcon`: 6.3.0 |
|
||||
| checkbox | 设置 Checkbox 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [CheckboxConfig\["classNames"\]](/components/checkbox-cn#semantic-dom), styles?: [CheckboxConfig\["styles"\]](/components/checkbox-cn#semantic-dom) } | - | 5.7.0, `classNames` 和 `styles`: 6.0.0 |
|
||||
| collapse | 设置 Collapse 组件的通用属性 | { className?: string, style?: React.CSSProperties, expandIcon?: (props) => ReactNode, classNames?: [CollapseProps\["classNames"\]](/components/collapse-cn#semantic-dom), styles?: [CollapseProps\["styles"\]](/components/collapse-cn#semantic-dom) } | - | 5.7.0, `expandIcon`: 5.15.0, `classNames` 和 `styles`: 6.0.0 |
|
||||
| colorPicker | 设置 ColorPicker 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [ColorPickerConfig\["classNames"\]](/components/color-picker-cn#semantic-dom), styles?: [ColorPickerConfig\["styles"\]](/components/color-picker-cn#semantic-dom) } | - | 5.7.0 |
|
||||
@@ -135,7 +135,7 @@ const {
|
||||
| flex | 设置 Flex 组件的通用属性 | { className?: string, style?: React.CSSProperties, vertical?: boolean } | - | 5.10.0 |
|
||||
| floatButton | 设置 FloatButton 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [FloatButtonProps\["classNames"\]](/components/float-button-cn#semantic-dom), styles?: [FloatButtonProps\["styles"\]](/components/float-button-cn#semantic-dom), backTopIcon?: React.ReactNode } | - | |
|
||||
| floatButtonGroup | 设置 FloatButton.Group 组件的通用属性 | { closeIcon?: React.ReactNode, className?: string, style?: React.CSSProperties, classNames?: [FloatButtonProps\["classNames"\]](/components/float-button-cn#semantic-dom), styles?: [FloatButtonProps\["styles"\]](/components/float-button-cn#semantic-dom) } | - | |
|
||||
| form | 设置 Form 组件的通用属性 | { className?: string, style?: React.CSSProperties, validateMessages?: [ValidateMessages](/components/form-cn#validatemessages), requiredMark?: boolean \| `optional`, colon?: boolean, scrollToFirstError?: boolean \| [Options](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options), classNames?:[FormConfig\["classNames"\]](/components/form-cn#semantic-dom), styles?: [FormConfig\["styles"\]](/components/form-cn#semantic-dom), tooltip?: [TooltipProps](/components/tooltip-cn#api) & { icon?: ReactNode }, labelAlign?: `left` \| `right` } | - | `requiredMark`: 4.8.0; `colon`: 4.18.0; `scrollToFirstError`: 5.2.0; `className` 和 `style`: 5.7.0; `tooltip`: 6.3.0; `labelAlign`: 6.4.0 |
|
||||
| form | 设置 Form 组件的通用属性 | { className?: string, style?: React.CSSProperties, validateMessages?: [ValidateMessages](/components/form-cn#validatemessages), requiredMark?: boolean \| `optional`, colon?: boolean, scrollToFirstError?: boolean \| [Options](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options), classNames?:[FormConfig\["classNames"\]](/components/form-cn#semantic-dom), styles?: [FormConfig\["styles"\]](/components/form-cn#semantic-dom), tooltip?: [TooltipProps](/components/tooltip-cn#api) & { icon?: ReactNode } } | - | `requiredMark`: 4.8.0; `colon`: 4.18.0; `scrollToFirstError`: 5.2.0; `className` 和 `style`: 5.7.0; `tooltip`: 6.3.0 |
|
||||
| image | 设置 Image 组件的通用属性 | { className?: string, style?: React.CSSProperties, preview?: { closeIcon?: React.ReactNode, classNames?:[ImageConfig\["classNames"\]](/components/image-cn#semantic-dom), styles?: [ImageConfig\["styles"\]](/components/image-cn#semantic-dom) }, fallback?: string } | - | 5.7.0, `closeIcon`: 5.14.0, `classNames` 和 `styles`: 6.0.0 |
|
||||
| input | 设置 Input 组件的通用属性 | { autoComplete?: string, className?: string, style?: React.CSSProperties,classNames?:[InputConfig\["classNames"\]](/components/input-cn#semantic-input), styles?: [InputConfig\["styles"\]](/components/input-cn#semantic-input), allowClear?: boolean \| { clearIcon?: ReactNode } } | - | 5.7.0, `allowClear`: 5.15.0 |
|
||||
| inputNumber | 设置 Input 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [InputNumberConfig\["classNames"\]](/components/input-number-cn#semantic-dom), styles?: [InputNumberConfig\["styles"\]](/components/input-number-cn#semantic-dom) } | - | |
|
||||
|
||||
@@ -5,10 +5,10 @@ import { DatePicker, Radio } from 'antd';
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [placement, setPlacement] = useState<DatePickerProps['placement']>('topLeft');
|
||||
const [placement, SetPlacement] = useState<DatePickerProps['placement']>('topLeft');
|
||||
|
||||
const placementChange = (e: RadioChangeEvent) => {
|
||||
setPlacement(e.target.value);
|
||||
SetPlacement(e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -88,6 +88,205 @@ Array [
|
||||
|
||||
exports[`renders components/drawer/demo/basic-right.tsx extend context correctly 2`] = `[]`;
|
||||
|
||||
exports[`renders components/drawer/demo/classNames.tsx extend context correctly 1`] = `
|
||||
Array [
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small css-var-test-id"
|
||||
>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Open
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
ConfigProvider
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-drawer ant-drawer-right css-var-test-id ant-drawer-open ant-drawer-inline"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask acss-c0hvaj"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 378px;"
|
||||
>
|
||||
<div
|
||||
aria-labelledby="test-id"
|
||||
aria-modal="true"
|
||||
class="ant-drawer-section acss-10412ne"
|
||||
role="dialog"
|
||||
style="box-shadow: -10px 0 10px #666;"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header acss-1l0wu1y"
|
||||
style="border-bottom: 1px solid rgb(22, 119, 255);"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header-title"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="ant-drawer-close"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="close"
|
||||
class="anticon anticon-close"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="close"
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-drawer-title"
|
||||
id="test-id"
|
||||
>
|
||||
Basic Drawer
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-drawer-body acss-pgpe64"
|
||||
style="font-size: 16px;"
|
||||
>
|
||||
<p>
|
||||
Some contents...
|
||||
</p>
|
||||
<p>
|
||||
Some contents...
|
||||
</p>
|
||||
<p>
|
||||
Some contents...
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="ant-drawer-footer acss-r4s437"
|
||||
style="border-top: 1px solid rgb(217, 217, 217);"
|
||||
>
|
||||
Footer
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-drawer ant-drawer-right css-var-test-id ant-drawer-open ant-drawer-inline"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask acss-c0hvaj"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 378px;"
|
||||
>
|
||||
<div
|
||||
aria-labelledby="test-id"
|
||||
aria-modal="true"
|
||||
class="ant-drawer-section acss-10412ne"
|
||||
role="dialog"
|
||||
style="box-shadow: -10px 0 10px #666;"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header acss-1l0wu1y"
|
||||
style="border-bottom: 1px solid rgb(22, 119, 255);"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header-title"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="ant-drawer-close"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="close"
|
||||
class="anticon anticon-close"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="close"
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-drawer-title"
|
||||
id="test-id"
|
||||
>
|
||||
Basic Drawer
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-drawer-body acss-pgpe64"
|
||||
style="font-size: 16px;"
|
||||
>
|
||||
<p>
|
||||
Some contents...
|
||||
</p>
|
||||
<p>
|
||||
Some contents...
|
||||
</p>
|
||||
<p>
|
||||
Some contents...
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="ant-drawer-footer acss-r4s437"
|
||||
style="border-top: 1px solid rgb(217, 217, 217);"
|
||||
>
|
||||
Footer
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders components/drawer/demo/classNames.tsx extend context correctly 2`] = `[]`;
|
||||
|
||||
exports[`renders components/drawer/demo/closable-placement.tsx extend context correctly 1`] = `
|
||||
Array [
|
||||
<button
|
||||
|
||||
@@ -11,6 +11,37 @@ exports[`renders components/drawer/demo/basic-right.tsx correctly 1`] = `
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`renders components/drawer/demo/classNames.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small css-var-test-id"
|
||||
>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Open
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
ConfigProvider
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders components/drawer/demo/closable-placement.tsx correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
|
||||
|
||||
7
components/drawer/demo/classNames.md
Normal file
7
components/drawer/demo/classNames.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
通过 `classNames` 属性设置抽屉内部区域(header、body、footer、mask、wrapper)的 `className`。
|
||||
|
||||
## en-US
|
||||
|
||||
Set the `className` of the build-in module (header, body, footer, mask, wrapper) of the drawer through the `classNames`.
|
||||
102
components/drawer/demo/classNames.tsx
Normal file
102
components/drawer/demo/classNames.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Button, ConfigProvider, Drawer, Space } from 'antd';
|
||||
import type { DrawerProps } from 'antd';
|
||||
import { createStyles, useTheme } from 'antd-style';
|
||||
|
||||
const useStyle = createStyles(({ token }) => ({
|
||||
'my-drawer-body': {
|
||||
background: token.blue1,
|
||||
},
|
||||
'my-drawer-mask': {
|
||||
boxShadow: `inset 0 0 15px #fff`,
|
||||
},
|
||||
'my-drawer-header': {
|
||||
background: token.green1,
|
||||
},
|
||||
'my-drawer-footer': {
|
||||
color: token.colorPrimary,
|
||||
},
|
||||
'my-drawer-section': {
|
||||
borderInlineStart: '2px dotted #333',
|
||||
},
|
||||
}));
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [open, setOpen] = useState([false, false]);
|
||||
const { styles } = useStyle();
|
||||
const token = useTheme();
|
||||
|
||||
const toggleDrawer = (idx: number, target: boolean) => {
|
||||
setOpen((p) => {
|
||||
p[idx] = target;
|
||||
return [...p];
|
||||
});
|
||||
};
|
||||
|
||||
const classNames: DrawerProps['classNames'] = {
|
||||
body: styles['my-drawer-body'],
|
||||
mask: styles['my-drawer-mask'],
|
||||
header: styles['my-drawer-header'],
|
||||
footer: styles['my-drawer-footer'],
|
||||
section: styles['my-drawer-section'],
|
||||
};
|
||||
|
||||
const drawerStyles: DrawerProps['styles'] = {
|
||||
mask: {
|
||||
backdropFilter: 'blur(10px)',
|
||||
},
|
||||
section: {
|
||||
boxShadow: '-10px 0 10px #666',
|
||||
},
|
||||
header: {
|
||||
borderBottom: `1px solid ${token.colorPrimary}`,
|
||||
},
|
||||
body: {
|
||||
fontSize: token.fontSizeLG,
|
||||
},
|
||||
footer: {
|
||||
borderTop: `1px solid ${token.colorBorder}`,
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Space>
|
||||
<Button type="primary" onClick={() => toggleDrawer(0, true)}>
|
||||
Open
|
||||
</Button>
|
||||
<Button type="primary" onClick={() => toggleDrawer(1, true)}>
|
||||
ConfigProvider
|
||||
</Button>
|
||||
</Space>
|
||||
<Drawer
|
||||
title="Basic Drawer"
|
||||
placement="right"
|
||||
footer="Footer"
|
||||
onClose={() => toggleDrawer(0, false)}
|
||||
open={open[0]}
|
||||
classNames={classNames}
|
||||
styles={drawerStyles}
|
||||
>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
</Drawer>
|
||||
<ConfigProvider drawer={{ classNames, styles: drawerStyles }}>
|
||||
<Drawer
|
||||
title="Basic Drawer"
|
||||
placement="right"
|
||||
footer="Footer"
|
||||
onClose={() => toggleDrawer(1, false)}
|
||||
open={open[1]}
|
||||
>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
</Drawer>
|
||||
</ConfigProvider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
@@ -54,8 +54,8 @@ const stylesFn: DrawerProps['styles'] = (info) => {
|
||||
};
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||
const [drawerFnOpen, setDrawerFnOpen] = useState(false);
|
||||
const [drawerOpen, setOpen] = useState(false);
|
||||
const [drawerFnOpen, setFnOpen] = useState(false);
|
||||
|
||||
const sharedProps: DrawerProps = {
|
||||
classNames,
|
||||
@@ -65,7 +65,7 @@ const App: React.FC = () => {
|
||||
const footer: React.ReactNode = (
|
||||
<Flex gap="middle" justify="flex-end">
|
||||
<Button
|
||||
onClick={() => setDrawerFnOpen(false)}
|
||||
onClick={() => setFnOpen(false)}
|
||||
styles={{ root: { borderColor: '#ccc', color: '#171717', backgroundColor: '#fff' } }}
|
||||
>
|
||||
Cancel
|
||||
@@ -73,7 +73,7 @@ const App: React.FC = () => {
|
||||
<Button
|
||||
type="primary"
|
||||
styles={{ root: { backgroundColor: '#171717' } }}
|
||||
onClick={() => setDrawerOpen(true)}
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
@@ -82,8 +82,8 @@ const App: React.FC = () => {
|
||||
|
||||
return (
|
||||
<Flex gap="middle">
|
||||
<Button onClick={() => setDrawerOpen(true)}>Open Style Drawer</Button>
|
||||
<Button type="primary" onClick={() => setDrawerFnOpen(true)}>
|
||||
<Button onClick={() => setOpen(true)}>Open Style Drawer</Button>
|
||||
<Button type="primary" onClick={() => setFnOpen(true)}>
|
||||
Open Function Drawer
|
||||
</Button>
|
||||
<Drawer
|
||||
@@ -92,7 +92,7 @@ const App: React.FC = () => {
|
||||
title="Custom Style Drawer"
|
||||
styles={styles}
|
||||
open={drawerOpen}
|
||||
onClose={() => setDrawerOpen(false)}
|
||||
onClose={() => setOpen(false)}
|
||||
>
|
||||
{sharedContent}
|
||||
</Drawer>
|
||||
@@ -103,7 +103,7 @@ const App: React.FC = () => {
|
||||
styles={stylesFn}
|
||||
mask={{ enabled: true, blur: true }}
|
||||
open={drawerFnOpen}
|
||||
onClose={() => setDrawerFnOpen(false)}
|
||||
onClose={() => setFnOpen(false)}
|
||||
>
|
||||
{sharedContent}
|
||||
</Drawer>
|
||||
|
||||
@@ -34,6 +34,7 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr
|
||||
<code src="./demo/user-profile.tsx">Preview drawer</code>
|
||||
<code src="./demo/multi-level-drawer.tsx">Multi-level drawer</code>
|
||||
<code src="./demo/size.tsx">Preset size</code>
|
||||
<code src="./demo/classNames.tsx">Customize className for build-in module</code>
|
||||
<code src="./demo/mask.tsx">mask</code>
|
||||
<code src="./demo/closable-placement.tsx" version="5.28.0">Closable placement</code>
|
||||
<code src="./demo/style-class.tsx" version="6.0.0">Custom semantic dom styling</code>
|
||||
|
||||
@@ -35,6 +35,7 @@ demo:
|
||||
<code src="./demo/multi-level-drawer.tsx">多层抽屉</code>
|
||||
<code src="./demo/size.tsx">预设宽度</code>
|
||||
<code src="./demo/mask.tsx">遮罩</code>
|
||||
<code src="./demo/classNames.tsx">自定义内部样式</code>
|
||||
<code src="./demo/closable-placement.tsx" version="5.28.0">关闭按钮位置</code>
|
||||
<code src="./demo/style-class.tsx" version="6.0.0">自定义语义结构的样式和类</code>
|
||||
<code src="./demo/config-provider.tsx" debug>ConfigProvider</code>
|
||||
|
||||
@@ -91,7 +91,6 @@ const InternalForm: React.ForwardRefRenderFunction<FormRef, FormProps> = (props,
|
||||
styles: contextStyles,
|
||||
classNames: contextClassNames,
|
||||
tooltip: contextTooltip,
|
||||
labelAlign: contextLabelAlign,
|
||||
} = useComponentConfig('form');
|
||||
|
||||
const {
|
||||
@@ -145,8 +144,6 @@ const InternalForm: React.ForwardRefRenderFunction<FormRef, FormProps> = (props,
|
||||
|
||||
const mergedColon = colon ?? contextColon;
|
||||
|
||||
const mergedLabelAlign = labelAlign ?? contextLabelAlign;
|
||||
|
||||
const mergedTooltip = { ...contextTooltip, ...tooltip };
|
||||
|
||||
const prefixCls = getPrefixCls('form', customizePrefixCls);
|
||||
@@ -197,7 +194,7 @@ const InternalForm: React.ForwardRefRenderFunction<FormRef, FormProps> = (props,
|
||||
const formContextValue = React.useMemo<FormContextProps>(
|
||||
() => ({
|
||||
name,
|
||||
labelAlign: mergedLabelAlign,
|
||||
labelAlign,
|
||||
labelCol,
|
||||
labelWrap,
|
||||
wrapperCol,
|
||||
@@ -213,7 +210,7 @@ const InternalForm: React.ForwardRefRenderFunction<FormRef, FormProps> = (props,
|
||||
}),
|
||||
[
|
||||
name,
|
||||
mergedLabelAlign,
|
||||
labelAlign,
|
||||
labelCol,
|
||||
wrapperCol,
|
||||
layout,
|
||||
|
||||
@@ -829,13 +829,13 @@ describe('Form', () => {
|
||||
// https://github.com/ant-design/ant-design/issues/20813
|
||||
it('should update help directly when provided', async () => {
|
||||
const App: React.FC = () => {
|
||||
const [message, setMessage] = React.useState('');
|
||||
const [message, updateMessage] = React.useState('');
|
||||
return (
|
||||
<Form>
|
||||
<Form.Item label="hello" help={message}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Button onClick={() => setMessage('bamboo')} />
|
||||
<Button onClick={() => updateMessage('bamboo')} />
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,10 +14,10 @@ const customizeRequiredMark = (label: React.ReactNode, { required }: { required:
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [form] = Form.useForm();
|
||||
const [requiredMark, setRequiredMark] = useState<RequiredMark>('optional');
|
||||
const [requiredMark, setRequiredMarkType] = useState<RequiredMark>('optional');
|
||||
|
||||
const onRequiredTypeChange: FormProps<any>['onValuesChange'] = ({ requiredMarkValue }) => {
|
||||
setRequiredMark(requiredMarkValue);
|
||||
setRequiredMarkType(requiredMarkValue);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -3146,7 +3146,7 @@ Array [
|
||||
style="width: 100px;"
|
||||
>
|
||||
<div
|
||||
class="ant-select-content"
|
||||
class="ant-select-content ant-select-content-has-value"
|
||||
title=""
|
||||
>
|
||||
<input
|
||||
|
||||
@@ -684,7 +684,7 @@ Array [
|
||||
style="width:100px"
|
||||
>
|
||||
<div
|
||||
class="ant-select-content"
|
||||
class="ant-select-content ant-select-content-has-value"
|
||||
title=""
|
||||
>
|
||||
<input
|
||||
|
||||
@@ -39,6 +39,39 @@ exports[`renders components/modal/demo/button-props.tsx extend context correctly
|
||||
|
||||
exports[`renders components/modal/demo/button-props.tsx extend context correctly 2`] = `[]`;
|
||||
|
||||
exports[`renders components/modal/demo/classNames.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small css-var-test-id"
|
||||
>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Open Modal
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
ConfigProvider
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders components/modal/demo/classNames.tsx extend context correctly 2`] = `[]`;
|
||||
|
||||
exports[`renders components/modal/demo/component-token.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
style="display: flex; flex-direction: column; row-gap: 16px;"
|
||||
|
||||
@@ -33,6 +33,37 @@ exports[`renders components/modal/demo/button-props.tsx correctly 1`] = `
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`renders components/modal/demo/classNames.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small css-var-test-id"
|
||||
>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Open Modal
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
ConfigProvider
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders components/modal/demo/component-token.tsx correctly 1`] = `
|
||||
<div
|
||||
style="display:flex;flex-direction:column;row-gap:16px"
|
||||
|
||||
7
components/modal/demo/classNames.md
Normal file
7
components/modal/demo/classNames.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
通过 `classNames` 属性设置弹窗内部区域(header、body、footer、mask、wrapper)的 `className`。
|
||||
|
||||
## en-US
|
||||
|
||||
Set the className of the build-in module (header, body, footer, mask, wrapper) of the modal through the classNames property.
|
||||
110
components/modal/demo/classNames.tsx
Normal file
110
components/modal/demo/classNames.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Button, ConfigProvider, Modal, Space } from 'antd';
|
||||
import { createStyles, useTheme } from 'antd-style';
|
||||
|
||||
const useStyle = createStyles(({ token }) => ({
|
||||
'my-modal-body': {
|
||||
background: token.blue1,
|
||||
padding: token.paddingSM,
|
||||
},
|
||||
'my-modal-mask': {
|
||||
boxShadow: `inset 0 0 15px #fff`,
|
||||
},
|
||||
'my-modal-header': {
|
||||
borderBottom: `1px dotted ${token.colorPrimary}`,
|
||||
},
|
||||
'my-modal-footer': {
|
||||
color: token.colorPrimary,
|
||||
},
|
||||
'my-modal-content': {
|
||||
border: '1px solid #333',
|
||||
},
|
||||
}));
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [isModalOpen, setIsModalOpen] = useState([false, false]);
|
||||
const { styles } = useStyle();
|
||||
const token = useTheme();
|
||||
|
||||
const toggleModal = (idx: number, target: boolean) => {
|
||||
setIsModalOpen((p) => {
|
||||
p[idx] = target;
|
||||
return [...p];
|
||||
});
|
||||
};
|
||||
|
||||
const classNames = {
|
||||
body: styles['my-modal-body'],
|
||||
mask: styles['my-modal-mask'],
|
||||
header: styles['my-modal-header'],
|
||||
footer: styles['my-modal-footer'],
|
||||
content: styles['my-modal-content'],
|
||||
};
|
||||
|
||||
const modalStyles = {
|
||||
header: {
|
||||
borderInlineStart: `5px solid ${token.colorPrimary}`,
|
||||
borderRadius: 0,
|
||||
paddingInlineStart: 5,
|
||||
},
|
||||
body: {
|
||||
boxShadow: 'inset 0 0 5px #999',
|
||||
borderRadius: 5,
|
||||
},
|
||||
mask: {
|
||||
backdropFilter: 'blur(10px)',
|
||||
},
|
||||
footer: {
|
||||
borderTop: '1px solid #333',
|
||||
},
|
||||
content: {
|
||||
boxShadow: '0 0 30px #999',
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Space>
|
||||
<Button type="primary" onClick={() => toggleModal(0, true)}>
|
||||
Open Modal
|
||||
</Button>
|
||||
<Button type="primary" onClick={() => toggleModal(1, true)}>
|
||||
ConfigProvider
|
||||
</Button>
|
||||
</Space>
|
||||
<Modal
|
||||
title="Basic Modal"
|
||||
open={isModalOpen[0]}
|
||||
onOk={() => toggleModal(0, false)}
|
||||
onCancel={() => toggleModal(0, false)}
|
||||
footer="Footer"
|
||||
classNames={classNames}
|
||||
styles={modalStyles}
|
||||
>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
</Modal>
|
||||
<ConfigProvider
|
||||
modal={{
|
||||
classNames,
|
||||
styles: modalStyles,
|
||||
}}
|
||||
>
|
||||
<Modal
|
||||
title="Basic Modal"
|
||||
open={isModalOpen[1]}
|
||||
onOk={() => toggleModal(1, false)}
|
||||
onCancel={() => toggleModal(1, false)}
|
||||
footer="Footer"
|
||||
>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
</Modal>
|
||||
</ConfigProvider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
@@ -60,8 +60,8 @@ const stylesFn: ModalProps['styles'] = (info) => {
|
||||
};
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [modalFnOpen, setModalFnOpen] = useState(false);
|
||||
const [modalOpen, setOpen] = useState(false);
|
||||
const [modalFnOpen, setFnOpen] = useState(false);
|
||||
|
||||
const sharedProps: ModalProps = {
|
||||
centered: true,
|
||||
@@ -71,7 +71,7 @@ const App: React.FC = () => {
|
||||
const footer: React.ReactNode = (
|
||||
<>
|
||||
<Button
|
||||
onClick={() => setModalFnOpen(false)}
|
||||
onClick={() => setFnOpen(false)}
|
||||
styles={{ root: { borderColor: '#ccc', color: '#171717', backgroundColor: '#fff' } }}
|
||||
>
|
||||
Cancel
|
||||
@@ -79,7 +79,7 @@ const App: React.FC = () => {
|
||||
<Button
|
||||
type="primary"
|
||||
styles={{ root: { backgroundColor: '#171717' } }}
|
||||
onClick={() => setModalOpen(true)}
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
@@ -88,8 +88,8 @@ const App: React.FC = () => {
|
||||
|
||||
return (
|
||||
<Flex gap="middle">
|
||||
<Button onClick={() => setModalOpen(true)}>Open Style Modal</Button>
|
||||
<Button type="primary" onClick={() => setModalFnOpen(true)}>
|
||||
<Button onClick={() => setOpen(true)}>Open Style Modal</Button>
|
||||
<Button type="primary" onClick={() => setFnOpen(true)}>
|
||||
Open Function Modal
|
||||
</Button>
|
||||
<Modal
|
||||
@@ -98,8 +98,8 @@ const App: React.FC = () => {
|
||||
title="Custom Style Modal"
|
||||
styles={styles}
|
||||
open={modalOpen}
|
||||
onOk={() => setModalOpen(false)}
|
||||
onCancel={() => setModalOpen(false)}
|
||||
onOk={() => setOpen(false)}
|
||||
onCancel={() => setOpen(false)}
|
||||
>
|
||||
{sharedContent}
|
||||
</Modal>
|
||||
@@ -110,8 +110,8 @@ const App: React.FC = () => {
|
||||
styles={stylesFn}
|
||||
mask={{ enabled: true, blur: true }}
|
||||
open={modalFnOpen}
|
||||
onOk={() => setModalFnOpen(false)}
|
||||
onCancel={() => setModalFnOpen(false)}
|
||||
onOk={() => setFnOpen(false)}
|
||||
onCancel={() => setFnOpen(false)}
|
||||
>
|
||||
{sharedContent}
|
||||
</Modal>
|
||||
|
||||
@@ -34,6 +34,7 @@ Additionally, if you need to show a simple confirmation dialog, you can use [`Ap
|
||||
<code src="./demo/width.tsx">To customize the width of modal</code>
|
||||
<code src="./demo/static-info.tsx">Static Method</code>
|
||||
<code src="./demo/confirm.tsx">Static confirmation</code>
|
||||
<code src="./demo/classNames.tsx">Customize className for build-in module</code>
|
||||
<code src="./demo/confirm-router.tsx">destroy confirmation modal dialog</code>
|
||||
<code src="./demo/style-class.tsx" version="6.0.0">Custom semantic dom styling</code>
|
||||
<code src="./demo/nested.tsx" debug>Nested Modal</code>
|
||||
|
||||
@@ -35,6 +35,7 @@ demo:
|
||||
<code src="./demo/width.tsx">自定义模态的宽度</code>
|
||||
<code src="./demo/static-info.tsx">静态方法</code>
|
||||
<code src="./demo/confirm.tsx">静态确认对话框</code>
|
||||
<code src="./demo/classNames.tsx">自定义内部模块 className</code>
|
||||
<code src="./demo/confirm-router.tsx">销毁确认对话框</code>
|
||||
<code src="./demo/style-class.tsx" version="6.0.0">自定义语义结构的样式和类</code>
|
||||
<code src="./demo/nested.tsx" debug>嵌套弹框</code>
|
||||
|
||||
@@ -148,7 +148,7 @@ const Pagination: React.FC<PaginationProps> = (props) => {
|
||||
|
||||
// Generate options
|
||||
const mergedPageSizeOptions = React.useMemo(() => {
|
||||
return pageSizeOptions ? pageSizeOptions.map<number>(Number) : undefined;
|
||||
return pageSizeOptions ? pageSizeOptions.map((option) => Number(option)) : undefined;
|
||||
}, [pageSizeOptions]);
|
||||
|
||||
// Render size changer
|
||||
|
||||
@@ -147,7 +147,6 @@ const genLineStyle: GenerateStyle<ProgressToken> = (token) => {
|
||||
borderRadius: token.lineBorderRadius,
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
|
||||
[`&${componentCls}-status-active`]: {
|
||||
|
||||
@@ -1778,9 +1778,7 @@ Array [
|
||||
exports[`renders components/select/demo/custom-tag-render.tsx extend context correctly 2`] = `[]`;
|
||||
|
||||
exports[`renders components/select/demo/debug.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-stretch ant-flex-gap-middle ant-flex-vertical"
|
||||
>
|
||||
Array [
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small css-var-test-id"
|
||||
style="flex-wrap: wrap; width: 500px; position: relative; z-index: 1; border: 1px solid red; background-color: rgb(255, 255, 255);"
|
||||
@@ -2212,184 +2210,9 @@ exports[`renders components/select/demo/debug.tsx extend context correctly 1`] =
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-outlined css-var-test-id ant-select-css-var ant-select-single ant-select-show-arrow"
|
||||
style="width: 120px;"
|
||||
>
|
||||
<div
|
||||
class="ant-select-content"
|
||||
title=" "
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
autocomplete="off"
|
||||
class="ant-select-input"
|
||||
id="test-id"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
type="search"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-suffix"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up css-var-test-id ant-select-css-var ant-select-dropdown-placement-bottomLeft"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; right: auto; bottom: auto; box-sizing: border-box;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
id="test-id_list"
|
||||
role="listbox"
|
||||
style="height: 0px; width: 0px; overflow: hidden;"
|
||||
>
|
||||
<div
|
||||
aria-label="Jack"
|
||||
aria-selected="false"
|
||||
id="test-id_list_0"
|
||||
role="option"
|
||||
>
|
||||
jack
|
||||
</div>
|
||||
<div
|
||||
aria-label="Lucy"
|
||||
aria-selected="false"
|
||||
id="test-id_list_1"
|
||||
role="option"
|
||||
>
|
||||
lucy
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rc-virtual-list"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
class="rc-virtual-list-holder"
|
||||
style="max-height: 256px; overflow-y: auto; overflow-anchor: none;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="rc-virtual-list-holder-inner"
|
||||
style="display: flex; flex-direction: column;"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item ant-select-item-option ant-select-item-option-active"
|
||||
title="Jack"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
Jack
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-item ant-select-item-option"
|
||||
title="Lucy"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
Lucy
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-item ant-select-item-option ant-select-item-option-disabled"
|
||||
title="Disabled"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
Disabled
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-item ant-select-item-option"
|
||||
title="yiminghe"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
yiminghe
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-item ant-select-item-option"
|
||||
title="I am super super long!"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
I am super super long!
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
style="width: 200px;"
|
||||
style="width: 200px; margin-top: 24px;"
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-outlined css-var-test-id ant-select-css-var ant-select-multiple ant-select-show-arrow ant-select-show-search"
|
||||
@@ -2556,113 +2379,8 @@ exports[`renders components/select/demo/debug.tsx extend context correctly 1`] =
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select ant-select-outlined css-var-test-id ant-select-css-var ant-select-single ant-select-show-arrow"
|
||||
>
|
||||
<div
|
||||
class="ant-select-content"
|
||||
title=""
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
autocomplete="off"
|
||||
class="ant-select-input"
|
||||
id="test-id"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
type="search"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-suffix"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up css-var-test-id ant-select-css-var ant-select-dropdown-empty ant-select-dropdown-placement-bottomLeft"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; right: auto; bottom: auto; box-sizing: border-box;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="ant-select-item-empty"
|
||||
id="test-id_list"
|
||||
role="listbox"
|
||||
>
|
||||
<div
|
||||
class="css-var-test-id ant-empty ant-empty-normal ant-empty-small"
|
||||
>
|
||||
<div
|
||||
class="ant-empty-image"
|
||||
>
|
||||
<svg
|
||||
height="41"
|
||||
viewBox="0 0 64 41"
|
||||
width="64"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<title>
|
||||
No data
|
||||
</title>
|
||||
<g
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
transform="translate(0 1)"
|
||||
>
|
||||
<ellipse
|
||||
cx="32"
|
||||
cy="33"
|
||||
fill="#f5f5f5"
|
||||
rx="32"
|
||||
ry="7"
|
||||
/>
|
||||
<g
|
||||
fill-rule="nonzero"
|
||||
stroke="#d9d9d9"
|
||||
>
|
||||
<path
|
||||
d="M55 12.8 44.9 1.3Q44 0 42.9 0H21.1q-1.2 0-2 1.3L9 12.8V22h46z"
|
||||
/>
|
||||
<path
|
||||
d="M41.6 16c0-1.7 1-3 2.2-3H55v18.1c0 2.2-1.3 3.9-3 3.9H12c-1.7 0-3-1.7-3-3.9V13h11.2c1.2 0 2.2 1.3 2.2 3s1 2.9 2.2 2.9h14.8c1.2 0 2.2-1.4 2.2-3"
|
||||
fill="#fafafa"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
class="ant-empty-description"
|
||||
>
|
||||
No data
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders components/select/demo/debug.tsx extend context correctly 2`] = `[]`;
|
||||
|
||||
@@ -741,9 +741,7 @@ exports[`renders components/select/demo/custom-tag-render.tsx correctly 1`] = `
|
||||
`;
|
||||
|
||||
exports[`renders components/select/demo/debug.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-stretch ant-flex-gap-middle ant-flex-vertical"
|
||||
>
|
||||
Array [
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small css-var-test-id"
|
||||
style="flex-wrap:wrap;width:500px;position:relative;z-index:1;border:1px solid red;background-color:#fff"
|
||||
@@ -926,58 +924,9 @@ exports[`renders components/select/demo/debug.tsx correctly 1`] = `
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-outlined css-var-test-id ant-select-css-var ant-select-single ant-select-show-arrow"
|
||||
style="width:120px"
|
||||
>
|
||||
<div
|
||||
class="ant-select-content"
|
||||
title=" "
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
autocomplete="off"
|
||||
class="ant-select-input"
|
||||
id="test-id"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
type="search"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-suffix"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
style="width:200px"
|
||||
style="width:200px;margin-top:24px"
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-outlined css-var-test-id ant-select-css-var ant-select-multiple ant-select-show-arrow ant-select-show-search"
|
||||
@@ -1069,52 +1018,8 @@ exports[`renders components/select/demo/debug.tsx correctly 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select ant-select-outlined css-var-test-id ant-select-css-var ant-select-single ant-select-show-arrow"
|
||||
>
|
||||
<div
|
||||
class="ant-select-content"
|
||||
title=""
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
autocomplete="off"
|
||||
class="ant-select-input"
|
||||
id="test-id"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
type="search"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-suffix"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders components/select/demo/debug-flip-shift.tsx correctly 1`] = `
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Button, Flex, Input, Select, Space } from 'antd';
|
||||
import { Button, Input, Select, Space } from 'antd';
|
||||
|
||||
const style: React.CSSProperties = {
|
||||
width: 500,
|
||||
@@ -14,7 +14,7 @@ const handleChange = (value: string | string[]) => {
|
||||
};
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Flex vertical gap="middle">
|
||||
<>
|
||||
<Space style={style} wrap>
|
||||
<Input style={{ width: 100 }} value="222" />
|
||||
<Select
|
||||
@@ -47,21 +47,8 @@ const App: React.FC = () => (
|
||||
/>
|
||||
<span className="debug-align">AntDesign</span>
|
||||
<Button>222</Button>
|
||||
{/* https://github.com/ant-design/ant-design/issues/56960 */}
|
||||
<Select
|
||||
style={{ width: 120 }}
|
||||
defaultValue=" "
|
||||
placeholder="Please select"
|
||||
options={[
|
||||
{ value: 'jack', label: 'Jack' },
|
||||
{ value: 'lucy', label: 'Lucy' },
|
||||
{ value: 'disabled', disabled: true, label: 'Disabled' },
|
||||
{ value: 'Yiminghe', label: 'yiminghe' },
|
||||
{ value: 'long', label: 'I am super super long!' },
|
||||
]}
|
||||
/>
|
||||
</Space>
|
||||
<div style={{ width: 200 }}>
|
||||
<div style={{ width: 200, marginTop: 24 }}>
|
||||
{/* https://github.com/ant-design/ant-design/issues/54179 */}
|
||||
<Select
|
||||
mode="multiple"
|
||||
@@ -75,9 +62,7 @@ const App: React.FC = () => (
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Select defaultValue="" />
|
||||
</Flex>
|
||||
</>
|
||||
);
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -15,12 +15,12 @@ const randomOptions = (count?: number) => {
|
||||
};
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [placement, setPlacement] = useState<SelectCommonPlacement>('topLeft');
|
||||
const [placement, SetPlacement] = useState<SelectCommonPlacement>('topLeft');
|
||||
const [open, setOpen] = useState(false);
|
||||
const [options, setOptions] = useState(() => randomOptions(3));
|
||||
|
||||
const placementChange = (e: RadioChangeEvent) => {
|
||||
setPlacement(e.target.value);
|
||||
SetPlacement(e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -5,10 +5,10 @@ import { Radio, Select } from 'antd';
|
||||
type SelectCommonPlacement = SelectProps['placement'];
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [placement, setPlacement] = useState<SelectCommonPlacement>('topLeft');
|
||||
const [placement, SetPlacement] = useState<SelectCommonPlacement>('topLeft');
|
||||
|
||||
const placementChange = (e: RadioChangeEvent) => {
|
||||
setPlacement(e.target.value);
|
||||
SetPlacement(e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -7,23 +7,17 @@ import DownOutlined from '@ant-design/icons/DownOutlined';
|
||||
import LoadingOutlined from '@ant-design/icons/LoadingOutlined';
|
||||
import SearchOutlined from '@ant-design/icons/SearchOutlined';
|
||||
|
||||
import fallbackProp from '../_util/fallbackProp';
|
||||
import { devUseWarning } from '../_util/warning';
|
||||
|
||||
type RenderNode = React.ReactNode | ((props: any) => React.ReactNode);
|
||||
|
||||
export default function useIcons({
|
||||
suffixIcon,
|
||||
contextSuffixIcon,
|
||||
clearIcon,
|
||||
contextClearIcon,
|
||||
menuItemSelectedIcon,
|
||||
removeIcon,
|
||||
contextRemoveIcon,
|
||||
loading,
|
||||
loadingIcon,
|
||||
searchIcon,
|
||||
contextSearchIcon,
|
||||
multiple,
|
||||
hasFeedback,
|
||||
showSuffixIcon,
|
||||
@@ -32,16 +26,11 @@ export default function useIcons({
|
||||
componentName,
|
||||
}: {
|
||||
suffixIcon?: React.ReactNode;
|
||||
contextSuffixIcon?: React.ReactNode;
|
||||
clearIcon?: React.ReactNode;
|
||||
contextClearIcon?: React.ReactNode;
|
||||
clearIcon?: RenderNode;
|
||||
menuItemSelectedIcon?: RenderNode;
|
||||
removeIcon?: RenderNode;
|
||||
contextRemoveIcon?: RenderNode;
|
||||
loading?: boolean;
|
||||
loadingIcon?: React.ReactNode;
|
||||
searchIcon?: React.ReactNode;
|
||||
contextSearchIcon?: React.ReactNode;
|
||||
multiple?: boolean;
|
||||
hasFeedback?: boolean;
|
||||
feedbackIcon?: ReactNode;
|
||||
@@ -56,72 +45,59 @@ export default function useIcons({
|
||||
warning.deprecated(!clearIcon, 'clearIcon', 'allowClear={{ clearIcon: React.ReactNode }}');
|
||||
}
|
||||
|
||||
return React.useMemo(() => {
|
||||
// Clear Icon
|
||||
const mergedClearIcon = fallbackProp(clearIcon, contextClearIcon, <CloseCircleFilled />);
|
||||
// Clear Icon
|
||||
const mergedClearIcon = clearIcon ?? <CloseCircleFilled />;
|
||||
|
||||
// Validation Feedback Icon
|
||||
const getSuffixIconNode = (arrowIcon?: ReactNode) => {
|
||||
if (suffixIcon === null && !hasFeedback && !showArrow) {
|
||||
return null;
|
||||
// Validation Feedback Icon
|
||||
const getSuffixIconNode = (arrowIcon?: ReactNode) => {
|
||||
if (suffixIcon === null && !hasFeedback && !showArrow) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{showSuffixIcon !== false && arrowIcon}
|
||||
{hasFeedback && feedbackIcon}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// Arrow item icon
|
||||
let mergedSuffixIcon = null;
|
||||
if (suffixIcon !== undefined) {
|
||||
mergedSuffixIcon = getSuffixIconNode(suffixIcon);
|
||||
} else if (loading) {
|
||||
mergedSuffixIcon = getSuffixIconNode(loadingIcon ?? <LoadingOutlined spin />);
|
||||
} else {
|
||||
mergedSuffixIcon = ({ open, showSearch }: { open: boolean; showSearch: boolean }) => {
|
||||
if (open && showSearch) {
|
||||
return getSuffixIconNode(<SearchOutlined />);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{showSuffixIcon !== false && arrowIcon}
|
||||
{hasFeedback && feedbackIcon}
|
||||
</>
|
||||
);
|
||||
return getSuffixIconNode(<DownOutlined />);
|
||||
};
|
||||
}
|
||||
|
||||
// Arrow item icon
|
||||
let mergedSuffixIcon = null;
|
||||
if (suffixIcon !== undefined) {
|
||||
mergedSuffixIcon = getSuffixIconNode(suffixIcon);
|
||||
} else if (loading) {
|
||||
mergedSuffixIcon = getSuffixIconNode(fallbackProp(loadingIcon, <LoadingOutlined spin />));
|
||||
} else {
|
||||
mergedSuffixIcon = ({ open, showSearch }: { open: boolean; showSearch: boolean }) => {
|
||||
if (open && showSearch) {
|
||||
return getSuffixIconNode(fallbackProp(searchIcon, contextSearchIcon, <SearchOutlined />));
|
||||
}
|
||||
return getSuffixIconNode(fallbackProp(contextSuffixIcon, <DownOutlined />));
|
||||
};
|
||||
}
|
||||
// Checked item icon
|
||||
let mergedItemIcon = null;
|
||||
if (menuItemSelectedIcon !== undefined) {
|
||||
mergedItemIcon = menuItemSelectedIcon;
|
||||
} else if (multiple) {
|
||||
mergedItemIcon = <CheckOutlined />;
|
||||
} else {
|
||||
mergedItemIcon = null;
|
||||
}
|
||||
|
||||
// Checked item icon
|
||||
let mergedItemIcon = null;
|
||||
if (menuItemSelectedIcon !== undefined) {
|
||||
mergedItemIcon = menuItemSelectedIcon;
|
||||
} else if (multiple) {
|
||||
mergedItemIcon = <CheckOutlined />;
|
||||
} else {
|
||||
mergedItemIcon = null;
|
||||
}
|
||||
let mergedRemoveIcon = null;
|
||||
if (removeIcon !== undefined) {
|
||||
mergedRemoveIcon = removeIcon;
|
||||
} else {
|
||||
mergedRemoveIcon = <CloseOutlined />;
|
||||
}
|
||||
|
||||
const mergedRemoveIcon = fallbackProp(removeIcon, contextRemoveIcon, <CloseOutlined />);
|
||||
|
||||
return {
|
||||
clearIcon: mergedClearIcon,
|
||||
suffixIcon: mergedSuffixIcon,
|
||||
itemIcon: mergedItemIcon,
|
||||
removeIcon: mergedRemoveIcon,
|
||||
};
|
||||
}, [
|
||||
suffixIcon,
|
||||
contextSuffixIcon,
|
||||
clearIcon,
|
||||
contextClearIcon,
|
||||
menuItemSelectedIcon,
|
||||
removeIcon,
|
||||
contextRemoveIcon,
|
||||
loading,
|
||||
loadingIcon,
|
||||
searchIcon,
|
||||
contextSearchIcon,
|
||||
multiple,
|
||||
hasFeedback,
|
||||
showSuffixIcon,
|
||||
feedbackIcon,
|
||||
showArrow,
|
||||
]);
|
||||
return {
|
||||
// TODO: remove as when all the deps bumped
|
||||
clearIcon: mergedClearIcon as React.ReactNode,
|
||||
suffixIcon: mergedSuffixIcon,
|
||||
itemIcon: mergedItemIcon,
|
||||
removeIcon: mergedRemoveIcon,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,14 +7,11 @@ export const InternalPanel = forwardRef<
|
||||
HTMLDivElement,
|
||||
React.PropsWithChildren<InternalPanelProps>
|
||||
>((props, ref) => {
|
||||
const { prefixCls, className, children, size, style = {}, supportMotion } = props;
|
||||
const { prefixCls, className, children, size, style = {} } = props;
|
||||
|
||||
const panelClassName = clsx(
|
||||
`${prefixCls}-panel`,
|
||||
{
|
||||
[`${prefixCls}-panel-hidden`]: size === 0,
|
||||
[`${prefixCls}-panel-transition`]: supportMotion,
|
||||
},
|
||||
{ [`${prefixCls}-panel-hidden`]: size === 0 },
|
||||
className,
|
||||
);
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ const Splitter: React.FC<React.PropsWithChildren<SplitterProps>> = (props) => {
|
||||
prefixCls: customizePrefixCls,
|
||||
className,
|
||||
classNames,
|
||||
collapsible,
|
||||
style,
|
||||
styles,
|
||||
layout,
|
||||
@@ -218,13 +217,9 @@ const Splitter: React.FC<React.PropsWithChildren<SplitterProps>> = (props) => {
|
||||
style: { ...mergedStyles.panel, ...item.style },
|
||||
};
|
||||
|
||||
// Panel
|
||||
const panel = (
|
||||
<InternalPanel
|
||||
{...panelProps}
|
||||
prefixCls={prefixCls}
|
||||
size={panelSizes[idx]}
|
||||
supportMotion={collapsible?.motion && movingIndex === undefined}
|
||||
/>
|
||||
<InternalPanel {...panelProps} prefixCls={prefixCls} size={panelSizes[idx]} />
|
||||
);
|
||||
|
||||
// Split Bar
|
||||
|
||||
@@ -4,40 +4,12 @@ exports[`renders components/splitter/demo/collapsible.tsx extend context correct
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-stretch ant-flex-gap-middle ant-flex-vertical"
|
||||
>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-gap-middle"
|
||||
>
|
||||
<button
|
||||
aria-checked="true"
|
||||
class="ant-switch css-var-test-id ant-switch-checked"
|
||||
role="switch"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="ant-switch-handle"
|
||||
/>
|
||||
<span
|
||||
class="ant-switch-inner"
|
||||
>
|
||||
<span
|
||||
class="ant-switch-inner-checked"
|
||||
>
|
||||
motion
|
||||
</span>
|
||||
<span
|
||||
class="ant-switch-inner-unchecked"
|
||||
>
|
||||
motion
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-splitter ant-splitter-horizontal css-var-test-id ant-splitter-css-var"
|
||||
style="box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); height: 200px;"
|
||||
>
|
||||
<div
|
||||
class="ant-splitter-panel ant-splitter-panel-transition"
|
||||
class="ant-splitter-panel"
|
||||
style="flex-basis: auto; flex-grow: 1;"
|
||||
>
|
||||
<div
|
||||
@@ -64,7 +36,7 @@ exports[`renders components/splitter/demo/collapsible.tsx extend context correct
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-splitter-panel ant-splitter-panel-transition"
|
||||
class="ant-splitter-panel"
|
||||
style="flex-basis: auto; flex-grow: 1;"
|
||||
>
|
||||
<div
|
||||
@@ -85,7 +57,7 @@ exports[`renders components/splitter/demo/collapsible.tsx extend context correct
|
||||
style="box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); height: 300px;"
|
||||
>
|
||||
<div
|
||||
class="ant-splitter-panel ant-splitter-panel-transition"
|
||||
class="ant-splitter-panel"
|
||||
style="flex-basis: auto; flex-grow: 1;"
|
||||
>
|
||||
<div
|
||||
@@ -112,7 +84,7 @@ exports[`renders components/splitter/demo/collapsible.tsx extend context correct
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-splitter-panel ant-splitter-panel-transition"
|
||||
class="ant-splitter-panel"
|
||||
style="flex-basis: auto; flex-grow: 1;"
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -4,40 +4,12 @@ exports[`renders components/splitter/demo/collapsible.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-stretch ant-flex-gap-middle ant-flex-vertical"
|
||||
>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-gap-middle"
|
||||
>
|
||||
<button
|
||||
aria-checked="true"
|
||||
class="ant-switch css-var-test-id ant-switch-checked"
|
||||
role="switch"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="ant-switch-handle"
|
||||
/>
|
||||
<span
|
||||
class="ant-switch-inner"
|
||||
>
|
||||
<span
|
||||
class="ant-switch-inner-checked"
|
||||
>
|
||||
motion
|
||||
</span>
|
||||
<span
|
||||
class="ant-switch-inner-unchecked"
|
||||
>
|
||||
motion
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-splitter ant-splitter-horizontal css-var-test-id ant-splitter-css-var"
|
||||
style="box-shadow:0 0 10px rgba(0, 0, 0, 0.1);height:200px"
|
||||
>
|
||||
<div
|
||||
class="ant-splitter-panel ant-splitter-panel-transition"
|
||||
class="ant-splitter-panel"
|
||||
style="flex-basis:auto;flex-grow:1"
|
||||
>
|
||||
<div
|
||||
@@ -64,7 +36,7 @@ exports[`renders components/splitter/demo/collapsible.tsx correctly 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-splitter-panel ant-splitter-panel-transition"
|
||||
class="ant-splitter-panel"
|
||||
style="flex-basis:auto;flex-grow:1"
|
||||
>
|
||||
<div
|
||||
@@ -85,7 +57,7 @@ exports[`renders components/splitter/demo/collapsible.tsx correctly 1`] = `
|
||||
style="box-shadow:0 0 10px rgba(0, 0, 0, 0.1);height:300px"
|
||||
>
|
||||
<div
|
||||
class="ant-splitter-panel ant-splitter-panel-transition"
|
||||
class="ant-splitter-panel"
|
||||
style="flex-basis:auto;flex-grow:1"
|
||||
>
|
||||
<div
|
||||
@@ -112,7 +84,7 @@ exports[`renders components/splitter/demo/collapsible.tsx correctly 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-splitter-panel ant-splitter-panel-transition"
|
||||
class="ant-splitter-panel"
|
||||
style="flex-basis:auto;flex-grow:1"
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -997,21 +997,6 @@ describe('Splitter', () => {
|
||||
expect(onCollapse).toHaveBeenCalledTimes(2);
|
||||
expect(onCollapse).toHaveBeenCalledWith([false, false], [50, 50]);
|
||||
});
|
||||
|
||||
it('should apply transition when motion is true', async () => {
|
||||
const { container } = render(
|
||||
<SplitterDemo
|
||||
items={[{ collapsible: true }, { collapsible: true }]}
|
||||
collapsible={{
|
||||
motion: true,
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(container.querySelector('.ant-splitter-panel')).toHaveClass(
|
||||
'ant-splitter-panel-transition',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('auto resize', async () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Flex, Splitter, Switch, Typography } from 'antd';
|
||||
import React from 'react';
|
||||
import { Flex, Splitter, Typography } from 'antd';
|
||||
import type { SplitterProps } from 'antd';
|
||||
|
||||
const Desc: React.FC<Readonly<{ text?: string | number }>> = (props) => (
|
||||
@@ -21,23 +21,11 @@ const CustomSplitter: React.FC<Readonly<SplitterProps>> = ({ style, ...restProps
|
||||
</Splitter>
|
||||
);
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [motion, setMotion] = useState(true);
|
||||
|
||||
return (
|
||||
<Flex vertical gap="middle">
|
||||
<Flex gap="middle">
|
||||
<Switch
|
||||
checked={motion}
|
||||
onChange={setMotion}
|
||||
checkedChildren="motion"
|
||||
unCheckedChildren="motion"
|
||||
/>
|
||||
</Flex>
|
||||
<CustomSplitter style={{ height: 200 }} collapsible={{ motion }} />
|
||||
<CustomSplitter style={{ height: 300 }} orientation="vertical" collapsible={{ motion }} />
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
const App: React.FC = () => (
|
||||
<Flex gap="middle" vertical>
|
||||
<CustomSplitter style={{ height: 200 }} />
|
||||
<CustomSplitter style={{ height: 300 }} orientation="vertical" />
|
||||
</Flex>
|
||||
);
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -44,7 +44,6 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| classNames | Customize class for each semantic structure inside the component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | |
|
||||
| collapsible | Collapse config. Set `motion: true` to enable collapse animation; duration is controlled by Component Token `panelMotionDuration` (inherits from `motionDurationSlow`) | `{ motion?: boolean }` | - | 6.4.0 |
|
||||
| collapsibleIcon | custom collapsible icon | `{start: ReactNode; end: ReactNode}` | - | 6.0.0 |
|
||||
| draggerIcon | custom dragger icon | `ReactNode` | - | 6.0.0 |
|
||||
| ~~layout~~ | Layout direction | `horizontal` \| `vertical` | `horizontal` | - |
|
||||
|
||||
@@ -45,7 +45,6 @@ demo:
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| classNames | 用于自定义组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | |
|
||||
| collapsible | 折叠配置。`motion: true` 时启用折叠动画,时长由组件 Token `panelMotionDuration` 控制(继承自 `motionDurationSlow`) | `{ motion?: boolean }` | - | 6.4.0 |
|
||||
| collapsibleIcon | 折叠图标 | `{start?: ReactNode; end?: ReactNode}` | - | 6.0.0 |
|
||||
| draggerIcon | 拖拽图标 | `ReactNode` | - | 6.0.0 |
|
||||
| ~~layout~~ | 布局方向 | `horizontal` \| `vertical` | `horizontal` | - |
|
||||
|
||||
@@ -46,10 +46,6 @@ export interface SplitterProps {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
classNames?: SplitterClassNamesType;
|
||||
/**
|
||||
* Collapse configuration. Set `motion: true` to enable collapse animation (duration follows Component Token).
|
||||
*/
|
||||
collapsible?: { motion?: boolean };
|
||||
style?: React.CSSProperties;
|
||||
styles?: SplitterStylesType;
|
||||
rootClassName?: string;
|
||||
@@ -91,7 +87,6 @@ export interface PanelProps {
|
||||
export interface InternalPanelProps extends PanelProps {
|
||||
className?: string;
|
||||
prefixCls?: string;
|
||||
supportMotion?: boolean;
|
||||
}
|
||||
|
||||
export interface UseResizeProps extends Pick<SplitterProps, 'onResize'> {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { CSSObject } from '@ant-design/cssinjs';
|
||||
|
||||
import { resetComponent } from '../../style';
|
||||
import { genNoMotionStyle } from '../../style/motion';
|
||||
import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal';
|
||||
import { genStyleHooks } from '../../theme/internal';
|
||||
import { genCssVar } from '../../theme/util/genStyleUtils';
|
||||
@@ -375,11 +374,6 @@ const genSplitterStyle: GenerateStyle<SplitterToken> = (token: SplitterToken): C
|
||||
[`&:has(${componentCls}:only-child)`]: {
|
||||
overflow: 'hidden',
|
||||
},
|
||||
|
||||
'&-transition': {
|
||||
transition: `flex-basis ${token.motionDurationSlow} ${token.motionEaseInOut}`,
|
||||
...genNoMotionStyle(),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { StepsProps } from 'antd';
|
||||
import { Button, Space, Steps } from 'antd';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [percent, setPercent] = useState<number | undefined>(0);
|
||||
const [percent, setPercentage] = useState<number | undefined>(0);
|
||||
const [current, setCurrent] = useState(1);
|
||||
const [status, setStatus] = useState<StepsProps['status']>('process');
|
||||
const content = 'This is a content.';
|
||||
@@ -25,10 +25,10 @@ const App: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<Space.Compact block>
|
||||
<Button onClick={() => setPercent(undefined)}>Percentage to undefined</Button>
|
||||
<Button onClick={() => setPercentage(undefined)}>Percentage to undefined</Button>
|
||||
<Button
|
||||
onClick={() =>
|
||||
setPercent((prev) => {
|
||||
setPercentage((prev) => {
|
||||
const next = (prev ?? 0) + 10;
|
||||
return next > 100 ? 0 : next;
|
||||
})
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
slideUpIn,
|
||||
slideUpOut,
|
||||
} from './slide';
|
||||
import { genNoMotionStyle } from './util';
|
||||
import {
|
||||
initZoomMotion,
|
||||
zoomBigIn,
|
||||
@@ -43,7 +42,6 @@ export {
|
||||
fadeIn,
|
||||
fadeOut,
|
||||
genCollapseMotion,
|
||||
genNoMotionStyle,
|
||||
initFadeMotion,
|
||||
initMoveMotion,
|
||||
initSlideMotion,
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import type { CSSObject } from '@ant-design/cssinjs';
|
||||
|
||||
export const genNoMotionStyle = (): CSSObject => {
|
||||
return {
|
||||
'@media (prefers-reduced-motion: reduce)': {
|
||||
transition: 'none',
|
||||
animation: 'none',
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -162,7 +162,6 @@ type ZoomMotionTypes =
|
||||
| 'zoom-right'
|
||||
| 'zoom-up'
|
||||
| 'zoom-down';
|
||||
|
||||
const zoomMotion: Record<ZoomMotionTypes, { inKeyframes: Keyframes; outKeyframes: Keyframes }> = {
|
||||
zoom: {
|
||||
inKeyframes: zoomIn,
|
||||
|
||||
@@ -3,7 +3,6 @@ import { unit } from '@ant-design/cssinjs';
|
||||
import { FastColor } from '@ant-design/fast-color';
|
||||
|
||||
import { genFocusStyle, resetComponent } from '../../style';
|
||||
import { genNoMotionStyle } from '../../style/motion';
|
||||
import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal';
|
||||
import { genStyleHooks, mergeToken } from '../../theme/internal';
|
||||
|
||||
@@ -209,7 +208,6 @@ const genSwitchHandleStyle: GenerateStyle<SwitchToken, CSSObject> = (token) => {
|
||||
width: handleSize,
|
||||
height: handleSize,
|
||||
transition: `all ${token.switchDuration} ease-in-out`,
|
||||
...genNoMotionStyle(),
|
||||
|
||||
'&::before': {
|
||||
position: 'absolute',
|
||||
@@ -222,7 +220,6 @@ const genSwitchHandleStyle: GenerateStyle<SwitchToken, CSSObject> = (token) => {
|
||||
boxShadow: handleShadow,
|
||||
transition: `all ${token.switchDuration} ease-in-out`,
|
||||
content: '""',
|
||||
...genNoMotionStyle(),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -273,7 +270,7 @@ const genSwitchInnerStyle: GenerateStyle<SwitchToken, CSSObject> = (token) => {
|
||||
transition: [`padding-inline-start`, `padding-inline-end`]
|
||||
.map((prop) => `${prop} ${switchDuration} ease-in-out`)
|
||||
.join(', '),
|
||||
...genNoMotionStyle(),
|
||||
|
||||
[`${switchInnerCls}-checked, ${switchInnerCls}-unchecked`]: {
|
||||
display: 'block',
|
||||
color: token.colorTextLightSolid,
|
||||
@@ -283,7 +280,6 @@ const genSwitchInnerStyle: GenerateStyle<SwitchToken, CSSObject> = (token) => {
|
||||
transition: [`margin-inline-start`, `margin-inline-end`]
|
||||
.map((prop) => `${prop} ${switchDuration} ease-in-out`)
|
||||
.join(', '),
|
||||
...genNoMotionStyle(),
|
||||
},
|
||||
|
||||
[`${switchInnerCls}-checked`]: {
|
||||
@@ -351,7 +347,7 @@ const genSwitchStyle = (token: SwitchToken): CSSObject => {
|
||||
cursor: 'pointer',
|
||||
transition: `all ${token.motionDurationMid}`,
|
||||
userSelect: 'none',
|
||||
...genNoMotionStyle(),
|
||||
|
||||
[`&:hover:not(${componentCls}-disabled)`]: {
|
||||
background: token.colorTextTertiary,
|
||||
},
|
||||
|
||||
@@ -2010,7 +2010,7 @@ describe('Table.filter', () => {
|
||||
];
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [data, setData] = React.useState<Array<DataType>>([
|
||||
const [ddd, setData] = React.useState<Array<DataType>>([
|
||||
{
|
||||
key: '1',
|
||||
name: 'John Brown',
|
||||
@@ -2089,7 +2089,7 @@ describe('Table.filter', () => {
|
||||
<span className="rest-btn" onClick={handleClick}>
|
||||
refresh
|
||||
</span>
|
||||
<Table columns={cs} dataSource={data} />
|
||||
<Table columns={cs} dataSource={ddd} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -295,7 +295,7 @@ const FilterDropdown = <RecordType extends AnyObject = AnyObject>(
|
||||
setSearchValue('');
|
||||
|
||||
if (filterResetToDefaultFilteredValue) {
|
||||
setFilteredKeysSync((defaultFilteredValue || []).map<string>(String));
|
||||
setFilteredKeysSync((defaultFilteredValue || []).map((key) => String(key)));
|
||||
} else {
|
||||
setFilteredKeysSync([]);
|
||||
}
|
||||
@@ -330,7 +330,7 @@ const FilterDropdown = <RecordType extends AnyObject = AnyObject>(
|
||||
|
||||
const onCheckAll = (e: CheckboxChangeEvent) => {
|
||||
if (e.target.checked) {
|
||||
const allFilterKeys = flattenKeys(column?.filters).map<string>(String);
|
||||
const allFilterKeys = flattenKeys(column?.filters).map((key) => String(key));
|
||||
setFilteredKeysSync(allFilterKeys);
|
||||
} else {
|
||||
setFilteredKeysSync([]);
|
||||
@@ -349,12 +349,11 @@ const FilterDropdown = <RecordType extends AnyObject = AnyObject>(
|
||||
}
|
||||
return item;
|
||||
});
|
||||
|
||||
const getFilterData = (node: FilterTreeDataNode): TreeColumnFilterItem => ({
|
||||
...node,
|
||||
text: node.title,
|
||||
value: node.key,
|
||||
children: node.children?.map<TreeColumnFilterItem>(getFilterData) || [],
|
||||
children: node.children?.map((item) => getFilterData(item)) || [],
|
||||
});
|
||||
|
||||
let dropdownContent: React.ReactNode;
|
||||
@@ -492,8 +491,13 @@ const FilterDropdown = <RecordType extends AnyObject = AnyObject>(
|
||||
|
||||
const getResetDisabled = () => {
|
||||
if (filterResetToDefaultFilteredValue) {
|
||||
return isEqual((defaultFilteredValue || []).map<string>(String), selectedKeys, true);
|
||||
return isEqual(
|
||||
(defaultFilteredValue || []).map((key) => String(key)),
|
||||
selectedKeys,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
return selectedKeys.length === 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -275,7 +275,7 @@ const useSelection = <RecordType extends AnyObject = AnyObject>(
|
||||
const triggerSingleSelection = useCallback(
|
||||
(key: Key, selected: boolean, keys: Key[], event: Event) => {
|
||||
if (onSelect) {
|
||||
const rows = keys.map<RecordType>(getRecordByKey);
|
||||
const rows = keys.map((k) => getRecordByKey(k));
|
||||
onSelect(getRecordByKey(key), selected, rows, event);
|
||||
}
|
||||
|
||||
@@ -426,8 +426,8 @@ const useSelection = <RecordType extends AnyObject = AnyObject>(
|
||||
|
||||
onSelectAll?.(
|
||||
!checkedCurrentAll,
|
||||
keys.map<RecordType>(getRecordByKey),
|
||||
changeKeys.map<RecordType>(getRecordByKey),
|
||||
keys.map((k) => getRecordByKey(k)),
|
||||
changeKeys.map((k) => getRecordByKey(k)),
|
||||
);
|
||||
|
||||
setSelectedKeys(keys, 'all');
|
||||
@@ -584,8 +584,8 @@ const useSelection = <RecordType extends AnyObject = AnyObject>(
|
||||
|
||||
onSelectMultiple?.(
|
||||
!checked,
|
||||
keys.map<RecordType>(getRecordByKey),
|
||||
changedKeys.map<RecordType>(getRecordByKey),
|
||||
keys.map((recordKey) => getRecordByKey(recordKey)),
|
||||
changedKeys.map((recordKey) => getRecordByKey(recordKey)),
|
||||
);
|
||||
|
||||
setSelectedKeys(keys, 'multiple');
|
||||
|
||||
@@ -128,7 +128,7 @@ describe('Tour', () => {
|
||||
it('button props onClick', () => {
|
||||
const App: React.FC = () => {
|
||||
const coverBtnRef = useRef<HTMLButtonElement>(null);
|
||||
const [btnName, setBtnName] = React.useState<string>('defaultBtn');
|
||||
const [btnName, steBtnName] = React.useState<string>('defaultBtn');
|
||||
return (
|
||||
<>
|
||||
<span id="btnName">{btnName}</span>
|
||||
@@ -143,17 +143,17 @@ describe('Tour', () => {
|
||||
description: '',
|
||||
target: () => coverBtnRef.current!,
|
||||
nextButtonProps: {
|
||||
onClick: () => setBtnName('nextButton'),
|
||||
onClick: () => steBtnName('nextButton'),
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
target: () => coverBtnRef.current!,
|
||||
prevButtonProps: {
|
||||
onClick: () => setBtnName('prevButton'),
|
||||
onClick: () => steBtnName('prevButton'),
|
||||
},
|
||||
nextButtonProps: {
|
||||
onClick: () => setBtnName('finishButton'),
|
||||
onClick: () => steBtnName('finishButton'),
|
||||
},
|
||||
},
|
||||
]}
|
||||
|
||||
@@ -229,7 +229,6 @@ const Transfer = <RecordType extends TransferItem = TransferItem>(
|
||||
const [hashId, cssVarCls] = useStyle(prefixCls);
|
||||
|
||||
const mergedActions = actions || operations || [];
|
||||
const isRtl = dir === 'rtl';
|
||||
|
||||
// Fill record with `key`
|
||||
const [mergedDataSource, leftDataSource, rightDataSource] = useData(
|
||||
@@ -335,7 +334,7 @@ const Transfer = <RecordType extends TransferItem = TransferItem>(
|
||||
|
||||
const onItemSelectAll = (
|
||||
direction: TransferDirection,
|
||||
keys: TransferKey[],
|
||||
keys: string[],
|
||||
checkAll: boolean | 'replace',
|
||||
) => {
|
||||
setStateKeys(direction, (prevKeys) => {
|
||||
@@ -356,15 +355,13 @@ const Transfer = <RecordType extends TransferItem = TransferItem>(
|
||||
setPrevSelectedIndex(direction, null);
|
||||
};
|
||||
|
||||
const onLeftItemSelectAll: TransferListProps<KeyWise<RecordType>>['onItemSelectAll'] = (
|
||||
keys,
|
||||
checkAll,
|
||||
) => onItemSelectAll('left', keys, checkAll);
|
||||
const onLeftItemSelectAll = (keys: string[], checkAll: boolean) => {
|
||||
onItemSelectAll('left', keys, checkAll);
|
||||
};
|
||||
|
||||
const onRightItemSelectAll: TransferListProps<KeyWise<RecordType>>['onItemSelectAll'] = (
|
||||
keys,
|
||||
checkAll,
|
||||
) => onItemSelectAll('right', keys, checkAll);
|
||||
const onRightItemSelectAll = (keys: string[], checkAll: boolean) => {
|
||||
onItemSelectAll('right', keys, checkAll);
|
||||
};
|
||||
|
||||
const leftFilter = (e: ChangeEvent<HTMLInputElement>) => onSearch?.('left', e.target.value);
|
||||
|
||||
@@ -410,15 +407,15 @@ const Transfer = <RecordType extends TransferItem = TransferItem>(
|
||||
multiple?: boolean,
|
||||
) => {
|
||||
const isLeftDirection = direction === 'left';
|
||||
const holder = isLeftDirection ? sourceSelectedKeys : targetSelectedKeys;
|
||||
const holder = [...(isLeftDirection ? sourceSelectedKeys : targetSelectedKeys)];
|
||||
const holderSet = new Set(holder);
|
||||
const data: KeyWise<RecordType>[] = (isLeftDirection ? leftDataSource : rightDataSource).filter(
|
||||
(item): item is KeyWise<RecordType> => !item.disabled,
|
||||
const data = [...(isLeftDirection ? leftDataSource : rightDataSource)].filter(
|
||||
(item) => !item?.disabled,
|
||||
);
|
||||
const currentSelectedIndex = data.findIndex((item) => item.key === selectedKey);
|
||||
// multiple select by hold down the shift key
|
||||
if (multiple && holder.length > 0) {
|
||||
handleMultipleSelect(direction, data, holderSet, currentSelectedIndex);
|
||||
handleMultipleSelect(direction, data as any, holderSet, currentSelectedIndex);
|
||||
} else {
|
||||
handleSingleSelect(direction, holderSet, selectedKey, checked, currentSelectedIndex);
|
||||
}
|
||||
@@ -437,11 +434,13 @@ const Transfer = <RecordType extends TransferItem = TransferItem>(
|
||||
onItemSelect('left', selectedKey, checked, e?.shiftKey);
|
||||
};
|
||||
|
||||
const onRightItemSelect: TransferListProps<KeyWise<RecordType>>['onItemSelect'] = (
|
||||
selectedKey,
|
||||
checked,
|
||||
e,
|
||||
) => onItemSelect('right', selectedKey, checked, e?.shiftKey);
|
||||
const onRightItemSelect = (
|
||||
selectedKey: TransferKey,
|
||||
checked: boolean,
|
||||
e?: React.MouseEvent<Element, MouseEvent>,
|
||||
) => {
|
||||
onItemSelect('right', selectedKey, checked, e?.shiftKey);
|
||||
};
|
||||
|
||||
const onRightItemRemove = (keys: TransferKey[]) => {
|
||||
setStateKeys('right', []);
|
||||
@@ -494,7 +493,7 @@ const Transfer = <RecordType extends TransferItem = TransferItem>(
|
||||
{
|
||||
[`${prefixCls}-disabled`]: mergedDisabled,
|
||||
[`${prefixCls}-customize-list`]: !!children,
|
||||
[`${prefixCls}-rtl`]: isRtl,
|
||||
[`${prefixCls}-rtl`]: dir === 'rtl',
|
||||
},
|
||||
getStatusClassNames(prefixCls, mergedStatus, hasFeedback),
|
||||
contextClassName,
|
||||
@@ -544,14 +543,14 @@ const Transfer = <RecordType extends TransferItem = TransferItem>(
|
||||
handleFilter={leftFilter}
|
||||
handleClear={handleLeftClear}
|
||||
onItemSelect={onLeftItemSelect}
|
||||
onItemSelectAll={onLeftItemSelectAll}
|
||||
onItemSelectAll={onLeftItemSelectAll as any}
|
||||
render={render}
|
||||
showSearch={showSearch}
|
||||
renderList={children as any}
|
||||
footer={footer as any}
|
||||
onScroll={handleLeftScroll}
|
||||
disabled={mergedDisabled}
|
||||
direction={isRtl ? 'right' : 'left'}
|
||||
direction={dir === 'rtl' ? 'right' : 'left'}
|
||||
showSelectAll={showSelectAll}
|
||||
selectAllLabel={selectAllLabels[0]}
|
||||
pagination={mergedPagination}
|
||||
@@ -585,7 +584,7 @@ const Transfer = <RecordType extends TransferItem = TransferItem>(
|
||||
handleFilter={rightFilter}
|
||||
handleClear={handleRightClear}
|
||||
onItemSelect={onRightItemSelect}
|
||||
onItemSelectAll={onRightItemSelectAll}
|
||||
onItemSelectAll={onRightItemSelectAll as any}
|
||||
onItemRemove={onRightItemRemove}
|
||||
render={render}
|
||||
showSearch={showSearch}
|
||||
@@ -593,7 +592,7 @@ const Transfer = <RecordType extends TransferItem = TransferItem>(
|
||||
footer={footer as any}
|
||||
onScroll={handleRightScroll}
|
||||
disabled={mergedDisabled}
|
||||
direction={isRtl ? 'left' : 'right'}
|
||||
direction={dir === 'rtl' ? 'left' : 'right'}
|
||||
showSelectAll={showSelectAll}
|
||||
selectAllLabel={selectAllLabels[1]}
|
||||
showRemove={oneWay}
|
||||
|
||||
@@ -37,10 +37,10 @@ const treeData = [
|
||||
},
|
||||
];
|
||||
const App: React.FC = () => {
|
||||
const [placement, setPlacement] = useState<SelectCommonPlacement>('topLeft');
|
||||
const [placement, SetPlacement] = useState<SelectCommonPlacement>('topLeft');
|
||||
|
||||
const placementChange = (e: RadioChangeEvent) => {
|
||||
setPlacement(e.target.value);
|
||||
SetPlacement(e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -280,12 +280,6 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject =>
|
||||
.equal(),
|
||||
},
|
||||
|
||||
// >>> Checkbox
|
||||
// https://github.com/ant-design/ant-design/issues/56957
|
||||
[`${treeCls}-checkbox`]: {
|
||||
flexShrink: 0,
|
||||
},
|
||||
|
||||
// >>> Switcher
|
||||
[`${treeCls}-switcher`]: {
|
||||
...getSwitchStyle(prefixCls, token),
|
||||
|
||||
@@ -16,6 +16,8 @@ export interface CopyBtnProps extends Omit<CopyConfig, 'onCopy'> {
|
||||
onCopy: React.MouseEventHandler<HTMLButtonElement>;
|
||||
iconOnly: boolean;
|
||||
loading: boolean;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
const CopyBtn: React.FC<CopyBtnProps> = ({
|
||||
@@ -28,6 +30,8 @@ const CopyBtn: React.FC<CopyBtnProps> = ({
|
||||
tabIndex,
|
||||
onCopy,
|
||||
loading: btnLoading,
|
||||
className,
|
||||
style,
|
||||
}) => {
|
||||
const tooltipNodes = toList(tooltips);
|
||||
const iconNodes = toList(icon);
|
||||
@@ -40,10 +44,11 @@ const CopyBtn: React.FC<CopyBtnProps> = ({
|
||||
<Tooltip title={copyTitle}>
|
||||
<button
|
||||
type="button"
|
||||
className={clsx(`${prefixCls}-copy`, {
|
||||
className={clsx(`${prefixCls}-copy`, className, {
|
||||
[`${prefixCls}-copy-success`]: copied,
|
||||
[`${prefixCls}-copy-icon-only`]: iconOnly,
|
||||
})}
|
||||
style={style}
|
||||
onClick={onCopy}
|
||||
aria-label={ariaLabel}
|
||||
tabIndex={tabIndex}
|
||||
|
||||
@@ -8,9 +8,10 @@ import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect';
|
||||
import { composeRef } from '@rc-component/util/lib/ref';
|
||||
import { clsx } from 'clsx';
|
||||
|
||||
import type { SemanticType } from '../../_util/hooks';
|
||||
import isNonNullable from '../../_util/isNonNullable';
|
||||
import { isStyleSupport } from '../../_util/styleChecker';
|
||||
import { ConfigContext } from '../../config-provider';
|
||||
import type { DirectionType } from '../../config-provider';
|
||||
import useLocale from '../../locale/useLocale';
|
||||
import type { TooltipProps } from '../../tooltip';
|
||||
import Tooltip from '../../tooltip';
|
||||
@@ -19,6 +20,7 @@ import useCopyClick from '../hooks/useCopyClick';
|
||||
import useMergedConfig from '../hooks/useMergedConfig';
|
||||
import usePrevious from '../hooks/usePrevious';
|
||||
import useTooltipProps from '../hooks/useTooltipProps';
|
||||
import { useTypographySemantic } from '../hooks/useTypographySemantic';
|
||||
import type { TypographyProps } from '../Typography';
|
||||
import Typography from '../Typography';
|
||||
import CopyBtn from './CopyBtn';
|
||||
@@ -28,6 +30,41 @@ import { isEleEllipsis, isValidText } from './util';
|
||||
|
||||
export type BaseType = 'secondary' | 'success' | 'warning' | 'danger';
|
||||
|
||||
// Base typography props without generic parameter for semantic types
|
||||
export interface BaseTypographyProps extends React.HTMLAttributes<HTMLElement> {
|
||||
id?: string;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
rootClassName?: string;
|
||||
style?: React.CSSProperties;
|
||||
classNames?: TypographyClassNamesType;
|
||||
styles?: TypographyStylesType;
|
||||
children?: React.ReactNode;
|
||||
'aria-label'?: string;
|
||||
direction?: DirectionType;
|
||||
/** @private */
|
||||
component?: keyof JSX.IntrinsicElements;
|
||||
}
|
||||
|
||||
export type TypographySemanticClassNames = {
|
||||
root?: string;
|
||||
actions?: string;
|
||||
action?: string;
|
||||
};
|
||||
|
||||
export type TypographySemanticStyles = {
|
||||
root?: React.CSSProperties;
|
||||
actions?: React.CSSProperties;
|
||||
action?: React.CSSProperties;
|
||||
};
|
||||
|
||||
export type TypographyClassNamesType = SemanticType<
|
||||
BaseTypographyProps,
|
||||
TypographySemanticClassNames
|
||||
>;
|
||||
|
||||
export type TypographyStylesType = SemanticType<BaseTypographyProps, TypographySemanticStyles>;
|
||||
|
||||
export interface CopyConfig {
|
||||
text?: string | (() => string | Promise<string>);
|
||||
onCopy?: (event?: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
@@ -65,9 +102,8 @@ export interface EllipsisConfig {
|
||||
tooltip?: React.ReactNode | TooltipProps;
|
||||
}
|
||||
|
||||
export interface BlockProps<
|
||||
C extends keyof JSX.IntrinsicElements = keyof JSX.IntrinsicElements,
|
||||
> extends TypographyProps<C> {
|
||||
export interface BlockProps<C extends keyof JSX.IntrinsicElements = keyof JSX.IntrinsicElements>
|
||||
extends TypographyProps<C> {
|
||||
title?: string;
|
||||
editable?: boolean | EditConfig;
|
||||
copyable?: boolean | CopyConfig;
|
||||
@@ -126,6 +162,9 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
||||
prefixCls: customizePrefixCls,
|
||||
className,
|
||||
style,
|
||||
classNames,
|
||||
styles,
|
||||
direction: typographyDirection,
|
||||
type,
|
||||
disabled,
|
||||
children,
|
||||
@@ -138,14 +177,18 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
||||
onMouseLeave,
|
||||
...restProps
|
||||
} = props;
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
const [textLocale] = useLocale('Text');
|
||||
|
||||
const typographyRef = React.useRef<HTMLElement>(null);
|
||||
const editIconRef = React.useRef<HTMLButtonElement>(null);
|
||||
|
||||
// ============================ MISC ============================
|
||||
const prefixCls = getPrefixCls('typography', customizePrefixCls);
|
||||
const [mergedClassNames, mergedStyles, prefixCls, direction] = useTypographySemantic(
|
||||
customizePrefixCls,
|
||||
classNames,
|
||||
styles,
|
||||
typographyDirection,
|
||||
props,
|
||||
);
|
||||
|
||||
const textProps = omit(restProps, DECORATION_PROPS);
|
||||
|
||||
@@ -356,7 +399,11 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
||||
<button
|
||||
type="button"
|
||||
key="expand"
|
||||
className={`${prefixCls}-${expanded ? 'collapse' : 'expand'}`}
|
||||
className={clsx(
|
||||
`${prefixCls}-${expanded ? 'collapse' : 'expand'}`,
|
||||
mergedClassNames.action,
|
||||
)}
|
||||
style={mergedStyles.action}
|
||||
onClick={(e) => onExpandClick(e!, { expanded: !expanded })}
|
||||
aria-label={expanded ? textLocale.collapse : textLocale?.expand}
|
||||
>
|
||||
@@ -381,7 +428,8 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
||||
<button
|
||||
type="button"
|
||||
ref={editIconRef}
|
||||
className={`${prefixCls}-edit`}
|
||||
className={clsx(`${prefixCls}-edit`, mergedClassNames.action)}
|
||||
style={mergedStyles.action}
|
||||
onClick={onEditClick}
|
||||
aria-label={ariaLabel}
|
||||
tabIndex={tabIndex}
|
||||
@@ -408,6 +456,8 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
||||
onCopy={onCopyClick}
|
||||
loading={copyLoading}
|
||||
iconOnly={!isNonNullable(children)}
|
||||
className={mergedClassNames.action}
|
||||
style={mergedStyles.action}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -424,7 +474,8 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
||||
return (
|
||||
<span
|
||||
key="operations"
|
||||
className={`${prefixCls}-actions`}
|
||||
className={clsx(`${prefixCls}-actions`, mergedClassNames.actions)}
|
||||
style={mergedStyles.actions}
|
||||
onMouseEnter={() => setIsHoveringOperations(true)}
|
||||
onMouseLeave={() => setIsHoveringOperations(false)}
|
||||
>
|
||||
@@ -474,6 +525,8 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
||||
},
|
||||
className,
|
||||
)}
|
||||
classNames={classNames}
|
||||
styles={styles}
|
||||
prefixCls={customizePrefixCls}
|
||||
style={{
|
||||
...style,
|
||||
|
||||
@@ -3,77 +3,120 @@ import type { JSX } from 'react';
|
||||
import { clsx } from 'clsx';
|
||||
|
||||
import type { DirectionType } from '../config-provider';
|
||||
import { useComponentConfig } from '../config-provider/context';
|
||||
import type {
|
||||
BaseTypographyProps,
|
||||
TypographySemanticClassNames,
|
||||
TypographySemanticStyles,
|
||||
} from './Base';
|
||||
import { useTypographySemantic } from './hooks/useTypographySemantic';
|
||||
import useStyle from './style';
|
||||
|
||||
export interface TypographyProps<C extends keyof JSX.IntrinsicElements>
|
||||
extends React.HTMLAttributes<HTMLElement> {
|
||||
id?: string;
|
||||
prefixCls?: string;
|
||||
extends BaseTypographyProps {
|
||||
/** @internal */
|
||||
component?: C;
|
||||
}
|
||||
|
||||
interface InternalProps {
|
||||
className?: string;
|
||||
rootClassName?: string;
|
||||
style?: React.CSSProperties;
|
||||
children?: React.ReactNode;
|
||||
/** @internal */
|
||||
component?: C;
|
||||
'aria-label'?: string;
|
||||
component?: keyof JSX.IntrinsicElements;
|
||||
direction?: DirectionType;
|
||||
classNames?: TypographySemanticClassNames;
|
||||
styles?: TypographySemanticStyles;
|
||||
prefixCls: string;
|
||||
}
|
||||
|
||||
interface InternalTypographyProps<C extends keyof JSX.IntrinsicElements>
|
||||
extends TypographyProps<C> {}
|
||||
|
||||
const Typography = React.forwardRef<
|
||||
HTMLElement,
|
||||
InternalTypographyProps<keyof JSX.IntrinsicElements>
|
||||
>((props, ref) => {
|
||||
const InternalTypography = React.forwardRef<HTMLElement, InternalProps>((props, ref) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
component: Component = 'article',
|
||||
className,
|
||||
rootClassName,
|
||||
children,
|
||||
direction: typographyDirection,
|
||||
direction,
|
||||
style,
|
||||
classNames,
|
||||
styles,
|
||||
prefixCls,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
const {
|
||||
getPrefixCls,
|
||||
direction: contextDirection,
|
||||
className: contextClassName,
|
||||
style: contextStyle,
|
||||
} = useComponentConfig('typography');
|
||||
|
||||
const direction = typographyDirection ?? contextDirection;
|
||||
const prefixCls = getPrefixCls('typography', customizePrefixCls);
|
||||
|
||||
// Style
|
||||
const [hashId, cssVarCls] = useStyle(prefixCls);
|
||||
|
||||
const componentClassName = clsx(
|
||||
prefixCls,
|
||||
contextClassName,
|
||||
hashId,
|
||||
cssVarCls,
|
||||
{
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
},
|
||||
className,
|
||||
rootClassName,
|
||||
hashId,
|
||||
cssVarCls,
|
||||
classNames?.root,
|
||||
);
|
||||
|
||||
const mergedStyle: React.CSSProperties = { ...contextStyle, ...style };
|
||||
const mergedStyle: React.CSSProperties = {
|
||||
...styles?.root,
|
||||
...style,
|
||||
};
|
||||
|
||||
return (
|
||||
// @ts-expect-error: Expression produces a union type that is too complex to represent.
|
||||
<Component className={componentClassName} style={mergedStyle} ref={ref} {...restProps}>
|
||||
<Component {...restProps} className={componentClassName} style={mergedStyle} ref={ref}>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
InternalTypography.displayName = 'InternalTypography';
|
||||
}
|
||||
|
||||
const Typography = React.forwardRef<HTMLElement, TypographyProps<keyof JSX.IntrinsicElements>>(
|
||||
(props, ref) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
className,
|
||||
rootClassName,
|
||||
children,
|
||||
direction: typographyDirection,
|
||||
style,
|
||||
classNames,
|
||||
styles,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
const [mergedClassNames, mergedStyles, prefixCls, direction] = useTypographySemantic(
|
||||
customizePrefixCls,
|
||||
classNames,
|
||||
styles,
|
||||
typographyDirection,
|
||||
props,
|
||||
);
|
||||
|
||||
return (
|
||||
<InternalTypography
|
||||
ref={ref}
|
||||
component="article"
|
||||
className={clsx(className, rootClassName)}
|
||||
direction={direction}
|
||||
style={style}
|
||||
classNames={mergedClassNames}
|
||||
styles={mergedStyles}
|
||||
prefixCls={prefixCls}
|
||||
{...restProps}
|
||||
>
|
||||
{children}
|
||||
</InternalTypography>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
Typography.displayName = 'Typography';
|
||||
}
|
||||
|
||||
export default Typography;
|
||||
export { InternalTypography };
|
||||
|
||||
@@ -59,7 +59,7 @@ exports[`renders components/typography/demo/basic.tsx extend context correctly 1
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/proximity"
|
||||
>
|
||||
Principles
|
||||
@@ -67,7 +67,7 @@ exports[`renders components/typography/demo/basic.tsx extend context correctly 1
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/overview"
|
||||
>
|
||||
Patterns
|
||||
@@ -75,7 +75,7 @@ exports[`renders components/typography/demo/basic.tsx extend context correctly 1
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/resources"
|
||||
>
|
||||
Resource Download
|
||||
@@ -163,7 +163,7 @@ exports[`renders components/typography/demo/basic.tsx extend context correctly 1
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/proximity-cn"
|
||||
>
|
||||
设计原则
|
||||
@@ -171,7 +171,7 @@ exports[`renders components/typography/demo/basic.tsx extend context correctly 1
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/overview-cn"
|
||||
>
|
||||
设计模式
|
||||
@@ -179,7 +179,7 @@ exports[`renders components/typography/demo/basic.tsx extend context correctly 1
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/resources-cn"
|
||||
>
|
||||
设计资源
|
||||
@@ -272,7 +272,7 @@ Array [
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/proximity"
|
||||
>
|
||||
Principles
|
||||
@@ -280,7 +280,7 @@ Array [
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/overview"
|
||||
>
|
||||
Patterns
|
||||
@@ -288,7 +288,7 @@ Array [
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/resources"
|
||||
>
|
||||
Resource Download
|
||||
@@ -371,7 +371,7 @@ Array [
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/proximity-cn"
|
||||
>
|
||||
设计原则
|
||||
@@ -379,7 +379,7 @@ Array [
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/overview-cn"
|
||||
>
|
||||
设计模式
|
||||
@@ -387,7 +387,7 @@ Array [
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/resources-cn"
|
||||
>
|
||||
设计资源
|
||||
@@ -422,17 +422,17 @@ Array [
|
||||
</div>
|
||||
</article>,
|
||||
<span
|
||||
class="ant-typography ant-typography-success css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-success"
|
||||
>
|
||||
Success but red
|
||||
</span>,
|
||||
<span
|
||||
class="ant-typography ant-typography-warning css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-warning"
|
||||
>
|
||||
Warning but green
|
||||
</span>,
|
||||
<span
|
||||
class="ant-typography ant-typography-danger css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-danger"
|
||||
>
|
||||
Danger but blue
|
||||
</span>,
|
||||
@@ -834,7 +834,7 @@ Array [
|
||||
</div>,
|
||||
<div
|
||||
aria-label="This is a loooooooooooooooooooooooooooooooong editable text with suffix."
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
>
|
||||
This is a loooooooooooooooooooooooooooooooong editable text with suffix.
|
||||
<span
|
||||
@@ -1588,20 +1588,20 @@ Array [
|
||||
</span>
|
||||
</button>,
|
||||
<div
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
>
|
||||
Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team.
|
||||
</div>,
|
||||
<div
|
||||
aria-label="Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team."
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
style=""
|
||||
>
|
||||
Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team.
|
||||
</div>,
|
||||
<span
|
||||
aria-describedby="test-id"
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="width: 200px;"
|
||||
>
|
||||
Ant Design, a design language for background applications, is refined by Ant UED Team.
|
||||
@@ -1628,7 +1628,7 @@ Array [
|
||||
</div>,
|
||||
<span
|
||||
aria-describedby="test-id"
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="width: 200px;"
|
||||
>
|
||||
<code>
|
||||
@@ -1740,7 +1740,7 @@ exports[`renders components/typography/demo/ellipsis-controlled.tsx extend conte
|
||||
</div>
|
||||
<div
|
||||
aria-label="Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team."
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
style=""
|
||||
>
|
||||
Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.
|
||||
@@ -1931,7 +1931,7 @@ Array [
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
>
|
||||
Ant Design, a design language for background applications, is refined by Ant UED Team. This is a nest sample
|
||||
<span
|
||||
@@ -1949,7 +1949,7 @@ Array [
|
||||
</div>,
|
||||
<span
|
||||
aria-label="In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development."
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
style="max-width: 400px; font-size: 24px;"
|
||||
>
|
||||
In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development.
|
||||
@@ -2007,7 +2007,7 @@ Array [
|
||||
<br />,
|
||||
<span
|
||||
aria-label="In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development."
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
style="max-width: 400px; font-size: 12px;"
|
||||
>
|
||||
In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development.
|
||||
@@ -2065,7 +2065,7 @@ Array [
|
||||
<br />,
|
||||
<span
|
||||
aria-label="In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development."
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
style="width: 400px; font-size: 24px;"
|
||||
>
|
||||
In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development.
|
||||
@@ -2123,7 +2123,7 @@ Array [
|
||||
<br />,
|
||||
<span
|
||||
aria-label="Ant Design is a design language for background applications, is refined by Ant UED Team."
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
style="width: 100px;"
|
||||
>
|
||||
Ant Design is a design language for background applications, is refined by Ant UED Team.
|
||||
@@ -2181,7 +2181,7 @@ Array [
|
||||
<p>
|
||||
[Before]
|
||||
<span
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
>
|
||||
not ellipsis
|
||||
</span>
|
||||
@@ -2192,7 +2192,7 @@ Array [
|
||||
>
|
||||
<span
|
||||
aria-describedby="test-id"
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="width: 100px;"
|
||||
>
|
||||
默认 display none 样式的超长文字, 悬停 tooltip 失效了
|
||||
@@ -2219,7 +2219,7 @@ Array [
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
style="width: 300px;"
|
||||
>
|
||||
In the process of internal desktop applications development,
|
||||
@@ -2238,7 +2238,7 @@ Array [
|
||||
- render like this
|
||||
- and this
|
||||
and that"
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
style=""
|
||||
>
|
||||
this is a multiline
|
||||
@@ -2252,7 +2252,7 @@ Array [
|
||||
<br />,
|
||||
<span
|
||||
aria-label="In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development."
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
style="width: 100px; white-space: nowrap;"
|
||||
>
|
||||
In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development.
|
||||
@@ -2326,7 +2326,7 @@ Array [
|
||||
<span
|
||||
aria-describedby="test-id"
|
||||
aria-label="In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development."
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
style="width: 280px; display: block;"
|
||||
>
|
||||
In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development.
|
||||
@@ -2410,7 +2410,7 @@ exports[`renders components/typography/demo/ellipsis-debug.tsx extend context co
|
||||
exports[`renders components/typography/demo/ellipsis-middle.tsx extend context correctly 1`] = `
|
||||
<span
|
||||
aria-label="In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of "
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
style="max-width: 100%;"
|
||||
>
|
||||
In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development.
|
||||
@@ -2430,7 +2430,7 @@ exports[`renders components/typography/demo/link-danger-debug.tsx extend context
|
||||
</span>
|
||||
<br />
|
||||
<a
|
||||
class="ant-typography ant-typography-danger ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-danger ant-typography-link"
|
||||
href="https://ant.design"
|
||||
>
|
||||
Danger Link
|
||||
@@ -2713,7 +2713,7 @@ Array [
|
||||
</div>,
|
||||
<div
|
||||
aria-label="To be, or not to be, that is the question: Whether it is nobler in the mind to suffer. The slings and arrows of outrageous fortune Or to take arms against a sea of troubles, And by opposing end them? To die: to sleep; No more; and by a sleep to say we end The heart-ache and the thousand natural shocks That flesh is heir to, 'tis a consummation Devoutly to be wish'd. To die, to sleep To sleep- perchance to dream: ay, there's the rub! For in that sleep of death what dreams may come When we have shuffled off this mortal coil, Must give us pause. There 's the respect That makes calamity of so long life"
|
||||
class="ant-typography ant-typography-ellipsis css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis"
|
||||
title="To be, or not to be, that is the question: Whether it is nobler in the mind to suffer. The slings and arrows of outrageous fortune Or to take arms against a sea of troubles, And by opposing end them? To die: to sleep; No more; and by a sleep to say we end The heart-ache and the thousand natural shocks That flesh is heir to, 'tis a consummation Devoutly to be wish'd. To die, to sleep To sleep- perchance to dream: ay, there's the rub! For in that sleep of death what dreams may come When we have shuffled off this mortal coil, Must give us pause. There 's the respect That makes calamity of so long life--William Shakespeare"
|
||||
>
|
||||
To be, or not to be, that is the question: Whether it is nobler in the mind to suffer. The slings and arrows of outrageous fortune Or to take arms against a sea of troubles, And by opposing end them? To die: to sleep; No more; and by a sleep to say we end The heart-ache and the thousand natural shocks That flesh is heir to, 'tis a consummation Devoutly to be wish'd. To die, to sleep To sleep- perchance to dream: ay, there's the rub! For in that sleep of death what dreams may come When we have shuffled off this mortal coil, Must give us pause. There 's the respect That makes calamity of so long life--William Shakespeare
|
||||
@@ -2740,7 +2740,7 @@ exports[`renders components/typography/demo/text.tsx extend context correctly 1`
|
||||
class="ant-space-item"
|
||||
>
|
||||
<span
|
||||
class="ant-typography ant-typography-secondary css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-secondary"
|
||||
>
|
||||
Ant Design (secondary)
|
||||
</span>
|
||||
@@ -2749,7 +2749,7 @@ exports[`renders components/typography/demo/text.tsx extend context correctly 1`
|
||||
class="ant-space-item"
|
||||
>
|
||||
<span
|
||||
class="ant-typography ant-typography-success css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-success"
|
||||
>
|
||||
Ant Design (success)
|
||||
</span>
|
||||
@@ -2758,7 +2758,7 @@ exports[`renders components/typography/demo/text.tsx extend context correctly 1`
|
||||
class="ant-space-item"
|
||||
>
|
||||
<span
|
||||
class="ant-typography ant-typography-warning css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-warning"
|
||||
>
|
||||
Ant Design (warning)
|
||||
</span>
|
||||
@@ -2767,7 +2767,7 @@ exports[`renders components/typography/demo/text.tsx extend context correctly 1`
|
||||
class="ant-space-item"
|
||||
>
|
||||
<span
|
||||
class="ant-typography ant-typography-danger css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-danger"
|
||||
>
|
||||
Ant Design (danger)
|
||||
</span>
|
||||
@@ -2776,7 +2776,7 @@ exports[`renders components/typography/demo/text.tsx extend context correctly 1`
|
||||
class="ant-space-item"
|
||||
>
|
||||
<span
|
||||
class="ant-typography ant-typography-disabled css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-disabled"
|
||||
>
|
||||
Ant Design (disabled)
|
||||
</span>
|
||||
@@ -2862,7 +2862,7 @@ exports[`renders components/typography/demo/text.tsx extend context correctly 1`
|
||||
class="ant-space-item"
|
||||
>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="https://ant.design"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
|
||||
@@ -0,0 +1,379 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`renders components/typography/demo/_semantic.tsx correctly 1`] = `
|
||||
<div
|
||||
class="acss-1ucck97"
|
||||
>
|
||||
<div
|
||||
class="ant-row css-var-test-id"
|
||||
>
|
||||
<div
|
||||
class="ant-col ant-col-16 acss-my3sst css-var-test-id"
|
||||
>
|
||||
<div
|
||||
aria-label="Ant Design is a design language for background applications, refined by Ant UED Team. It aims to uniform the user interface specs for internal background projects, lower the unnecessary cost of design differences and implementation and liberate the resources of design and front-end development."
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis semantic-mark-root"
|
||||
style=""
|
||||
>
|
||||
Ant Design is a design language for background applications, refined by Ant UED Team. It aims to uniform the user interface specs for internal background projects, lower the unnecessary cost of design differences and implementation and liberate the resources of design and front-end development.
|
||||
<span
|
||||
class="ant-typography-actions semantic-mark-actions"
|
||||
>
|
||||
<button
|
||||
aria-label="Edit"
|
||||
class="ant-typography-edit semantic-mark-action"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="edit"
|
||||
class="anticon anticon-edit"
|
||||
role="button"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="edit"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M257.7 752c2 0 4-.2 6-.5L431.9 722c2-.4 3.9-1.3 5.3-2.8l423.9-423.9a9.96 9.96 0 000-14.1L694.9 114.9c-1.9-1.9-4.4-2.9-7.1-2.9s-5.2 1-7.1 2.9L256.8 538.8c-1.5 1.5-2.4 3.3-2.8 5.3l-29.5 168.2a33.5 33.5 0 009.4 29.8c6.6 6.4 14.9 9.9 23.8 9.9zm67.4-174.4L687.8 215l73.3 73.3-362.7 362.6-88.9 15.7 15.6-89zM880 836H144c-17.7 0-32 14.3-32 32v36c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-36c0-17.7-14.3-32-32-32z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Copy"
|
||||
class="ant-typography-copy semantic-mark-action"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="copy"
|
||||
class="anticon anticon-copy"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="copy"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-8 css-var-test-id"
|
||||
>
|
||||
<ul
|
||||
class="acss-1ry21g5"
|
||||
>
|
||||
<li
|
||||
class="acss-1ehfz5v"
|
||||
>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-stretch ant-flex-gap-small ant-flex-vertical"
|
||||
>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-center ant-flex-justify-space-between ant-flex-gap-small"
|
||||
>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-center ant-flex-gap-small"
|
||||
>
|
||||
<h5
|
||||
class="ant-typography css-var-test-id"
|
||||
style="margin: 0px;"
|
||||
>
|
||||
root
|
||||
</h5>
|
||||
<span
|
||||
class="ant-tag ant-tag-filled ant-tag-blue css-var-test-id"
|
||||
>
|
||||
6.4.0
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-center ant-flex-gap-small"
|
||||
>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-text ant-btn-sm ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="pushpin"
|
||||
class="anticon anticon-pushpin"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="pushpin"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M878.3 392.1L631.9 145.7c-6.5-6.5-15-9.7-23.5-9.7s-17 3.2-23.5 9.7L423.8 306.9c-12.2-1.4-24.5-2-36.8-2-73.2 0-146.4 24.1-206.5 72.3a33.23 33.23 0 00-2.7 49.4l181.7 181.7-215.4 215.2a15.8 15.8 0 00-4.6 9.8l-3.4 37.2c-.9 9.4 6.6 17.4 15.9 17.4.5 0 1 0 1.5-.1l37.2-3.4c3.7-.3 7.2-2 9.8-4.6l215.4-215.4 181.7 181.7c6.5 6.5 15 9.7 23.5 9.7 9.7 0 19.3-4.2 25.9-12.4 56.3-70.3 79.7-158.3 70.2-243.4l161.1-161.1c12.9-12.8 12.9-33.8 0-46.8zM666.2 549.3l-24.5 24.5 3.8 34.4a259.92 259.92 0 01-30.4 153.9L262 408.8c12.9-7.1 26.3-13.1 40.3-17.9 27.2-9.4 55.7-14.1 84.7-14.1 9.6 0 19.3.5 28.9 1.6l34.4 3.8 24.5-24.5L608.5 224 800 415.5 666.2 549.3z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
class="ant-btn css-var-test-id ant-btn-text ant-btn-color-default ant-btn-variant-text ant-btn-sm ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="info-circle"
|
||||
class="anticon anticon-info-circle"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="info-circle"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
|
||||
/>
|
||||
<path
|
||||
d="M464 336a48 48 0 1096 0 48 48 0 10-96 0zm72 112h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V456c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-typography css-var-test-id"
|
||||
style="margin: 0px; font-size: 12px;"
|
||||
>
|
||||
根元素,包含排版基础样式、布局和定位
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="acss-1ehfz5v"
|
||||
>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-stretch ant-flex-gap-small ant-flex-vertical"
|
||||
>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-center ant-flex-justify-space-between ant-flex-gap-small"
|
||||
>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-center ant-flex-gap-small"
|
||||
>
|
||||
<h5
|
||||
class="ant-typography css-var-test-id"
|
||||
style="margin: 0px;"
|
||||
>
|
||||
actions
|
||||
</h5>
|
||||
<span
|
||||
class="ant-tag ant-tag-filled ant-tag-blue css-var-test-id"
|
||||
>
|
||||
6.4.0
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-center ant-flex-gap-small"
|
||||
>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-text ant-btn-sm ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="pushpin"
|
||||
class="anticon anticon-pushpin"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="pushpin"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M878.3 392.1L631.9 145.7c-6.5-6.5-15-9.7-23.5-9.7s-17 3.2-23.5 9.7L423.8 306.9c-12.2-1.4-24.5-2-36.8-2-73.2 0-146.4 24.1-206.5 72.3a33.23 33.23 0 00-2.7 49.4l181.7 181.7-215.4 215.2a15.8 15.8 0 00-4.6 9.8l-3.4 37.2c-.9 9.4 6.6 17.4 15.9 17.4.5 0 1 0 1.5-.1l37.2-3.4c3.7-.3 7.2-2 9.8-4.6l215.4-215.4 181.7 181.7c6.5 6.5 15 9.7 23.5 9.7 9.7 0 19.3-4.2 25.9-12.4 56.3-70.3 79.7-158.3 70.2-243.4l161.1-161.1c12.9-12.8 12.9-33.8 0-46.8zM666.2 549.3l-24.5 24.5 3.8 34.4a259.92 259.92 0 01-30.4 153.9L262 408.8c12.9-7.1 26.3-13.1 40.3-17.9 27.2-9.4 55.7-14.1 84.7-14.1 9.6 0 19.3.5 28.9 1.6l34.4 3.8 24.5-24.5L608.5 224 800 415.5 666.2 549.3z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
class="ant-btn css-var-test-id ant-btn-text ant-btn-color-default ant-btn-variant-text ant-btn-sm ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="info-circle"
|
||||
class="anticon anticon-info-circle"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="info-circle"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
|
||||
/>
|
||||
<path
|
||||
d="M464 336a48 48 0 1096 0 48 48 0 10-96 0zm72 112h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V456c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-typography css-var-test-id"
|
||||
style="margin: 0px; font-size: 12px;"
|
||||
>
|
||||
操作区域元素,包含复制、编辑、展开/收起等操作按钮的布局和间距样式
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="acss-1ehfz5v"
|
||||
>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-stretch ant-flex-gap-small ant-flex-vertical"
|
||||
>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-center ant-flex-justify-space-between ant-flex-gap-small"
|
||||
>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-center ant-flex-gap-small"
|
||||
>
|
||||
<h5
|
||||
class="ant-typography css-var-test-id"
|
||||
style="margin: 0px;"
|
||||
>
|
||||
action
|
||||
</h5>
|
||||
<span
|
||||
class="ant-tag ant-tag-filled ant-tag-blue css-var-test-id"
|
||||
>
|
||||
6.4.0
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-flex css-var-test-id ant-flex-align-center ant-flex-gap-small"
|
||||
>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-text ant-btn-sm ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="pushpin"
|
||||
class="anticon anticon-pushpin"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="pushpin"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M878.3 392.1L631.9 145.7c-6.5-6.5-15-9.7-23.5-9.7s-17 3.2-23.5 9.7L423.8 306.9c-12.2-1.4-24.5-2-36.8-2-73.2 0-146.4 24.1-206.5 72.3a33.23 33.23 0 00-2.7 49.4l181.7 181.7-215.4 215.2a15.8 15.8 0 00-4.6 9.8l-3.4 37.2c-.9 9.4 6.6 17.4 15.9 17.4.5 0 1 0 1.5-.1l37.2-3.4c3.7-.3 7.2-2 9.8-4.6l215.4-215.4 181.7 181.7c6.5 6.5 15 9.7 23.5 9.7 9.7 0 19.3-4.2 25.9-12.4 56.3-70.3 79.7-158.3 70.2-243.4l161.1-161.1c12.9-12.8 12.9-33.8 0-46.8zM666.2 549.3l-24.5 24.5 3.8 34.4a259.92 259.92 0 01-30.4 153.9L262 408.8c12.9-7.1 26.3-13.1 40.3-17.9 27.2-9.4 55.7-14.1 84.7-14.1 9.6 0 19.3.5 28.9 1.6l34.4 3.8 24.5-24.5L608.5 224 800 415.5 666.2 549.3z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
class="ant-btn css-var-test-id ant-btn-text ant-btn-color-default ant-btn-variant-text ant-btn-sm ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="info-circle"
|
||||
class="anticon anticon-info-circle"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="info-circle"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
|
||||
/>
|
||||
<path
|
||||
d="M464 336a48 48 0 1096 0 48 48 0 10-96 0zm72 112h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V456c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-typography css-var-test-id"
|
||||
style="margin: 0px; font-size: 12px;"
|
||||
>
|
||||
单个操作按钮元素,包括复制、编辑、展开、收起按钮的样式,如内边距、圆角、颜色等
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -60,7 +60,7 @@ exports[`renders components/typography/demo/basic.tsx correctly 1`] = `
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/proximity"
|
||||
>
|
||||
Principles
|
||||
@@ -68,7 +68,7 @@ exports[`renders components/typography/demo/basic.tsx correctly 1`] = `
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/overview"
|
||||
>
|
||||
Patterns
|
||||
@@ -76,7 +76,7 @@ exports[`renders components/typography/demo/basic.tsx correctly 1`] = `
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/resources"
|
||||
>
|
||||
Resource Download
|
||||
@@ -164,7 +164,7 @@ exports[`renders components/typography/demo/basic.tsx correctly 1`] = `
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/proximity-cn"
|
||||
>
|
||||
设计原则
|
||||
@@ -172,7 +172,7 @@ exports[`renders components/typography/demo/basic.tsx correctly 1`] = `
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/overview-cn"
|
||||
>
|
||||
设计模式
|
||||
@@ -180,7 +180,7 @@ exports[`renders components/typography/demo/basic.tsx correctly 1`] = `
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/resources-cn"
|
||||
>
|
||||
设计资源
|
||||
@@ -272,7 +272,7 @@ Array [
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/proximity"
|
||||
>
|
||||
Principles
|
||||
@@ -280,7 +280,7 @@ Array [
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/overview"
|
||||
>
|
||||
Patterns
|
||||
@@ -288,7 +288,7 @@ Array [
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/resources"
|
||||
>
|
||||
Resource Download
|
||||
@@ -371,7 +371,7 @@ Array [
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/proximity-cn"
|
||||
>
|
||||
设计原则
|
||||
@@ -379,7 +379,7 @@ Array [
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/spec/overview-cn"
|
||||
>
|
||||
设计模式
|
||||
@@ -387,7 +387,7 @@ Array [
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="/docs/resources-cn"
|
||||
>
|
||||
设计资源
|
||||
@@ -422,17 +422,17 @@ Array [
|
||||
</div>
|
||||
</article>,
|
||||
<span
|
||||
class="ant-typography ant-typography-success css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-success"
|
||||
>
|
||||
Success but red
|
||||
</span>,
|
||||
<span
|
||||
class="ant-typography ant-typography-warning css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-warning"
|
||||
>
|
||||
Warning but green
|
||||
</span>,
|
||||
<span
|
||||
class="ant-typography ant-typography-danger css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-danger"
|
||||
>
|
||||
Danger but blue
|
||||
</span>,
|
||||
@@ -684,7 +684,7 @@ Array [
|
||||
</span>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
>
|
||||
This is a loooooooooooooooooooooooooooooooong editable text
|
||||
<!-- -->
|
||||
@@ -1190,24 +1190,24 @@ Array [
|
||||
</span>
|
||||
</button>,
|
||||
<div
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
>
|
||||
Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team.
|
||||
</div>,
|
||||
<div
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-multiple-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-multiple-line"
|
||||
style="-webkit-line-clamp:2"
|
||||
>
|
||||
Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team.
|
||||
</div>,
|
||||
<span
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="width:200px"
|
||||
>
|
||||
Ant Design, a design language for background applications, is refined by Ant UED Team.
|
||||
</span>,
|
||||
<span
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="width:200px"
|
||||
>
|
||||
<code>
|
||||
@@ -1275,7 +1275,7 @@ exports[`renders components/typography/demo/ellipsis-controlled.tsx correctly 1`
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-multiple-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-multiple-line"
|
||||
style="-webkit-line-clamp:2"
|
||||
>
|
||||
Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.Ant Design, a design language for background applications, is refined by Ant UED Team.
|
||||
@@ -1422,7 +1422,7 @@ Array [
|
||||
/>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
>
|
||||
Ant Design, a design language for background applications, is refined by Ant UED Team. This is a nest sample
|
||||
<!-- -->
|
||||
@@ -1441,7 +1441,7 @@ Array [
|
||||
case. Bnt Design, a design language for background applications, is refined by Ant UED Team. Cnt Design, a design language for background applications, is refined by Ant UED Team. Dnt Design, a design language for background applications, is refined by Ant UED Team. Ent Design, a design language for background applications, is refined by Ant UED Team.
|
||||
</div>,
|
||||
<span
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="max-width:400px;font-size:24px"
|
||||
>
|
||||
In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development.
|
||||
@@ -1477,7 +1477,7 @@ Array [
|
||||
</span>,
|
||||
<br />,
|
||||
<span
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="max-width:400px;font-size:12px"
|
||||
>
|
||||
In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development.
|
||||
@@ -1513,7 +1513,7 @@ Array [
|
||||
</span>,
|
||||
<br />,
|
||||
<span
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="width:400px;font-size:24px"
|
||||
>
|
||||
In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development.
|
||||
@@ -1549,7 +1549,7 @@ Array [
|
||||
</span>,
|
||||
<br />,
|
||||
<span
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="width:100px"
|
||||
>
|
||||
Ant Design is a design language for background applications, is refined by Ant UED Team.
|
||||
@@ -1586,7 +1586,7 @@ Array [
|
||||
<p>
|
||||
[Before]
|
||||
<span
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
>
|
||||
not ellipsis
|
||||
</span>
|
||||
@@ -1596,14 +1596,14 @@ Array [
|
||||
style="display:none"
|
||||
>
|
||||
<span
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="width:100px"
|
||||
>
|
||||
默认 display none 样式的超长文字, 悬停 tooltip 失效了
|
||||
</span>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-multiple-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-multiple-line"
|
||||
style="width:300px;-webkit-line-clamp:3"
|
||||
>
|
||||
In the process of internal desktop applications development,
|
||||
@@ -1616,7 +1616,7 @@ Array [
|
||||
</div>,
|
||||
<pre>
|
||||
<div
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-multiple-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-multiple-line"
|
||||
style="-webkit-line-clamp:2"
|
||||
>
|
||||
this is a multiline
|
||||
@@ -1629,7 +1629,7 @@ Array [
|
||||
</pre>,
|
||||
<br />,
|
||||
<span
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="width:100px;white-space:nowrap"
|
||||
>
|
||||
In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development.
|
||||
@@ -1680,7 +1680,7 @@ Array [
|
||||
3. Move from copy button back to the text (without leaving the block) → ellipsis tooltip should show again.
|
||||
</div>
|
||||
<span
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="width:280px;display:block"
|
||||
>
|
||||
In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of development.
|
||||
@@ -1720,7 +1720,7 @@ Array [
|
||||
|
||||
exports[`renders components/typography/demo/ellipsis-middle.tsx correctly 1`] = `
|
||||
<span
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
style="max-width:100%"
|
||||
>
|
||||
In the process of internal desktop applications development, many different design specs and implementations would be involved, which might cause designers and developers difficulties and duplication and reduce the efficiency of
|
||||
@@ -1740,7 +1740,7 @@ exports[`renders components/typography/demo/link-danger-debug.tsx correctly 1`]
|
||||
</span>
|
||||
<br />
|
||||
<a
|
||||
class="ant-typography ant-typography-danger ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-danger ant-typography-link"
|
||||
href="https://ant.design"
|
||||
>
|
||||
Danger Link
|
||||
@@ -1997,7 +1997,7 @@ Array [
|
||||
/>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-typography ant-typography-ellipsis ant-typography-ellipsis-single-line css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-ellipsis ant-typography-ellipsis-single-line"
|
||||
title="To be, or not to be, that is the question: Whether it is nobler in the mind to suffer. The slings and arrows of outrageous fortune Or to take arms against a sea of troubles, And by opposing end them? To die: to sleep; No more; and by a sleep to say we end The heart-ache and the thousand natural shocks That flesh is heir to, 'tis a consummation Devoutly to be wish'd. To die, to sleep To sleep- perchance to dream: ay, there's the rub! For in that sleep of death what dreams may come When we have shuffled off this mortal coil, Must give us pause. There 's the respect That makes calamity of so long life--William Shakespeare"
|
||||
>
|
||||
To be, or not to be, that is the question: Whether it is nobler in the mind to suffer. The slings and arrows of outrageous fortune Or to take arms against a sea of troubles, And by opposing end them? To die: to sleep; No more; and by a sleep to say we end The heart-ache and the thousand natural shocks That flesh is heir to, 'tis a consummation Devoutly to be wish'd. To die, to sleep To sleep- perchance to dream: ay, there's the rub! For in that sleep of death what dreams may come When we have shuffled off this mortal coil, Must give us pause. There 's the respect That makes calamity of so long life
|
||||
@@ -2024,7 +2024,7 @@ exports[`renders components/typography/demo/text.tsx correctly 1`] = `
|
||||
class="ant-space-item"
|
||||
>
|
||||
<span
|
||||
class="ant-typography ant-typography-secondary css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-secondary"
|
||||
>
|
||||
Ant Design (secondary)
|
||||
</span>
|
||||
@@ -2033,7 +2033,7 @@ exports[`renders components/typography/demo/text.tsx correctly 1`] = `
|
||||
class="ant-space-item"
|
||||
>
|
||||
<span
|
||||
class="ant-typography ant-typography-success css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-success"
|
||||
>
|
||||
Ant Design (success)
|
||||
</span>
|
||||
@@ -2042,7 +2042,7 @@ exports[`renders components/typography/demo/text.tsx correctly 1`] = `
|
||||
class="ant-space-item"
|
||||
>
|
||||
<span
|
||||
class="ant-typography ant-typography-warning css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-warning"
|
||||
>
|
||||
Ant Design (warning)
|
||||
</span>
|
||||
@@ -2051,7 +2051,7 @@ exports[`renders components/typography/demo/text.tsx correctly 1`] = `
|
||||
class="ant-space-item"
|
||||
>
|
||||
<span
|
||||
class="ant-typography ant-typography-danger css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-danger"
|
||||
>
|
||||
Ant Design (danger)
|
||||
</span>
|
||||
@@ -2060,7 +2060,7 @@ exports[`renders components/typography/demo/text.tsx correctly 1`] = `
|
||||
class="ant-space-item"
|
||||
>
|
||||
<span
|
||||
class="ant-typography ant-typography-disabled css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-disabled"
|
||||
>
|
||||
Ant Design (disabled)
|
||||
</span>
|
||||
@@ -2146,7 +2146,7 @@ exports[`renders components/typography/demo/text.tsx correctly 1`] = `
|
||||
class="ant-space-item"
|
||||
>
|
||||
<a
|
||||
class="ant-typography ant-typography-link css-var-test-id"
|
||||
class="ant-typography css-var-test-id ant-typography-link"
|
||||
href="https://ant.design"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
|
||||
@@ -2,24 +2,24 @@
|
||||
|
||||
exports[`Typography rtl render component should be rendered correctly in RTL direction 1`] = `
|
||||
<div
|
||||
class="ant-typography ant-typography-rtl css-var-root"
|
||||
class="ant-typography css-var-root ant-typography-rtl"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`Typography rtl render component should be rendered correctly in RTL direction 2`] = `
|
||||
<article
|
||||
class="ant-typography ant-typography-rtl css-var-root"
|
||||
class="ant-typography css-var-root ant-typography-rtl"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`Typography rtl render component should be rendered correctly in RTL direction 3`] = `
|
||||
<h1
|
||||
class="ant-typography ant-typography-rtl css-var-root"
|
||||
class="ant-typography css-var-root ant-typography-rtl"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`Typography rtl render component should be rendered correctly in RTL direction 4`] = `
|
||||
<a
|
||||
class="ant-typography ant-typography-rtl ant-typography-link css-var-root"
|
||||
class="ant-typography css-var-root ant-typography-rtl ant-typography-link"
|
||||
/>
|
||||
`;
|
||||
|
||||
3
components/typography/__tests__/demo-semantic.test.tsx
Normal file
3
components/typography/__tests__/demo-semantic.test.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
import { semanticDemoTest } from '../../../tests/shared/demoTest';
|
||||
|
||||
semanticDemoTest('typography');
|
||||
@@ -644,12 +644,12 @@ describe('Typography.Ellipsis', () => {
|
||||
it('Switch locale', async () => {
|
||||
const ref = React.createRef<HTMLElement>();
|
||||
const App = () => {
|
||||
const [locale, setLocale] = React.useState<Locale>();
|
||||
const [locale, setLocal] = React.useState<Locale>();
|
||||
|
||||
return (
|
||||
<ConfigProvider locale={locale}>
|
||||
<div>
|
||||
<button type="button" onClick={() => setLocale(zhCN)}>
|
||||
<button type="button" onClick={() => setLocal(zhCN)}>
|
||||
zhcn
|
||||
</button>
|
||||
<Base
|
||||
|
||||
122
components/typography/__tests__/semantic.test.tsx
Normal file
122
components/typography/__tests__/semantic.test.tsx
Normal file
@@ -0,0 +1,122 @@
|
||||
import React from 'react';
|
||||
import { clsx } from 'clsx';
|
||||
|
||||
import Typography from '..';
|
||||
import { render } from '../../../tests/utils';
|
||||
import ConfigProvider from '../../config-provider';
|
||||
import type { TypographyClassNamesType, TypographyStylesType } from '../Base';
|
||||
|
||||
describe('Typography.Semantic', () => {
|
||||
it('should support classNames and styles for root, actions, and action', () => {
|
||||
const classNamesFn: TypographyClassNamesType = jest.fn(() => ({
|
||||
root: 'custom-typography',
|
||||
actions: 'custom-actions',
|
||||
action: 'custom-action',
|
||||
}));
|
||||
|
||||
const stylesFn: TypographyStylesType = jest.fn(() => ({
|
||||
root: { color: '#1890ff' },
|
||||
actions: { backgroundColor: '#f0f0f0' },
|
||||
action: { padding: '5px' },
|
||||
}));
|
||||
|
||||
const { rerender } = render(
|
||||
<Typography.Paragraph classNames={classNamesFn} styles={stylesFn} copyable>
|
||||
Test Typography
|
||||
</Typography.Paragraph>,
|
||||
);
|
||||
|
||||
expect(classNamesFn).toHaveBeenCalled();
|
||||
expect(stylesFn).toHaveBeenCalled();
|
||||
|
||||
const rootElement = document.querySelector<HTMLElement>('.ant-typography');
|
||||
expect(rootElement).toHaveClass('custom-typography');
|
||||
expect(rootElement).toHaveStyle({ color: 'rgb(24, 144, 255)' });
|
||||
|
||||
const actionsElement = document.querySelector<HTMLElement>('.ant-typography-actions');
|
||||
expect(actionsElement).toHaveClass('custom-actions');
|
||||
expect(actionsElement).toHaveStyle({ backgroundColor: 'rgb(240, 240, 240)' });
|
||||
|
||||
const actionButton = document.querySelector<HTMLElement>('.ant-typography-actions button');
|
||||
expect(actionButton).toHaveClass('custom-action');
|
||||
expect(actionButton).toHaveStyle({ padding: '5px' });
|
||||
|
||||
rerender(
|
||||
<Typography.Paragraph
|
||||
classNames={{
|
||||
root: 'obj-root',
|
||||
actions: 'obj-actions',
|
||||
action: 'obj-action',
|
||||
}}
|
||||
styles={{
|
||||
root: { fontSize: '16px', color: '#52c41a' },
|
||||
actions: { margin: '10px' },
|
||||
action: { borderRadius: '4px' },
|
||||
}}
|
||||
copyable
|
||||
>
|
||||
Updated Typography
|
||||
</Typography.Paragraph>,
|
||||
);
|
||||
|
||||
const updatedRootElement = document.querySelector<HTMLElement>('.ant-typography');
|
||||
expect(updatedRootElement).toHaveClass('obj-root');
|
||||
expect(updatedRootElement).toHaveStyle({ fontSize: '16px', color: 'rgb(82, 196, 26)' });
|
||||
|
||||
const updatedActionsElement = document.querySelector<HTMLElement>('.ant-typography-actions');
|
||||
expect(updatedActionsElement).toHaveClass('obj-actions');
|
||||
expect(updatedActionsElement).toHaveStyle({ margin: '10px' });
|
||||
|
||||
const updatedActionButton = document.querySelector<HTMLElement>(
|
||||
'.ant-typography-actions button',
|
||||
);
|
||||
expect(updatedActionButton).toHaveClass('obj-action');
|
||||
expect(updatedActionButton).toHaveStyle({ borderRadius: '4px' });
|
||||
});
|
||||
|
||||
it('should merge context and component classNames and styles', () => {
|
||||
const contextClassNames: TypographyClassNamesType = {
|
||||
root: 'context-root',
|
||||
actions: 'context-actions',
|
||||
};
|
||||
const contextStyles: TypographyStylesType = {
|
||||
root: { padding: '10px' },
|
||||
actions: { margin: '5px' },
|
||||
};
|
||||
const componentClassNames: TypographyClassNamesType = {
|
||||
root: 'component-root',
|
||||
};
|
||||
const componentStyles: TypographyStylesType = {
|
||||
root: { fontSize: '14px' },
|
||||
};
|
||||
|
||||
render(
|
||||
<ConfigProvider>
|
||||
<ConfigProvider
|
||||
typography={{
|
||||
className: undefined,
|
||||
style: undefined,
|
||||
classNames: contextClassNames,
|
||||
styles: contextStyles,
|
||||
}}
|
||||
>
|
||||
<Typography.Paragraph classNames={componentClassNames} styles={componentStyles} copyable>
|
||||
Test Typography
|
||||
</Typography.Paragraph>
|
||||
</ConfigProvider>
|
||||
</ConfigProvider>,
|
||||
);
|
||||
|
||||
const rootElement = document.querySelector<HTMLElement>('.ant-typography');
|
||||
const actionsElement = document.querySelector<HTMLElement>('.ant-typography-actions');
|
||||
|
||||
expect(rootElement).toHaveClass(clsx(contextClassNames.root, componentClassNames.root));
|
||||
expect(actionsElement).toHaveClass(contextClassNames.actions!);
|
||||
|
||||
expect(rootElement).toHaveStyle({
|
||||
padding: contextStyles.root?.padding,
|
||||
fontSize: componentStyles.root?.fontSize,
|
||||
});
|
||||
expect(actionsElement).toHaveStyle({ margin: contextStyles.actions?.margin });
|
||||
});
|
||||
});
|
||||
43
components/typography/demo/_semantic.tsx
Normal file
43
components/typography/demo/_semantic.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import { Typography } from 'antd';
|
||||
|
||||
import useLocale from '../../../.dumi/hooks/useLocale';
|
||||
import SemanticPreview from '../../../.dumi/theme/common/SemanticPreview';
|
||||
|
||||
const locales = {
|
||||
cn: {
|
||||
root: '根元素,包含排版基础样式、布局和定位',
|
||||
actions: '操作区域元素,包含复制、编辑、展开/收起等操作按钮的布局和间距样式',
|
||||
action: '单个操作按钮元素,包括复制、编辑、展开、收起按钮的样式,如内边距、圆角、颜色等',
|
||||
},
|
||||
en: {
|
||||
root: 'Root element with base typography styles, layout, and positioning',
|
||||
actions:
|
||||
'Actions element with layout and spacing styles for copy, edit, expand/collapse buttons',
|
||||
action:
|
||||
'Individual action button element including copy, edit, expand, collapse button styles like padding, border radius, colors, etc.',
|
||||
},
|
||||
};
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<SemanticPreview
|
||||
componentName="Typography"
|
||||
semantics={[
|
||||
{ name: 'root', desc: locale.root, version: '6.4.0' },
|
||||
{ name: 'actions', desc: locale.actions, version: '6.4.0' },
|
||||
{ name: 'action', desc: locale.action, version: '6.4.0' },
|
||||
]}
|
||||
>
|
||||
<Typography.Paragraph copyable editable ellipsis={{ rows: 2, expandable: true }}>
|
||||
Ant Design is a design language for background applications, refined by Ant UED Team. It
|
||||
aims to uniform the user interface specs for internal background projects, lower the
|
||||
unnecessary cost of design differences and implementation and liberate the resources of
|
||||
design and front-end development.
|
||||
</Typography.Paragraph>
|
||||
</SemanticPreview>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
62
components/typography/hooks/useTypographySemantic.ts
Normal file
62
components/typography/hooks/useTypographySemantic.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { useMergeSemantic } from '../../_util/hooks';
|
||||
import type { DirectionType } from '../../config-provider';
|
||||
import { useComponentConfig } from '../../config-provider/context';
|
||||
import type {
|
||||
BaseTypographyProps,
|
||||
TypographyClassNamesType,
|
||||
TypographySemanticClassNames,
|
||||
TypographySemanticStyles,
|
||||
TypographyStylesType,
|
||||
} from '../Base';
|
||||
|
||||
type UseTypographySemanticResult = [
|
||||
mergedClassNames: TypographySemanticClassNames,
|
||||
mergedStyles: TypographySemanticStyles,
|
||||
prefixCls: string,
|
||||
direction: DirectionType | undefined,
|
||||
];
|
||||
|
||||
export const useTypographySemantic = (
|
||||
customizePrefixCls?: string,
|
||||
classNames?: TypographyClassNamesType | undefined,
|
||||
styles?: TypographyStylesType | undefined,
|
||||
typographyDirection?: DirectionType,
|
||||
props?: BaseTypographyProps,
|
||||
): UseTypographySemanticResult => {
|
||||
const {
|
||||
getPrefixCls,
|
||||
direction: contextDirection,
|
||||
className: contextClassName,
|
||||
style: contextStyle,
|
||||
classNames: contextClassNames,
|
||||
styles: contextStyles,
|
||||
} = useComponentConfig('typography');
|
||||
|
||||
const direction = typographyDirection ?? contextDirection;
|
||||
const prefixCls = getPrefixCls('typography', customizePrefixCls);
|
||||
|
||||
const mergedProps: BaseTypographyProps = {
|
||||
...props,
|
||||
prefixCls,
|
||||
direction,
|
||||
};
|
||||
|
||||
const contextClassNamesObject = useMemo(() => ({ root: contextClassName }), [contextClassName]);
|
||||
const contextStylesObject = useMemo(() => ({ root: contextStyle }), [contextStyle]);
|
||||
|
||||
const [mergedClassNames, mergedStyles] = useMergeSemantic<
|
||||
TypographyClassNamesType,
|
||||
TypographyStylesType,
|
||||
BaseTypographyProps
|
||||
>(
|
||||
[contextClassNamesObject, contextClassNames, classNames],
|
||||
[contextStylesObject, contextStyles, styles],
|
||||
{
|
||||
props: mergedProps,
|
||||
},
|
||||
);
|
||||
|
||||
return [mergedClassNames, mergedStyles, prefixCls, direction];
|
||||
};
|
||||
@@ -4,14 +4,16 @@ import Text from './Text';
|
||||
import Title from './Title';
|
||||
import OriginTypography from './Typography';
|
||||
|
||||
export type TypographyProps = typeof OriginTypography & {
|
||||
export type { TypographyProps } from './Typography';
|
||||
|
||||
type CompoundedComponent = typeof OriginTypography & {
|
||||
Text: typeof Text;
|
||||
Link: typeof Link;
|
||||
Title: typeof Title;
|
||||
Paragraph: typeof Paragraph;
|
||||
};
|
||||
|
||||
const Typography = OriginTypography as TypographyProps;
|
||||
const Typography = OriginTypography as CompoundedComponent;
|
||||
Typography.Text = Text;
|
||||
Typography.Link = Link;
|
||||
Typography.Title = Title;
|
||||
|
||||
@@ -21,13 +21,13 @@ export type AppendWatermark = (
|
||||
container: HTMLElement,
|
||||
) => void;
|
||||
|
||||
function useWatermark(
|
||||
export default function useWatermark(
|
||||
markStyle: React.CSSProperties,
|
||||
onRemove?: () => void,
|
||||
): [
|
||||
appendWatermark: AppendWatermark,
|
||||
removeWatermark: (container: HTMLElement) => void,
|
||||
isWatermarkEle: (ele: Node, index?: number) => boolean,
|
||||
isWatermarkEle: (ele: Node) => boolean,
|
||||
] {
|
||||
const watermarkMap = React.useRef(new Map<HTMLElement, HTMLDivElement>());
|
||||
const onRemoveEvent = useEvent(onRemove);
|
||||
@@ -79,7 +79,5 @@ function useWatermark(
|
||||
|
||||
const isWatermarkEle = (ele: any) => Array.from(watermarkMap.current.values()).includes(ele);
|
||||
|
||||
return [appendWatermark, removeWatermark, isWatermarkEle] as const;
|
||||
return [appendWatermark, removeWatermark, isWatermarkEle];
|
||||
}
|
||||
|
||||
export default useWatermark;
|
||||
|
||||
@@ -15,14 +15,11 @@ export function getPixelRatio() {
|
||||
}
|
||||
|
||||
/** Whether to re-render the watermark */
|
||||
export const reRendering = (
|
||||
mutation: MutationRecord,
|
||||
isWatermarkEle: (ele: Node, index?: number) => boolean,
|
||||
) => {
|
||||
export const reRendering = (mutation: MutationRecord, isWatermarkEle: (ele: Node) => boolean) => {
|
||||
let flag = false;
|
||||
// Whether to delete the watermark node
|
||||
if (mutation.removedNodes.length) {
|
||||
flag = Array.from<Node>(mutation.removedNodes).some(isWatermarkEle);
|
||||
flag = Array.from<Node>(mutation.removedNodes).some((node) => isWatermarkEle(node));
|
||||
}
|
||||
// Whether the watermark dom property value has been modified
|
||||
if (mutation.type === 'attributes' && isWatermarkEle(mutation.target)) {
|
||||
|
||||
@@ -65,6 +65,7 @@ export default antfu(
|
||||
'react-hooks/refs': 'off',
|
||||
'react/no-implicit-key': 'off',
|
||||
'react-naming-convention/ref-name': 'off',
|
||||
'react-naming-convention/use-state': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
"@rc-component/rate": "~1.0.1",
|
||||
"@rc-component/resize-observer": "^1.1.1",
|
||||
"@rc-component/segmented": "~1.3.0",
|
||||
"@rc-component/select": "~1.6.9",
|
||||
"@rc-component/select": "~1.6.5",
|
||||
"@rc-component/slider": "~1.0.1",
|
||||
"@rc-component/steps": "~1.2.2",
|
||||
"@rc-component/switch": "~1.0.3",
|
||||
|
||||
@@ -27,15 +27,9 @@ describe('site test', () => {
|
||||
const html: string = await res.text();
|
||||
const root = new DOMParser().parseFromString(html, 'text/html');
|
||||
function getTextContent(node: any): string {
|
||||
if (!node) {
|
||||
return '';
|
||||
}
|
||||
if (typeof node.textContent === 'string') {
|
||||
return node.textContent.trim();
|
||||
}
|
||||
if (typeof node.innerText === 'string') {
|
||||
return node.innerText.trim();
|
||||
}
|
||||
if (!node) return '';
|
||||
if (typeof node.textContent === 'string') return node.textContent.trim();
|
||||
if (typeof node.innerText === 'string') return node.innerText.trim();
|
||||
// Fallback: recursively get text from children
|
||||
if (node.children && node.children.length > 0) {
|
||||
return Array.from(node.children)
|
||||
@@ -50,10 +44,8 @@ describe('site test', () => {
|
||||
return {
|
||||
length: list.length,
|
||||
text: () => {
|
||||
if (list.length === 0) {
|
||||
return '';
|
||||
}
|
||||
return list.map<string>(getTextContent).join('');
|
||||
if (list.length === 0) return '';
|
||||
return list.map((n) => getTextContent(n)).join('');
|
||||
},
|
||||
first: () => wrap(list.slice(0, 1)),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user