-
Notifications
You must be signed in to change notification settings - Fork 2.1k
feat(tab): Add tab indicator #2461
Changes from 56 commits
1b3bac3
8bd43c0
9d33e3b
0bbfe73
d531675
8753c18
7fe42d5
9f1053c
2205fcb
dbb6a3d
0feb3ab
f1c3097
52187c1
3cc11f3
0f2e7fa
2cc6387
b6b7380
d130f43
22a5656
047a45f
a016ecf
3744249
f15e991
1c0d1cc
fa5be74
5fa0260
dab80ce
dd8554e
55d9f5e
88dae47
d1a7de3
f63bfea
2e0f946
352bc66
3820453
6239108
80bb55d
915e572
06093c7
394d115
4a27603
0c52e85
d9739ef
3a65619
c80c9f5
d42b3ad
56aebed
35ba5d2
961f84b
6aaf004
6ba4fbe
8603321
1ba59fc
e015586
00af9db
5841b72
38c868f
164089a
8a41020
6b563c2
e4d6b76
6e1b1a4
66b550f
058998e
7aa0362
c5ca744
60463e4
ad27e5c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
<!DOCTYPE html> | ||
<!-- | ||
Copyright 2018 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 | ||
|
||
https://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 | ||
--> | ||
<html> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add more cases where the tabs are different widths. And remove the fading bar demo. |
||
<head> | ||
<meta charset="utf-8"> | ||
<title>Tab Indicator - Material Components Catalog</title> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<link rel="icon" type="image/png" href="/images/logo_components_color_2x_web_48dp.png"> | ||
<link rel="stylesheet" href="/assets/tab-indicator.css"> | ||
<script src="/ready.js"></script> | ||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Mono"> | ||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"> | ||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> | ||
</head> | ||
|
||
<body class="mdc-typography"> | ||
<header class="mdc-toolbar mdc-toolbar--fixed"> | ||
<div class="mdc-toolbar__row"> | ||
<section class="mdc-toolbar__section mdc-toolbar__section--align-start"> | ||
<span class="catalog-back"> | ||
<a href="/" class="mdc-toolbar__menu-icon"><i class="material-icons"></i></a> | ||
</span> | ||
<span class="mdc-toolbar__title catalog-title">Tab Indicator</span> | ||
</section> | ||
</div> | ||
</header> | ||
|
||
<main class="mdc-toolbar-fixed-adjust"> | ||
<section class="hero"> | ||
<div class="demo-inner"> | ||
<div class="demo-item"> | ||
<label class="demo-label"><input type="radio" name="demo1" checked> Active</label> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I used native radios because this is just the tab indicator demo, not the tab with tab indicator demo. The idea of the demo page is to show how the indicator can be used across multiple items. I guess I should add some information about that. |
||
<span class="mdc-tab-indicator mdc-tab-indicator--active demo-indicator"></span> | ||
</div> | ||
<div class="demo-item demo-item--wide"> | ||
<label class="demo-label"><input type="radio" name="demo1"> Active</label> | ||
<span class="mdc-tab-indicator demo-indicator"></span> | ||
</div> | ||
<div class="demo-item demo-item--narrow"> | ||
<label class="demo-label"><input type="radio" name="demo1"> Active</label> | ||
<span class="mdc-tab-indicator demo-indicator"></span> | ||
</div> | ||
<div class="demo-item"> | ||
<label class="demo-label"><input type="radio" name="demo1"> Active</label> | ||
<span class="mdc-tab-indicator demo-indicator"></span> | ||
</div> | ||
</div> | ||
|
||
<div class="demo-inner"> | ||
<div class="demo-item demo-item--wide"> | ||
<label class="demo-label"><input type="radio" name="demo2" checked> Active</label> | ||
<span class="mdc-tab-indicator mdc-tab-indicator--icon mdc-tab-indicator--active demo-indicator material-icons">favorite</span> | ||
</div> | ||
<div class="demo-item"> | ||
<label class="demo-label"><input type="radio" name="demo2"> Active</label> | ||
<span class="mdc-tab-indicator mdc-tab-indicator--icon demo-indicator material-icons">lens</span> | ||
</div> | ||
<div class="demo-item"> | ||
<label class="demo-label"><input type="radio" name="demo2"> Active</label> | ||
<span class="mdc-tab-indicator mdc-tab-indicator--icon demo-indicator material-icons">change_history</span> | ||
</div> | ||
<div class="demo-item demo-item--narrow"> | ||
<label class="demo-label"><input type="radio" name="demo2"> Active</label> | ||
<span class="mdc-tab-indicator mdc-tab-indicator--icon demo-indicator material-icons">star</span> | ||
</div> | ||
</div> | ||
</section> | ||
</main> | ||
|
||
<script src="/assets/material-components-web.js" async></script> | ||
<script src="/assets/common.js" async></script> | ||
<script> | ||
demoReady(function() { | ||
var demoItems = document.querySelectorAll('.demo-item'); | ||
var activeIndicator; | ||
for (var i = 0; i < demoItems.length; i++) { | ||
(function(i) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Can you create a named function for this? An IIFE feels a little convoluted here. |
||
var demoItem = demoItems[i]; | ||
var demoIndicator = demoItem.querySelector('.demo-indicator'); | ||
var indicator = new mdc.tabIndicator.MDCTabIndicator(demoIndicator); | ||
var demoId = 'demo' + i; | ||
window[demoId] = indicator; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Can we use a locally-scoped variable inside |
||
var demoRadio = demoItem.querySelector('input[type="radio"]'); | ||
var activeName = 'active_' + demoRadio.name; | ||
if (demoIndicator.classList.contains('mdc-tab-indicator--active')) { | ||
window[activeName] = indicator; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Ditto |
||
} | ||
demoRadio.addEventListener('change', function (event) { | ||
var activeIndicator = window[activeName]; | ||
activeIndicator.deactivate(); | ||
window[demoId].activate(activeIndicator.clientRect); | ||
window[activeName] = window[demoId]; | ||
}); | ||
})(i); | ||
} | ||
}); | ||
</script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
@import "./common"; | ||
@import "../packages/mdc-tab-indicator/mixins"; | ||
@import "../packages/mdc-tab-indicator/mdc-tab-indicator"; | ||
@import "../packages/mdc-elevation/mixins"; | ||
@import "../packages/mdc-theme/color-palette"; | ||
|
||
.hero { | ||
flex-direction: column; | ||
} | ||
|
||
.demo-inner { | ||
display: flex; | ||
align-items: center; | ||
height: 50px; | ||
margin: 2rem 0; | ||
} | ||
|
||
.demo-item { | ||
display: flex; | ||
position: relative; | ||
flex: 1 0 auto; | ||
align-items: center; | ||
justify-content: center; | ||
width: 150px; | ||
height: inherit; | ||
margin: 1rem; | ||
background-color: $material-color-grey-50; | ||
text-align: center; | ||
} | ||
|
||
.demo-item--wide { | ||
width: 250px; | ||
} | ||
|
||
.demo-item--narrow { | ||
width: 100px; | ||
} | ||
|
||
.demo-label { | ||
position: relative; | ||
z-index: 2; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<!--docs: | ||
title: "Tab Indicator" | ||
layout: detail | ||
section: components | ||
excerpt: "Tab Indicator is a visual guide that shows which Tab is active" | ||
iconId: tab | ||
path: /catalog/tab/ | ||
--> | ||
|
||
# Tab Indicator | ||
|
||
<!--<div class="article__asset"> | ||
<a class="article__asset-link" | ||
href="https://material-components-web.appspot.com/tab-indicator.html"> | ||
<img src="{{ site.rootpath }}/images/mdc_web_screenshots/tab-indicator.png" width="363" alt="Tab indicator screenshot"> | ||
</a> | ||
</div>--> | ||
|
||
Tab Indicator is a visual guide that shows which Tab is active | ||
|
||
## Design & API Documentation | ||
|
||
<!-- | ||
<ul class="icon-list"> | ||
<li class="icon-list-item icon-list-item--spec"> | ||
<a href="https://material.io/guidelines/components/tabs.html">Material Design guidelines: Tab Indicator</a> | ||
</li> | ||
<li class="icon-list-item icon-list-item--link"> | ||
<a href="https://material-components-web.appspot.com/tab-indicator.html">Demo</a> | ||
</li> | ||
</ul> | ||
--> | ||
|
||
## Installation | ||
``` | ||
npm install --save @material/tab-indicator | ||
``` | ||
|
||
## Usage | ||
|
||
### HTML Structure | ||
|
||
```html | ||
<span class="mdc-tab-indicator"></span> | ||
``` | ||
|
||
##### Tab Indicator Icon | ||
|
||
We recommend you load [Material Icons](https://material.io/icons/) from Google Fonts. However, users are free to use whatever icons they like. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use Material Icons from Google Fonts within your Fading Icon Indicator, or you can use your own icons |
||
|
||
```html | ||
<span class="mdc-tab-indicator mdc-tab-indicator--icon"> | ||
<i class="material-icons">lens</i> | ||
</span> | ||
``` | ||
|
||
### CSS Classes | ||
|
||
CSS Class | Description | ||
--- | --- | ||
`mdc-tab-indicator` | Mandatory. | ||
`mdc-tab-indicator--icon` | Optional. Sets up the tab indicator to appear as an icon | ||
|
||
### Sass Mixins | ||
|
||
To customize the tab indicator, use the following mixins. | ||
|
||
Mixin | Description | ||
--- | --- | ||
`mdc-tab-indicator-color($color)` | Customizes the color of the tab indicator | ||
`mdc-tab-indicator-height($height)` | Customizes the height of the tab indicator | ||
`mdc-tab-indicator-top-radius($radius)` | Customizes the top left and top right border radius of the tab indicator | ||
|
||
### `MDCTabIndicator` | ||
|
||
Method Signature | Description | ||
--- | --- | ||
`activate(previousTabClientRect: ClientRect) => void` | Activates the tab indicator | ||
`deactivate() => void` | Deactivates the tab indicator | ||
|
||
Property | Value Type | Description | ||
--- | --- | --- | ||
`clientRect` | `ClientRect` | Getter for the indicator's bounding client rect | ||
|
||
### `MDCTabIndicatorAdapter` | ||
|
||
Method Signature | Description | ||
--- | --- | ||
`addClass(className: string) => void` | Adds a class to the root element | ||
`removeClass(className: string) => void` | Removes a class from the root element | ||
`registerEventHandler(evtType: string, handler: EventListener) => void` | Registers an event listener on the root element | ||
`deregisterEventHandler(evtType: string, handler: EventListener) => void` | Deregisters an event listener on the root element | ||
`setStyleProp(property: string, value: string) => void` | Sets the style property of the root element | ||
|
||
### `MDCTabIndicatorFoundation` | ||
|
||
Method Signature | Description | ||
--- | --- | ||
`handleTransitionEnd(evt: Event) => void` | Handles the logic for the `"transitionend"` event on the root element | ||
`activate(previousTabIndicatorRect: ClientRect) => void` | Activates the tab indicator | ||
`deactivate() => void` | Deactivates the tab indicator | ||
`getClientRect() => ClientRect` | Returns the root element's bounding client rect |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/** | ||
* @license | ||
* Copyright 2018 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 "@material/theme/mixins"; | ||
|
||
@mixin mdc-tab-indicator-active { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make this private-ish with an underscore, and sort to bottom of file |
||
.mdc-tab-indicator { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dont put the "Block" CSS classname in the selector |
||
opacity: 1; | ||
} | ||
} | ||
|
||
@mixin mdc-tab-indicator-color($color) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this mixin will probably end up outputting more CSS than the client needs. I would recommend we only support |
||
.mdc-tab-indicator { | ||
@include mdc-tab-indicator-bar-color_($color); | ||
} | ||
|
||
.mdc-tab-indicator--icon { | ||
@include mdc-tab-indicator-icon-color_($color); | ||
} | ||
} | ||
|
||
@mixin mdc-tab-indicator-height($height) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this mixin will probably end up outputting more CSS than the client needs. I would recommend we only support |
||
.mdc-tab-indicator { | ||
@include mdc-tab-indicator-bar-height_($height); | ||
} | ||
|
||
.mdc-tab-indicator--icon { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess this makes sense...you could have a separate mixin for just customizing the height of the icon variant...like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Definitely |
||
@include mdc-tab-indicator-icon-height_($height); | ||
} | ||
} | ||
|
||
@mixin mdc-tab-indicator-top-border-radius($radius) { | ||
.mdc-tab-indicator { | ||
@include mdc-tab-indicator-bar-top-corner-radius_($radius); | ||
} | ||
} | ||
|
||
// Private mixins | ||
|
||
@mixin mdc-tab-indicator-bar-color_($color) { | ||
@include mdc-theme-prop(background-color, $color); | ||
} | ||
|
||
@mixin mdc-tab-indicator-bar-height_($height) { | ||
height: $height; | ||
} | ||
|
||
@mixin mdc-tab-indicator-bar-top-corner-radius_($radius) { | ||
border-top-left-radius: $radius; | ||
border-top-right-radius: $radius; | ||
} | ||
|
||
@mixin mdc-tab-indicator-icon-color_($color) { | ||
@include mdc-theme-prop(color, $color); | ||
|
||
background: none; | ||
} | ||
|
||
@mixin mdc-tab-indicator-icon-height_($height) { | ||
height: $height; | ||
font-size: $height; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This demo page needs some restructure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated