antd#Image TypeScript Examples
The following examples show how to use
antd#Image.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TrackListHeader.tsx From spotify-recently-played-readme with MIT License | 6 votes |
/**
* Track list header component.
*/
export default function TrackListHeader(props: Props): JSX.Element {
return (
<div style={{ display: 'flex' }}>
<Space>
<a
target="_blank"
rel="noopener noreferrer"
href={`https://open.spotify.com/user/${props.username}`}
style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<Image preview={false} className="spotify-icon" src={SpotifyIcon} width={100}></Image>
</a>
<Text className="spotify-title">Recently Played</Text>
</Space>
</div>
);
}
Example #2
Source File: GeneralImage.spec.tsx From next-basics with GNU General Public License v3.0 | 6 votes |
describe("GeneralImages", () => {
it("should work", () => {
const props = {
src: "/images/1234.jpg",
extra: {
useBrick: {
brick: "div",
properties: {
textContent: "1234.jpg",
},
},
},
};
const wrapper = shallow<GeneralImageProps>(<GeneralImage {...props} />);
const imageProps = wrapper.find(Image).props();
expect(imageProps.src).toEqual("/images/1234.jpg");
expect(imageProps.preview).toBeUndefined();
const handleVisibleChange = jest.fn();
wrapper.setProps({ visible: true, onVisibleChange: handleVisibleChange });
const preview = wrapper.find(Image).prop("preview") as ImagePreviewType;
expect(preview.visible).toBe(true);
act(() => {
preview.onVisibleChange(false, true);
});
expect(handleVisibleChange).toBeCalledWith(false, true);
});
});
Example #3
Source File: GeneralImage.tsx From next-basics with GNU General Public License v3.0 | 6 votes |
export function GeneralImage(props: GeneralImageProps): React.ReactElement {
const {
width,
height,
src,
alt,
preview,
visible,
onVisibleChange,
placeholder,
fallback,
extra,
extraContainerStyle,
dataSource,
} = props;
return (
<div>
<Image
width={width}
height={height}
src={src}
alt={alt}
preview={!isNil(visible) ? { visible, onVisibleChange } : preview}
placeholder={placeholder}
fallback={fallback}
/>
{extra && (
<div className={style.extraContainer} style={extraContainerStyle}>
<BrickAsComponent useBrick={extra.useBrick} data={dataSource} />
</div>
)}
</div>
);
}
Example #4
Source File: TopCard.tsx From condo with MIT License | 6 votes |
TopCardTitle: React.FC<TopCardTitleProps> = ({ logoSrc, title, description }) => {
const { width } = useWindowSize()
const isSmallLayout = Boolean(width && width < TITLE_VERTICAL_MARK)
const rowMargins: CSSProperties = isSmallLayout ? { marginTop: 180 } : { marginLeft: 200, marginTop: 12 }
return (
<>
<LogoContainer centered={isSmallLayout}>
<Image src={logoSrc || FALLBACK_IMAGE} style={IMAGE_STYLES} preview={false} fallback={FALLBACK_IMAGE}/>
</LogoContainer>
<Row gutter={[0, 16]} style={rowMargins}>
<Col span={24}>
<Typography.Title level={4} style={WRAP_TEXT_STYLES}>
{title}
</Typography.Title>
</Col>
<Col span={24}>
<Typography.Paragraph style={WRAP_TEXT_STYLES} type={'secondary'}>
{description}
</Typography.Paragraph>
</Col>
</Row>
</>
)
}
Example #5
Source File: Logo.tsx From condo with MIT License | 6 votes |
Logo: React.FC<ILogoProps> = (props) => {
const {
onClick,
minified,
fillColor = colors.logoPurple,
} = props
if (minified) {
return (
<LogoWrapper onClick={onClick}>
<svg width="29" height="31" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill="#fff" d="M0 0h29v31H0z"/>
<path fillRule="evenodd" clipRule="evenodd" d="M12.5635 7.1615c-.7113-.572-1.7329-.5692-2.4409.0069L.7004 14.8348C.257 15.1957 0 15.7333 0 16.3006v12.7995c0 1.0492.8619 1.8998 1.925 1.8998h18.9622c1.0632 0 1.9251-.8506 1.9251-1.8998V16.3072c0-.571-.2603-1.1118-.7089-1.4726l-9.5399-7.673Zm6.3986 20.0389v-9.9907l-7.6078-6.1191-7.5041 6.1059v10.0039H18.962Z" fill="url(#a)"/>
<path d="M29 4.0124c0 2.216-1.8177 4.0124-4.0598 4.0124-2.2422 0-4.0598-1.7964-4.0598-4.0124S22.698 0 24.9402 0C27.1823 0 29 1.7964 29 4.0124Z" fill="#FDCF5A"/>
<defs>
<linearGradient id="a" x1="0" y1="18.8671" x2="18.2733" y2="27.9744" gradientUnits="userSpaceOnUse">
<stop stopColor="#4CD174"/><stop offset="1" stopColor="#6DB8F2"/>
</linearGradient>
</defs>
</svg>
</LogoWrapper>
)
}
return (
<LogoWrapper onClick={onClick}>
<Image preview={false} css={SunCSS} src={'/logoSun.svg'}/>
<Image preview={false} src={'/logoDoma.svg'}/>
</LogoWrapper>
)
}
Example #6
Source File: Comment.tsx From condo with MIT License | 6 votes |
CommentFileList: React.FC<CommentFileListProps> = ({ comment }) => {
const files = get(comment, 'files')
const fileList = useMemo(() => files.map(({ id, file }, index) => {
const fileNameArr = file.originalFilename.split('.')
const fileExt = fileNameArr.pop()
const fileName = fileNameArr.join('.')
const mimetype = get(file, 'mimetype')
const url = get(file, 'publicUrl')
const TextWrapComponent = mimetype.startsWith('image') ? Typography.Paragraph : Typography.Link
return (
<TextWrapComponent
href={url}
key={index}
style={TEXT_WRAP_COMPONENT_STYLES}
>
{getFilePreviewByMimetype(mimetype, url)}
<Typography.Paragraph ellipsis={ELLIPSIS_CONFIG} style={FILENAME_TEXT_STYLES}>
{fileName}
<Typography.Text type={'secondary'}>
.{fileExt}
</Typography.Text>
</Typography.Paragraph>
</TextWrapComponent>
)
}), [files])
if (isEmpty(files)) return null
return (
<Image.PreviewGroup>
<CommentFileListWrapper>
{fileList}
</CommentFileListWrapper>
</Image.PreviewGroup>
)
}
Example #7
Source File: index.tsx From metaplex with Apache License 2.0 | 6 votes |
CachedImageContent = ({
uri,
className,
preview,
style,
}: {
uri?: string;
className?: string;
preview?: boolean;
style?: React.CSSProperties;
}) => {
const { cachedBlob } = useCachedImage(uri || '');
return (
<Image
fallback="image-placeholder.svg"
src={cachedBlob}
preview={preview}
wrapperClassName={className}
loading="lazy"
wrapperStyle={{ ...style }}
placeholder={<ThreeDots />}
/>
);
}
Example #8
Source File: index.tsx From metaplex with Apache License 2.0 | 6 votes |
ReviewAndMintStep = ({
uri,
name,
description,
supplyByMetadataKey,
allowedAmountToRedeem,
distributionType,
}: ReviewAndMintStepProps): ReactElement => {
const totalNFTs = getTotalNFTsCount(supplyByMetadataKey);
const numberOfPacks = Math.floor(totalNFTs / allowedAmountToRedeem) || 0;
const isUnlimited = distributionType === PackDistributionType.Unlimited;
return (
<div className="review-step-wrapper">
<Image
wrapperClassName="review-step-wrapper__image-wrapper"
className="review-step-wrapper__image"
src={uri}
preview
loading="lazy"
/>
<p className="review-step-wrapper__title">{name}</p>
<p className="review-step-wrapper__text">{description}</p>
<p className="review-step-wrapper__subtitle">Number of packs</p>
<p className="review-step-wrapper__text">
{isUnlimited ? 'Unlimited' : numberOfPacks}
</p>
<p className="review-step-wrapper__subtitle">Total NFTs</p>
<p className="review-step-wrapper__text">
{isUnlimited ? 'Unlimited' : totalNFTs}
</p>
</div>
);
}
Example #9
Source File: UserWelcomeTitle.tsx From condo with MIT License | 6 votes |
WelcomeHeaderTitle: React.FC = () => {
const intl = useIntl()
const WelcomeTitleMessage = intl.formatMessage({ id: 'pages.auth.IAmResident' })
return (
<Row style={ROW_TITLE_STYLE} gutter={ITEMS_HEADER_GUTTER}>
<Image
preview={false}
src={'/WomanHeaderWelcome.png'}
css={WomanPictureCSS}
/>
<Image
preview={false}
src={'/ManHeaderWelcome.png'}
css={ManPictureCSS}
/>
<Typography.Text
onClick={() => Router.push(LANDING_PAGE_ADDRESS)}
css={WelcomeTypographyCSS}
underline
>
{WelcomeTitleMessage}
</Typography.Text>
</Row>
)
}
Example #10
Source File: everyDay.tsx From Search-Next with GNU General Public License v3.0 | 6 votes |
EveryDay: React.FC<EveryDayProps> = ({ data }) => {
const [url, setUrl] = React.useState<string>('');
React.useEffect(() => {
if (data && data?.url) {
setUrl(data?.url);
}
}, [data]);
return (
<div>
<Alert severity="info">每天更新背景,来源:必应壁纸</Alert>
{url && (
<div
className={classNames(
'm-2 rounded overflow-hidden',
css`
.ant-image {
display: block;
}
`,
)}
>
<Image src={url} />
</div>
)}
</div>
);
}
Example #11
Source File: AppSelectCard.tsx From condo with MIT License | 5 votes |
AppSelectCard: React.FC<AppSelectCardProps> = ({ logoSrc, tag, disabled, url, title, description }) => {
const intl = useIntl()
const MoreMessage = intl.formatMessage({ id: 'miniapps.More' })
const router = useRouter()
const clickHandler = () => {
if (disabled) return
router.push(url)
}
return (
<CardWrapper disabled={disabled}>
<Card
title={<Image src={logoSrc || FALLBACK_IMAGE} style={IMAGE_STYLES} preview={false} fallback={FALLBACK_IMAGE}/>}
bordered={false}
onClick={clickHandler}
>
<Row gutter={[0, 12]}>
<Col span={24}>
<Typography.Title level={5} ellipsis={true}>
{title}
</Typography.Title>
</Col>
<Col span={24}>
<Typography.Paragraph style={PARAGRAPH_STYLE} ellipsis={{ rows: 3 }}>
<Typography.Text type={'secondary'}>
{description}
</Typography.Text>
</Typography.Paragraph>
</Col>
<Col span={24}>
<Button
style={BUTTON_STYLES}
type={'sberBlack'}
disabled={disabled}
>
{MoreMessage}
</Button>
</Col>
</Row>
</Card>
{
tag && (
<TagContainer right={4} top={4}>
<Typography.Text type={'secondary'}>
{tag}
</Typography.Text>
</TagContainer>
)
}
</CardWrapper>
)
}
Example #12
Source File: AboutCard.tsx From condo with MIT License | 5 votes |
AboutCard: React.FC<AboutCardProps> = ({ sections }) => {
const intl = useIntl()
const AboutServiceMessage = intl.formatMessage({ id: 'miniapps.AboutService' })
const { width } = useWindowSize()
const isSingleRow = Boolean(width && width < SINGLE_CARD_WIDTH_MARK)
return (
<CardWrapper>
<Card bordered={false}>
<Row gutter={[0, 40]}>
<Col span={24}>
<Typography.Title level={4}>
{AboutServiceMessage}
</Typography.Title>
</Col>
<Col span={24}>
<Row gutter={[40, 40]}>
{
sections.map((section, index) => {
return (
<Col span={isSingleRow ? 24 : 12} key={index}>
<Card bordered={false} className={'about-block-card'}>
<AboutImageWrapper>
<Image
src={section.imageSrc}
style={IMAGE_STYLE}
preview={false}
className={'about-block-image'}
/>
</AboutImageWrapper>
<Row gutter={[0, 8]} style={TEXT_BLOCK_STYLE}>
<Col span={24}>
<Typography.Title level={5} ellipsis={true}>
{section.title}
</Typography.Title>
</Col>
<Col span={24}>
<Typography.Paragraph style={DESCRIPTION_TEXT_STYLE} type={'secondary'}>
{section.description}
</Typography.Paragraph>
</Col>
</Row>
</Card>
</Col>
)
})
}
</Row>
</Col>
</Row>
</Card>
</CardWrapper>
)
}
Example #13
Source File: WelcomePopup.tsx From condo with MIT License | 5 votes |
export function WelcomePopup () {
const intl = useIntl()
const [step, setStep] = useState(0)
const [visible, setVisible] = useState(true)
const handleModalClose = useCallback(() => setVisible(false), [setVisible])
const stepToContent: WelcomePopupStep[] = useMemo(() => ([
{
imageBackgroundColor: WELCOME_POPUP_BACKGROUND_COLORS.firstStep,
images: [{ src: '/welcomePopupStep1.png', style: { maxHeight: '236px' } }],
},
{
imageBackgroundColor: WELCOME_POPUP_BACKGROUND_COLORS.secondStep,
images: [{ src: '/welcomePopupStep2_1.png', style: { maxHeight: '257px' } }, { src: '/welcomePopupStep2_2.png', style: { maxHeight: '202px', position: 'relative', bottom: '8px' } }],
},
{
imageBackgroundColor: WELCOME_POPUP_BACKGROUND_COLORS.thirdStep,
images: [{ src: '/welcomePopupStep3.png', style: { maxHeight: '202px' } }],
},
]), [])
const stepImages = useMemo(() => stepToContent[step].images.map(image => (
<Col key={image.src}>
<Image style={image.style} src={image.src} preview={false}/>
</Col>
)), [step, stepToContent])
const backgroundImageStyles = useMemo(() => (
{ backgroundColor: stepToContent[step].imageBackgroundColor, height: '300px', display: 'flex', alignItems: 'center', justifyContent: 'center', borderRadius: '12px' }
), [step, stepToContent])
return (
<Modal
css={modalCss}
centered
visible={visible}
closable={false}
onCancel={handleModalClose}
title={<ModalHeader handleModalClose={handleModalClose}/>}
footer={<ModalFooter step={step} setStep={setStep} handleModalClose={handleModalClose}/>}
width={570}
>
<Row gutter={[0, 24]}>
<Col span={24} style={backgroundImageStyles}>
<Row gutter={[0, 20]}>
{stepImages}
</Row>
</Col>
<Col span={24}>
<Row gutter={[0, 12]}>
<Col>
<Typography.Title level={5}>
{intl.formatMessage({ id: `WelcomePopup.step${step + 1}.title` })}
</Typography.Title>
</Col>
<Col>
<Typography.Paragraph style={BODY_TEXT_STYLES}>
{intl.formatMessage({ id: `WelcomePopup.step${step + 1}.text` })}
</Typography.Paragraph>
</Col>
</Row>
</Col>
</Row>
</Modal>
)
}
Example #14
Source File: AuthHeader.tsx From condo with MIT License | 5 votes |
AuthHeader: React.FC<IAuthHeaderProps> = ({ headerAction }) => {
const { isSmall } = useLayoutContext()
const router = useRouter()
const { isAuthenticated } = useAuth()
const handleLogoClick = useCallback(() => {
if (isAuthenticated) {
router.push('/')
} else {
router.push('/auth/signin')
}
}, [isAuthenticated, router])
return (
isSmall
? (
<>
<MobileHeader>
<Row style={LOGO_HEADER_STYLES}>
<Col style={HEADER_LOGO_STYLE}>
<Logo fillColor={colors.backgroundLightGrey} onClick={handleLogoClick}/>
</Col>
<Col style={HEADER_ACTION_STYLES}>
<ActionContainer>{headerAction}</ActionContainer>
</Col>
</Row>
<Row justify={'center'}>
<Col style={MINI_POSTER_STYLES}>
<Image preview={false} src={'/miniPoster.png'}/>
</Col>
</Row>
</MobileHeader>
</>
)
: (
<Row>
<Header>
<Row style={LOGO_HEADER_STYLES}>
<Col style={HEADER_LOGO_STYLE}>
<Logo fillColor={colors.scampi} onClick={handleLogoClick}/>
</Col>
<Col style={HEADER_ACTION_STYLES}>
{headerAction}
</Col>
</Row>
</Header>
</Row>
)
)
}
Example #15
Source File: index.tsx From dashboard with Apache License 2.0 | 5 votes |
ImageUploader: React.FC<ImageUploaderProps> = (props) => {
const {value, onChange} = props;
const [loading, setLoading] = useState<boolean>(false);
return (
<Upload
accept={'.jpg,.png,.jpeg'}
name='avatar'
listType='picture-card'
className={styles.imageUploader}
showUploadList={false}
beforeUpload={(file) => {
if (!['image/jpeg', 'image/png', 'image/jpg'].includes(file.type)) {
message.error('只能上传jpg和png格式');
return false;
}
if (file.size / 1024 / 1024 > 20) {
message.error('图片最大20M');
return false;
}
return true;
}}
onChange={(info) => {
if (info.file.status === 'uploading') {
setLoading(true);
return;
}
if (info.file.status === 'done') {
setLoading(false);
}
}}
{...(_.omit(props, ['value']))}
>
<div>
{value && (
<Badge
count={
<CloseCircleFilled
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (onChange) {
onChange('');
}
setLoading(false);
}}
style={{color: 'rgb(199,199,199)'}}
/>
}
>
<Image
preview={false}
className={styles.image}
src={value}
fallback={defaultImage}
/>
</Badge>
)}
{!value && (
<div className={styles.button}>
{loading ? <LoadingOutlined/> : <PlusCircleFilled/>}
<div className={styles.text}>上传图片</div>
</div>
)}
</div>
</Upload>
);
}
Example #16
Source File: index.tsx From dashboard with Apache License 2.0 | 5 votes |
fileMap = {
'formImage': {
accept: '.jpg,.png',
contentType: ['image/png', 'image/jpg'],
limitSize: 2,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
existValueRender: (value: any, fileInfo: any, fileType: string) => (
<Image
preview={false}
className={styles.image}
src={value}
fallback={defaultImage}
/>
),
// eslint-disable-next-line @typescript-eslint/no-unused-vars
noValueRender: (loading: boolean, fileType: string) => (
<div className={styles.formImageButton}>
{loading ? <LoadingOutlined/> : <PlusCircleFilled/>}
<div className={styles.text}>上传图片</div>
</div>
),
},
'海报': {
accept: '.jpg,.png',
contentType: ['image/png', 'image/jpg'],
limitSize: 2,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
existValueRender: (value: any, fileInfo: any, fileType: string) => (
<Image
preview={false}
className={styles.image}
src={value}
fallback={defaultImage}
/>
),
noValueRender: (loading: boolean, fileType: string) => commonNoValueRender(loading, fileType)
},
'视频': {
accept: '.mp4',
contentType: ['video/mp4'],
limitSize: 10,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
existValueRender: (value: any, fileInfo: any, fileType: string) => (
<video src={value} style={{width: 260}} controls={true}></video>
),
noValueRender: (loading: boolean, fileType: string) => commonNoValueRender(loading, fileType),
},
'PDF': {
accept: '.pdf',
contentType: ['application/pdf'],
limitSize: 20,
image: pdfImage,
existValueRender: (value: any, fileInfo: any, fileType: string) => commonExistValueRender(value, fileInfo, fileType),
noValueRender: (loading: boolean, fileType: string) => commonNoValueRender(loading, fileType),
},
'PPT': {
accept: '.pptx,.ppt',
contentType: ['application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'],
limitSize: 20,
image: pptImage,
existValueRender: (value: any, fileInfo: any, fileType: string) => commonExistValueRender(value, fileInfo, fileType),
noValueRender: (loading: boolean, fileType: string) => commonNoValueRender(loading, fileType),
},
'表格': {
accept: '.xls,.xlsx',
contentType: ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
limitSize: 20,
image: excelImage,
existValueRender: (value: any, fileInfo: any, fileType: string) => commonExistValueRender(value, fileInfo, fileType),
noValueRender: (loading: boolean, fileType: string) => commonNoValueRender(loading, fileType),
},
'文档': {
accept: '.doc,.docx',
contentType: ['application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
limitSize: 20,
image: wordImage,
existValueRender: (value: any, fileInfo: any, fileType: string) => commonExistValueRender(value, fileInfo, fileType),
noValueRender: (loading: boolean, fileType: string) => commonNoValueRender(loading, fileType),
}
}
Example #17
Source File: ScriptContentPreView.tsx From dashboard with Apache License 2.0 | 5 votes |
ScriptContentPreView: React.FC<ScriptContentPreViewProps> = (props) => {
const {script} = props
return (
<div>
{
script.reply_details.map((reply: any, index) => {
if (index < 2) {
return <div style={{width: 200}}>
{
reply.content_type === 2 && <div key={reply.id} style={{width: '100%', margin: '8px 0'}}>
<ExpandableParagraph content={reply.quick_reply_content?.text?.content} rows={4}/>
</div>
}
{
reply.content_type === 3 && <div key={reply.id} className={styles.imageOverview}>
<div className={styles.leftPart}>
<Image src={reply.quick_reply_content?.image?.picurl} width={iconWidth} fallback={damagedImage}/>
</div>
<div className={styles.rightPart}>
<p>{reply.quick_reply_content?.image?.title}</p>
<p>{parseFileSize(reply.quick_reply_content?.image?.size)}</p>
</div>
</div>
}
{
reply.content_type === 4 && <div className={styles.imageOverview}>
<div className={styles.leftPart}>
<Image src={reply.quick_reply_content?.link?.picurl} width={iconWidth} fallback={damagedImage}/>
</div>
<div className={styles.rightPart}>
<Tooltip placement="topLeft" title={reply.quick_reply_content?.link?.title}>
<p>{reply.quick_reply_content?.link?.title}</p>
</Tooltip>
<Tooltip placement="topLeft" title={reply.quick_reply_content?.link?.desc}>
<p>{reply.quick_reply_content?.link?.desc}</p>
</Tooltip>
</div>
</div>
}
{
reply.content_type === 5 && <div className={styles.imageOverview}>
<div className={styles.leftPart}>
<Image src={pdfImage} width={iconWidth} preview={false} fallback={damagedImage}/>
</div>
<div className={styles.rightPart}>
<p>{reply.quick_reply_content?.pdf?.title}</p>
<p>{parseFileSize(reply.quick_reply_content?.pdf?.size)}</p>
</div>
</div>
}
{
reply.content_type === 6 && <div className={styles.imageOverview}>
<div className={styles.leftPart}>
<Image src={videoImage} width={iconWidth} preview={false} fallback={damagedImage}/>
</div>
<div className={styles.rightPart}>
<p>{reply.quick_reply_content?.video?.title}</p>
<p>{parseFileSize(reply.quick_reply_content?.video?.size)}</p>
</div>
</div>
}
</div>
}
if (index === 3) {
return <div style={{color: '#666'}}>...</div>
}
return <></>
})
}
<div style={{color: '#666'}}>共{script.reply_details.length}条</div>
</div>
)
}
Example #18
Source File: index.tsx From dashboard with Apache License 2.0 | 5 votes |
fileMap = {
'formImage': {
accept: '.jpg,.png',
contentType: [ 'image/png', 'image/jpg'],
limitSize: 2,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
existValueRender: (value: any, fileInfo: any, fileType: string) => (
<Image
preview={false}
className={styles.image}
src={value}
fallback={defaultImage}
/>
),
// eslint-disable-next-line @typescript-eslint/no-unused-vars
noValueRender: (loading: boolean, fileType: string) => (
<div className={styles.formImageButton}>
{loading ? <LoadingOutlined/> : <PlusCircleFilled/>}
<div className={styles.text}>上传图片</div>
</div>
),
},
'视频': {
accept: '.mp4',
contentType: ['video/mp4'],
limitSize: 10,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
existValueRender: (value: any, fileInfo: any, fileType: string) => (
<video src={value} style={{width: 260}} controls={true}></video>
),
noValueRender: (loading: boolean, fileType: string) => commonNoValueRender(loading, fileType),
},
'PDF': {
accept: '.pdf',
contentType: ['application/pdf'],
limitSize: 20,
image: pdfImage,
existValueRender: (value: any, fileInfo: any, fileType: string) => commonExistValueRender(value, fileInfo, fileType),
noValueRender: (loading: boolean, fileType: string) => commonNoValueRender(loading, fileType),
},
}
Example #19
Source File: image-renderer.tsx From electron-playground with MIT License | 5 votes |
CodeRenderer: React.FunctionComponent<IMarkdownProps> = props => {
const { src } = props
const parseObj = queryString.parseUrl(src)
return <Image src={src} {...parseObj.query} />
}
Example #20
Source File: UnusedResourceView.tsx From joplin-utils with MIT License | 5 votes |
UnusedResourceView: React.FC = () => {
const [list, setList] = useState<Pick<ResourceProperties, 'id' | 'title' | 'mime'>[]>([])
const [loadingMsg, setLoadingMsg] = useState('')
const [state, onCheck] = useAsyncFn(async () => {
try {
const list = await unusedResourceService.getUnusedResource().on('process', (info) => {
setLoadingMsg(i18n.t('unusedResource.msg.process', info))
})
console.log('list: ', list)
setList(list)
} catch (e) {
message.error(i18n.t('unusedResource.msg.error'))
}
})
async function onRemoveResource(id: string) {
setList(produce((list) => list.filter((item) => item.id !== id)))
await joplinApiGenerator.resourceApi.remove(id)
}
async function onOpenResource(id: string) {
await downloadUrl(buildResourceUrl(id))
}
const [onRemoveAllState, onRemoveAll] = useAsyncFn(async () => {
await AsyncArray.forEach(list, async (item) => {
await joplinApiGenerator.resourceApi.remove(item.id)
})
setList([])
}, [list])
return (
<Card
title={i18n.t('unusedResource.title')}
extra={
<Space>
<Button onClick={onCheck}>{i18n.t('common.action.check')}</Button>
<Button disabled={list.length === 0} danger={true} loading={onRemoveAllState.loading} onClick={onRemoveAll}>
{i18n.t('unusedResource.action.removeAll')}
</Button>
</Space>
}
>
<List
dataSource={list}
locale={{
emptyText: i18n.t('unusedResource.listEmptyText'),
}}
renderItem={(item) => (
<List.Item
key={item.id}
actions={[
<Button onClick={() => onRemoveResource(item.id)}>{i18n.t('common.action.remove')}</Button>,
<Button onClick={() => onOpenResource(item.id)}>{i18n.t('common.action.download')}</Button>,
]}
extra={item.mime.startsWith('image/') && <Image src={buildResourceUrl(item.id)} width={300} />}
>
<List.Item.Meta title={item.title} />
</List.Item>
)}
loading={
{
spinning: state.loading,
tip: loadingMsg,
} as SpinProps
}
/>
</Card>
)
}
Example #21
Source File: AppCarouselCard.tsx From condo with MIT License | 5 votes |
AppCarouselCard: React.FC<AppCarouselCardProps> = ({ logoSrc, title, url }) => {
const intl = useIntl()
const ConnectedLabel = intl.formatMessage({ id: 'Connected' })
const router = useRouter()
const handleCardClick = useCallback(() => {
router.push(url)
}, [router, url])
return (
<CardWrapper>
<Card
onClick={handleCardClick}
bordered={false}
>
<Row gutter={[0, 12]}>
<Col span={24}>
<LogoContainer>
<Image src={logoSrc || FALLBACK_LOGO} height={24} style={IMAGE_STYLES} preview={false} fallback={FALLBACK_LOGO}/>
</LogoContainer>
</Col>
<Col span={24}>
<Typography.Paragraph style={TEXT_BLOCK_STYLE} ellipsis={{ rows: 2 }}>
<Typography.Title level={5} style={TEXT_STYLE}>
{title}
</Typography.Title>
</Typography.Paragraph>
</Col>
<Col span={24}>
<Space size={10} direction={'horizontal'}>
<CheckIcon fill={'#222'}/>
<ConnectContainer>
{ConnectedLabel}
</ConnectContainer>
</Space>
</Col>
</Row>
</Card>
</CardWrapper>
)
}
Example #22
Source File: Comment.tsx From condo with MIT License | 5 votes |
getFilePreviewByMimetype = (mimetype, url) => {
if (mimetype.startsWith('image')) return <Image src={url} width={64} height={64} />
return <CommentFileCard>{getIconByMimetype(mimetype)}</CommentFileCard>
}
Example #23
Source File: link.tsx From Search-Next with GNU General Public License v3.0 | 5 votes |
Link: React.FC<LinkProps> = (props) => {
const { onChange, data } = props;
const [url, setUrl] = React.useState<string>('');
const [blur, setBlur] = React.useState<boolean>(false);
const [isUrl, setIsUrl] = React.useState<boolean>(false);
React.useEffect(() => {
setUrl(data ? data.url : '');
setIsUrl(true);
setBlur(true);
}, [data]);
return (
<div>
<AccordionDetailItem
title="在线图片地址"
action={
<TextField
size="small"
label="链接"
value={url}
placeholder="请输入图片链接"
onFocus={() => setBlur(false)}
onChange={(e) => {
setIsUrl(false);
setUrl(e.target.value);
}}
onBlur={(e) => {
setBlur(true);
const check = isHttpLink.test(url);
if (!check && url.length > 0) {
toast.error('请输入有效的链接');
setIsUrl(false);
}
if (check && url.length > 0) {
setIsUrl(true);
onChange(url);
}
}}
/>
}
/>
{url && blur && isUrl && (
<div
className={classNames(
'm-2 rounded overflow-hidden',
css`
.ant-image {
display: block;
}
`,
)}
>
<Image src={url} />
</div>
)}
</div>
);
}
Example #24
Source File: contact.tsx From fe-v5 with Apache License 2.0 | 5 votes |
export default function version() {
return (
<PageLayout
title={
<>
<Icon component={SystemInfoSvg as any} /> 联系我们
</>
}
hideCluster
>
<div style={{ padding: 10 }}>
<div style={{ padding: 20 }}>
<ul style={{ paddingLeft: 10 }}>
<li>
文档国外地址:
<a href='https://n9e.github.io/' target='_blank'>
https://n9e.github.io/
</a>
</li>
<li>
文档国内地址:
<a href='https://n9e.gitee.io/' target='_blank'>
https://n9e.gitee.io/
</a>
</li>
</ul>
<div style={{ display: 'flex' }}>
<Card style={{ width: 250, marginRight: 10 }} cover={<Image style={{ border: '1px solid #efefef', height: 305 }} preview={false} src={'/image/wx_n9e.png'} />}>
<Meta title={<div style={{ textAlign: 'center' }}>微信公众号</div>} />
</Card>
{/* <Card style={{ width: 250, marginRight: 10 }} cover={<Image style={{ border: '1px solid #efefef', height: 305 }} preview={false} src={'/image/dingtalk.png'} />}>
<Meta title={<div style={{ textAlign: 'center' }}>钉钉交流群</div>} />
</Card>
<Card style={{ width: 250 }} cover={<Image style={{ border: '1px solid #efefef', height: 305 }} preview={false} src={'/image/zhihu.png'} />}>
<Meta title={<div style={{ textAlign: 'center' }}>知乎话题</div>} />
</Card> */}
</div>
</div>
</div>
</PageLayout>
);
}
Example #25
Source File: index.tsx From ant-simple-draw with MIT License | 5 votes |
Img: FC<FormProps<string | null>> = memo(function Img({ value, onChange }) {
const [visible, setVisible] = useState<boolean>(false);
const [url, setUrl] = useState<string | null>(null);
const acceptCallback = useCallback(
(val: string) => {
setUrl(val);
triggerChange(val);
},
[url],
);
const remove = () => {
setUrl(null);
triggerChange(null);
};
const triggerChange = useCallback(
(changedValue: string | null) => {
onChange && onChange(changedValue);
},
[url],
);
const styles = useMemo(() => {
if (url) {
return { width: '48%' };
}
return { width: '100%' };
}, [url]);
useEffect(() => {
if (value) {
setUrl(value);
}
}, [value]);
return (
<div className={style.image}>
<div className={style.main}>{url ? <Image width={100} src={url} /> : null}</div>
<div className={style.btn}>
<Button style={{ ...styles }} onClick={() => setVisible(true)}>
上传
</Button>
{url ? (
<Button style={{ ...styles }} danger onClick={remove}>
清除
</Button>
) : null}
</div>
<ImageGallery
visible={visible}
onCancel={() => setVisible(false)}
callBack={acceptCallback}
/>
</div>
);
})
Example #26
Source File: MarkdownDisplay.tsx From next-basics with GNU General Public License v3.0 | 5 votes |
export function MarkdownDisplay({
value,
imagePreview = true,
}: MarkdownDisplayProps): React.ReactElement {
const history = getHistory();
const baseUrl = location.origin + history.createHref(history.location);
const renderer = {
link(href: string, title: string, text: string) {
href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
if (href === null) {
return text;
}
if (href.startsWith("?")) {
href = location.origin + location.pathname + href;
}
if (href.startsWith("#")) {
href = location.origin + location.pathname + location.search + href;
}
let out = '<a href="' + escape(href) + '"';
if (title) {
out += ' title="' + title + '"';
}
out += ">" + text + "</a>";
return out;
},
image(href: string, _title: string, text: string) {
const imgId = uniqueId(text ?? "");
if (imagePreview) {
const errorImage =
"data:image/png;base64,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";
setTimeout(() => {
ReactDOM.render(
<Image src={href} alt={text} fallback={errorImage} />,
document.getElementById(imgId)
);
});
return `<div class="img-preview" id="${imgId}">
<img src="${errorImage}">
</div>`;
} else {
return `<img src="${href}" alt="${text}">`;
}
},
} as Partial<marked.Renderer> as marked.Renderer;
// https://marked.js.org/using_pro#use
marked.use({ renderer });
DOMPurify.setConfig({ ADD_ATTR: ["target"] });
return (
<div
className={style.customMarkdown}
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(
marked(value || "", {
baseUrl,
breaks: true,
})
),
}}
/>
);
}
Example #27
Source File: YakEnvironment.tsx From yakit with GNU Affero General Public License v3.0 | 4 votes |
YakEnvironment: React.FC<YakEnvironmentProp> = (props) => {
const [connected, setConnected] = useState(false);
const [host, setHost] = useState("127.0.0.1");
const [port, setPort] = useState(8087);
const [tls, setTls] = useState(false);
const [password, setPassword] = useState("");
const [caPem, setCaPem] = useState("");
const [mode, setMode] = useState<"local" | "remote">("local");
const [localLoading, setLocalLoading] = useState(false);
const [historySelected, setHistorySelected] = useState(false);
const [name, setName] = useState("");
const [allowSave, setAllowSave] = useState(false);
const [version, setVersion] = useState("-");
const [existedProcess, setExistedProcesses] = useState<yakProcess[]>([]);
useEffect(() => {
ipcRenderer.invoke("yakit-version").then(setVersion)
}, [])
useEffect(() => {
// setLocalError("");
if (mode) {
props.setMode(mode);
}
// setLocalYakStarted(false);
if (mode !== "local") {
return
}
setHost("127.0.0.1")
}, [mode])
const login = (newHost?: string, newPort?: number) => {
setLocalLoading(true)
// info("正在连接 ... Yak 核心引擎")
let params = {
host: newHost || host,
port: newPort || port,
password, caPem,
};
render.invoke("connect-yak", {...params}).then(() => {
props.onConnected()
if (mode === "remote" && allowSave) {
saveAuthInfo({
...params, tls, name,
})
}
}
).catch(() => {
notification["error"]({message: "设置 Yak gRPC 引擎地址失败"})
}).finally(() => {
setTimeout(() => {
setLocalLoading(false)
}, 200);
})
}
if (!connected) {
return <Spin
spinning={localLoading}
>
<div style={{
textAlign: "center",
marginLeft: 150, marginRight: 150
}}>
<Image src={YakLogoBanner}
style={{marginTop: 120, marginBottom: 40}}
preview={false} width={400}
/>
<br/>
<Text style={{color: "#999"}}>社区专业版:{version}</Text>
<SelectOne label={" "} colon={false} data={[
{value: "local", text: "本地模式(本地启动 Yak gRPC)"},
{value: "remote", text: "远程模式(TeamServer 模式)"}
]} value={mode} setValue={setMode}/>
{mode === "local" && <>
<YakLocalProcess onConnected={((newPort: any, newHost: any) => {
login(newHost, newPort)
})} onProcess={setExistedProcesses}/>
</>}
<Form
style={{textAlign: "left"}}
onSubmitCapture={e => {
e.preventDefault()
// setLocalYakStarted(false)
setLocalLoading(false)
login()
}} labelCol={{span: 7}} wrapperCol={{span: 12}}>
{mode === "remote" && <>
<YakRemoteAuth onSelected={(info) => {
setHistorySelected(true);
setHost(info.host);
setPort(info.port);
setTls(info.tls);
setCaPem(info.caPem);
setPassword(info.password);
}}/>
<SwitchItem value={allowSave} setValue={setAllowSave} label={"保存历史连接"}/>
{allowSave && <InputItem
label={"连接名"}
value={name} setValue={setName}
help={"可选,如果填写了,将会保存历史记录,之后可以选择该记录"}
/>}
<FormItem label={"Yak gRPC 主机地址"}>
<Input value={host} onChange={e => {
setHost(e.target.value)
props.onAddrChanged(`${e.target.value}:${port}`)
}} style={{width: "100%"}}/>
</FormItem>
<FormItem label={"Yak gRPC 端口"}>
<InputNumber
min={1} max={65535}
value={port}
style={{width: "100%"}}
onChange={e => {
setPort(e)
props.onAddrChanged(`${host}:${e}`)
}}
/>
</FormItem>
<SwitchItem label={"启用通信加密认证TLS"} value={tls} setValue={e => {
setTls(e)
props.onTlsGRPC(e)
}}/>
{tls ? <>
<Form.Item
required={true} label={<div>
gRPC Root-CA 证书(PEM)
<Popover content={<div style={{width: 500}}>
<Space direction={"vertical"} style={{width: "100%"}}>
<div>需要 PEM 格式的证书</div>
<div>在通过 <Tag>yak grpc --tls</Tag> 启动核心服务器的时候,会把 RootCA 打印到屏幕上,复制到该输入框即可:</div>
<br/>
<div>例如如下内容:</div>
<div style={{width: 500, height: 400}}>
<YakEditor readOnly={true} value={pemPlaceHolder}/>
</div>
</Space>
</div>}>
<Button
style={{color: "#2f74d0"}}
icon={<QuestionCircleOutlined/>}
type={"link"} ghost={true}
/>
</Popover>
</div>}
>
<div style={{height: 420}}>
<YakEditor
value={caPem} setValue={setCaPem} type={"pem"}
/>
</div>
</Form.Item>
<InputItem
label={"密码"}
setValue={setPassword}
value={password}
type={"password"}
/>
</> : ""}
</>}
{mode !== "local" && <div style={{textAlign: "center"}}>
<Button
style={{
width: 480, height: 50,
}}
htmlType={"submit"}
type={"primary"}
>
<p style={{fontSize: 18, marginBottom: 0}}>Yakit 连接 Yak 核心引擎[{host}:{port}]</p>
</Button>
</div>}
<div style={{textAlign: "center"}}>
<Space style={{
color: '#888',
marginBottom: tls ? 200 : 0,
}}>
<Button type={"link"} onClick={() => {
showModal({
title: "用户协议",
content: <>
{UserProtocol()}
</>
})
}}>用户协议</Button>
<Button.Group>
<Button
onClick={() => {
let m = showModal({
keyboard: false,
title: "引擎升级管理页面",
width: "50%",
content: <>
<YakUpgrade onFinished={() => {
m.destroy()
}} existed={existedProcess}/>
</>
})
}}
>
<p
style={{marginBottom: 0}}
>核心引擎安装与升级</p>
</Button>
<Button
onClick={() => {
let m = showModal({
keyboard: false,
title: "Yakit 升级",
width: "50%",
content: <>
<YakitUpgrade onFinished={() => {
m.destroy()
}}/>
</>
})
}}
>
<p
style={{marginBottom: 0}}
>Yakit 升级</p>
</Button>
</Button.Group>
</Space>
</div>
</Form>
</div>
</Spin>
}
return <div>
</div>
}
Example #28
Source File: RenderMapInit.tsx From amiya with MIT License | 4 votes |
install = (registerTableRender: (key: string, render: (props: RenderProps) => ReactNode) => void) => {
registerTableRender('__options', ({ field, text }: RenderProps) => {
let option = field.options.find((option: Option) => option.value === text)
return option ? option.label : text
})
registerTableRender('__ellipsis', ({ text, field }: RenderProps) => {
return (
<Tooltip placement={field.placement || 'topLeft'} title={text}>
<span>{text || ''}</span>
</Tooltip>
)
})
registerTableRender('datetime', ({ text, field }: RenderProps) => {
if (!text) {
return ''
}
return moment(text).format(field.format || 'YYYY-MM-DD HH:mm:ss')
})
registerTableRender('editable-cell-input', ({ text, field }: RenderProps) => {
const inputRef = useRef<any>(null)
return ({ editing, mode, save }: AnyKeyProps) => {
useEffect(() => {
if (editing && mode === 'col') {
inputRef.current.focus()
}
}, [editing])
return !editing ? (
text
) : (
<Input placeholder="请输入" {...field.contentProps} ref={inputRef} onBlur={save} onPressEnter={save} />
)
}
})
registerTableRender('editable-cell-select', ({ text, field }: RenderProps) => {
const selectRef = useRef<any>(null)
const options = field.options || []
let label = ''
if (Array.isArray(text)) {
if (!text.length) {
text = FORM_READONLY_EMPTY
}
label = text.map((item: any) => getValueByOptions(item, field.options)).join(field.splitText || '、')
} else {
label = getValueByOptions(text, field.options)
}
return ({ editing, save, mode }: AnyKeyProps) => {
useEffect(() => {
if (editing && mode === 'col') {
selectRef.current.focus()
}
}, [editing])
return !editing ? (
label
) : (
<AySelect
placeholder="请选择"
style={{ width: '100%' }}
{...field.contentProps}
ref={selectRef}
options={options}
onBlur={save}
/>
)
}
})
registerTableRender('image', ({ text, field }: RenderProps) => {
return <Image width={100} {...field.props} src={text} />
})
registerTableRender('html', ({ text, field }: RenderProps) => {
return <div dangerouslySetInnerHTML={{ __html: text }}></div>
})
registerTableRender('tags', ({ text, field }: RenderProps) => {
if (!Array.isArray(text) || !field.colorMap) {
return text
}
return text.map((item: string) => (
<Tag key={item} color={field.colorMap[item]}>
{item}
</Tag>
))
})
registerTableRender('unit', ({ text, field }: RenderProps) => {
return (
<div>
{field.prefix}
{text}
{field.suffix}
</div>
)
})
/**
* 5
* @decs 状态加文字
*
* @returns ReactNode
*/
registerTableRender('status', ({ text, field }: AnyKeyProps) => {
const { options = [] } = field
return renderStatus(text, options, field.type)
})
}
Example #29
Source File: index.tsx From amiya with MIT License | 4 votes |
fields = [ { title: <AySearchList.SelectionAll />, key: 'selection', width: 50, onCell, render: (value: string, record: Record) => ( <AySearchList.Selection record={record} disabled={record.rowSpan === 0} /> ) }, { title: '商品名称&店铺', key: 'name', onCell, width: 300, render: (value: string, record: Record) => { return ( <div style={{ height: '100%' }}> <Space> <Image style={{ flexShrink: 0 }} src={record.image} width={80} height={80} /> <div> <div> <a href={record.shopUrl}> {record.details.length > 0 && <span style={{ color: 'orange' }}>[多规格]</span>} {value} </a> </div> <span className="tag">{record.shopName}</span> </div> </Space> </div> ) }, search: { title: '商品名称', type: 'input-group', key: '__group', children: [ { type: 'select', key: 'keywordType', options: [ { label: '商品名称', value: 1 }, { label: '规格名称', value: 2 } ], defaultValue: 1, allowClear: false, style: { width: 100 } }, { key: 'keyword', style: { width: `calc(100% - 100px)` } } ] } }, { title: '父规格', key: 'spu', width: 120, search: { title: '规格', key: 'sku', type: 'select', style: { width: 120 }, options: [ { label: '规格选项A', value: 1 }, { label: '规格选项B', value: 2 } ] }, render: (value: string) => value || '-', onCell }, { table: false, search: { title: '排序', key: 'sort', type: 'select', style: { width: 120 }, options: [ { label: '排序A', value: 1 }, { label: '排序B', value: 2 } ] } }, { title: '规格', dataIndex: ['child', 'name'], key: 'childName', render: (value: string, record: Record) => ( <span> {value} <AySearchList.Selection style={{ display: 'none' }} record={record} disabled={record.rowSpan === 0} /> </span> ) }, { title: '价格', dataIndex: ['child', 'price'], key: 'childPrice', align: 'right', renderType: 'unit', prefix: '¥' }, { title: '库存', dataIndex: ['child', 'stock'], key: 'childStock', align: 'right', renderType: 'unit', prefix: 'x' }, { title: '创建时间', width: 120, key: 'createDateTime', renderType: 'datetime', onCell }, { title: '创建时间', width: 120, key: 'updateDatetime', renderType: 'datetime', onCell } ]