From 7e6b09a3348464a652d6660bf2c5abe02fca6d45 Mon Sep 17 00:00:00 2001 From: Zadielerick Date: Mon, 4 Jan 2016 15:39:36 -0600 Subject: [PATCH] Update Documentation for Lists --- docs/src/app/app-routes.jsx | 4 +- docs/src/app/components/app-left-nav.jsx | 4 +- .../pages/components/List/ExampleChat.jsx | 45 + .../pages/components/List/ExampleContacts.jsx | 53 ++ .../pages/components/List/ExampleFolders.jsx | 48 + .../pages/components/List/ExampleMessages.jsx | 159 ++++ .../pages/components/List/ExampleNested.jsx | 40 + .../pages/components/List/ExamplePhone.jsx | 39 + .../components/List/ExampleSelectable.jsx | 59 ++ .../pages/components/List/ExampleSettings.jsx | 58 ++ .../pages/components/List/ExampleSimple.jsx | 31 + .../components/pages/components/List/Page.jsx | 67 ++ .../pages/components/List/README.md | 6 + .../pages/components/List/SelectableHelp.md | 41 + .../app/components/pages/components/lists.jsx | 870 ------------------ .../app/components/raw-code/lists-code.txt | 123 --- src/lists/list-item.jsx | 124 ++- src/lists/list.jsx | 21 + 18 files changed, 794 insertions(+), 998 deletions(-) create mode 100644 docs/src/app/components/pages/components/List/ExampleChat.jsx create mode 100644 docs/src/app/components/pages/components/List/ExampleContacts.jsx create mode 100644 docs/src/app/components/pages/components/List/ExampleFolders.jsx create mode 100644 docs/src/app/components/pages/components/List/ExampleMessages.jsx create mode 100644 docs/src/app/components/pages/components/List/ExampleNested.jsx create mode 100644 docs/src/app/components/pages/components/List/ExamplePhone.jsx create mode 100644 docs/src/app/components/pages/components/List/ExampleSelectable.jsx create mode 100644 docs/src/app/components/pages/components/List/ExampleSettings.jsx create mode 100644 docs/src/app/components/pages/components/List/ExampleSimple.jsx create mode 100644 docs/src/app/components/pages/components/List/Page.jsx create mode 100644 docs/src/app/components/pages/components/List/README.md create mode 100644 docs/src/app/components/pages/components/List/SelectableHelp.md delete mode 100644 docs/src/app/components/pages/components/lists.jsx delete mode 100644 docs/src/app/components/raw-code/lists-code.txt diff --git a/docs/src/app/app-routes.jsx b/docs/src/app/app-routes.jsx index 8fbe82249fe4dc..0d47a686cbd33e 100644 --- a/docs/src/app/app-routes.jsx +++ b/docs/src/app/app-routes.jsx @@ -34,7 +34,7 @@ import Icons from './components/pages/components/icons'; import IconButtonPage from './components/pages/components/IconButton/Page'; import IconMenus from './components/pages/components/icon-menus'; import LeftNavPage from './components/pages/components/LeftNav/Page'; -import Lists from './components/pages/components/lists'; +import ListPage from './components/pages/components/List/Page'; import Menus from './components/pages/components/menus'; import Paper from './components/pages/components/paper'; import Popover from './components/pages/components/popover'; @@ -95,7 +95,7 @@ const AppRoutes = ( - + diff --git a/docs/src/app/components/app-left-nav.jsx b/docs/src/app/components/app-left-nav.jsx index d9914f8936897d..32614836b1c6d9 100644 --- a/docs/src/app/components/app-left-nav.jsx +++ b/docs/src/app/components/app-left-nav.jsx @@ -199,8 +199,8 @@ const AppLeftNav = React.createClass({ primaryText="Left Nav" />, , ( + + + } + rightIcon={} /> + } + rightIcon={} /> + } + rightIcon={} /> + } + rightIcon={} /> + } + rightIcon={} /> + + + + } /> + } /> + + +); + +export default ListExampleChat; diff --git a/docs/src/app/components/pages/components/List/ExampleContacts.jsx b/docs/src/app/components/pages/components/List/ExampleContacts.jsx new file mode 100644 index 00000000000000..f3b779814ac0b7 --- /dev/null +++ b/docs/src/app/components/pages/components/List/ExampleContacts.jsx @@ -0,0 +1,53 @@ +import React from 'react'; +import MobileTearSheet from '../../../MobileTearSheet'; +import List from 'material-ui/lib/lists/list'; +import ListItem from 'material-ui/lib/lists/list-item'; +import ActionGrade from 'material-ui/lib/svg-icons/action/grade'; +import Divider from 'material-ui/lib/divider'; +import Avatar from 'material-ui/lib/avatar'; +import Colors from 'material-ui/lib/styles/colors'; + +const ListExampleContacts = () => ( + + + } + rightAvatar={} /> + } /> + } /> + } /> + + + + A} + rightAvatar={} /> + } /> + } /> + } /> + + +); + +export default ListExampleContacts; diff --git a/docs/src/app/components/pages/components/List/ExampleFolders.jsx b/docs/src/app/components/pages/components/List/ExampleFolders.jsx new file mode 100644 index 00000000000000..4c1ee06f214b6d --- /dev/null +++ b/docs/src/app/components/pages/components/List/ExampleFolders.jsx @@ -0,0 +1,48 @@ +import React from 'react'; +import MobileTearSheet from '../../../MobileTearSheet'; +import List from 'material-ui/lib/lists/list'; +import ListItem from 'material-ui/lib/lists/list-item'; +import ActionInfo from 'material-ui/lib/svg-icons/action/info'; +import Divider from 'material-ui/lib/divider'; +import Avatar from 'material-ui/lib/avatar'; +import FileFolder from 'material-ui/lib/svg-icons/file/folder'; +import ActionAssignment from 'material-ui/lib/svg-icons/action/assignment'; +import Colors from 'material-ui/lib/styles/colors'; +import EditorInsertChart from 'material-ui/lib/svg-icons/editor/insert-chart'; + +const ListExampleFolder = () => ( + + + } />} + rightIcon={} + primaryText="Photos" + secondaryText="Jan 9, 2014" /> + } />} + rightIcon={} + primaryText="Recipes" + secondaryText="Jan 17, 2014" /> + } />} + rightIcon={} + primaryText="Work" + secondaryText="Jan 28, 2014" /> + + + + } backgroundColor={Colors.blue500} />} + rightIcon={} + primaryText="Vacation itinerary" + secondaryText="Jan 20, 2014" /> + } backgroundColor={Colors.yellow600} />} + rightIcon={} + primaryText="Kitchen remodel" + secondaryText="Jan 10, 2014" /> + + +); + +export default ListExampleFolder; diff --git a/docs/src/app/components/pages/components/List/ExampleMessages.jsx b/docs/src/app/components/pages/components/List/ExampleMessages.jsx new file mode 100644 index 00000000000000..7f19bc5dabee97 --- /dev/null +++ b/docs/src/app/components/pages/components/List/ExampleMessages.jsx @@ -0,0 +1,159 @@ +import React from 'react'; +import MobileTearSheet from '../../../MobileTearSheet'; +import List from 'material-ui/lib/lists/list'; +import ListItem from 'material-ui/lib/lists/list-item'; +import Divider from 'material-ui/lib/divider'; +import Avatar from 'material-ui/lib/avatar'; +import Colors from 'material-ui/lib/styles/colors'; +import IconButton from 'material-ui/lib/icon-button'; +import MoreVertIcon from 'material-ui/lib/svg-icons/navigation/more-vert'; +import IconMenu from 'material-ui/lib/menus/icon-menu'; +import MenuItem from 'material-ui/lib/menus/menu-item'; + +const iconButtonElement = ( + + + +); + +const rightIconMenu = ( + + Reply + Forward + Delete + +); + +const ListExampleMessages = () => ( +
+ + + } + primaryText="Brunch this weekend?" + secondaryText={ +

+ Brendan Lim -- + I'll be in your neighborhood doing errands this weekend. Do you want to grab brunch? +

+ } + secondaryTextLines={2} /> + + } + primaryText={ +

Summer BBQ  4

+ } + secondaryText={ +

+ to me, Scott, Jennifer -- + Wish I could come, but I'm out of town this weekend. +

+ } + secondaryTextLines={2} /> + + } + primaryText="Oui oui" + secondaryText={ +

+ Grace Ng -- + Do you have Paris recommendations? Have you ever been? +

+ } + secondaryTextLines={2} /> + + } + primaryText="Birdthday gift" + secondaryText={ +

+ Kerem Suer -- + Do you have any ideas what we can get Heidi for her birthday? How about a pony? +

+ } + secondaryTextLines={2} /> + + } + primaryText="Recipe to try" + secondaryText={ +

+ Raquel Parrado -- + We should eat this: grated squash. Corn and tomatillo tacos. +

+ } + secondaryTextLines={2} /> +
+
+ + + + } + rightIconButton={rightIconMenu} + primaryText="Brendan Lim" + secondaryText={ +

+ Brunch this weekend?
+ I'll be in your neighborhood doing errands this weekend. Do you want to grab brunch? +

+ } + secondaryTextLines={2} /> + + } + rightIconButton={rightIconMenu} + primaryText="me, Scott, Jennifer" + secondaryText={ +

+ Summer BBQ
+ Wish I could come, but I'm out of town this weekend. +

+ } + secondaryTextLines={2} /> + + } + rightIconButton={rightIconMenu} + primaryText="Grace Ng" + secondaryText={ +

+ Oui oui
+ Do you have any Paris recs? Have you ever been? +

+ } + secondaryTextLines={2} /> + + } + rightIconButton={rightIconMenu} + primaryText="Kerem Suer" + secondaryText={ +

+ Birthday gift
+ Do you have any ideas what we can get Heidi for her birthday? How about a pony? +

+ } + secondaryTextLines={2} /> + + } + rightIconButton={rightIconMenu} + primaryText="Raquel Parrado" + secondaryText={ +

+ Recipe to try
+ We should eat this: grated squash. Corn and tomatillo tacos. +

+ } + secondaryTextLines={2} /> +
+
+
+); + +export default ListExampleMessages; diff --git a/docs/src/app/components/pages/components/List/ExampleNested.jsx b/docs/src/app/components/pages/components/List/ExampleNested.jsx new file mode 100644 index 00000000000000..94e503c93d5f54 --- /dev/null +++ b/docs/src/app/components/pages/components/List/ExampleNested.jsx @@ -0,0 +1,40 @@ +import React from 'react'; +import MobileTearSheet from '../../../MobileTearSheet'; +import List from 'material-ui/lib/lists/list'; +import ListItem from 'material-ui/lib/lists/list-item'; +import ActionGrade from 'material-ui/lib/svg-icons/action/grade'; +import ContentInbox from 'material-ui/lib/svg-icons/content/inbox'; +import ContentDrafts from 'material-ui/lib/svg-icons/content/drafts'; +import ContentSend from 'material-ui/lib/svg-icons/content/send'; + +const ListExampleNested = () => ( + + + } /> + } /> + } + initiallyOpen={true} + primaryTogglesNestedList={true} + nestedItems={[ + } />, + } + disabled={true} + nestedItems={[ + } />, + ]} + />, + ]} + /> + + +); + +export default ListExampleNested; diff --git a/docs/src/app/components/pages/components/List/ExamplePhone.jsx b/docs/src/app/components/pages/components/List/ExamplePhone.jsx new file mode 100644 index 00000000000000..034366f89a9b76 --- /dev/null +++ b/docs/src/app/components/pages/components/List/ExamplePhone.jsx @@ -0,0 +1,39 @@ +import React from 'react'; +import MobileTearSheet from '../../../MobileTearSheet'; +import List from 'material-ui/lib/lists/list'; +import ListItem from 'material-ui/lib/lists/list-item'; +import Divider from 'material-ui/lib/divider'; +import CommunicationCall from 'material-ui/lib/svg-icons/communication/call'; +import CommunicationChatBubble from 'material-ui/lib/svg-icons/communication/chat-bubble'; +import Colors from 'material-ui/lib/styles/colors'; +import CommunicationEmail from 'material-ui/lib/svg-icons/communication/email'; + +const ListExamplePhone = () => ( + + + } + rightIcon={} + primaryText="(650) 555 - 1234" + secondaryText="Mobile" /> + } + primaryText="(323) 555 - 6789" + secondaryText="Work" /> + + + + } + primaryText="aliconnors@example.com" + secondaryText="Personal" /> + + + +); + +export default ListExamplePhone; diff --git a/docs/src/app/components/pages/components/List/ExampleSelectable.jsx b/docs/src/app/components/pages/components/List/ExampleSelectable.jsx new file mode 100644 index 00000000000000..65960d41734f92 --- /dev/null +++ b/docs/src/app/components/pages/components/List/ExampleSelectable.jsx @@ -0,0 +1,59 @@ +import React from 'react'; +import MobileTearSheet from '../../../MobileTearSheet'; +import List from 'material-ui/lib/lists/list'; +import ListItem from 'material-ui/lib/lists/list-item'; +import Avatar from 'material-ui/lib/avatar'; +import {SelectableContainerEnhance} from 'material-ui/lib/hoc/selectable-enhance'; +let SelectableList = SelectableContainerEnhance(List); + +function wrapState(ComposedComponent) { + const StateWrapper = React.createClass({ + getInitialState() { + return {selectedIndex: 1}; + }, + handleUpdateSelectedIndex(e, index) { + this.setState({ + selectedIndex: index, + }); + }, + render() { + return ( + + ); + }, + }); + return StateWrapper; +} + +SelectableList = wrapState(SelectableList); + +const ListExampleSelectable = () => ( + + + + } + nestedItems={[ + } />, + ]} /> + } /> + } /> + } /> + + +); + +export default ListExampleSelectable; diff --git a/docs/src/app/components/pages/components/List/ExampleSettings.jsx b/docs/src/app/components/pages/components/List/ExampleSettings.jsx new file mode 100644 index 00000000000000..5c19707a6d3f6b --- /dev/null +++ b/docs/src/app/components/pages/components/List/ExampleSettings.jsx @@ -0,0 +1,58 @@ +import React from 'react'; +import MobileTearSheet from '../../../MobileTearSheet'; +import List from 'material-ui/lib/lists/list'; +import ListItem from 'material-ui/lib/lists/list-item'; +import Divider from 'material-ui/lib/divider'; +import Checkbox from 'material-ui/lib/checkbox'; +import Toggle from 'material-ui/lib/toggle'; + +const ListExampleSettings = () => ( +
+ + + + + + + + } + primaryText="Notifications" + secondaryText="Allow notifications" /> + } + primaryText="Sounds" + secondaryText="Hangouts message" /> + } + primaryText="Video sounds" + secondaryText="Hangouts video call" /> + + + + + + + + + } /> + } /> + } /> + + + + } /> + } /> + } /> + + +
+); + +export default ListExampleSettings; diff --git a/docs/src/app/components/pages/components/List/ExampleSimple.jsx b/docs/src/app/components/pages/components/List/ExampleSimple.jsx new file mode 100644 index 00000000000000..1cc97b6cf2215d --- /dev/null +++ b/docs/src/app/components/pages/components/List/ExampleSimple.jsx @@ -0,0 +1,31 @@ +import React from 'react'; +import MobileTearSheet from '../../../MobileTearSheet'; +import List from 'material-ui/lib/lists/list'; +import ListItem from 'material-ui/lib/lists/list-item'; +import ActionGrade from 'material-ui/lib/svg-icons/action/grade'; +import ActionInfo from 'material-ui/lib/svg-icons/action/info'; +import ContentInbox from 'material-ui/lib/svg-icons/content/inbox'; +import ContentDrafts from 'material-ui/lib/svg-icons/content/drafts'; +import ContentSend from 'material-ui/lib/svg-icons/content/send'; +import Divider from 'material-ui/lib/divider'; + +const ListExampleSimple = () => ( + + + } /> + } /> + } /> + } /> + } /> + + + + } /> + } /> + } /> + } /> + + +); + +export default ListExampleSimple; diff --git a/docs/src/app/components/pages/components/List/Page.jsx b/docs/src/app/components/pages/components/List/Page.jsx new file mode 100644 index 00000000000000..5df5477ca5ec0c --- /dev/null +++ b/docs/src/app/components/pages/components/List/Page.jsx @@ -0,0 +1,67 @@ +import React from 'react'; +import CodeExample from '../../../CodeExample'; +import PropTypeDescription from '../../../PropTypeDescription'; +import MarkdownElement from '../../../MarkdownElement'; + +import listReadmeText from './README'; +import selectableHelpText from './SelectableHelp'; +import listCode from '!raw!material-ui/lib/lists/list'; +import listItemCode from '!raw!material-ui/lib/lists/list-item'; +import listExampleSimpleCode from '!raw!./ExampleSimple.jsx'; +import ListExampleSimple from './ExampleSimple.jsx'; +import listExampleChatCode from '!raw!./ExampleChat.jsx'; +import ListExampleChat from './ExampleChat.jsx'; +import listExampleContactsCode from '!raw!./ExampleContacts.jsx'; +import ListExampleContacts from './ExampleContacts.jsx'; +import listExampleFoldersCode from '!raw!./ExampleFolders.jsx'; +import ListExampleFolders from './ExampleFolders.jsx'; +import listExampleNestedCode from '!raw!./ExampleNested.jsx'; +import ListExampleNested from './ExampleNested.jsx'; +//ExampleNested causes warning! +import listExampleSettingsCode from '!raw!./ExampleSettings.jsx'; +import ListExampleSettings from './ExampleSettings.jsx'; +import listExamplePhoneCode from '!raw!./ExamplePhone.jsx'; +import ListExamplePhone from './ExamplePhone.jsx'; +import listExampleMessagesCode from '!raw!./ExampleMessages.jsx'; +import ListExampleMessages from './ExampleMessages.jsx'; +import listExampleSelectableCode from '!raw!./ExampleSelectable.jsx'; +import ListExampleSelectable from './ExampleSelectable.jsx'; + +const ListPage = () => ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +); + +export default ListPage; diff --git a/docs/src/app/components/pages/components/List/README.md b/docs/src/app/components/pages/components/List/README.md new file mode 100644 index 00000000000000..9e520c635dfb21 --- /dev/null +++ b/docs/src/app/components/pages/components/List/README.md @@ -0,0 +1,6 @@ +## List +[Lists](https://www.google.com/design/spec/components/lists.html#) are used to present +multiple items vertically as a single continuous element. They can be configured for +many uses such as a contacts list, nested lists, etc. + +### Examples diff --git a/docs/src/app/components/pages/components/List/SelectableHelp.md b/docs/src/app/components/pages/components/List/SelectableHelp.md new file mode 100644 index 00000000000000..b0e4a0023c6e0a --- /dev/null +++ b/docs/src/app/components/pages/components/List/SelectableHelp.md @@ -0,0 +1,41 @@ +## Selectable List +Basically three steps are needed: +* enhance `List` with HOC +* decide where to put state +* implement and set valueLink + +### Enhance List +Wrapping the `List` component with the higher order component "SelectableEnhance" +enables the clicked `ListItem` to be highlighted. +```javascript +import { SelectableContainerEnhance } from 'material-ui/lib/hoc/selectable-enhance'; +. +. +. +let SelectableList = SelectableContainerEnhance(List); +``` +### Where to put state +If this component is used in conjunction with flux or redux this is a no-brainer. The callback-handler just has to update the store. Otherwise the state can be held within e.g the parent, but it is to be to considered that each time a `ListItem` is clicked, the state will update and the parent - including it's children - will rerender. + +A possible solution for this is to use another hoc. An example can be found in the source-code of docs/src/app/components/pages/components/lists.jsx. +### The valueLink +The prop 'valueLink' of `List` has to be set, to make the highlighting controllable: +```javascript +valueLink={{ + value: this.state.selectedIndex, + requestChange: this.handleUpdateSelectedIndex}} +``` +A sample implementation might look like this. +```javascript +getInitialState() { + return { selectedIndex: 1 }; +}, +handleUpdateSelectedIndex(e,index) { + this.setState({ + selectedIndex: index, +}); +``` +### Adjust the `ListItem` +The `value` prop on each ListItem has to be set. This makes the item +addressable for the callback. +*** diff --git a/docs/src/app/components/pages/components/lists.jsx b/docs/src/app/components/pages/components/lists.jsx deleted file mode 100644 index 05320b3b379190..00000000000000 --- a/docs/src/app/components/pages/components/lists.jsx +++ /dev/null @@ -1,870 +0,0 @@ -import React from 'react'; -import mui from 'material-ui'; -import ComponentDoc from '../../component-doc'; -import MobileTearSheet from '../../MobileTearSheet'; -import ActionAssignment from 'material-ui/svg-icons/action/assignment'; -import ActionGrade from 'material-ui/svg-icons/action/grade'; -import ActionInfo from 'material-ui/svg-icons/action/info'; -import CommunicationCall from 'material-ui/svg-icons/communication/call'; -import CommunicationChatBubble from 'material-ui/svg-icons/communication/chat-bubble'; -import CommunicationEmail from 'material-ui/svg-icons/communication/email'; -import ContentDrafts from 'material-ui/svg-icons/content/drafts'; -import ContentInbox from 'material-ui/svg-icons/content/inbox'; -import ContentSend from 'material-ui/svg-icons/content/send'; -import EditorInsertChart from 'material-ui/svg-icons/editor/insert-chart'; -import FileFolder from 'material-ui/svg-icons/file/folder'; -import MoreVertIcon from 'material-ui/svg-icons/navigation/more-vert'; -import {SelectableContainerEnhance} from 'material-ui/hoc/selectable-enhance'; - -const { - Avatar, - Checkbox, - IconButton, - List, - Divider, - ListItem, - Styles, - Toggle, - Paper, -} = mui; - -import IconMenu from 'menus/icon-menu'; -import MenuItem from 'menus/menu-item'; - -const {Colors} = Styles; -import Code from 'lists-code'; -import CodeExample from '../../CodeExample'; -import CodeBlock from '../../CodeExample/CodeBlock'; -let SelectableList = SelectableContainerEnhance(List); - -const Typography = Styles.Typography; -let styles = { - headline: { - fontSize: '24px', - lineHeight: '32px', - paddingTop: '16px', - marginBottom: '12px', - letterSpacing: '0', - fontWeight: Typography.fontWeightNormal, - color: Typography.textDarkBlack, - }, - subheadline: { - fontSize: 18, - lineHeight: '27px', - paddingTop: 12, - marginBottom: 9, - letterSpacing: '0', - fontWeight: Typography.fontWeightNormal, - color: Typography.textDarkBlack, - }, - codeblock: { - padding: 24, - marginBottom: 32, - }, -}; - -function wrapState(ComposedComponent) { - const StateWrapper = React.createClass({ - getInitialState() { - return {selectedIndex: 1}; - }, - handleUpdateSelectedIndex(e, index) { - this.setState({ - selectedIndex: index, - }); - }, - render() { - return ( - - ); - }, - }); - return StateWrapper; -} - -SelectableList = wrapState(SelectableList); - - -export default class ListsPage extends React.Component { - - constructor(props) { - super(props); - this.state = {selectedIndex: 1}; - - this.handleUpdateSelectedIndex = (e, index) => { - this.setState({ - selectedIndex: index, - }); - }; - } - - render() { - - let componentInfo = [ - { - name: 'List Props', - infoArray: [ - { - name: 'insetSubheader', - type: 'bool', - header: 'default: false', - desc: 'If true, the subheader will be indented by 72px.', - }, - { - name: 'selectedItemStyle', - type: 'object', - header: 'optional, only available if HOC SelectableContainerEnhance is used', - desc: 'Override the choosen inline-styles to indicate a is highlighted.' + - ' You can set e.g. the background color here like this way: {{backgroundColor: #da4e49}}.', - }, - { - name: 'style', - type: 'object', - header: 'optional', - desc: 'Override the inline-styles of the list\'s root element.', - }, - { - name: 'subheader', - type: 'node', - header: 'optional', - desc: 'The subheader string that will be displayed at the top of the list.', - }, - { - name: 'subheaderStyle', - type: 'object', - header: 'optional', - desc: 'The style object to override subheader styles.', - }, - { - name: 'valueLink', - type: 'valueLink', - header: 'optional, only available if HOC SelectableContainerEnhance is used', - desc: 'Makes List controllable. Highlights the ListItem whose index prop matches' + - ' this "selectedLink.value". ' + - '"selectedLink.requestChange" represents a callback function to change that value (e.g. in state).', - }, - ], - }, - { - name: 'ListItem Props', - infoArray: [ - { - name: 'autoGenerateNestedIndicator', - type: 'bool', - header: 'default: true', - desc: 'Generate a nested list indicator icon when nested list items are detected.' + - ' Set to false if you do not want an indicator auto-generated. ' + - 'Note that an indicator will not be created if a rightIcon/Button has been specified.', - }, - { - name: 'disabled', - type: 'bool', - header: 'default: false', - desc: `If true, the list-item will not be clickable and will not display hover affects. -This is automatically disabled if leftCheckbox or rightToggle is set.`, - }, - { - name: 'insetChildren', - type: 'bool', - header: 'default: false', - desc: `If true, the children will be indented by 72px. - Only needed if there is no left avatar or left icon.`, - }, - { - name: 'leftAvatar', - type: 'element', - header: 'optional', - desc: 'This is the Avatar element to be displayed on the left side.', - }, - { - name: 'leftCheckbox', - type: 'element', - header: 'optional', - desc: 'This is the Checkbox element to be displayed on the left side.', - }, - { - name: 'leftIcon', - type: 'element', - header: 'optional', - desc: 'This is the SvgIcon or FontIcon to be displayed on the left side.', - }, - { - name: 'nestedItems', - type: 'Array of elements', - header: 'optional', - desc: 'An array of ListItems to nest underneath the current ListItem.', - }, - { - name: 'nestedLevel', - type: 'number', - header: 'optional', - desc: `Controls how deep a ListItem appears. - This property is automatically managed so modify at your own risk.`, - }, - { - name: 'initiallyOpen', - type: 'bool', - header: 'default: false', - desc: 'Controls whether or not the child ListItems are initially displayed.', - }, - { - name: 'primaryText', - type: 'node', - header: 'optional', - desc: 'This is the block element that contains the primary text. If a string is passed in, a div ' + - 'tag will be rendered.', - }, - { - name: 'primaryTogglesNestedList', - type: 'bool', - header: 'default: false', - desc: 'If provided, tapping on the primary text of the item toggles the nested list.', - }, - { - name: 'rightAvatar', - type: 'element', - header: 'optional', - desc: 'This is the avatar element to be displayed on the right side.', - }, - { - name: 'rightIcon', - type: 'element', - header: 'optional', - desc: 'This is the SvgIcon or FontIcon to be displayed on the right side.', - }, - { - name: 'rightIconButton', - type: 'element', - header: 'optional', - desc: 'This is the IconButton to be displayed on the right side. Hovering over this button will ' + - 'remove the ListItem hover. Also, clicking on this button will not trigger a ListItem ripple. The ' + - 'event will be stopped and prevented from bubbling up to cause a ListItem click.', - }, - { - name: 'rightToggle', - type: 'element', - header: 'optional', - desc: 'This is the Toggle element to display on the right side.', - }, - { - name: 'secondaryText', - type: 'node', - header: 'optional', - desc: 'This is the block element that contains the secondary text. If a string is passed in, a div ' + - 'tag will be rendered.', - }, - { - name: 'secondaryTextLines', - type: 'oneOf [1,2]', - header: 'default: 1', - desc: 'Can be 1 or 2. This is the number of secondary text lines before ellipsis will show.', - }, - { - name: 'style', - type: 'object', - header: 'optional', - desc: 'Override the inline-styles of the list item\'s root element.', - }, - { - name: 'value', - type: 'number', - header: 'optional, only available if HOC SelectableContainerEnhance is used', - desc: `If valueLink prop is passed to List component, this prop is also required. - It assigns an identifier to the listItem so that it can be hightlighted by the List.`, - }, - ], - }, - { - name: 'ListItem Events', - infoArray: [ - { - name: 'onKeyboardFocus', - type: 'function(event, isKeyboardFocused)', - header: 'optional', - desc: 'Called when the ListItem has keyboard focus.', - }, - { - name: 'onMouseLeave', - type: 'function(event)', - header: 'optional', - desc: 'Called when the mouse is no longer over the ListItem.', - }, - { - name: 'onMouseEnter', - type: 'function(event)', - header: 'optional', - desc: 'Called when the mouse is over the ListItem.', - }, - { - name: 'onNestedListToggle', - type: 'function(this)', - header: 'optional', - desc: 'Called when the ListItem toggles its nested ListItems.', - }, - { - name: 'onTouchStart', - type: 'function(event)', - header: 'optional', - desc: 'Called when touches start.', - }, - { - name: 'onTouchTap', - type: 'function(event)', - header: 'optional', - desc: 'Called when a touch tap event occures on the component.', - }, - ], - }, - ]; - - let iconButtonElement = ( - - - - ); - - let rightIconMenu = ( - - Reply - Forward - Delete - - ); - - return ( - - - - - { - `//Import statement: -import List from 'material-ui/lib/lists/list'; -import Divider from 'material-ui/lib/divider'; -import ListItem from 'material-ui/lib/lists/list-item'; - -//See material-ui/lib/index.js for more - ` - } - - - - - - - } /> - } /> - } /> - } /> - } /> - - - - } /> - } /> - } /> - } /> - - - - - - } - rightIcon={} /> - } - rightIcon={} /> - } - rightIcon={} /> - } - rightIcon={} /> - } - rightIcon={} /> - - - - } /> - } /> - - - - - - } - rightAvatar={} /> - } /> - } /> - } /> - - - - A} - rightAvatar={} /> - } /> - } /> - } /> - - - - - - } />} - rightIcon={} - primaryText="Photos" - secondaryText="Jan 9, 2014" /> - } />} - rightIcon={} - primaryText="Recipes" - secondaryText="Jan 17, 2014" /> - } />} - rightIcon={} - primaryText="Work" - secondaryText="Jan 28, 2014" /> - - - - } backgroundColor={Colors.blue500} />} - rightIcon={} - primaryText="Vacation itinerary" - secondaryText="Jan 20, 2014" /> - } backgroundColor={Colors.yellow600} />} - rightIcon={} - primaryText="Kitchen remodel" - secondaryText="Jan 10, 2014" /> - - - - - } /> - } /> - } - initiallyOpen={true} - primaryTogglesNestedList={true} - nestedItems={[ - } />, - } - disabled={true} - nestedItems={[ - } />, - ]} - />, - ]} - /> - - - - - - - - - - } - primaryText="Notifications" - secondaryText="Allow notifications" /> - } - primaryText="Sounds" - secondaryText="Hangouts message" /> - } - primaryText="Video sounds" - secondaryText="Hangouts video call" /> - - - - - - - - - } /> - } /> - } /> - - - - } /> - } /> - } /> - - - - - - } - rightIcon={} - primaryText="(650) 555 - 1234" - secondaryText="Mobile" /> - } - primaryText="(323) 555 - 6789" - secondaryText="Work" /> - - - - } - primaryText="aliconnors@example.com" - secondaryText="Personal" /> - - - - - - - } - primaryText="Brunch this weekend?" - secondaryText={ -

- Brendan Lim -- - I'll be in your neighborhood this weekend. -

- } /> - - } - primaryText={ -

Summer BBQ  4

- } - secondaryText={ -

- to me, Scott, Jennifer -- - Wish I could but I can -

- } /> - - } - primaryText="Oui oui" - secondaryText={ -

- Grace Ng -- - Do you have Paris recommendations? -

- } /> - - } - primaryText="Birthday gift" - secondaryText={ -

- Kerem Suer -- - Do you have any ideas on what I -

- } /> - - } - primaryText="Recipe to try" - secondaryText={ -

- Raquel Parrado -- - We should eat this: grated cheese -

- } /> - - } - primaryText="Giants game" - secondaryText={ -

- Chelsea Otakan -- - Any interest in seeing the Giants -

- } /> -
-
- - - - } - primaryText="Brunch this weekend?" - secondaryText={ -

- Brendan Lim -- - I'll be in your neighborhood doing errands this weekend. Do you want to grab brunch? -

- } - secondaryTextLines={2} /> - - } - primaryText={ -

Summer BBQ  4

- } - secondaryText={ -

- to me, Scott, Jennifer -- - Wish I could come, but I'm out of town this weekend. -

- } - secondaryTextLines={2} /> - - } - primaryText="Oui oui" - secondaryText={ -

- Grace Ng -- - Do you have Paris recommendations? Have you ever been? -

- } - secondaryTextLines={2} /> - - } - primaryText="Birdthday gift" - secondaryText={ -

- Kerem Suer -- - Do you have any ideas what we can get Heidi for her birthday? How about a pony? -

- } - secondaryTextLines={2} /> - - } - primaryText="Recipe to try" - secondaryText={ -

- Raquel Parrado -- - We should eat this: grated squash. Corn and tomatillo tacos. -

- } - secondaryTextLines={2} /> -
-
- - - - } - rightIconButton={rightIconMenu} - primaryText="Brendan Lim" - secondaryText={ -

- Brunch this weekend?
- I'll be in your neighborhood doing errands this weekend. Do you want to grab brunch? -

- } - secondaryTextLines={2} /> - - } - rightIconButton={rightIconMenu} - primaryText="me, Scott, Jennifer" - secondaryText={ -

- Summer BBQ
- Wish I could come, but I'm out of town this weekend. -

- } - secondaryTextLines={2} /> - - } - rightIconButton={rightIconMenu} - primaryText="Grace Ng" - secondaryText={ -

- Oui oui
- Do you have any Paris recs? Have you ever been? -

- } - secondaryTextLines={2} /> - - } - rightIconButton={rightIconMenu} - primaryText="Kerem Suer" - secondaryText={ -

- Birthday gift
- Do you have any ideas what we can get Heidi for her birthday? How about a pony? -

- } - secondaryTextLines={2} /> - - } - rightIconButton={rightIconMenu} - primaryText="Raquel Parrado" - secondaryText={ -

- Recipe to try
- We should eat this: grated squash. Corn and tomatillo tacos. -

- } - secondaryTextLines={2} /> -
-
- - - - } - nestedItems={[ - } />, - ]} /> - } /> - } /> - } /> - - -
- - -
-

Selectable Lists

-

- Basically three steps are needed: -

-
    -
  • enhance <List> with HOC
  • -
  • decide where to put state
  • -
  • implement and set valueLink
  • -
- - -

Enhance List

-

- Wrapping the <List> component with the higher order component "SelectableEnhance" enables - the clicked <ListItem> to be highlighted. -

-
- - {`import { SelectableContainerEnhance } from 'material-ui/lib/hoc/selectable-enhance'; -. -. -. -var SelectableList = SelectableContainerEnhance(List); -`} - -
- - -

Where to put state

-

- If this component is used in conjunction with flux or redux this is a no-brainer. The callback-handler - just has to update the store. Otherwise the state can be held within e.g the parent, but it is to be to - considered that each time a <ListItem> - is clicked, the state will update and the parent - including it's - children - will rerender. -

-

- A possible solution for this is to use another hoc. An example can be found in the sourcecode - of docs/src/app/components/pages/components/lists.jsx. -

-

The valueLink

-

- The prop 'valueLink' of <List> has to be set, to make the highlighting controllable: -

-
- -{`valueLink={{ - value: this.state.selectedIndex, - requestChange: this.handleUpdateSelectedIndex}} -`} - -
- A sample implementation might look like this. -
- -{`getInitialState() { - return { selectedIndex: 1 }; -}, -handleUpdateSelectedIndex(e,index) { - this.setState({ - selectedIndex: index, -}); -`} - -
-

Adjust the <ListItem>

-

- The prop "value" on each ListItem has to be set. This makes the item addressable for the callback. -

-
-
-
- ); - - } -} diff --git a/docs/src/app/components/raw-code/lists-code.txt b/docs/src/app/components/raw-code/lists-code.txt deleted file mode 100644 index 1f89fc0ce40f52..00000000000000 --- a/docs/src/app/components/raw-code/lists-code.txt +++ /dev/null @@ -1,123 +0,0 @@ -//First Example - - } /> - } /> - } /> - } /> - } /> - - - - } /> - } /> - } /> - } /> - - -//Last Example - - } - rightIconButton={rightIconMenu} - primaryText="Brendan Lim" - secondaryText={ -

- Brunch this weekend?
- I'll be in your neighborhood doing errands this weekend. Do you want to grab brunch? -

- } - secondaryTextLines={2} /> - - } - rightIconButton={rightIconMenu} - primaryText="me, Scott, Jennifer" - secondaryText={ -

- Summer BBQ
- Wish I could come, but I'm out of town this weekend. -

- } - secondaryTextLines={2} /> - - } - rightIconButton={rightIconMenu} - primaryText="Grace Ng" - secondaryText={ -

- Oui oui
- Do you have any Paris recs? Have you ever been? -

- } - secondaryTextLines={2} /> - - } - rightIconButton={rightIconMenu} - primaryText="Kerem Suer" - secondaryText={ -

- Birthday gift
- Do you have any ideas what we can get Heidi for her birthday? How about a pony? -

- } - secondaryTextLines={2} /> - - } - rightIconButton={rightIconMenu} - primaryText="Raquel Parrado" - secondaryText={ -

- Recipe to try
- We should eat this: grated squash. Corn and tomatillo tacos. -

- } - secondaryTextLines={2} /> -
- -// Nested List Items - - } /> - } /> - } - initiallyOpen={true} - nestedItems={[ - } />, - } - nestedItems={[ - } />, - ]} - />, - ]} - /> - - -// List with selected indicator based on HOC - - } - nestedItems={[ - } /> - ]} /> - } /> - } /> - } /> - diff --git a/src/lists/list-item.jsx b/src/lists/list-item.jsx index b594e0fa4a7d33..0301f0a5377af4 100644 --- a/src/lists/list-item.jsx +++ b/src/lists/list-item.jsx @@ -17,32 +17,151 @@ import ThemeManager from '../styles/theme-manager'; const ListItem = React.createClass({ propTypes: { + /** + * Generate a nested list indicator icon when + * nested list items are detected. Set to false + * if you do not want an indicator auto-generated. + * Note that an indicator will not be created if a + * rightIcon/Button has been specified. + */ autoGenerateNestedIndicator: React.PropTypes.bool, + + /** + * Children passed into the ListItem. + */ children: React.PropTypes.node, + + /** + * Does not allow the element to be focused by the keyboard. + */ disableKeyboardFocus: React.PropTypes.bool, + + /** + * If true, the list-item will not be clickable + * and will not display hover affects. + * This is automatically disabled if leftCheckbox + * or rightToggle is set. + */ disabled: React.PropTypes.bool, + + /** + * Controls whether or not the child ListItems are initially displayed. + */ initiallyOpen: React.PropTypes.bool, + + /** + * Style prop for the innder div element. + */ innerDivStyle: React.PropTypes.object, - innerStyle: React.PropTypes.object, + + /** + * If true, the children will be indented by 72px. + * Only needed if there is no left avatar or left icon. + */ insetChildren: React.PropTypes.bool, + + /** + * This is the Avatar element to be displayed on the left side. + */ leftAvatar: React.PropTypes.element, + + /** + * This is the Checkbox element to be displayed on the left side. + */ leftCheckbox: React.PropTypes.element, + + /** + * This is the SvgIcon or FontIcon to be displayed on the left side. + */ leftIcon: React.PropTypes.element, + + /** + * An array of ListItems to nest underneath the current ListItem. + */ nestedItems: React.PropTypes.arrayOf(React.PropTypes.element), + + /** + * Controls how deep a ListItem appears. + * This property is automatically managed so modify at your own risk. + */ nestedLevel: React.PropTypes.number, + + /** + * Called when the ListItem has keyboard focus. + */ onKeyboardFocus: React.PropTypes.func, + + /** + * Called when the mouse is over the ListItem. + */ onMouseEnter: React.PropTypes.func, + + /** + * Called when the mouse is no longer over the ListItem. + */ onMouseLeave: React.PropTypes.func, + + /** + * Called when the ListItem toggles its nested ListItems. + */ onNestedListToggle: React.PropTypes.func, + + /** + * Called when touches start. + */ onTouchStart: React.PropTypes.func, + + /** + * Called when a touch tap event occures on the component. + */ onTouchTap: React.PropTypes.func, + + /** + * This is the block element that contains the primary text. + * If a string is passed in, a div tag will be rendered. + */ primaryText: React.PropTypes.node, + + /** + * If provided, tapping on the primary text + * of the item toggles the nested list. + */ primaryTogglesNestedList: React.PropTypes.bool, + + /** + * This is the avatar element to be displayed on the right side. + */ rightAvatar: React.PropTypes.element, + + /** + * This is the SvgIcon or FontIcon to be displayed on the right side. + */ rightIcon: React.PropTypes.element, + + /** + * This is the IconButton to be displayed on the right side. + * Hovering over this button will remove the ListItem hover. + * Also, clicking on this button will not trigger a + * ListItem ripple. The event will be stopped and prevented + * from bubbling up to cause a ListItem click. + */ rightIconButton: React.PropTypes.element, + + /** + * This is the Toggle element to display on the right side. + */ rightToggle: React.PropTypes.element, + + /** + * This is the block element that contains the secondary text. + * If a string is passed in, a div tag will be rendered. + */ secondaryText: React.PropTypes.node, + + /** + * Can be 1 or 2. This is the number of secondary + * text lines before ellipsis will show. + */ secondaryTextLines: React.PropTypes.oneOf([1, 2]), /** @@ -68,7 +187,10 @@ const ListItem = React.createClass({ getDefaultProps() { return { autoGenerateNestedIndicator: true, + disableKeyboardFocus: false, + disabled: false, initiallyOpen: false, + insetChildren: false, nestedItems: [], nestedLevel: 0, onKeyboardFocus: () => {}, diff --git a/src/lists/list.jsx b/src/lists/list.jsx index 9de8e6d3dfd1c6..cc3b2d55a2a7f5 100644 --- a/src/lists/list.jsx +++ b/src/lists/list.jsx @@ -10,15 +10,35 @@ import ThemeManager from '../styles/theme-manager'; const List = React.createClass({ propTypes: { + /** + * These are usually ListItems that are passed to + * be part of the list. + */ children: React.PropTypes.node, + + /** + * If true, the subheader will be indented by 72px. + */ insetSubheader: React.PropTypes.bool, /** * Override the inline-styles of the root element. */ style: React.PropTypes.object, + + /** + * The subheader string that will be displayed at the top of the list. + */ subheader: React.PropTypes.node, + + /** + * The style object to override subheader styles. + */ subheaderStyle: React.PropTypes.object, + + /** + * The zDepth prop passed to the Paper element inside list. + */ zDepth: PropTypes.zDepth, }, @@ -38,6 +58,7 @@ const List = React.createClass({ getDefaultProps() { return { + insetSubheader: false, zDepth: 0, }; },