Collection.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright 2017-2020 @polkadot/react-components authors & contributors
  2. // This software may be modified and distributed under the terms
  3. // of the Apache-2.0 license. See the LICENSE file for details.
  4. import { I18nProps } from '@polkadot/react-components/types';
  5. import React from 'react';
  6. export interface CollectionProps extends I18nProps {
  7. banner?: React.ReactNode;
  8. buttons?: React.ReactNode;
  9. children: React.ReactNode;
  10. className?: string;
  11. headerText?: React.ReactNode;
  12. isEmpty?: boolean;
  13. emptyText?: React.ReactNode;
  14. showEmptyText?: boolean;
  15. }
  16. export interface CollectionState {
  17. isEmpty: boolean;
  18. showHeader?: boolean;
  19. }
  20. export const collectionStyles = `
  21. .ui--Collection-header {
  22. display: flex;
  23. margin-bottom: 0.5rem;
  24. min-height: 2.75rem;
  25. h1 {
  26. flex: 1 1;
  27. margin: 0;
  28. text-transform: lowercase;
  29. }
  30. }
  31. .ui--Collection-lowercase {
  32. text-transform: lowercase;
  33. }
  34. `;
  35. export default class Collection<P extends CollectionProps, S extends CollectionState> extends React.PureComponent<P, S> {
  36. constructor (props: P) {
  37. super(props);
  38. this.state = {
  39. isEmpty: Collection.isEmpty(props.children)
  40. } as S;
  41. }
  42. private static isEmpty (children?: React.ReactNode): boolean {
  43. return !children || (Array.isArray(children) && children.length === 0);
  44. }
  45. public static getDerivedStateFromProps ({ children, isEmpty }: CollectionProps): CollectionState {
  46. return {
  47. isEmpty: isEmpty === undefined ? Collection.isEmpty(children) : isEmpty
  48. };
  49. }
  50. public render (): React.ReactNode {
  51. const { banner, className } = this.props;
  52. const { isEmpty, showHeader } = this.state;
  53. return (
  54. <div className={className}>
  55. {showHeader && this.renderHeader()}
  56. {banner}
  57. {isEmpty
  58. ? this.renderEmpty()
  59. : this.renderCollection()
  60. }
  61. </div>
  62. );
  63. }
  64. protected renderHeader (): React.ReactNode {
  65. const { buttons, headerText } = this.props;
  66. if (!headerText && !buttons) {
  67. return null;
  68. }
  69. return (
  70. <div className='ui--Collection-header'>
  71. <h1>{headerText}</h1>
  72. {buttons && (
  73. <div className='ui--Collection-buttons'>
  74. {buttons}
  75. </div>
  76. )}
  77. </div>
  78. );
  79. }
  80. protected renderEmpty (): React.ReactNode {
  81. const { emptyText = this.props.t('No items'), showEmptyText = true } = this.props;
  82. if (!showEmptyText) {
  83. return null;
  84. }
  85. return (
  86. <article>
  87. <div className='ui--Collection-lowercase'>
  88. {emptyText}
  89. </div>
  90. </article>
  91. );
  92. }
  93. protected renderCollection (): React.ReactNode {
  94. const { children } = this.props;
  95. return children;
  96. }
  97. }