Skip to content

Commit

Permalink
feat(grid-list): Implement mdc-grid-list (#47) (#359)
Browse files Browse the repository at this point in the history
  • Loading branch information
yeelan0319 authored Mar 10, 2017
1 parent cc939ea commit 5b84e73
Show file tree
Hide file tree
Showing 14 changed files with 1,442 additions and 0 deletions.
666 changes: 666 additions & 0 deletions demos/grid-list.html

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions demos/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<li><a href="drawer/permanent-drawer-below-toolbar.html">Drawer (permanent, below toolbar)</a></li>
<li><a href="elevation.html">Elevation</a></li>
<li><a href="fab.html">FAB</a></li>
<li><a href="grid-list.html">Grid List</a></li>
<li><a href="icon-toggle.html">Icon Toggle</a></li>
<li><a href="layout-grid.html">Layout grid</a></li>
<li><a href="list.html">List</a></li>
Expand Down
3 changes: 3 additions & 0 deletions packages/material-components-web/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import * as base from '@material/base';
import * as checkbox from '@material/checkbox';
import * as formField from '@material/form-field';
import * as gridList from '@material/grid-list';
import * as iconToggle from '@material/icon-toggle';
import * as radio from '@material/radio';
import * as ripple from '@material/ripple';
Expand All @@ -31,6 +32,7 @@ import autoInit from '@material/auto-init';
autoInit.register('MDCCheckbox', checkbox.MDCCheckbox);
autoInit.register('MDCTemporaryDrawer', drawer.MDCTemporaryDrawer);
autoInit.register('MDCRipple', ripple.MDCRipple);
autoInit.register('MDCGridList', gridList.MDCGridList);
autoInit.register('MDCIconToggle', iconToggle.MDCIconToggle);
autoInit.register('MDCRadio', radio.MDCRadio);
autoInit.register('MDCSnackbar', snackbar.MDCSnackbar);
Expand All @@ -43,6 +45,7 @@ export {
base,
checkbox,
formField,
gridList,
iconToggle,
radio,
ripple,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
@import "@material/elevation/mdc-elevation";
@import "@material/fab/mdc-fab";
@import "@material/form-field/mdc-form-field";
@import "@material/grid-list/mdc-grid-list";
@import "@material/icon-toggle/mdc-icon-toggle";
@import "@material/layout-grid/mdc-layout-grid";
@import "@material/list/mdc-list";
Expand Down
1 change: 1 addition & 0 deletions packages/material-components-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@material/elevation": "^0.1.3",
"@material/fab": "^0.3.3",
"@material/form-field": "^0.2.1",
"@material/grid-list": "^0.0.0",
"@material/icon-toggle": "^0.1.5",
"@material/layout-grid": "^0.1.1",
"@material/list": "^0.2.3",
Expand Down
264 changes: 264 additions & 0 deletions packages/mdc-grid-list/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
# MDC Grid list

MDC Grid list provides a RTL-aware Material Design Grid list component adhering to the
[Material Design Grid list spec](https://material.io/guidelines/components/grid-lists.html).
Grid Lists are best suited for presenting homogeneous data, typically images.
Each item in a grid list is called a **tile**. Tiles maintain consistent width, height, and padding
across screen sizes.


## Installation

```
npm install --save @material/grid-list
```


## Usage

Basic Grid list has the following structure:

```html
<div class="mdc-grid-list">
<ul class="mdc-grid-list__tiles">
<li class="mdc-grid-tile">
<div class="mdc-grid-tile__primary">
<img class="mdc-grid-tile__primary-content" src="my-image.jpg" />
</div>
<span class="mdc-grid-tile__secondary">
<span class="mdc-grid-tile__title">Title</span>
</span>
</li>
<li class="mdc-grid-tile">
<div class="mdc-grid-tile__primary">
<img class="mdc-grid-tile__primary-content" src="my-image.jpg" />
</div>
<span class="mdc-grid-tile__secondary">
<span class="mdc-grid-tile__title">Title</span>
</span>
</li>
</ul>
</div>
```

The above markup will give you a Grid list of tiles that:

- Have 4px padding in between themselves
- Have a 1x1 aspect ratio
- Have a one-line footer caption with no icon

You just need to put the content you want to load in `src` of
`<img class="mdc-grid-tile__primary-content" src="..."/>`. However, if your
assets don't have the same aspect ratio you as specified in the tile, it will
distort those assets. We provide a solution of that case in
[Using a div in place of an img](#using-a-div-in-place-of-an-img) section.


### Setting the tile width

The tile width is set to 200px by default. There are three ways that you can
overwrite the default value for your grid list:

1. Using CSS variables

```css
.mdc-grid-tile {
--mdc-grid-list-tile-width: 300px;
}
```

2. Overwriting SCSS variable

You can overwrite the scss variable by

```scss
@import "@material/grid-list/mdc-grid-list";
$mdc-grid-list-tile-width: 300px;
```

3. Add own style to tile

```html
<style>
.my-grid-list .mdc-grid-tile {
width : 300px;
}
</style>
<div class="mdc-grid-list my-grid-list">
<ul class="mdc-grid-list__tiles">
<li class="mdc-grid-tile"></li>
...
</ul>
</div>
```

### Change tile padding

Grid list tiles can have 1px padding instead of 4px by adding
`mdc-grid-list--tile-gutter-1` modifier.

```html
<div class="mdc-grid-list mdc-grid-list--tile-gutter-1">
<ul class="mdc-grid-list__tiles">
...
</ul>
</div>
```

### Image only tile

Grid lists support image only tile. You can remove `mdc-grid-tile__secondary`
and create a image only grid list.

```html
<div class="mdc-grid-list mdc-grid-list--tile-gutter-1">
<ul class="mdc-grid-list__tiles">
<li class="mdc-grid-tile">
<div class="mdc-grid-tile__primary">
<img class="mdc-grid-tile__primary-content" src="images/1-1.jpg" />
</div>
</li>
</ul>
</div>
```

### Header caption

Grid lists support header caption. You can change the footer caption to be a
header caption by adding `mdc-grid-list--header-caption` modifier.

```html
<div class="mdc-grid-list mdc-grid-list--header-caption">
<ul class="mdc-grid-list__tiles">
...
</ul>
</div>
```

### Add support text to secondary content (caption)

Grid lists support a one-line caption by default. You can add an additional line of support
text if needed by adding the `mdc-grid-list--twoline-caption` modifier and additional
markup

```html
<div class="mdc-grid-list mdc-grid-list--twoline-caption">
<ul class="mdc-grid-list__tiles">
<li class="mdc-grid-tile">
<div class="mdc-grid-tile__primary">
<img class="mdc-grid-tile__primary-content" src="my-image.jpg" />
</div>
<span class="mdc-grid-tile__secondary">
<span class="mdc-grid-tile__title">Title</span>
<span class="mdc-grid-tile__support-text">Support text</span>
</span>
</li>
</ul>
</div>
```

### Add icon to secondary content (caption)

You can add an icon to a caption by adding `mdc-grid-list--with-icon-align-start` or
`mdc-grid-list--with-icon-align-end` and changing the markup.

```html
<div class="mdc-grid-list mdc-grid-list--with-icon-align-start">
<ul class="mdc-grid-list__tiles">
<li class="mdc-grid-tile">
<div class="mdc-grid-tile__primary">
<img class="mdc-grid-tile__primary-content" src="my-image.jpg" />
</div>
<span class="mdc-grid-tile__secondary">
<i class="mdc-grid-tile__icon material-icons">star_border</i>
<span class="mdc-grid-tile__title">Title</span>
</span>
</li>
</ul>
</div>
```

### Change aspect ratio of tile

Grid list tiles support all material guideline recommended aspect ratio:

- 1x1
- 16x9
- 2x3
- 3x2
- 4x3
- 3x4

You can use the modifier class `mdc-grid-list--tile-aspect-$ASPECT_RATIO` to apply these aspect
ratios to your grid list. Simply replace `$ASPECT_RATIO` with any of the predefined ratios.

```html
<!-- Example of 16x9 tile -->
<div class="mdc-grid-list mdc-grid-list--tile-aspect-16x9">
<ul class="mdc-grid-list__tiles">
...
</ul>
</div>
```

As pointed out in the previous section, if your
assets don't have the same aspect ratio you as specified in the tile, it will
distort those assets. We provide a solution of that case in
[Using a div in place of an img](#using-a-div-in-place-of-an-img) section.

### Using a div in place of an img

In case you cannot ensure all your assets will have the same aspect ratio, you
can use `div` instead of `img` markup. It will resize the assets to cover the tile
and crop the assets to display the center part.

```html
<style>
.my-tile-image {
background-image: url(my-image.jpg);
}
</style>
<div class="mdc-grid-list">
<ul class="mdc-grid-list__tiles">
<li class="mdc-grid-tile">
<div class="mdc-grid-tile__primary">
<div class="mdc-grid-tile__primary-content my-tile-image"></div>
</div>
<span class="mdc-grid-tile__secondary">
<span class="mdc-grid-tile__title">Title</span>
</span>
</li>
</ul>
</div>
```

However, the method results in a less semantic markup, so we don't use this method by
default.


### RTL Support

`mdc-grid-list` is automatically RTL-aware, and will re-position elements whenever
it, or its ancestors, have a `dir="rtl"` attribute.


### Theme

`mdc-grid-list` supports theming. `mdc-grid-tile__primary` uses the theme's background
color for its background color. `mdc-grid-tile__secondary` uses the theme's primary
color for it's background color, and the theme's `text-primary-on-primary` color for its text color.

### Using the Foundation Class

MDCGridList ships with an `MDCGridListFoundation` class that external frameworks and libraries
can use to build their own MDCGridList components with minimal effort. As with all foundation
classes, an adapter object must be provided. The adapter for Grid list must provide the following
functions, with correct signatures:

| Method Signature | Description |
| --- | --- |
| `getOffsetWidth() => number` | Get root element `mdc-grid-list` offsetWidth. |
| `getOffsetWidthForTileAtIndex(index: number) => number` | Get offsetWidth of `mdc-grid-tile` at specified index. |
| `setStyleForTilesElement(property: string, value: number) => void` | Set `mdc-grid-list__tiles` style property to provided value. |
| `registerResizeHandler(handler: Function) => void` | Registers a handler to be called when the surface (or its viewport) resizes. Our default implementation adds the handler as a listener to the window's `resize()` event. |
| `deregisterResizeHandler(handler: Function) => void` | Unregisters a handler to be called when the surface (or its viewport) resizes. Our default implementation removes the handler as a listener to the window's `resize()` event. |
19 changes: 19 additions & 0 deletions packages/mdc-grid-list/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const strings = {
TILES_SELECTOR: '.mdc-grid-list__tiles',
TILE_SELECTOR: '.mdc-grid-tile',
};
61 changes: 61 additions & 0 deletions packages/mdc-grid-list/foundation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {MDCFoundation} from '@material/base';
import {strings} from './constants';

export default class MDCGridListFoundation extends MDCFoundation {
static get strings() {
return strings;
}

static get defaultAdapter() {
return {
getOffsetWidth: () => /* number */ 0,
getOffsetWidthForTileAtIndex: (/* index: number */) => /* number */ 0,
setStyleForTilesElement: (/* property: string, value: string */) => {},
registerResizeHandler: (/* handler: EventListener */) => {},
deregisterResizeHandler: (/* handler: EventListener */) => {},
};
}
constructor(adapter) {
super(Object.assign(MDCGridListFoundation.defaultAdapter, adapter));
this.resizeHandler_ = () => this.alignCenter();
this.resizeFrame_ = 0;
}
init() {
this.alignCenter();
this.adapter_.registerResizeHandler(this.resizeHandler_);
}
destroy() {
this.adapter_.deregisterResizeHandler(this.resizeHandler_);
}
alignCenter() {
if (this.resizeFrame_ !== 0) {
cancelAnimationFrame(this.resizeFrame_);
}
this.resizeFrame_ = requestAnimationFrame(() => {
this.alignCenter_();
this.resizeFrame_ = 0;
});
}
alignCenter_() {
const gridWidth = this.adapter_.getOffsetWidth();
const itemWidth = this.adapter_.getOffsetWidthForTileAtIndex(0);
const tilesWidth = itemWidth * Math.floor(gridWidth / itemWidth);
this.adapter_.setStyleForTilesElement('width', `${tilesWidth}px`);
}
}
Loading

0 comments on commit 5b84e73

Please sign in to comment.