Procházet zdrojové kódy

impl grid with bootstrap grid system

Yuki Takei před 6 roky
rodič
revize
9f97fd6824

+ 88 - 16
packages/growi-plugin-attachment-refs/src/client/js/components/ExtractedAttachments.jsx

@@ -13,22 +13,24 @@ const AttachmentLink = Attachment;
  */
 export default class ExtractedAttachments extends React.PureComponent {
 
-  renderExtractedImage(attachment, styles) {
-    const { refsContext } = this.props;
-    const { options } = refsContext;
+  /**
+   * Splits an array into an array of smaller arrays containing `chunkSize` members
+   * @see https://gist.github.com/webinista/11240585#gistcomment-1421302
+   * @param {Array} array
+   * @param {number} chunkSize
+   */
+  splitToChunks(array, chunkSize) {
+    const sets = [];
+    const chunks = array.length / chunkSize;
 
-    // determine alt
-    let alt = refsContext.isSingle ? options.alt : undefined; // use only when single mode
-    alt = alt || attachment.originalName; //                     use 'originalName' if options.alt is not specified
+    for (let i = 0, j = 0; i < chunks; i++, j += chunkSize) {
+      sets[i] = array.slice(j, j + chunkSize);
+    }
 
-    return (
-      <a key={attachment._id} href="#" style={styles}>
-        <img src={attachment.filePathProxied} alt={alt} style={styles} />
-      </a>
-    );
+    return sets;
   }
 
-  render() {
+  getClassesAndStyles() {
     const { refsContext } = this.props;
     const { options } = refsContext;
 
@@ -37,19 +39,89 @@ export default class ExtractedAttachments extends React.PureComponent {
       height,
       'max-width': maxWidth,
       'max-height': maxHeight,
+      display = 'block',
     } = options;
 
-    const styles = {
-      width, height, maxWidth, maxHeight, display: 'block',
+    let anchorClasses = [];
+    let imageClasses = [];
+    const anchorStyles = {
+      width, height, maxWidth, maxHeight,
     };
+    const imageStyles = {
+      height, maxHeight,
+    };
+
+    const columnSize = refsContext.getOptColumnSize();
+    // grid mode
+    if (columnSize != null) {
+      anchorClasses = anchorClasses.concat([`col-sm-${columnSize}`]);
+      // fit image to the parent
+      imageClasses = imageClasses.concat(['w-100']);
+      Object.assign(imageStyles, { objectFit: 'cover' });
+    }
+    else {
+      // init width/maxWidth
+      Object.assign(imageStyles, { width, maxWidth });
+    }
+
+    Object.assign(anchorStyles, { display });
+
+    return {
+      anchorClasses,
+      imageClasses,
+      anchorStyles,
+      imageStyles,
+    };
+  }
+
+  renderExtractedImage(attachment) {
+    const { refsContext } = this.props;
+    const { options } = refsContext;
 
-    return this.props.attachments.map((attachment) => {
+    // determine alt
+    let alt = refsContext.isSingle ? options.alt : undefined; // use only when single mode
+    alt = alt || attachment.originalName; //                     use 'originalName' if options.alt is not specified
+
+    // get styles
+    const {
+      anchorClasses, imageClasses, anchorStyles, imageStyles,
+    } = this.getClassesAndStyles();
+
+    return (
+      <a key={attachment._id} href="#" className={anchorClasses.join(' ')} style={anchorStyles}>
+        <img src={attachment.filePathProxied} alt={alt} className={imageClasses.join(' ')} style={imageStyles} />
+      </a>
+    );
+  }
+
+  render() {
+    const { refsContext } = this.props;
+
+    const contents = this.props.attachments.map((attachment) => {
       const isImage = attachment.fileFormat.startsWith('image/');
 
       return (isImage)
-        ? this.renderExtractedImage(attachment, styles)
+        ? this.renderExtractedImage(attachment)
         : <AttachmentLink key={attachment._id} attachment={attachment} />;
     });
+
+    const columnSize = refsContext.getOptColumnSize();
+    let contentChunks; // [[c1, c2, c3], [c4, c5, c6], ...]
+    if (columnSize != null) {
+      contentChunks = this.splitToChunks(contents, 12 / columnSize);
+    }
+    else {
+      contentChunks = [contents];
+    }
+
+    return contentChunks.map((chunk, index) => {
+      return (
+        // eslint-disable-next-line react/no-array-index-key
+        <div key={`row-chunk-${index}`} className="row mt-5">
+          {chunk}
+        </div>
+      );
+    });
   }
 
 }

+ 28 - 1
packages/growi-plugin-attachment-refs/src/client/js/util/RefsContext.js

@@ -91,7 +91,6 @@ export default class RefsContext extends TagContext {
 
       this.pagePath = this.getAbsolutePathFor(specifiedPath);
     }
-
   }
 
   // resolve pagePath
@@ -112,6 +111,34 @@ export default class RefsContext extends TagContext {
     return OptionParser.parseRange(this.options.depth);
   }
 
+  getOptColumnSize() {
+    const { grid } = this.options;
+
+    let columnSize = null;
+
+    if (grid != null) {
+      switch (grid) {
+        case 'col-6':
+          columnSize = 6;
+          break;
+        case 'col-4':
+          columnSize = 4;
+          break;
+        case 'col-3':
+          columnSize = 3;
+          break;
+        case 'col-2':
+          columnSize = 2;
+          break;
+        case 'col-1':
+          columnSize = 1;
+          break;
+      }
+    }
+
+    return columnSize;
+  }
+
   /**
    * return absolute path for the specified path
    *