Design system.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

107 line
2.6 KiB

  1. import * as React from 'react';
  2. import { tailwind } from '@tesseract-design/web-base';
  3. const { tw } = tailwind;
  4. const KeyValueTableDerivedElementComponent = 'dl' as const;
  5. /**
  6. * Derived HTML element of the {@link KeyValueTable} component.
  7. */
  8. export type KeyValueTableDerivedElement = HTMLElementTagNameMap[
  9. typeof KeyValueTableDerivedElementComponent
  10. ];
  11. const KeyValueTablePropertyElementComponent = 'div' as const;
  12. const KeyValueTableKeyElementComponent = 'dt' as const;
  13. const KeyValueTableValueElementComponent = 'dd' as const;
  14. /**
  15. * Individual property of the {@link KeyValueTable} component.
  16. */
  17. export interface KeyValueTableProperty {
  18. /**
  19. * Key of the property.
  20. */
  21. key: string;
  22. /**
  23. * Class name of the property.
  24. */
  25. className?: string;
  26. /**
  27. * Value of the property.
  28. */
  29. valueProps?: React.HTMLProps<HTMLElement>;
  30. }
  31. /**
  32. * Props of the {@link KeyValueTable} component.
  33. */
  34. export interface KeyValueTableProps extends Omit<React.HTMLProps<KeyValueTableDerivedElement>, 'children'> {
  35. /**
  36. * Should the keys be hidden?
  37. */
  38. hiddenKeys?: boolean;
  39. /**
  40. * Properties displayed on the component.
  41. */
  42. properties?: (KeyValueTableProperty | boolean | null | undefined)[];
  43. }
  44. /**
  45. * Component for displaying key-value pairs.
  46. */
  47. export const KeyValueTable = React.forwardRef<KeyValueTableDerivedElement, KeyValueTableProps>((
  48. {
  49. hiddenKeys = false,
  50. properties = [],
  51. className,
  52. style,
  53. ...etcProps
  54. },
  55. forwardedRef,
  56. ) => (
  57. <KeyValueTableDerivedElementComponent
  58. {...etcProps}
  59. className={tw(
  60. 'grid gap-y-1 grid-cols-3',
  61. className,
  62. )}
  63. ref={forwardedRef}
  64. style={style}
  65. >
  66. {properties.map((property) => typeof property === 'object' && property && (
  67. <KeyValueTablePropertyElementComponent
  68. key={property.key}
  69. className={tw('contents', property.className)}
  70. >
  71. <KeyValueTableKeyElementComponent
  72. className={tw(hiddenKeys && 'sr-only', 'pr-4')}
  73. >
  74. {property.key}
  75. </KeyValueTableKeyElementComponent>
  76. <KeyValueTableValueElementComponent
  77. {...(property.valueProps ?? {})}
  78. className={tw(
  79. 'm-0 text-ellipsis overflow-hidden',
  80. !hiddenKeys && 'col-span-2',
  81. hiddenKeys && 'col-span-3',
  82. property.valueProps?.className,
  83. )}
  84. >
  85. {property.valueProps?.children}
  86. </KeyValueTableValueElementComponent>
  87. </KeyValueTablePropertyElementComponent>
  88. ))}
  89. </KeyValueTableDerivedElementComponent>
  90. ));
  91. KeyValueTable.displayName = 'KeyValueTable';
  92. KeyValueTable.defaultProps = {
  93. hiddenKeys: false,
  94. properties: [],
  95. };