Browse Source

fix: preview-img style (#38662)

* docs: PreviewImg

* docs: add preview-img style

* chore: style

* chore: clean
pull/38668/head
MadCcc 2 years ago
committed by GitHub
parent
commit
4b490834a0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .dumi/rehypeAntd.ts
  2. 163
      .dumi/theme/builtins/ImagePreview/index.jsx
  3. 9
      .dumi/theme/common/GlobalStyles.tsx

2
.dumi/rehypeAntd.ts

@ -6,7 +6,7 @@ import { type HastRoot, type UnifiedTransformer, unistUtilVisit } from 'dumi';
*/
function rehypeAntd(): UnifiedTransformer<HastRoot> {
return (tree, vFile) => {
unistUtilVisit.visit(tree, 'element', node => {
unistUtilVisit.visit(tree, 'element', (node) => {
if (node.tagName === 'DumiDemoGrid') {
// replace DumiDemoGrid to DemoWrapper, to implement demo toolbar
node.tagName = 'DemoWrapper';

163
.dumi/theme/builtins/ImagePreview/index.jsx

@ -0,0 +1,163 @@
import React from 'react';
import classNames from 'classnames';
import { Modal, Carousel } from 'antd';
function isGood(className) {
return /\bgood\b/i.test(className);
}
function isBad(className) {
return /\bbad\b/i.test(className);
}
function isInline(className) {
return /\binline\b/i.test(className);
}
function PreviewImageBox({
cover,
coverMeta,
imgs,
style,
previewVisible,
comparable,
onClick,
onCancel,
}) {
const onlyOneImg = comparable || imgs.length === 1;
const imageWrapperClassName = classNames('preview-image-wrapper', {
good: coverMeta.isGood,
bad: coverMeta.isBad,
});
return (
<div className="preview-image-box" style={style}>
<div onClick={onClick} className={imageWrapperClassName}>
<img className={coverMeta.className} src={coverMeta.src} alt={coverMeta.alt} />
</div>
<div className="preview-image-title">{coverMeta.alt}</div>
<div
className="preview-image-description"
dangerouslySetInnerHTML={{ __html: coverMeta.description }}
/>
<Modal
className="image-modal"
width={960}
visible={previewVisible}
title={null}
footer={null}
onCancel={onCancel}
>
<Carousel
className={`${onlyOneImg ? 'image-modal-single' : ''}`}
draggable={!onlyOneImg}
adaptiveHeight
>
{comparable ? cover : imgs}
</Carousel>
<div className="preview-image-title">{coverMeta.alt}</div>
</Modal>
</div>
);
}
function isGoodBadImg(imgMeta) {
return imgMeta.isGood || imgMeta.isBad;
}
function isCompareImg(imgMeta) {
return isGoodBadImg(imgMeta) || imgMeta.inline;
}
export default class ImagePreview extends React.Component {
constructor(props) {
super(props);
this.state = {
previewVisible: {},
};
}
handleClick = index => {
this.setState({
previewVisible: {
[index]: true,
},
});
};
handleCancel = () => {
this.setState({
previewVisible: {},
});
};
render() {
const { imgs } = this.props;
const imgsMeta = imgs.map(img => {
const { alt, description, src } = img;
const imgClassName = img.class;
return {
className: imgClassName,
alt,
description,
src,
isGood: isGood(imgClassName),
isBad: isBad(imgClassName),
inline: isInline(imgClassName),
};
});
const imagesList = imgsMeta.map((meta, index) => {
const metaCopy = { ...meta };
delete metaCopy.description;
delete metaCopy.isGood;
delete metaCopy.isBad;
return (
<div key={index}>
<div className="image-modal-container">
<img {...metaCopy} alt={meta.alt} />
</div>
</div>
);
});
const comparable =
(imgs.length === 2 && imgsMeta.every(isCompareImg)) ||
(imgs.length >= 2 && imgsMeta.every(isGoodBadImg));
const style = comparable ? { width: `${(100 / imgs.length).toFixed(3)}%` } : null;
const hasCarousel = imgs.length > 1 && !comparable;
const previewClassName = classNames({
'preview-image-boxes': true,
clearfix: true,
'preview-image-boxes-compare': comparable,
'preview-image-boxes-with-carousel': hasCarousel,
});
return (
<div className={previewClassName}>
{imagesList.map((_, index) => {
if (!comparable && index !== 0) {
return null;
}
return (
<PreviewImageBox
key={index}
style={style}
comparable={comparable}
previewVisible={!!this.state.previewVisible[index]}
cover={imagesList[index]}
coverMeta={imgsMeta[index]}
imgs={imagesList}
onClick={() => {
this.handleClick(index);
}}
onCancel={this.handleCancel}
/>
);
})}
</div>
);
}
}

9
.dumi/theme/common/GlobalStyles.tsx

@ -1892,6 +1892,15 @@ const GlobalStyles = () => {
box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.3);
}
.preview-img {
max-width: 496px !important;
clear: both;
float: right;
margin: 0 0 70px 64px;
background-color: #f2f4f5;
padding: 16px;
}
.image-modal {
text-align: center;

Loading…
Cancel
Save