Design system.
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

154 linhas
5.4 KiB

  1. import * as React from 'react';
  2. import {augmentBinaryFile, getMimeTypeDescription} from 'packages/web-kitchensink-reactnext/src/utils/blob';
  3. import {formatFileSize, formatNumeral} from 'packages/web-kitchensink-reactnext/src/utils/numeral';
  4. import {useFileMetadata, useFileUrl} from 'src/index';
  5. import clsx from 'clsx';
  6. import {KeyValueTable} from 'categories/information/react';
  7. import {BinaryDataCanvas} from 'packages/react-binary-data-canvas';
  8. import {useClientSide} from 'packages/react-utils';
  9. import type {CommonPreviewProps} from '../../../../../categories/blob/react/src/components/FileSelectBox';
  10. export type BinaryFilePreviewDerivedElement = HTMLDivElement;
  11. export interface BinaryFilePreviewProps<F extends Partial<File> = Partial<File>>
  12. extends React.HTMLProps<BinaryFilePreviewDerivedElement>, CommonPreviewProps<F> {}
  13. export const BinaryFilePreview = React.forwardRef<BinaryFilePreviewDerivedElement, BinaryFilePreviewProps>(({
  14. file,
  15. className,
  16. style,
  17. enhanced: enhancedProp = false,
  18. ...etcProps
  19. }, forwardedRef) => {
  20. const { fileWithUrl } = useFileUrl({ file });
  21. const { fileWithMetadata, error } = useFileMetadata({
  22. file: fileWithUrl,
  23. augmentFunction: augmentBinaryFile,
  24. });
  25. const { clientSide } = useClientSide({ clientSide: enhancedProp });
  26. if (!fileWithMetadata) {
  27. return null;
  28. }
  29. return (
  30. <div
  31. className={clsx(
  32. 'flex flex-col sm:grid sm:grid-cols-3 gap-8 w-full',
  33. className,
  34. )}
  35. style={style}
  36. key={`${fileWithMetadata?.url ?? ''}:${fileWithMetadata?.type ?? ''}`}
  37. >
  38. <div className="h-full relative">
  39. <div className="absolute top-0 left-0 w-full h-full">
  40. {
  41. fileWithMetadata.metadata && (fileWithMetadata.metadata?.contents instanceof ArrayBuffer)
  42. && (
  43. <div
  44. {...etcProps}
  45. data-testid="preview"
  46. role="presentation"
  47. className="w-full h-full select-none overflow-hidden text-xs"
  48. ref={forwardedRef}
  49. key={`${fileWithMetadata.url}:${fileWithMetadata.type}`}
  50. >
  51. <BinaryDataCanvas
  52. arrayBuffer={fileWithMetadata.metadata?.contents}
  53. className="overflow-visible binary-file-preview"
  54. headers
  55. byteClassName={(byte, index) => {
  56. if (byte < 0x10) {
  57. return 'x00';
  58. }
  59. if (byte < 0x20) {
  60. return 'x10';
  61. }
  62. if (byte < 0x30) {
  63. return 'x20';
  64. }
  65. if (byte < 0x40) {
  66. return 'x30';
  67. }
  68. if (byte < 0x50) {
  69. return 'x40';
  70. }
  71. if (byte < 0x60) {
  72. return 'x50';
  73. }
  74. if (byte < 0x70) {
  75. return 'x60';
  76. }
  77. if (byte < 0x80) {
  78. return 'x70';
  79. }
  80. if (byte < 0x90) {
  81. return 'x80';
  82. }
  83. if (byte < 0xA0) {
  84. return 'x90';
  85. }
  86. if (byte < 0xB0) {
  87. return 'xa0';
  88. }
  89. if (byte < 0xC0) {
  90. return 'xb0';
  91. }
  92. if (byte < 0xD0) {
  93. return 'xc0';
  94. }
  95. if (byte < 0xE0) {
  96. return 'xd0';
  97. }
  98. if (byte < 0xF0) {
  99. return 'xe0';
  100. }
  101. return 'xf0';
  102. }}
  103. />
  104. </div>
  105. )
  106. }
  107. </div>
  108. </div>
  109. <div className="col-span-2 flex-shrink-0 m-0 flex flex-col gap-4 justify-between">
  110. <KeyValueTable
  111. hiddenKeys
  112. data-testid="infoBox"
  113. properties={[
  114. Boolean(fileWithMetadata.name) && {
  115. key: 'Name',
  116. className: 'font-bold',
  117. valueProps: {
  118. children: fileWithMetadata.name,
  119. title: fileWithMetadata.name,
  120. },
  121. },
  122. (clientSide && Boolean(getMimeTypeDescription(fileWithMetadata.type, fileWithMetadata.name) || '(Loading)') || Boolean(fileWithMetadata.type)) && {
  123. key: 'Type',
  124. valueProps: {
  125. className: clsx(
  126. !getMimeTypeDescription(fileWithMetadata.type, fileWithMetadata.name) && 'opacity-50'
  127. ),
  128. children: getMimeTypeDescription(fileWithMetadata.type, fileWithMetadata.name) || '(Loading)',
  129. },
  130. },
  131. (clientSide && Boolean(formatFileSize(fileWithMetadata.size) || '(Loading)') || Boolean(fileWithMetadata.size)) && {
  132. key: 'Size',
  133. valueProps: {
  134. className: clsx(
  135. !formatFileSize(fileWithMetadata.size) && 'opacity-50'
  136. ),
  137. title: `${formatNumeral(fileWithMetadata.size ?? 0)} byte(s)`,
  138. children: formatFileSize(fileWithMetadata.size) || '(Loading)',
  139. },
  140. },
  141. ]}
  142. />
  143. </div>
  144. </div>
  145. );
  146. });
  147. BinaryFilePreview.displayName = 'BinaryFilePreview';