Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.

Feat/top app bar/iss 499 #688

Merged
merged 37 commits into from
Feb 27, 2019
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
f8834a3
fix(infrastructure): Upgrade resemblejs to v3 (#634)
gugu Jan 28, 2019
9d4ceb7
feat(infrastructure): Fix screenshot tests for external contributors …
gugu Jan 29, 2019
c33c2dd
feat(snackbar): new component (#620)
gugu Jan 29, 2019
6593e91
fix(text-field): Do not import constants from @material/textfield int…
gugu Jan 29, 2019
8cf11cc
fix(chips): copy selectedChipIds before calling setState (#645)
Jan 30, 2019
f9238ef
docs(list): fix ListDivider example (#647)
bmihelac Feb 6, 2019
9841e18
fix(chips): ChipSet no longer overwrites handle[Interaction|Select|Re…
mgr34 Feb 6, 2019
a376474
feat(chips): implements missing adapter method notifyTrailingIconInte…
mgr34 Feb 6, 2019
d141be1
fix(ripple): Ripple triggers twice on mobile (#646)
aluminick Feb 7, 2019
dbaaf70
feat(fab): exited (#661)
mgr34 Feb 8, 2019
6a06518
fix(chips): id shuold be required prop (#649)
mgr34 Feb 8, 2019
802066a
fix(infrastructure): Windows development (#662)
madaz Feb 8, 2019
9b66812
docs(drawer): Update README.md (#666)
ZeJ0hn Feb 12, 2019
9ef9ab9
docs(text-field): fix example compilation issue (#670)
ZeJ0hn Feb 12, 2019
7563dff
fix(tab): return ScrollContentWidth (#633)
seraph17 Feb 12, 2019
457afee
fix(top-app-bar): clientHeight unit test (#668)
Feb 12, 2019
02da75c
fix(list): renders a list with children which is not DOM (#674)
Feb 14, 2019
291cb67
fix(button): Support anchor and button HTML attributes (#679) (#680)
Feb 15, 2019
0505902
fix(infrastructure): fix source mappings under dist directory (#682)
Feb 15, 2019
a79dc3a
fix(checkbox): enable name attribute (#678)
nicklasisraelsson Feb 15, 2019
928d249
feat(top-app-bar): WIP for a more compositional syntax
mgr34 Feb 20, 2019
db46248
merge in rc0.11.0
mgr34 Feb 20, 2019
e78306e
feat(top-app-bar): declarative syntax
mgr34 Feb 21, 2019
a74c1bf
feat(top-app-bar): add all unit tests
mgr34 Feb 21, 2019
dc798f8
feat(top-app-bar): note short variant has 1 action item and describe …
mgr34 Feb 21, 2019
38c0417
feat(top-app-bar): add new components
mgr34 Feb 21, 2019
117d091
feat(top-app-bar): include aria-label in example for a11y reasons.
mgr34 Feb 21, 2019
132cb84
feat(top-app-bar): PR review changes (#688)
mgr34 Feb 25, 2019
100c132
Merge remote-tracking branch 'origin/rc0.11.0' into feat/top-app-bar/…
mgr34 Feb 25, 2019
2f6db89
feat(top-app-bar): add todo to remove istanbul ignore and deprecated …
mgr34 Feb 26, 2019
1ba5108
feat(top-app-bar): set state.scrollTarget as optional property
mgr34 Feb 26, 2019
54cb68b
feat(top-app-bar): export Icon inteface
mgr34 Feb 26, 2019
116aa67
feat(top-app-bar): extend HTMLElement
mgr34 Feb 26, 2019
49dd822
feat(top-app-bar): extend HTMLElement
mgr34 Feb 26, 2019
688c5af
feat(top-app-bar): limit to one actionItem for now
mgr34 Feb 26, 2019
19846dd
feat(top-app-bar): iss #499 update golden.sjon
mgr34 Feb 27, 2019
409ccea
feat(top-app-bar): fix spelling twoRose => twoRows
mgr34 Feb 27, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions packages/top-app-bar/Icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// The MIT License
//
// Copyright (c) 2019 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import * as React from 'react';
import * as classnames from 'classnames';
import {cssClasses} from './constants';
// @ts-ignore no mdc .d.ts file


interface IconProps<T> extends React.HTMLProps<T> {
actionItem?: boolean;
className?: string;
children: React.ReactElement<any>;
navIcon?: boolean;
}


const Icon: <T extends {} = HTMLElement>(props: IconProps<T> ) =>
React.ReactElement<HTMLElement> = ({
/* eslint-disable react/prop-types */
actionItem = false,
navIcon = false,
className,
children,
...otherProps
/* eslint-enable react/prop-types */
}) =>
React.cloneElement(children, {
...otherProps,
className: classnames(className, children.props.className, {
[cssClasses.ACTION_ITEM]: actionItem,
[cssClasses.NAV_ICON]: navIcon,
}),
});

export default Icon;
83 changes: 65 additions & 18 deletions packages/top-app-bar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,38 @@ import '@material/react-material-icon/dist/material-icon.css';

### Javascript Instantiation
```js
import TopAppBar, {TopAppBarFixedAdjust} from '@material/react-top-app-bar';
import TopAppBar, {
TopAppBarFixedAdjust,
TopAppBarIcon,
TopAppBarRow,
TopAppBarSection,
TopAppBarTitle,
} from '@material/react-top-app-bar';
import MaterialIcon from '@material/react-material-icon';

const MyComponent = () => {
return (
<div>
<TopAppBar
title='Miami, FL'
navigationIcon={<MaterialIcon
icon='menu'
onClick={() => console.log('click')}
/>}
actionItems={[<MaterialIcon key='item' icon='bookmark' />]}
/>
<TopAppBar>
<TopAppBarRow>
<TopAppBarSection align='start'>
<TopAppBarIcon navIcon tabIndex={0}>
<MaterialIcon hasRipple icon='menu' onClick={() => console.log('click')}/>
</TopAppBarIcon>
<TopAppBarTitle>Miami, FL</TopAppBarTitle>
</TopAppBarSection>
<TopAppBarSection align='end' role='toolbar'>
<TopAppBarIcon actionItem tabIndex={0}>
<MaterialIcon
aria-label="print page"
hasRipple
icon='print'
onClick={() => console.log('print')}
/>
</TopAppBarIcon>
</TopAppBarSection>
</TopAppBarRow>
</TopAppBar>
<TopAppBarFixedAdjust>
My exciting content!
</TopAppBarFixedAdjust>
Expand All @@ -56,17 +74,45 @@ Use the `<TopAppBarFixedAdjust />` component to give your content top-padding, s

Prop Name | Type | Description
--- | --- | ---
actionItems | Array | Accepts an array of elements that should be rendered to the opposite side of the title. Note that a single action item should also be passed as an array.
className | String | Classes to be applied to the root element.
title | String | The title of the Top App Bar.
navigationIcon | Element | Appears adjacent to the title. This acts as the main action of the Top App Bar.
short | Boolean | Enables short variant.
shortCollapsed | Boolean | Enables short collapsed variant.
prominent | Boolean | Enables prominent variant.
fixed | Boolean | Enables fixed variant.
dense | Boolean | Enables dense variant.
scrollTarget | React.RefObject | Sets scroll target to different DOM node (default is `window`)
tag | String | Customizes the `TopAppBar` HTML tag. (default: `<header>`)

> NOTES: As per design guidelines, prominent and dense variants should not be used with short or short collapsed. Additionally, dense variants should only be used on desktop.
> NOTES: As per design guidelines, prominent and dense variants should not be used with short or short collapsed. Additionally, dense variants should only be used on desktop. Additionally short top-app-bars should be used with no more than 1 action item.

### TopAppBarRow
Prop Name | Type | Description
--- | --- | ---
className | String | Classes to be applied to the root element.
tag | String | Customizes the `TopAppBarRow` tag. (default: `<div>`)

### TopAppBarSection
Prop Name | Type | Description
--- | --- | ---
align | Sring ('start' or 'end') | optional property tha aligns section content to either start or end of section
className | String | Classes to be applied to the root element.
tag | String | Customizes the `TopAppBarSection` tag. (default: `<section>`)
> Note: if section contains action items it is reccomended to add property role='toolbar' for a11y purposes

### TopAppBarTitle
Prop Name | Type | Description
--- | --- | ---
className | String | Classes to be applied to the root element.
tag | String | Customizes the `TopAppBarTitle` tag. (default: `<span>`)

### TopAppBarIcon
Prop Name | Type | Description
--- | --- | ---
className | String | Classes to be applied to the root element.
actionItem | Boolean | applies action-item class to icon
navIcon | Boolean | applies nav-icon class to icon
children | React.ReactElement<any> | can be any icon. Material Icons are reccomended
> Notes: (1) consider adding `aria-label` to actionItem's. (2) you may need to manually add ripple or tabindex to icon. (3) Short top-app-bars shold be used with no more than 1 action item.

### TopAppBarFixedAdjust

Expand All @@ -89,8 +135,9 @@ Use of [Material Icon's](../material-icon/README.md) for Action Items and Naviga
The navigation icon can be a `<a>`, `<i>`, `<svg>`, `<image>`, `<span>`, etc., but again must be wrapped with the `withRipple HOC`.

```js
<TopAppBar
navigationIcon={<i className='material-icons'>menu</i>} />
<TopAppBarIcon navIcon>
<i className='material-icons'>menu</i>
</TopAppBarIcon>
```

If you decide to use a React Component please see [Integrating with Components](./../../docs/guidelines.md#integrating-with-components).
Expand All @@ -100,13 +147,13 @@ If you decide to use a React Component please see [Integrating with Components](
Similar to the [navigation icon](#navigation-icon), it can be `<a>`, `<i>`, `<svg>`, `<image>`, `<span>`, etc., and must be wrapped with the `withRipple HOC`.

```js
<TopAppBar
actionItems={[<i className='material-icons'>bookmark</i>]} />
<TopAppBarIcon actionItem>
<i className='material-icons'>bookmark</i
</TopAppBarIcon>
```

If you decide to use a React Component please see [Integrating with Components](./../../docs/guidelines.md#integrating-with-components).

> NOTE: `actionItems` prop is expecting an array of elements.

## Sass Mixins

Expand Down
47 changes: 47 additions & 0 deletions packages/top-app-bar/Row.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// The MIT License
//
// Copyright (c) 2019 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import * as React from 'react';
import * as classnames from 'classnames';
import {cssClasses} from './constants';

export interface RowProps<T> extends React.HTMLProps<T> {
className?: string;
tag?: string;
};

const Row: <T extends {} = HTMLDivElement>(props: RowProps<T>) =>
React.ReactElement<T> = ({
/* eslint-disable react/prop-types */
children,
className,
tag: Tag = 'div',
...otherProps
/* eslint-enable react/prop-types */
}) => (
// @ts-ignore https://github.com/Microsoft/TypeScript/issues/28892
<Tag className={classnames(className, cssClasses.ROW)} {...otherProps}>
{children}
</Tag>
);

export default Row;
55 changes: 55 additions & 0 deletions packages/top-app-bar/Section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// The MIT License
//
// Copyright (c) 2019 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import * as React from 'react';
import * as classnames from 'classnames';
import {cssClasses} from './constants';

export interface SectionProps<T> extends React.HTMLProps<T> {
align?: 'start' | 'end';
className?: string;
tag?: string;
};

const Section: <T extends {} = HTMLElement>(props: SectionProps<T>) =>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extend HTMLElement here too

Copy link
Contributor Author

@mgr34 mgr34 Feb 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it not already extending HTMLElement?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean <T extends HTMLElement = HTMLElement>. This just forces T to always be a derivative of HTMLElement

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah gotcha. I think this should also be changed in the Dialog component I worked on last month. Should I open an issue? I probably won't get to implementing anything this week.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! Ya an issue would be great.

React.ReactElement<T> = ({
/* eslint-disable react/prop-types */
align,
className,
children,
tag: Tag = 'section',
...otherProps
/* eslint-enable react/prop-types */
}) => (
// @ts-ignore https://github.com/Microsoft/TypeScript/issues/28892
<Tag
className={classnames(className, cssClasses.SECTION, {
[cssClasses.SECTION_START]: align === 'start',
[cssClasses.SECTION_END]: align === 'end',
})}
{...otherProps}
>
{children}
</Tag>
);

export default Section;
47 changes: 47 additions & 0 deletions packages/top-app-bar/Title.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// The MIT License
//
// Copyright (c) 2019 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import * as React from 'react';
import * as classnames from 'classnames';
import {cssClasses} from './constants';

export interface TitleProps<T> extends React.HTMLProps<T> {
className?: string;
tag?: string;
};

const Title: <T extends {} = HTMLSpanElement>(props: TitleProps<T>) =>
React.ReactElement<T> = ({
/* eslint-disable react/prop-types */
children,
className,
tag: Tag = 'span',
...otherProps
/* eslint-enable react/prop-types */
}) => (
// @ts-ignore https://github.com/Microsoft/TypeScript/issues/28892
<Tag className={classnames(className, cssClasses.TITLE)} {...otherProps} >
{children}
</Tag>
);

export default Title;
39 changes: 39 additions & 0 deletions packages/top-app-bar/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// The MIT License
//
// Copyright (c) 2019 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
const BASE = 'mdc-top-app-bar';
const SECTION = `${BASE}__section`;
const cssClasses = {
BASE,
ROW: `${BASE}__row`,
SECTION,
SECTION_START: `${SECTION}--align-start`,
SECTION_END: `${SECTION}--align-end`,
FIXED: `${BASE}--fixed`,
SHORT: `${BASE}--short`,
SHORT_COLLAPSED: `${BASE}--short-collapsed`,
PROMINENT: `${BASE}--prominent`,
DENSE: `${BASE}--dense`,
TITLE: `${BASE}__title`,
ACTION_ITEM: `${BASE}__action-item`,
NAV_ICON: `${BASE}__navigation-icon`,
};

export {cssClasses};
Loading