From 5a08d410c57c3bac8635a45f1504d3da548164f3 Mon Sep 17 00:00:00 2001 From: Benjy Cui Date: Wed, 2 Mar 2016 17:12:43 +0800 Subject: [PATCH] chore: support preview image in Modal --- docs/pattern/advanced-search.md | 3 +- docs/pattern/complex-table.md | 3 +- docs/pattern/form.md | 7 +- docs/pattern/index.md | 3 +- docs/pattern/list.md | 11 +-- docs/pattern/navigation.md | 19 ++--- docs/pattern/table.md | 7 +- docs/practice/cases.md | 8 +- site/common/lib.js | 1 + site/common/styles/preview-img.less | 87 ++++++++++++++++++++ site/component/Article/ImagePreview.jsx | 101 ++++++++++++++++++++++++ site/component/Article/index.jsx | 25 +++++- site/component/MainContent/index.jsx | 6 +- site/component/utils.js | 4 + site/entry/utils.js | 8 +- 15 files changed, 262 insertions(+), 31 deletions(-) create mode 100644 site/common/styles/preview-img.less create mode 100644 site/component/Article/ImagePreview.jsx diff --git a/docs/pattern/advanced-search.md b/docs/pattern/advanced-search.md index 03cfaa15bd..b31591e1ec 100644 --- a/docs/pattern/advanced-search.md +++ b/docs/pattern/advanced-search.md @@ -1,7 +1,8 @@ -# 高级搜索 +# Advanced Search - category: 6 - order: 6 +- chinese: 高级搜索 --- diff --git a/docs/pattern/complex-table.md b/docs/pattern/complex-table.md index 2c4e103a70..71498649c4 100644 --- a/docs/pattern/complex-table.md +++ b/docs/pattern/complex-table.md @@ -1,7 +1,8 @@ -# 表格:复杂数据 +# Complex Table - category: 5 - order: 5 +- chinese: 表格:复杂数据 --- diff --git a/docs/pattern/form.md b/docs/pattern/form.md index ac865a1b5f..6107320cf9 100644 --- a/docs/pattern/form.md +++ b/docs/pattern/form.md @@ -1,7 +1,8 @@ -# 表单 +# Form - category: 2 - order: 2 +- chinese: 表单 --- @@ -121,8 +122,8 @@ ### 输入框宽度 -正确示例 -错误示例 +正确示例 +错误示例 当内容可预知,可以根据内容长短进行定义其落在多少个栅格上。 diff --git a/docs/pattern/index.md b/docs/pattern/index.md index 4f064c76e9..04a6e0d98f 100644 --- a/docs/pattern/index.md +++ b/docs/pattern/index.md @@ -1,8 +1,9 @@ -# 典型页面 +# Classic - category: 0 - order: 0 - disabled: true +- chinese: 典型页面 --- diff --git a/docs/pattern/list.md b/docs/pattern/list.md index 2abd1a1d6b..8849d95af7 100644 --- a/docs/pattern/list.md +++ b/docs/pattern/list.md @@ -1,7 +1,8 @@ -# 列表 +# List - category: 3 - order: 3 +- chinese: 列表 --- @@ -17,7 +18,7 @@ ### 显示详情信息 -气泡显示示例 +气泡显示示例 气泡显示:用户鼠标点击/悬停某个链接或内容时,在悬浮层上显示该条列表项少量的详情信息。 @@ -60,19 +61,19 @@
-对等网格示例 +对等网格示例 对等网格:以网格或者矩阵的方式排列内容元素,其中每个元素都有相仿的视觉重量。 ### 显示图片 -走马灯示例 +走马灯示例 走马灯:以一维的形式来显示图片,可用户主动触发或者系统自动播放。
-缩略图网格示例 +缩略图网格示例 缩略图网格:以二维的形式来展现图片/Icon,具有强烈的视觉效果,可以吸引用户注意。 diff --git a/docs/pattern/navigation.md b/docs/pattern/navigation.md index 7f2c68132b..b9aee6805a 100644 --- a/docs/pattern/navigation.md +++ b/docs/pattern/navigation.md @@ -1,7 +1,8 @@ -# 导航 +# Navigation - category: 1 - order: 1 +- chinese: 导航 --- @@ -44,7 +45,7 @@ --- -结构示例 +结构示例 导航的结构由以下几部分组成。 @@ -63,11 +64,11 @@
-一级类目 +一级类目 -二级类目 +二级类目 -三级类目及以上 +三级类目及以上 我们定义了不同类目层级所对应的导航样式。 @@ -76,7 +77,7 @@ --- -结构示例 +结构示例 导航的结构由以下几部分组成。 @@ -87,10 +88,10 @@
-一级类目 +一级类目 -二级类目 +二级类目 -三级类目及以上 +三级类目及以上 不同类目层级。 diff --git a/docs/pattern/table.md b/docs/pattern/table.md index 67f56b6ac1..07e127a647 100644 --- a/docs/pattern/table.md +++ b/docs/pattern/table.md @@ -1,7 +1,8 @@ -# 表格 +# Table - category: 4 - order: 4 +- chinese: 表格 --- @@ -138,9 +139,9 @@ ### 列宽 -错误示例 +错误示例 -正确示例 +正确示例 一般是根据栅格来排版,通过设定每一列的宽度比列,来保证一定尺寸之上(eg:1366px)有好的浏览效果。需要注意: diff --git a/docs/practice/cases.md b/docs/practice/cases.md index c7c7094e87..b4239f77e9 100644 --- a/docs/practice/cases.md +++ b/docs/practice/cases.md @@ -18,7 +18,7 @@ Ant Design 目前在外部也有 [许多产品实践](https://github.com/ant-des ### 金融云 - + @@ -30,7 +30,7 @@ Ant Design 目前在外部也有 [许多产品实践](https://github.com/ant-des ### OceanBase Cloud Platform - + @@ -42,7 +42,7 @@ OceanBase 是一款真正意义上的云端分布式关系型数据库,而 Oce ### 服务宝体验平台 - + @@ -56,7 +56,7 @@ OceanBase 是一款真正意义上的云端分布式关系型数据库,而 Oce ### AntV - + diff --git a/site/common/lib.js b/site/common/lib.js index 291f4cfef0..63b118065a 100644 --- a/site/common/lib.js +++ b/site/common/lib.js @@ -9,3 +9,4 @@ import './styles/clearfix.less'; import './styles/demo.less'; import './styles/page-nav.less'; import './styles/footer.less'; +import './styles/preview-img.less'; diff --git a/site/common/styles/preview-img.less b/site/common/styles/preview-img.less new file mode 100644 index 0000000000..452b9c3b6e --- /dev/null +++ b/site/common/styles/preview-img.less @@ -0,0 +1,87 @@ +.preview-image-boxes { + float: right; + margin: 0 0 110px 60px; + width: 616px; + + &-with-popup { + width: 420px; + } +} + +.preview-image-boxes + .preview-image-boxes { + margin-top: -75px; +} + +.preview-image-box { + width: 100%; + float: left; + padding: 0 8px; +} + +.preview-image-wrapper { + background: #f4f4f4; + padding: 16px; + display: inline-block; + text-align: center; + width: 100%; + position: relative; +} + +.preview-image-wrapper.good:after { + content: ''; + width: 100%; + height: 3px; + background: #2db7f5; + display: block; + position: absolute; + bottom: 0; + left: 0; +} + +.preview-image-wrapper.bad:after { + content: ''; + width: 100%; + height: 3px; + background: #f50; + display: block; + position: absolute; + bottom: 0; + left: 0; +} + +.preview-image-title { + font-size: 12px; + margin-top: 5px; + color: #666; +} + +.preview-image-description { + font-size: 12px; + margin-top: 2px; + color: #999; + line-height: 1.5; +} + +.preview-image-description hr { + margin: 2px 0; + border: 0; + background: none; +} + +.preview-image-box img { + cursor: pointer; + max-width: 100%; + transition: all 0.3s ease; + background: #fff; + padding: 12px; + border-radius: 6px; +} + +.preview-image-boxes.pack img { + padding: 0; + box-shadow: 0 1px 0 0 #ddd, 0 3px 0 0 #fff, 0 4px 0 0 #ddd, 0 6px 0 0 #fff, 0 7px 0 0 #ddd; +} + +.preview-image-box img:hover { + box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.3); +} \ No newline at end of file diff --git a/site/component/Article/ImagePreview.jsx b/site/component/Article/ImagePreview.jsx new file mode 100644 index 0000000000..8cae831e52 --- /dev/null +++ b/site/component/Article/ImagePreview.jsx @@ -0,0 +1,101 @@ +import React from 'react'; +import { Modal, Carousel } from '../../../'; + +function isGood(className) { + return /\bgood\b/i.test(className); +} +function isBad(className) { + return /\bbad\b/i.test(className); +} + +const parser = new DOMParser(); +export default class ImagePreview extends React.Component { + constructor(props) { + super(props); + + this.state = { + leftVisible: false, + rightVisible: false, + }; + } + + handleClick(side) { + this.setState({ [`${side}Visible`]: true }); + } + + handleCancel() { + this.setState({ + leftVisible: false, + rightVisible: false, + }); + } + + render() { + const { className, imgs } = this.props; + const imgsMeta = imgs.map((img) => { + const xml = parser.parseFromString(img, 'application/xml'); + const attributes = xml.firstChild.attributes; + const { alt, description, src } = attributes; + const imgClassName = attributes.class.nodeValue; + return { + alt: alt && alt.nodeValue, + description: description && description.nodeValue, + src: src.nodeValue, + isGood: isGood(imgClassName), + isBad: isBad(imgClassName), + }; + }); + + const cover = imgsMeta[0]; + const imagesList = imgsMeta.map((meta, index) => { + return ; + }); + const comparable = imgs.length === 2 && + (imgsMeta[0].isGood || imgsMeta[0].isBad) && + (imgsMeta[1].isGood || imgsMeta[1].isBad); + const style = comparable ? { width: '50%' } : null; + return ( +
+
+
+ Sample Picture +
+
{cover.alt}
+
+ {cover.description} +
+ + + + { comparable ? imagesList[0] : imagesList } + + +
+ { + comparable ? +
+
+ Sample Picture +
+
{imgsMeta[1].alt}
+
+ {imgsMeta[1].description} +
+ + + + { comparable ? imagesList[1] : imagesList } + + +
: null + } +
+ ); + } +} diff --git a/site/component/Article/index.jsx b/site/component/Article/index.jsx index e23b09da20..529ac187a7 100644 --- a/site/component/Article/index.jsx +++ b/site/component/Article/index.jsx @@ -1,6 +1,27 @@ import React from 'react'; +import classNames from 'classnames'; +import ImagePreview from './ImagePreview'; import * as utils from '../utils'; +function isPreviewImg(string) { + return /^ 1; + const previewClassName = classNames({ + 'preview-image-boxes': true, + clearfix: true, + 'preview-image-boxes-with-popup': hasPopup, + }); + return ; +} + export default class Article extends React.Component { render() { const content = this.props.content; @@ -10,9 +31,11 @@ export default class Article extends React.Component { return
  • { node.children }
  • ; }); + content.description = content.description.map(imgToPreview); + return (
    -

    { content.meta.title }

    +

    { content.meta.chinese }

    { jumper.length > 0 ?
      { jumper }
    : diff --git a/site/component/MainContent/index.jsx b/site/component/MainContent/index.jsx index c3b8ea21b8..e09c4cd0a3 100644 --- a/site/component/MainContent/index.jsx +++ b/site/component/MainContent/index.jsx @@ -3,11 +3,15 @@ import { Link } from 'react-router'; import { Row, Col, Menu } from '../../../'; import * as utils from '../utils'; +function dashed(name) { + return name.toLowerCase().trim().replace(/\s+/g, '-'); +} + export default class MainContent extends React.Component { getMenuItems() { const props = this.props; return props.menuItems.map((item) => { - const key = item.english.toLowerCase(); + const key = dashed(item.english); const text = item.chinese || item.english; const disabled = item.disabled === 'true'; diff --git a/site/component/utils.js b/site/component/utils.js index 8a437f2e59..080726d42f 100644 --- a/site/component/utils.js +++ b/site/component/utils.js @@ -9,6 +9,10 @@ function isHeading(type) { export function objectToComponent(object, index) { if (object === null) return; + if (React.isValidElement(object)) { + return React.cloneElement(object, { key: index }); + } + if (typeof object === 'string') { return { object }; } diff --git a/site/entry/utils.js b/site/entry/utils.js index aff88072f2..35d7d8087f 100644 --- a/site/entry/utils.js +++ b/site/entry/utils.js @@ -2,12 +2,16 @@ import React from 'react'; import { Route, IndexRedirect } from 'react-router'; import Article from '../component/Article'; +function dashed(name) { + return name.toLowerCase().trim().replace(/\s+/g, '-'); +} + export function generateChildren(pagesData) { const children = pagesData.map((pageData, index) => { const ArticleWrapper = () =>
    ; return ( ); }); @@ -16,7 +20,7 @@ export function generateChildren(pagesData) { }); children.unshift( + to={dashed(firstChild.meta.english)} /> ); return children; }