Просмотр исходного кода

Replace old List component with a custom RMWC List

Tatiana Inama 6 лет назад
Родитель
Сommit
94adb2b3c9

recipes/src/components/List2/List.stories.tsx → recipes/src/components/List/List.stories.tsx


+ 33 - 39
recipes/src/components/List/index.tsx

@@ -1,49 +1,43 @@
-import React from 'react';
-import classnames from 'classnames';
-import { includes } from 'ramda';
+import React, { FunctionComponent, CSSProperties } from 'react';
+import cx from 'classnames';
+import {
+  List as RMWCList,
+  ListProps as RMWCListProps,
+  SimpleListItem,
+  SimpleListItemProps as ListItemProps
+} from '@rmwc/list';
 
+import '@rmwc/list/styles';
 import './styles.scss';
 
-type ItemProps = { focused?: boolean } ;
-
-type ListProps<T extends any> = {
-  nonInteractive?: boolean,
-  focusOnClick?: boolean,
-  dense?: boolean,
-  focusMultiple?: T[],
-  focus?: number,
-  items: T[],
-  render: (item: T, index: number) => React.ComponentElement<T, any>,
-  onClick?: (item: T, index: number) => void,
+export interface ListProps extends RMWCListProps {
+  items: ListItemProps[],
+  className?: string,
+  listItemClassName?: string,
+  style?: CSSProperties
 }
 
-const CBKList = <T extends any>({onClick = () => {}, ...props}: ListProps<T>) => {
+export const List: FunctionComponent<ListProps> = ({ items, className, listItemClassName, ...props }) => {
+  
   return (
-    <ul className={
-      classnames({
-        'cbk-list': true,
-        'cbk-list--non-interactive': props.nonInteractive,
-        'cbk-list--dense': props.dense
-      })
-    }>
+    <RMWCList
+      {...props}
+      twoLine={items.some(item => item.secondaryText)}
+      className={cx('cbk-list', className)}
+    >
       {
-        props.items.map((item, index) => (
-          <li
-            key={index}
-            className={
-              classnames({
-                'cbk-list__item': true,
-                'cbk-list__item--focus': index === props.focus || (props.focusMultiple && includes(item, props.focusMultiple))
-              })
-            }
-            onClick={() => onClick(item, index)}
-          >
-            {props.render(item, index)}
-          </li>
-        ))
+        items.map((item, i) => {
+          return (
+            <SimpleListItem
+              { ...item }
+              key={i}
+              className={cx(listItemClassName, 'cbk-list__item')}
+            />
+          )
+        })
       }
-    </ul>
-  );
+    </RMWCList>
+  )
 };
 
-export default CBKList
+export default List;

+ 15 - 40
recipes/src/components/List/styles.scss

@@ -1,47 +1,22 @@
-@import 'styles/_variables';
+@import 'styles/_variables.scss';
 
-.cbk-list {
-  padding: 8px 0;
-  width: 100%;
-
-  &__item {
-    display: flex;
-    position: relative;
-    align-items: center;
-    justify-content: space-between;
-    height: 48px;
-    padding: 0 16px;
-    overflow: hidden;
-    cursor: pointer;
-    &:hover,
-    &--focus {
-      background-color: $yellow
-      ;
+.cbk-list.mdc-list {
+  .mdc-list-item {
+    font-family: $font-family-text;
+    font-weight: 400;
+    
+    &--selected,
+    &--activated {
+      background-color: $yellow;
+      color: $black;
     }
-    .primary-text,
-    .secondary-text {
-      display: block
+    
+    &__primary-text {
+      font-weight: 600;
     }
-    .secondary-text {
-      font-size: 0.75rem;
+    &__secondary-text {
       font-style: italic;
-      color: $grey-500;
-    }
-    .actions { 
-      display: flex;
-      align-items: center;
-      width: 20%;
-    }
-  }
-  &--dense {
-    padding: 0;
-    .cbk-list__item {
-      height: auto;
-    }
-  }
-  &--non-interactive {
-    .cbk-list__item {
-      cursor: default;
     }
+    
   }
 }

+ 0 - 39
recipes/src/components/List2/index.tsx

@@ -1,39 +0,0 @@
-import React, { FunctionComponent } from 'react';
-import cx from 'classnames';
-import {
-  List as RMWCList,
-  ListProps as RMWCListProps,
-  SimpleListItem,
-  SimpleListItemProps as ListItemProps
-} from '@rmwc/list';
-
-import '@rmwc/list/styles';
-import './styles.scss';
-
-export interface ListProps extends RMWCListProps {
-  items: ListItemProps[],
-  className?: string,
-  listItemClassName?: string
-}
-
-export const List: FunctionComponent<ListProps> = ({ items, ...props }) => {
-  return (
-    <RMWCList
-      twoLine={items.some(item => item.secondaryText)}
-      className={cx(props.className, 'cbk-list')}
-      {...props}
-    >
-      {
-        items.map((item, i) => (
-          <SimpleListItem
-            key={i}
-            className={cx(props.listItemClassName, 'cbk-list__item')}
-            { ...item }
-          />
-        ))
-      }
-    </RMWCList>
-  )
-};
-
-export default List;

+ 0 - 22
recipes/src/components/List2/styles.scss

@@ -1,22 +0,0 @@
-@import 'styles/_variables.scss';
-
-.cbk-list.mdc-list {
-  .mdc-list-item {
-    font-family: $font-family-text;
-    font-weight: 400;
-    
-    &--selected,
-    &--activated {
-      background-color: $yellow;
-      color: $black;
-    }
-    
-    &__primary-text {
-      font-weight: 600;
-    }
-    &__secondary-text {
-      font-style: italic;
-    }
-    
-  }
-}

+ 17 - 15
recipes/src/components/RecipeSearch/index.tsx

@@ -118,22 +118,24 @@ class RecipeSearch extends React.Component<Props, State> {
       />
         {
           results.length && openResult ? (
-          <div className='cbk-recipe-search__results'>
-            <List<DBRecipe>
+            <List
+              items={results.map((recipe, i) => ({
+                children: (
+                  <div 
+                    className="cbk-recipe-search__results__item" title={recipe.name}
+                    onMouseDown={(e) => e.preventDefault()}
+                  >
+                    { recipe.name }
+                  </div>
+                ),
+                selected: cursor === i
+              }))}
+              onAction={(e) => this.selectRecipe(results[e.detail.index])}
               dense
-              items={results}
-              focus={cursor}
-              render={(recipe: DBRecipe) => (
-                <div
-                  className='cbk-recipe-search__results__item'
-                  onMouseDown={(e) => { e.preventDefault(); }}
-                  onClick={() => this.selectRecipe(recipe)}
-                >
-                  {recipe.name}
-                </div>
-              )}
-            />
-            </div>
+              className="cbk-recipe-search__results"
+            >
+
+            </List>
           ) : null
         }
     </div>

+ 2 - 10
recipes/src/components/RecipeSearch/styles.scss

@@ -9,25 +9,17 @@
     width: 100%;
     position: absolute;
     z-index: 10000;
-    background-color: white;
+    background: white;
     @include solidBoxShadow();
     .cbk-list {
       max-height: 21rem;
       overflow: hidden;
       padding: 0;
-      .cbk-list__item--focus,
-      .cbk-list__item:hover
-       {
-         cursor: pointer;
-        background-color: $yellow;
-      }
     }
     &__item {
       overflow: hidden;
       text-overflow: ellipsis;
-      display: -webkit-box;
-      -webkit-line-clamp: 2;
-      -webkit-box-orient: vertical;
+      white-space: nowrap;
     }
   }
 }

+ 8 - 19
recipes/src/containers/ShoppingCart/View/index.tsx

@@ -2,7 +2,7 @@ import React from 'react';
 import { connect } from 'react-redux';
 import { ThunkDispatch } from 'redux-thunk';
 import { bindActionCreators } from 'redux';
-import { remove, equals } from 'ramda';
+import { remove, equals, includes } from 'ramda';
 import { toast } from "react-toastify";
 
 import Button from 'components/Button';
@@ -190,24 +190,13 @@ class ShoppingCartView extends React.Component<ShoppingCartViewProps, ShoppingCa
                   <div className='cbk-shopping-list'>
                     <List
                       dense
-                      focusMultiple={this.state.selected}
-                      items={this.props.items}
-                      render={ item => (
-                        <div className='cbk-shopping-list__item'>
-                          <div className='cbk-shopping-list__item__name'>
-                            {item.name}
-                            <div className='cbk-shopping-list__item__name__recipes'>
-                              {
-                                item.recipeName && item.recipeName.join(', ')
-                              }
-                            </div>
-                          </div>
-                          <div className='cbk-shopping-list__item__quantity'>
-                            {item.quantity} {item.unit}
-                          </div>
-                        </div>
-                      )}
-                      onClick={ item => this.selectItem(item) }
+                      items={this.props.items.map(item => ({
+                        selected: includes(item, this.state.selected),
+                        text: item.name,
+                        secondaryText: item.recipeName.join(', '),
+                        meta: `${item.quantity} ${item.unit}`
+                      }))}
+                      onAction={({ detail }) => this.selectItem(this.props.items[detail.index])}
                     />
                   </div>
                 </div>