Bläddra i källkod

Extract all categories outside kitchen sink

Define all categories presently implemented.
pull/1/head
TheoryOfNekomata 1 år sedan
förälder
incheckning
231b0382df
94 ändrade filer med 1094 tillägg och 423 borttagningar
  1. +3
    -3
      categories/action/react/src/components/ActionButton/index.tsx
  2. +9
    -0
      categories/blob/react/.eslintrc
  3. +107
    -0
      categories/blob/react/.gitignore
  4. +7
    -0
      categories/blob/react/LICENSE
  5. +81
    -0
      categories/blob/react/package.json
  6. +3
    -0
      categories/blob/react/pridepack.json
  7. +35
    -53
      categories/blob/react/src/components/FileSelectBox/index.tsx
  8. +1
    -0
      categories/blob/react/src/index.ts
  9. +21
    -0
      categories/blob/react/tsconfig.eslint.json
  10. +21
    -0
      categories/blob/react/tsconfig.json
  11. +8
    -0
      categories/blob/react/vitest.config.ts
  12. +3
    -1
      categories/choice/react/package.json
  13. +4
    -4
      categories/multichoice/react/src/components/TagInput/TagInput.css
  14. +3
    -3
      categories/navigation/react/src/components/LinkButton/index.tsx
  15. +3
    -1
      categories/number/react/package.json
  16. +9
    -0
      packages/blob-utils/.eslintrc
  17. +107
    -0
      packages/blob-utils/.gitignore
  18. +7
    -0
      packages/blob-utils/LICENSE
  19. +70
    -0
      packages/blob-utils/package.json
  20. +3
    -0
      packages/blob-utils/pridepack.json
  21. +49
    -0
      packages/blob-utils/src/content-type.ts
  22. +59
    -0
      packages/blob-utils/src/description.ts
  23. +2
    -0
      packages/blob-utils/src/index.ts
  24. +21
    -0
      packages/blob-utils/tsconfig.eslint.json
  25. +21
    -0
      packages/blob-utils/tsconfig.json
  26. +9
    -0
      packages/react-blob-previews/.eslintrc
  27. +107
    -0
      packages/react-blob-previews/.gitignore
  28. +7
    -0
      packages/react-blob-previews/LICENSE
  29. +77
    -0
      packages/react-blob-previews/package.json
  30. +3
    -0
      packages/react-blob-previews/pridepack.json
  31. +9
    -9
      packages/react-blob-previews/src/components/AudioFilePreview/index.tsx
  32. +5
    -5
      packages/react-blob-previews/src/components/AudioMiniFilePreview/index.tsx
  33. +7
    -7
      packages/react-blob-previews/src/components/BinaryFilePreview/index.tsx
  34. +7
    -7
      packages/react-blob-previews/src/components/ImageFilePreview/index.tsx
  35. +7
    -7
      packages/react-blob-previews/src/components/TextFilePreview/index.tsx
  36. +7
    -7
      packages/react-blob-previews/src/components/VideoFilePreview/index.tsx
  37. +0
    -0
      packages/react-blob-previews/src/hooks/blob/index.ts
  38. +1
    -1
      packages/react-blob-previews/src/hooks/blob/metadata.ts
  39. +0
    -0
      packages/react-blob-previews/src/hooks/interactive/image.ts
  40. +0
    -0
      packages/react-blob-previews/src/hooks/interactive/index.ts
  41. +0
    -0
      packages/react-blob-previews/src/hooks/interactive/media.ts
  42. +0
    -1
      packages/react-blob-previews/src/index.ts
  43. +21
    -0
      packages/react-blob-previews/tsconfig.eslint.json
  44. +21
    -0
      packages/react-blob-previews/tsconfig.json
  45. +8
    -0
      packages/react-blob-previews/vitest.config.ts
  46. +0
    -10
      packages/web-kitchensink-reactnext/src/categories/blob/react/common.ts
  47. +0
    -187
      packages/web-kitchensink-reactnext/src/pages/categories/blob/index.tsx
  48. +138
    -7
      pnpm-lock.yaml
  49. +1
    -0
      pnpm-workspace.yaml
  50. +0
    -0
      showcases/web-kitchensink-reactnext/.eslintrc.json
  51. +0
    -0
      showcases/web-kitchensink-reactnext/.gitignore
  52. +0
    -0
      showcases/web-kitchensink-reactnext/README.md
  53. +0
    -0
      showcases/web-kitchensink-reactnext/colorthief.d.ts
  54. +0
    -0
      showcases/web-kitchensink-reactnext/next.config.js
  55. +1
    -0
      showcases/web-kitchensink-reactnext/package.json
  56. +0
    -0
      showcases/web-kitchensink-reactnext/pnpm-lock.yaml
  57. +0
    -0
      showcases/web-kitchensink-reactnext/postcss.config.js
  58. +0
    -0
      showcases/web-kitchensink-reactnext/public/audio.wav
  59. +0
    -0
      showcases/web-kitchensink-reactnext/public/binary.bin
  60. +0
    -0
      showcases/web-kitchensink-reactnext/public/code.py
  61. +0
    -0
      showcases/web-kitchensink-reactnext/public/favicon.ico
  62. +0
    -0
      showcases/web-kitchensink-reactnext/public/image.png
  63. +0
    -0
      showcases/web-kitchensink-reactnext/public/next.svg
  64. +0
    -0
      showcases/web-kitchensink-reactnext/public/plaintext.txt
  65. +0
    -0
      showcases/web-kitchensink-reactnext/public/vercel.svg
  66. +0
    -0
      showcases/web-kitchensink-reactnext/public/video.mp4
  67. +0
    -0
      showcases/web-kitchensink-reactnext/react-refractor.d.ts
  68. +0
    -0
      showcases/web-kitchensink-reactnext/src/components/DefaultLayout/index.tsx
  69. +0
    -0
      showcases/web-kitchensink-reactnext/src/components/Section/index.tsx
  70. +0
    -0
      showcases/web-kitchensink-reactnext/src/packages/react-refractor/index.tsx
  71. +0
    -0
      showcases/web-kitchensink-reactnext/src/packages/react-refractor/style.module.css
  72. +0
    -0
      showcases/web-kitchensink-reactnext/src/packages/react-wavesurfer/SpectrogramCanvas/index.tsx
  73. +0
    -0
      showcases/web-kitchensink-reactnext/src/packages/react-wavesurfer/WaveformCanvas/index.tsx
  74. +0
    -0
      showcases/web-kitchensink-reactnext/src/packages/react-wavesurfer/index.ts
  75. +0
    -0
      showcases/web-kitchensink-reactnext/src/pages/_app.tsx
  76. +0
    -0
      showcases/web-kitchensink-reactnext/src/pages/_document.tsx
  77. +0
    -0
      showcases/web-kitchensink-reactnext/src/pages/api/hello.ts
  78. +0
    -0
      showcases/web-kitchensink-reactnext/src/pages/categories/action/index.tsx
  79. +0
    -0
      showcases/web-kitchensink-reactnext/src/pages/categories/code/index.tsx
  80. +0
    -0
      showcases/web-kitchensink-reactnext/src/pages/categories/freeform/index.tsx
  81. +0
    -0
      showcases/web-kitchensink-reactnext/src/pages/categories/navigation/index.tsx
  82. +0
    -0
      showcases/web-kitchensink-reactnext/src/pages/categories/number/index.tsx
  83. +0
    -0
      showcases/web-kitchensink-reactnext/src/pages/categories/option/index.tsx
  84. +0
    -0
      showcases/web-kitchensink-reactnext/src/pages/categories/presentation/index.tsx
  85. +0
    -0
      showcases/web-kitchensink-reactnext/src/pages/examples/blog-post/index.tsx
  86. +1
    -1
      showcases/web-kitchensink-reactnext/src/pages/examples/registration-form/index.tsx
  87. +0
    -0
      showcases/web-kitchensink-reactnext/src/pages/index.tsx
  88. +0
    -0
      showcases/web-kitchensink-reactnext/src/styles/globals.css
  89. +0
    -0
      showcases/web-kitchensink-reactnext/src/styles/kitchen-sink.css
  90. +0
    -0
      showcases/web-kitchensink-reactnext/src/styles/theme.ts
  91. +0
    -109
      showcases/web-kitchensink-reactnext/src/utils/blob.ts
  92. +0
    -0
      showcases/web-kitchensink-reactnext/src/utils/numeral.ts
  93. +0
    -0
      showcases/web-kitchensink-reactnext/tailwind.config.js
  94. +0
    -0
      showcases/web-kitchensink-reactnext/tsconfig.json

+ 3
- 3
categories/action/react/src/components/ActionButton/index.tsx Visa fil

@@ -33,7 +33,7 @@ export const ActionButton = React.forwardRef<ActionButtonDerivedElement, ActionB
type={type}
ref={forwardedRef}
className={clsx(
'items-center justify-center rounded overflow-hidden ring-secondary/50 leading-none gap-4 select-none',
'items-center justify-center rounded overflow-hidden ring-secondary/50 leading-none select-none',
'focus:outline-0 focus:ring-4',
'active:ring-tertiary/50',
'disabled:opacity-50 disabled:cursor-not-allowed',
@@ -42,8 +42,8 @@ export const ActionButton = React.forwardRef<ActionButtonDerivedElement, ActionB
'inline-flex max-w-full align-middle': !block,
},
{
'pl-2': compact,
'pl-4': !compact,
'pl-2 gap-2': compact,
'pl-4 gap-4': !compact,
'pr-4': !(compact || menuItem),
'pr-2': compact || menuItem,
},


+ 9
- 0
categories/blob/react/.eslintrc Visa fil

@@ -0,0 +1,9 @@
{
"root": true,
"extends": [
"lxsmnsyc/typescript/react"
],
"parserOptions": {
"project": "./tsconfig.eslint.json"
}
}

+ 107
- 0
categories/blob/react/.gitignore Visa fil

@@ -0,0 +1,107 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.production
.env.development

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

.npmrc

+ 7
- 0
categories/blob/react/LICENSE Visa fil

@@ -0,0 +1,7 @@
MIT License Copyright (c) 2023 TheoryOfNekomata <allan.crisostomo@outlook.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 81
- 0
categories/blob/react/package.json Visa fil

@@ -0,0 +1,81 @@
{
"name": "@tesseract-design/web-blob-react",
"version": "0.0.0",
"files": [
"dist",
"src"
],
"engines": {
"node": ">=12"
},
"license": "MIT",
"keywords": [
"pridepack"
],
"devDependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@types/node": "^18.14.1",
"@types/react": "^18.0.27",
"eslint": "^8.35.0",
"eslint-config-lxsmnsyc": "^0.5.0",
"jsdom": "^21.1.0",
"pridepack": "2.4.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-test-renderer": "^18.2.0",
"tslib": "^2.5.0",
"typescript": "^4.9.5",
"vitest": "^0.28.1"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"scripts": {
"prepublishOnly": "pridepack clean && pridepack build",
"build": "pridepack build",
"type-check": "pridepack check",
"lint": "pridepack lint",
"clean": "pridepack clean",
"watch": "pridepack watch",
"start": "pridepack start",
"dev": "pridepack dev",
"test": "vitest"
},
"private": false,
"description": "Tesseract components for displaying data.",
"repository": {
"url": "",
"type": "git"
},
"homepage": "",
"bugs": {
"url": ""
},
"author": "TheoryOfNekomata <allan.crisostomo@outlook.com>",
"publishConfig": {
"access": "public"
},
"dependencies": {
"clsx": "^1.2.1",
"@modal-sh/react-utils": "workspace:*"
},
"types": "./dist/types/index.d.ts",
"main": "./dist/cjs/production/index.js",
"module": "./dist/esm/production/index.js",
"exports": {
".": {
"development": {
"require": "./dist/cjs/development/index.js",
"import": "./dist/esm/development/index.js"
},
"require": "./dist/cjs/production/index.js",
"import": "./dist/esm/production/index.js",
"types": "./dist/types/index.d.ts"
}
},
"typesVersions": {
"*": {}
}
}

+ 3
- 0
categories/blob/react/pridepack.json Visa fil

@@ -0,0 +1,3 @@
{
"target": "es2018"
}

packages/web-kitchensink-reactnext/src/categories/blob/react/components/FileSelectBox/index.tsx → categories/blob/react/src/components/FileSelectBox/index.tsx Visa fil

@@ -1,27 +1,20 @@
import * as React from 'react';
import {ContentType, FileWithResolvedContentType, getContentType, getMimeTypeDescription} from '@/utils/blob';
import {formatFileSize} from '@/utils/numeral';
import {AudioFilePreview} from '../AudioFilePreview';
import {BinaryFilePreview} from '../BinaryFilePreview';
import {ImageFilePreview} from '../ImageFilePreview';
import {VideoFilePreview} from '../VideoFilePreview';
import {TextFilePreview} from '../TextFilePreview';
import {AudioMiniFilePreview} from '../AudioMiniFilePreview';
import {delegateTriggerEvent, useClientSide} from '@modal-sh/react-utils';
import { delegateTriggerEvent, useClientSide } from '@modal-sh/react-utils';
import clsx from 'clsx';
import {FilePreviewComponent} from '@/categories/blob/react/common';

const FILE_PREVIEW_COMPONENTS: Record<ContentType, FilePreviewComponent> = {
[ContentType.IMAGE]: ImageFilePreview,
[ContentType.AUDIO]: AudioFilePreview,
[ContentType.VIDEO]: VideoFilePreview,
[ContentType.BINARY]: BinaryFilePreview,
[ContentType.TEXT]: TextFilePreview,
};
export interface CommonPreviewProps<F extends Partial<File> = Partial<File>> {
file?: F;
disabled?: boolean;
enhanced?: boolean;
mini?: boolean;
}

export type FileSelectBoxDerivedElement = HTMLInputElement;

export interface FileSelectBoxProps extends Omit<React.HTMLProps<FileSelectBoxDerivedElement>, 'size' | 'type' | 'style' | 'label' | 'list'> {
export interface FileSelectBoxProps<
F extends Partial<File> = Partial<File>,
P extends CommonPreviewProps<F> = CommonPreviewProps<F>
> extends Omit<React.HTMLProps<FileSelectBoxDerivedElement>, 'size' | 'type' | 'style' | 'label' | 'list'> {
/**
* Should the component display a border?
*/
@@ -43,6 +36,7 @@ export interface FileSelectBoxProps extends Omit<React.HTMLProps<FileSelectBoxDe
* Is the label hidden?
*/
hiddenLabel?: boolean,
previewComponent: React.ElementType<P>,
}

export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileSelectBoxProps>(
@@ -59,6 +53,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
disabled = false,
className,
id: idProp,
previewComponent: FilePreviewComponent,
...etcProps
}: FileSelectBoxProps,
forwardedRef,
@@ -101,7 +96,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
const cancelEvent = (e: React.DragEvent) => {
e.stopPropagation();
e.preventDefault();
}
};

const handleDropZone: React.DragEventHandler<HTMLDivElement> = async (e) => {
cancelEvent(e);
@@ -122,7 +117,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
setTimeout(() => {
delegateTriggerEvent('change', current);
});
}
};

const filesCount = fileList?.length ?? 0;

@@ -131,6 +126,8 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
className={clsx(
'relative rounded ring-secondary/50 group',
'focus-within:ring-4',
block && 'w-full',
!block && 'inline-block min-w-64',
className,
)}
onDragEnter={cancelEvent}
@@ -207,34 +204,19 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
&& (
<div className="w-full h-full overflow-auto -mx-4 px-4">
<div className="w-full grid gap-4 grid-cols-3">
{Array.from(fileList ?? []).map((file: File) => {
const f = file as unknown as FileWithResolvedContentType;
const fileContentType = getContentType(file.type, file.name);
{Array.from(fileList ?? []).map((file, i) => {
return (
<div
key={`${file.name}:${i}`}
data-testid="selectedFileItem"
key={f?.url ?? f?.name}
className={`w-full aspect-square rounded overflow-hidden relative before:absolute before:content-[''] before:bg-current before:top-0 before:left-0 before:w-full before:h-full before:opacity-10`}
title={[f.name, getMimeTypeDescription(f.type), formatFileSize(f.size)].join(', ')}
>
{
fileContentType === ContentType.IMAGE
&& typeof f?.url === 'string'
&& (
<img
className="block w-full h-full object-center object-cover"
src={f.url}
alt={f.name}
data-testid="preview"
/>
)
}
{
fileContentType === ContentType.AUDIO
&& (
<AudioMiniFilePreview file={f} />
)
}
<FilePreviewComponent
file={file}
enhanced={clientSide}
disabled={disabled}
mini
/>
</div>
);
})}
@@ -244,25 +226,25 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
}
{
!multiple
&& Array.from(fileList ?? []).map((file) => {
const f = file as unknown as FileWithResolvedContentType;
const fileContentType = getContentType(file.type, file.name);
const { [fileContentType]: FilePreviewComponent = BinaryFilePreview } = FILE_PREVIEW_COMPONENTS;
&& Array.from(fileList ?? []).map((file, i) => {
return (
<div
key={f?.url ?? f?.name}
key={`${file.name}:${i}`}
className="w-full h-full"
>
<div
data-testid="selectedFileItem"
className="h-full w-full p-4 box-border rounded overflow-hidden relative before:absolute before:content-[''] before:bg-current before:top-0 before:left-0 before:w-full before:h-full before:opacity-10"
>
<FilePreviewComponent
<div
className="w-full h-full relative"
file={f}
enhanced={clientSide}
disabled={disabled}
/>
>
<FilePreviewComponent
file={file}
enhanced={clientSide}
disabled={disabled}
/>
</div>
</div>
</div>
)

+ 1
- 0
categories/blob/react/src/index.ts Visa fil

@@ -0,0 +1 @@
export * from './components/FileSelectBox';

+ 21
- 0
categories/blob/react/tsconfig.eslint.json Visa fil

@@ -0,0 +1,21 @@
{
"exclude": ["node_modules"],
"include": ["src", "types", "test"],
"compilerOptions": {
"module": "ESNext",
"lib": ["DOM", "ESNext"],
"importHelpers": true,
"declaration": true,
"sourceMap": true,
"rootDir": "./",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"jsx": "react",
"esModuleInterop": true,
"target": "es2018"
}
}

+ 21
- 0
categories/blob/react/tsconfig.json Visa fil

@@ -0,0 +1,21 @@
{
"exclude": ["node_modules"],
"include": ["src", "types"],
"compilerOptions": {
"module": "ESNext",
"lib": ["DOM", "ESNext"],
"importHelpers": true,
"declaration": true,
"sourceMap": true,
"rootDir": "./src",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"jsx": "react",
"esModuleInterop": true,
"target": "es2018"
}
}

+ 8
- 0
categories/blob/react/vitest.config.ts Visa fil

@@ -0,0 +1,8 @@
/// <reference types="vitest" />

export default ({
test: {
global: true,
environment: 'jsdom',
},
});

+ 3
- 1
categories/choice/react/package.json Visa fil

@@ -74,7 +74,9 @@
"require": "./dist/cjs/production/index.js",
"import": "./dist/esm/production/index.js",
"types": "./dist/types/index.d.ts"
}
},
"./dist/RadioButton.css": "./dist/RadioButton.css",
"./dist/RadioTickBox.css": "./dist/RadioTickBox.css"
},
"typesVersions": {
"*": {}


+ 4
- 4
categories/multichoice/react/src/components/TagInput/TagInput.css Visa fil

@@ -73,24 +73,24 @@
padding-right: 4rem;
}

.tesseract-design-tag-input.tag-input textarea + div > span {
.tesseract-design-tag-input textarea + div > span {
padding: 0.125rem;
border-radius: 0.25rem;
line-height: 1;
background-color: rgb(var(--color-positive) / 25%);
}

.tesseract-design-tag-input.tag-input textarea + div > span span {
.tesseract-design-tag-input textarea + div > span span {
pointer-events: none;
}

.tesseract-design-tag-input.tag-input textarea + div > span button {
.tesseract-design-tag-input textarea + div > span button {
color: rgb(var(--color-primary));
padding: 0;
width: 1rem;
margin-left: 0.25rem;
}

.tesseract-design-tag-input.tag-input textarea + div > span button:hover {
.tesseract-design-tag-input textarea + div > span button:hover {
color: rgb(var(--color-primary));
}

+ 3
- 3
categories/navigation/react/src/components/LinkButton/index.tsx Visa fil

@@ -32,7 +32,7 @@ export const LinkButton = React.forwardRef<LinkButtonDerivedElement, LinkButtonP
{...etcProps}
ref={forwardedRef}
className={clsx(
'items-center justify-center rounded overflow-hidden ring-secondary/50 leading-none gap-4 select-none',
'items-center justify-center rounded overflow-hidden ring-secondary/50 leading-none select-none',
'focus:outline-0 focus:ring-4',
'active:ring-tertiary/50',
{
@@ -40,8 +40,8 @@ export const LinkButton = React.forwardRef<LinkButtonDerivedElement, LinkButtonP
'inline-flex max-w-full align-middle': !block,
},
{
'pl-2': compact,
'pl-4': !compact,
'pl-2 gap-2': compact,
'pl-4 gap-4': !compact,
'pr-4': !(compact || menuItem),
'pr-2': compact || menuItem,
},


+ 3
- 1
categories/number/react/package.json Visa fil

@@ -74,7 +74,9 @@
"require": "./dist/cjs/production/index.js",
"import": "./dist/esm/production/index.js",
"types": "./dist/types/index.d.ts"
}
},
"./dist/Slider.css": "./dist/Slider.css",
"./dist/Spinner.css": "./dist/Spinner.css"
},
"typesVersions": {
"*": {}


+ 9
- 0
packages/blob-utils/.eslintrc Visa fil

@@ -0,0 +1,9 @@
{
"root": true,
"extends": [
"lxsmnsyc/typescript"
],
"parserOptions": {
"project": "./tsconfig.eslint.json"
}
}

+ 107
- 0
packages/blob-utils/.gitignore Visa fil

@@ -0,0 +1,107 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.production
.env.development

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

.npmrc

+ 7
- 0
packages/blob-utils/LICENSE Visa fil

@@ -0,0 +1,7 @@
MIT License Copyright (c) 2023 TheoryOfNekomata <allan.crisostomo@outlook.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 70
- 0
packages/blob-utils/package.json Visa fil

@@ -0,0 +1,70 @@
{
"name": "@modal-sh/blob-utils",
"version": "0.0.0",
"files": [
"dist",
"src"
],
"engines": {
"node": ">=12"
},
"license": "MIT",
"keywords": [
"pridepack"
],
"devDependencies": {
"@types/mime-types": "^2.1.1",
"@types/node": "^18.14.1",
"eslint": "^8.35.0",
"eslint-config-lxsmnsyc": "^0.5.0",
"pridepack": "2.4.4",
"tslib": "^2.5.0",
"typescript": "^4.9.5",
"vitest": "^0.28.1"
},
"scripts": {
"prepublishOnly": "pridepack clean && pridepack build",
"build": "pridepack build",
"type-check": "pridepack check",
"lint": "pridepack lint",
"clean": "pridepack clean",
"watch": "pridepack watch",
"start": "pridepack start",
"dev": "pridepack dev",
"test": "vitest"
},
"private": false,
"description": "Utilities for binary data.",
"repository": {
"url": "",
"type": "git"
},
"homepage": "",
"bugs": {
"url": ""
},
"author": "TheoryOfNekomata <allan.crisostomo@outlook.com>",
"publishConfig": {
"access": "public"
},
"types": "./dist/types/index.d.ts",
"main": "./dist/cjs/production/index.js",
"module": "./dist/esm/production/index.js",
"exports": {
".": {
"development": {
"require": "./dist/cjs/development/index.js",
"import": "./dist/esm/development/index.js"
},
"require": "./dist/cjs/production/index.js",
"import": "./dist/esm/production/index.js",
"types": "./dist/types/index.d.ts"
}
},
"typesVersions": {
"*": {}
},
"dependencies": {
"mime-types": "^2.1.35"
}
}

+ 3
- 0
packages/blob-utils/pridepack.json Visa fil

@@ -0,0 +1,3 @@
{
"target": "es2018"
}

+ 49
- 0
packages/blob-utils/src/content-type.ts Visa fil

@@ -0,0 +1,49 @@
import * as mimeTypes from 'mime-types';

export enum ContentType {
TEXT = 'text',
AUDIO = 'audio',
VIDEO = 'video',
IMAGE = 'image',
BINARY = 'binary',
}

export const getContentType = (mimeType?: string, filename?: string) => {
let effectiveMimeType: string;
if (typeof mimeType !== 'string') {
if (typeof filename !== 'string') {
return ContentType.BINARY;
}
const lookupMimeType = mimeTypes.lookup(filename);

if (typeof lookupMimeType !== 'string') {
return ContentType.BINARY;
}

effectiveMimeType = lookupMimeType;
} else {
effectiveMimeType = mimeType;
}

if (
effectiveMimeType === 'application/json'
|| effectiveMimeType === 'application/xml'
|| effectiveMimeType.startsWith('text/')
) {
return ContentType.TEXT;
}

if (effectiveMimeType.startsWith('video/')) {
return ContentType.VIDEO;
}

if (effectiveMimeType.startsWith('audio/')) {
return ContentType.AUDIO;
}

if (effectiveMimeType.startsWith('image/')) {
return ContentType.IMAGE;
}

return ContentType.BINARY;
};

+ 59
- 0
packages/blob-utils/src/description.ts Visa fil

@@ -0,0 +1,59 @@
const MIME_TYPE_DESCRIPTIONS = {
'image/gif': 'GIF Image',
'image/jpeg': 'JPEG Image',
'image/png': 'PNG Image',
'image/tiff': 'TIFF Image',
'image/svg+xml': 'SVG Image',
'image/webp': 'WEBP Image',
'audio/wav': 'WAVE Audio',
'audio/ogg': 'OGG Audio',
'audio/mpeg': 'MPEG Audio',
'audio/mid': 'MIDI Track',
'application/json': 'JSON Data',
'application/xml': 'XML Data',
'application/x-bittorrent': 'Torrent File',
'application/x-zip-compressed': 'Compressed ZIP Archive',
'application/x-x509-ca-cert': 'Certificate File',
'application/x-tar': 'Compressed TAR Archive',
'application/x-rar': 'Compressed RAR Archive',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'Workbook',
'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'Slideshow Presentation',
'application/msword': 'Microsoft Word Document',
'application/pdf': 'PDF Document',
'application/postscript': 'PostScript Document',
'application/epub+zip': 'EPUB Document',
'message/rfc822': 'Email Message',
'video/mp4': 'MP4 Video',
} as const;

const EXTENSION_DESCRIPTIONS = {
rar: 'Compressed RAR Archive',
'7z': 'Compressed 7-Zip Archive',
psd: 'Adobe Photoshop Document',
dmg: 'Disk Image',
'fb2k-component': 'foobar2000 Component',
} as const;

export const getFileDescription = (type?: string, filename?: string) => {
if (typeof (type as unknown) !== 'string') {
return '';
}

if (type === 'application/octet-stream' || type === '') {
if (typeof filename === 'string' && filename.includes('.')) {
const extension = filename.slice(filename.lastIndexOf('.') + '.'.length).toLowerCase();
const {
[extension as keyof typeof EXTENSION_DESCRIPTIONS]: extensionDescription = `${extension.toUpperCase()} File`,
} = EXTENSION_DESCRIPTIONS;

return extensionDescription;
}
return `${type} File`;
}

const {
[type as keyof typeof MIME_TYPE_DESCRIPTIONS]: description = type,
} = MIME_TYPE_DESCRIPTIONS;

return description;
};

+ 2
- 0
packages/blob-utils/src/index.ts Visa fil

@@ -0,0 +1,2 @@
export * from './content-type';
export * from './description';

+ 21
- 0
packages/blob-utils/tsconfig.eslint.json Visa fil

@@ -0,0 +1,21 @@
{
"exclude": ["node_modules"],
"include": ["src", "types", "test"],
"compilerOptions": {
"module": "ESNext",
"lib": ["ESNext"],
"importHelpers": true,
"declaration": true,
"sourceMap": true,
"rootDir": "./",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"jsx": "react",
"esModuleInterop": true,
"target": "es2018"
}
}

+ 21
- 0
packages/blob-utils/tsconfig.json Visa fil

@@ -0,0 +1,21 @@
{
"exclude": ["node_modules"],
"include": ["src", "types"],
"compilerOptions": {
"module": "ESNext",
"lib": ["ESNext"],
"importHelpers": true,
"declaration": true,
"sourceMap": true,
"rootDir": "./src",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"jsx": "react",
"esModuleInterop": true,
"target": "es2018"
}
}

+ 9
- 0
packages/react-blob-previews/.eslintrc Visa fil

@@ -0,0 +1,9 @@
{
"root": true,
"extends": [
"lxsmnsyc/typescript/react"
],
"parserOptions": {
"project": "./tsconfig.eslint.json"
}
}

+ 107
- 0
packages/react-blob-previews/.gitignore Visa fil

@@ -0,0 +1,107 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.production
.env.development

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

.npmrc

+ 7
- 0
packages/react-blob-previews/LICENSE Visa fil

@@ -0,0 +1,7 @@
MIT License Copyright (c) 2023 TheoryOfNekomata <allan.crisostomo@outlook.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 77
- 0
packages/react-blob-previews/package.json Visa fil

@@ -0,0 +1,77 @@
{
"name": "@modal-sh/react-utils",
"version": "0.0.0",
"files": [
"dist",
"src"
],
"engines": {
"node": ">=12"
},
"license": "MIT",
"keywords": [
"pridepack"
],
"devDependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@types/node": "^18.14.1",
"@types/react": "^18.0.27",
"eslint": "^8.35.0",
"eslint-config-lxsmnsyc": "^0.5.0",
"jsdom": "^21.1.0",
"pridepack": "2.4.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-test-renderer": "^18.2.0",
"tslib": "^2.5.0",
"typescript": "^4.9.5",
"vitest": "^0.28.1"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"scripts": {
"prepublishOnly": "pridepack clean && pridepack build",
"build": "pridepack build",
"type-check": "pridepack check",
"lint": "pridepack lint",
"clean": "pridepack clean",
"watch": "pridepack watch",
"start": "pridepack start",
"dev": "pridepack dev",
"test": "vitest"
},
"private": false,
"description": "Utilities for React.",
"repository": {
"url": "",
"type": "git"
},
"homepage": "",
"bugs": {
"url": ""
},
"author": "TheoryOfNekomata <allan.crisostomo@outlook.com>",
"publishConfig": {
"access": "public"
},
"types": "./dist/types/index.d.ts",
"main": "./dist/cjs/production/index.js",
"module": "./dist/esm/production/index.js",
"exports": {
".": {
"development": {
"require": "./dist/cjs/development/index.js",
"import": "./dist/esm/development/index.js"
},
"require": "./dist/cjs/production/index.js",
"import": "./dist/esm/production/index.js",
"types": "./dist/types/index.d.ts"
}
},
"typesVersions": {
"*": {}
}
}

+ 3
- 0
packages/react-blob-previews/pridepack.json Visa fil

@@ -0,0 +1,3 @@
{
"target": "es2018"
}

packages/web-kitchensink-reactnext/src/categories/blob/react/components/AudioFilePreview/index.tsx → packages/react-blob-previews/src/components/AudioFilePreview/index.tsx Visa fil

@@ -1,21 +1,21 @@
import * as React from 'react';
import {augmentAudioFile, getMimeTypeDescription} from '@/utils/blob';
import {augmentAudioFile, getMimeTypeDescription} from 'packages/web-kitchensink-reactnext/src/utils/blob';
import {
formatFileSize,
formatNumeral,
formatSecondsDurationConcise,
formatSecondsDurationPrecise,
} from '@/utils/numeral';
import theme from '@/styles/theme';
} from 'packages/web-kitchensink-reactnext/src/utils/numeral';
import theme from 'packages/web-kitchensink-reactnext/src/styles/theme';
import {useMediaControls} from '../../hooks/interactive';
import {useFileMetadata, useFileUrl} from '@/categories/blob/react';
import {useFileMetadata, useFileUrl} from 'src/index';

import clsx from 'clsx';
import {SpectrogramCanvas, WaveformCanvas} from '@modal-sh/react-wavesurfer';
import {Slider} from '@tesseract-design/web-number-react';
import {KeyValueTable} from '@tesseract-design/web-information-react';
import {useClientSide} from '@modal-sh/react-utils';
import {CommonPreviewProps} from '@/categories/blob/react/common';
import {SpectrogramCanvas, WaveformCanvas} from 'packages/web-kitchensink-reactnext/src/packages/react-wavesurfer';
import {Slider} from 'categories/number/react';
import {KeyValueTable} from 'categories/information/react';
import {useClientSide} from 'packages/react-utils';
import type {CommonPreviewProps} from '../../../../../categories/blob/react/src/components/FileSelectBox';

export type AudioFilePreviewDerivedElement = HTMLAudioElement;


packages/web-kitchensink-reactnext/src/categories/blob/react/components/AudioMiniFilePreview/index.tsx → packages/react-blob-previews/src/components/AudioMiniFilePreview/index.tsx Visa fil

@@ -1,11 +1,11 @@
import * as React from 'react';
import {augmentAudioFile} from '@/utils/blob';
import theme from '@/styles/theme';
import {augmentAudioFile} from 'packages/web-kitchensink-reactnext/src/utils/blob';
import theme from 'packages/web-kitchensink-reactnext/src/styles/theme';
import {useMediaControls} from '../../hooks/interactive';
import {useFileMetadata, useFileUrl} from '@/categories/blob/react';
import {useFileMetadata, useFileUrl} from 'src/index';
import clsx from 'clsx';
import {SpectrogramCanvas, WaveformCanvas} from '@modal-sh/react-wavesurfer';
import {useClientSide} from '@modal-sh/react-utils';
import {SpectrogramCanvas, WaveformCanvas} from 'packages/web-kitchensink-reactnext/src/packages/react-wavesurfer';
import {useClientSide} from 'packages/react-utils';

export type AudioMiniFilePreviewDerivedElement = HTMLAudioElement;


packages/web-kitchensink-reactnext/src/categories/blob/react/components/BinaryFilePreview/index.tsx → packages/react-blob-previews/src/components/BinaryFilePreview/index.tsx Visa fil

@@ -1,12 +1,12 @@
import * as React from 'react';
import {augmentBinaryFile, getMimeTypeDescription} from '@/utils/blob';
import {formatFileSize, formatNumeral} from '@/utils/numeral';
import {useFileMetadata, useFileUrl} from '@/categories/blob/react';
import {augmentBinaryFile, getMimeTypeDescription} from 'packages/web-kitchensink-reactnext/src/utils/blob';
import {formatFileSize, formatNumeral} from 'packages/web-kitchensink-reactnext/src/utils/numeral';
import {useFileMetadata, useFileUrl} from 'src/index';
import clsx from 'clsx';
import {KeyValueTable} from '@tesseract-design/web-information-react';
import {BinaryDataCanvas} from '@modal-sh/react-binary-data-canvas';
import {useClientSide} from '@modal-sh/react-utils';
import {CommonPreviewProps} from '@/categories/blob/react/common';
import {KeyValueTable} from 'categories/information/react';
import {BinaryDataCanvas} from 'packages/react-binary-data-canvas';
import {useClientSide} from 'packages/react-utils';
import type {CommonPreviewProps} from '../../../../../categories/blob/react/src/components/FileSelectBox';

export type BinaryFilePreviewDerivedElement = HTMLDivElement;


packages/web-kitchensink-reactnext/src/categories/blob/react/components/ImageFilePreview/index.tsx → packages/react-blob-previews/src/components/ImageFilePreview/index.tsx Visa fil

@@ -1,12 +1,12 @@
import * as React from 'react';
import {augmentImageFile, getMimeTypeDescription} from '@/utils/blob';
import {formatFileSize, formatNumeral} from '@/utils/numeral';
import {augmentImageFile, getMimeTypeDescription} from 'packages/web-kitchensink-reactnext/src/utils/blob';
import {formatFileSize, formatNumeral} from 'packages/web-kitchensink-reactnext/src/utils/numeral';
import clsx from 'clsx';
import {useFileMetadata, useFileUrl, useImageControls} from '@/categories/blob/react';
import {KeyValueTable} from '@tesseract-design/web-information-react';
import {useClientSide} from '@modal-sh/react-utils';
import {CommonPreviewProps} from '@/categories/blob/react/common';
import {Swatch} from '@tesseract-design/web-color-react';
import {useFileMetadata, useFileUrl, useImageControls} from 'src/index';
import {KeyValueTable} from 'categories/information/react';
import {useClientSide} from 'packages/react-utils';
import type {CommonPreviewProps} from '../../../../../categories/blob/react/src/components/FileSelectBox';
import {Swatch} from 'categories/color/react';

export type ImageFilePreviewDerivedElement = HTMLImageElement;


packages/web-kitchensink-reactnext/src/categories/blob/react/components/TextFilePreview/index.tsx → packages/react-blob-previews/src/components/TextFilePreview/index.tsx Visa fil

@@ -1,12 +1,12 @@
import * as React from 'react';
import {formatFileSize, formatNumeral} from '@/utils/numeral';
import {useFileMetadata, useFileUrl} from '@/categories/blob/react';
import {augmentTextFile, getMimeTypeDescription} from '@/utils/blob';
import {formatFileSize, formatNumeral} from 'packages/web-kitchensink-reactnext/src/utils/numeral';
import {useFileMetadata, useFileUrl} from 'src/index';
import {augmentTextFile, getMimeTypeDescription} from 'packages/web-kitchensink-reactnext/src/utils/blob';
import clsx from 'clsx';
import {KeyValueTable} from '@tesseract-design/web-information-react';
import {Refractor} from '@modal-sh/react-refractor';
import {useClientSide} from '@modal-sh/react-utils';
import {CommonPreviewProps} from '@/categories/blob/react/common';
import {KeyValueTable} from 'categories/information/react';
import {Refractor} from 'packages/web-kitchensink-reactnext/src/packages/react-refractor';
import {useClientSide} from 'packages/react-utils';
import type {CommonPreviewProps} from '../../../../../categories/blob/react/src/components/FileSelectBox';

type TextFilePreviewDerivedComponent = HTMLDivElement;


packages/web-kitchensink-reactnext/src/categories/blob/react/components/VideoFilePreview/index.tsx → packages/react-blob-previews/src/components/VideoFilePreview/index.tsx Visa fil

@@ -1,12 +1,12 @@
import * as React from 'react';
import {augmentVideoFile, getMimeTypeDescription} from '@/utils/blob';
import {formatFileSize, formatNumeral, formatSecondsDurationConcise} from '@/utils/numeral';
import {useFileMetadata, useFileUrl, useMediaControls} from '@tesseract-design/web-blob-react';
import {augmentVideoFile, getMimeTypeDescription} from 'packages/web-kitchensink-reactnext/src/utils/blob';
import {formatFileSize, formatNumeral, formatSecondsDurationConcise} from 'packages/web-kitchensink-reactnext/src/utils/numeral';
import {useFileMetadata, useFileUrl, useMediaControls} from 'src/index';
import clsx from 'clsx';
import {Slider} from '@tesseract-design/web-number-react';
import {KeyValueTable} from '@tesseract-design/web-information-react';
import {useClientSide} from '@modal-sh/react-utils';
import {CommonPreviewProps} from '@/categories/blob/react/common';
import {Slider} from 'categories/number/react';
import {KeyValueTable} from 'categories/information/react';
import {useClientSide} from 'packages/react-utils';
import type {CommonPreviewProps} from '../../../../../categories/blob/react/src/components/FileSelectBox';

export type VideoFilePreviewDerivedComponent = HTMLVideoElement;


packages/web-kitchensink-reactnext/src/categories/blob/react/hooks/blob/index.ts → packages/react-blob-previews/src/hooks/blob/index.ts Visa fil


packages/web-kitchensink-reactnext/src/categories/blob/react/hooks/blob/metadata.ts → packages/react-blob-previews/src/hooks/blob/metadata.ts Visa fil

@@ -1,5 +1,5 @@
import * as React from 'react';
import {addDataUrl, FileWithDataUrl} from '@/utils/blob';
import {addDataUrl, FileWithDataUrl} from 'packages/web-kitchensink-reactnext/src/utils/blob';

export interface UseFileUrlOptions {
file?: Partial<File>;

packages/web-kitchensink-reactnext/src/categories/blob/react/hooks/interactive/image.ts → packages/react-blob-previews/src/hooks/interactive/image.ts Visa fil


packages/web-kitchensink-reactnext/src/categories/blob/react/hooks/interactive/index.ts → packages/react-blob-previews/src/hooks/interactive/index.ts Visa fil


packages/web-kitchensink-reactnext/src/categories/blob/react/hooks/interactive/media.ts → packages/react-blob-previews/src/hooks/interactive/media.ts Visa fil


packages/web-kitchensink-reactnext/src/categories/blob/react/index.ts → packages/react-blob-previews/src/index.ts Visa fil

@@ -1,7 +1,6 @@
export * from './components/AudioFilePreview';
export * from './components/AudioMiniFilePreview';
export * from './components/BinaryFilePreview';
export * from './components/FileSelectBox';
export * from './components/ImageFilePreview';
export * from './components/TextFilePreview';
export * from './components/VideoFilePreview';

+ 21
- 0
packages/react-blob-previews/tsconfig.eslint.json Visa fil

@@ -0,0 +1,21 @@
{
"exclude": ["node_modules"],
"include": ["src", "types", "test"],
"compilerOptions": {
"module": "ESNext",
"lib": ["DOM", "ESNext"],
"importHelpers": true,
"declaration": true,
"sourceMap": true,
"rootDir": "./",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"jsx": "react",
"esModuleInterop": true,
"target": "es2018"
}
}

+ 21
- 0
packages/react-blob-previews/tsconfig.json Visa fil

@@ -0,0 +1,21 @@
{
"exclude": ["node_modules"],
"include": ["src", "types"],
"compilerOptions": {
"module": "ESNext",
"lib": ["DOM", "ESNext"],
"importHelpers": true,
"declaration": true,
"sourceMap": true,
"rootDir": "./src",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"jsx": "react",
"esModuleInterop": true,
"target": "es2018"
}
}

+ 8
- 0
packages/react-blob-previews/vitest.config.ts Visa fil

@@ -0,0 +1,8 @@
/// <reference types="vitest" />

export default ({
test: {
global: true,
environment: 'jsdom',
},
});

+ 0
- 10
packages/web-kitchensink-reactnext/src/categories/blob/react/common.ts Visa fil

@@ -1,10 +0,0 @@
import * as React from 'react';

export interface CommonPreviewProps<F extends Partial<File> = Partial<File>> {
file?: F;
disabled?: boolean;
enhanced?: boolean;
mini?: boolean;
}

export type FilePreviewComponent<T extends CommonPreviewProps = CommonPreviewProps> = (props: T) => React.ReactNode;

+ 0
- 187
packages/web-kitchensink-reactnext/src/pages/categories/blob/index.tsx Visa fil

@@ -1,187 +0,0 @@
import {NextPage} from 'next';
import * as React from 'react';
import * as BlobReact from '@tesseract-design/web-blob-react';
import {DefaultLayout} from '@/components/DefaultLayout';
import {Section, Subsection} from '@/components/Section';
import {addDataUrl} from '@/utils/blob';

const BlobPage: NextPage = () => {
const [imageFile, setImageFile] = React.useState<Partial<File>>();
React.useEffect(() => {
fetch('/image.png').then((response) => {
response.blob().then(async (blob) => {
const imageFile = new File([blob], 'image.png', {
type: 'image/png',
});
const theFile = await addDataUrl(imageFile);
setImageFile(theFile);
});
});
}, []);

const [videoFile, setVideoFile] = React.useState<File>();
React.useEffect(() => {
fetch('/video.mp4').then((response) => {
response.blob().then((blob) => {
setVideoFile(new File([blob], 'video.mp4', {
type: 'video/mp4',
}));
});
});
}, []);

const [audioFile, setAudioFile] = React.useState<File>();
React.useEffect(() => {
fetch('/audio.wav').then((response) => {
response.blob().then((blob) => {
setAudioFile(new File([blob], 'audio.wav', {
type: 'audio/wav',
}));
});
});
}, []);

const [binaryFile, setBinaryFile] = React.useState<File>();
React.useEffect(() => {
fetch('/binary.bin').then((response) => {
response.blob().then((blob) => {
setBinaryFile(new File([blob], 'binary.bin', {
type: 'application/octet-stream',
}));
});
});
}, []);

const [plaintextFile, setPlaintextFile] = React.useState<File>();
React.useEffect(() => {
fetch('/plaintext.txt').then((response) => {
response.blob().then((blob) => {
setPlaintextFile(new File([blob], 'plaintext.txt', {
type: 'text/plain',
}));
});
});
}, []);

const [codeFile, setCodeFile] = React.useState<File>();
React.useEffect(() => {
fetch('/code.py').then((response) => {
response.blob().then((blob) => {
setCodeFile(new File([blob], 'code.py', {
type: 'text/x-python',
}));
});
});
}, []);

return (
<DefaultLayout title="Blob">
<Section title="ImageFilePreview">
<Subsection title="Single File">
<BlobReact.ImageFilePreview
enhanced
file={
imageFile
?? {
name: 'image.png',
type: 'image/png',
url: '/image.png',
} as Partial<File>
}
className="sm:h-64"
/>
</Subsection>
</Section>
<Section title="VideoFilePreview">
<Subsection title="Single File">
<BlobReact.VideoFilePreview
file={
videoFile
?? {
name: 'video.mp4',
type: 'video/mp4',
url: '/video.mp4',
} as Partial<File>
}
className="sm:h-64"
enhanced
/>
</Subsection>
</Section>
<Section title="AudioFilePreview">
<Subsection title="Single File">
<BlobReact.AudioFilePreview
file={
audioFile
?? {
name: 'audio.wav',
type: 'audio/wav',
url: '/audio.wav',
} as Partial<File>
}
className="sm:h-64"
enhanced
/>
</Subsection>
</Section>
<Section title="BinaryFilePreview">
<Subsection title="Single File">
<BlobReact.BinaryFilePreview
file={
binaryFile
?? {
name: 'binary.bin',
type: 'application/octet-stream',
url: '/binary.bin',
} as Partial<File>
}
className="sm:h-64"
/>
</Subsection>
</Section>
<Section title="TextFilePreview">
<Subsection title="Single File (Plaintext)">
<BlobReact.TextFilePreview
file={
plaintextFile
?? {
name: 'plaintext.txt',
type: 'text/plain',
url: '/plaintext.txt',
} as Partial<File>
}
className="sm:h-64"
/>
</Subsection>
<Subsection title="Single File (Code)">
<BlobReact.TextFilePreview
file={
codeFile
?? {
name: 'code.py',
type: 'text/x-python',
url: '/code.py',
} as Partial<File>
}
className="sm:h-64"
/>
</Subsection>
</Section>
<Section title="FileSelectBox">
<Subsection title="Single File">
<BlobReact.FileSelectBox
border
enhanced
label="Primary Image"
hint="Select any files here"
block
className="sm:h-96"
onChange={(e) => console.log(e.currentTarget.files)}
/>
</Subsection>
</Section>
</DefaultLayout>
)
}

export default BlobPage;

+ 138
- 7
pnpm-lock.yaml Visa fil

@@ -82,6 +82,58 @@ importers:
specifier: ^0.28.1
version: 0.28.1(jsdom@21.1.0)

categories/blob/react:
dependencies:
'@modal-sh/react-utils':
specifier: workspace:*
version: link:../../../packages/react-utils
clsx:
specifier: ^1.2.1
version: 1.2.1
devDependencies:
'@testing-library/jest-dom':
specifier: ^5.16.5
version: 5.16.5
'@testing-library/react':
specifier: ^13.4.0
version: 13.4.0(react-dom@18.2.0)(react@18.2.0)
'@types/node':
specifier: ^18.14.1
version: 18.14.1
'@types/react':
specifier: ^18.0.27
version: 18.2.14
eslint:
specifier: ^8.35.0
version: 8.43.0
eslint-config-lxsmnsyc:
specifier: ^0.5.0
version: 0.5.0(eslint@8.43.0)(typescript@4.9.5)
jsdom:
specifier: ^21.1.0
version: 21.1.0
pridepack:
specifier: 2.4.4
version: 2.4.4(eslint@8.43.0)(tslib@2.6.0)(typescript@4.9.5)
react:
specifier: ^18.2.0
version: 18.2.0
react-dom:
specifier: ^18.2.0
version: 18.2.0(react@18.2.0)
react-test-renderer:
specifier: ^18.2.0
version: 18.2.0(react@18.2.0)
tslib:
specifier: ^2.5.0
version: 2.6.0
typescript:
specifier: ^4.9.5
version: 4.9.5
vitest:
specifier: ^0.28.1
version: 0.28.1(jsdom@21.1.0)

categories/choice/react:
dependencies:
'@tesseract-design/web-base':
@@ -535,6 +587,37 @@ importers:
specifier: ^0.28.1
version: 0.28.1(jsdom@21.1.0)

packages/blob-utils:
dependencies:
mime-types:
specifier: ^2.1.35
version: 2.1.35
devDependencies:
'@types/mime-types':
specifier: ^2.1.1
version: 2.1.1
'@types/node':
specifier: ^18.14.1
version: 18.14.1
eslint:
specifier: ^8.35.0
version: 8.43.0
eslint-config-lxsmnsyc:
specifier: ^0.5.0
version: 0.5.0(eslint@8.43.0)(typescript@4.9.5)
pridepack:
specifier: 2.4.4
version: 2.4.4(eslint@8.43.0)(tslib@2.6.0)(typescript@4.9.5)
tslib:
specifier: ^2.5.0
version: 2.6.0
typescript:
specifier: ^4.9.5
version: 4.9.5
vitest:
specifier: ^0.28.1
version: 0.28.1(jsdom@21.1.0)

packages/image-utils:
dependencies:
colorthief:
@@ -617,6 +700,51 @@ importers:
specifier: ^0.28.1
version: 0.28.1(jsdom@21.1.0)

packages/react-blob-previews:
devDependencies:
'@testing-library/jest-dom':
specifier: ^5.16.5
version: 5.16.5
'@testing-library/react':
specifier: ^13.4.0
version: 13.4.0(react-dom@18.2.0)(react@18.2.0)
'@types/node':
specifier: ^18.14.1
version: 18.14.1
'@types/react':
specifier: ^18.0.27
version: 18.2.14
eslint:
specifier: ^8.35.0
version: 8.43.0
eslint-config-lxsmnsyc:
specifier: ^0.5.0
version: 0.5.0(eslint@8.43.0)(typescript@4.9.5)
jsdom:
specifier: ^21.1.0
version: 21.1.0
pridepack:
specifier: 2.4.4
version: 2.4.4(eslint@8.43.0)(tslib@2.6.0)(typescript@4.9.5)
react:
specifier: ^18.2.0
version: 18.2.0
react-dom:
specifier: ^18.2.0
version: 18.2.0(react@18.2.0)
react-test-renderer:
specifier: ^18.2.0
version: 18.2.0(react@18.2.0)
tslib:
specifier: ^2.5.0
version: 2.6.0
typescript:
specifier: ^4.9.5
version: 4.9.5
vitest:
specifier: ^0.28.1
version: 0.28.1(jsdom@21.1.0)

packages/react-utils:
devDependencies:
'@testing-library/jest-dom':
@@ -720,32 +848,35 @@ importers:
specifier: ^0.28.1
version: 0.28.1(jsdom@21.1.0)

packages/web-kitchensink-reactnext:
showcases/web-kitchensink-reactnext:
dependencies:
'@modal-sh/audio-utils':
specifier: workspace:*
version: link:../audio-utils
version: link:../../packages/audio-utils
'@modal-sh/image-utils':
specifier: workspace:*
version: link:../image-utils
version: link:../../packages/image-utils
'@modal-sh/react-binary-data-canvas':
specifier: workspace:*
version: link:../react-binary-data-canvas
version: link:../../packages/react-binary-data-canvas
'@modal-sh/react-utils':
specifier: workspace:*
version: link:../react-utils
version: link:../../packages/react-utils
'@modal-sh/text-utils':
specifier: workspace:*
version: link:../text-utils
version: link:../../packages/text-utils
'@modal-sh/video-utils':
specifier: workspace:*
version: link:../video-utils
version: link:../../packages/video-utils
'@tesseract-design/web-action-react':
specifier: workspace:*
version: link:../../categories/action/react
'@tesseract-design/web-base':
specifier: workspace:*
version: link:../../base
'@tesseract-design/web-blob-react':
specifier: workspace:*
version: link:../../categories/blob/react
'@tesseract-design/web-choice-react':
specifier: workspace:*
version: link:../../categories/choice/react


+ 1
- 0
pnpm-workspace.yaml Visa fil

@@ -2,3 +2,4 @@ packages:
- 'base'
- 'packages/*'
- 'categories/**'
- 'showcases/**'

packages/web-kitchensink-reactnext/.eslintrc.json → showcases/web-kitchensink-reactnext/.eslintrc.json Visa fil


packages/web-kitchensink-reactnext/.gitignore → showcases/web-kitchensink-reactnext/.gitignore Visa fil


packages/web-kitchensink-reactnext/README.md → showcases/web-kitchensink-reactnext/README.md Visa fil


packages/web-kitchensink-reactnext/colorthief.d.ts → showcases/web-kitchensink-reactnext/colorthief.d.ts Visa fil


packages/web-kitchensink-reactnext/next.config.js → showcases/web-kitchensink-reactnext/next.config.js Visa fil


packages/web-kitchensink-reactnext/package.json → showcases/web-kitchensink-reactnext/package.json Visa fil

@@ -38,6 +38,7 @@
"@modal-sh/react-binary-data-canvas": "workspace:*",
"@tesseract-design/web-base": "workspace:*",
"@tesseract-design/web-action-react": "workspace:*",
"@tesseract-design/web-blob-react": "workspace:*",
"@tesseract-design/web-color-react": "workspace:*",
"@tesseract-design/web-choice-react": "workspace:*",
"@tesseract-design/web-formatted-react": "workspace:*",

packages/web-kitchensink-reactnext/pnpm-lock.yaml → showcases/web-kitchensink-reactnext/pnpm-lock.yaml Visa fil


packages/web-kitchensink-reactnext/postcss.config.js → showcases/web-kitchensink-reactnext/postcss.config.js Visa fil


packages/web-kitchensink-reactnext/public/audio.wav → showcases/web-kitchensink-reactnext/public/audio.wav Visa fil


packages/web-kitchensink-reactnext/public/binary.bin → showcases/web-kitchensink-reactnext/public/binary.bin Visa fil


packages/web-kitchensink-reactnext/public/code.py → showcases/web-kitchensink-reactnext/public/code.py Visa fil


packages/web-kitchensink-reactnext/public/favicon.ico → showcases/web-kitchensink-reactnext/public/favicon.ico Visa fil


packages/web-kitchensink-reactnext/public/image.png → showcases/web-kitchensink-reactnext/public/image.png Visa fil


packages/web-kitchensink-reactnext/public/next.svg → showcases/web-kitchensink-reactnext/public/next.svg Visa fil


packages/web-kitchensink-reactnext/public/plaintext.txt → showcases/web-kitchensink-reactnext/public/plaintext.txt Visa fil


packages/web-kitchensink-reactnext/public/vercel.svg → showcases/web-kitchensink-reactnext/public/vercel.svg Visa fil


packages/web-kitchensink-reactnext/public/video.mp4 → showcases/web-kitchensink-reactnext/public/video.mp4 Visa fil


packages/web-kitchensink-reactnext/react-refractor.d.ts → showcases/web-kitchensink-reactnext/react-refractor.d.ts Visa fil


packages/web-kitchensink-reactnext/src/components/DefaultLayout/index.tsx → showcases/web-kitchensink-reactnext/src/components/DefaultLayout/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/components/Section/index.tsx → showcases/web-kitchensink-reactnext/src/components/Section/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/packages/react-refractor/index.tsx → showcases/web-kitchensink-reactnext/src/packages/react-refractor/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/packages/react-refractor/style.module.css → showcases/web-kitchensink-reactnext/src/packages/react-refractor/style.module.css Visa fil


packages/web-kitchensink-reactnext/src/packages/react-wavesurfer/SpectrogramCanvas/index.tsx → showcases/web-kitchensink-reactnext/src/packages/react-wavesurfer/SpectrogramCanvas/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/packages/react-wavesurfer/WaveformCanvas/index.tsx → showcases/web-kitchensink-reactnext/src/packages/react-wavesurfer/WaveformCanvas/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/packages/react-wavesurfer/index.ts → showcases/web-kitchensink-reactnext/src/packages/react-wavesurfer/index.ts Visa fil


packages/web-kitchensink-reactnext/src/pages/_app.tsx → showcases/web-kitchensink-reactnext/src/pages/_app.tsx Visa fil


packages/web-kitchensink-reactnext/src/pages/_document.tsx → showcases/web-kitchensink-reactnext/src/pages/_document.tsx Visa fil


packages/web-kitchensink-reactnext/src/pages/api/hello.ts → showcases/web-kitchensink-reactnext/src/pages/api/hello.ts Visa fil


packages/web-kitchensink-reactnext/src/pages/categories/action/index.tsx → showcases/web-kitchensink-reactnext/src/pages/categories/action/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/pages/categories/code/index.tsx → showcases/web-kitchensink-reactnext/src/pages/categories/code/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/pages/categories/freeform/index.tsx → showcases/web-kitchensink-reactnext/src/pages/categories/freeform/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/pages/categories/navigation/index.tsx → showcases/web-kitchensink-reactnext/src/pages/categories/navigation/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/pages/categories/number/index.tsx → showcases/web-kitchensink-reactnext/src/pages/categories/number/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/pages/categories/option/index.tsx → showcases/web-kitchensink-reactnext/src/pages/categories/option/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/pages/categories/presentation/index.tsx → showcases/web-kitchensink-reactnext/src/pages/categories/presentation/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/pages/examples/blog-post/index.tsx → showcases/web-kitchensink-reactnext/src/pages/examples/blog-post/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/pages/examples/registration-form/index.tsx → showcases/web-kitchensink-reactnext/src/pages/examples/registration-form/index.tsx Visa fil

@@ -1,5 +1,5 @@
import { NextPage } from 'next';
import * as Freeform from '../../../../../../categories/freeform/react/src';
import * as Freeform from '@tesseract-design/web-freeform-react';
import * as Action from '@tesseract-design/web-action-react';

const RegistrationFormPage: NextPage = () => {

packages/web-kitchensink-reactnext/src/pages/index.tsx → showcases/web-kitchensink-reactnext/src/pages/index.tsx Visa fil


packages/web-kitchensink-reactnext/src/styles/globals.css → showcases/web-kitchensink-reactnext/src/styles/globals.css Visa fil


packages/web-kitchensink-reactnext/src/styles/kitchen-sink.css → showcases/web-kitchensink-reactnext/src/styles/kitchen-sink.css Visa fil


packages/web-kitchensink-reactnext/src/styles/theme.ts → showcases/web-kitchensink-reactnext/src/styles/theme.ts Visa fil


packages/web-kitchensink-reactnext/src/utils/blob.ts → showcases/web-kitchensink-reactnext/src/utils/blob.ts Visa fil

@@ -1,117 +1,8 @@
import * as mimeTypes from 'mime-types';
import {getTextMetadata, TextMetadata} from '@modal-sh/text-utils';
import {getMetadataFromUrl as getImageMetadataFromUrl, ImageMetadata} from '@modal-sh/image-utils';
import {getMetadataFromUrl as getAudioMetadataFromUrl, AudioMetadata} from '@modal-sh/audio-utils';
import {getMetadataFromUrl as getVideoMetadataFromUrl, VideoMetadata} from '@modal-sh/video-utils';

const MIME_TYPE_DESCRIPTIONS = {
'image/gif': 'GIF Image',
'image/jpeg': 'JPEG Image',
'image/png': 'PNG Image',
'image/tiff': 'TIFF Image',
'image/svg+xml': 'SVG Image',
'image/webp': 'WEBP Image',
'audio/wav': 'WAVE Audio',
'audio/ogg': 'OGG Audio',
'audio/mpeg': 'MPEG Audio',
'audio/mid': 'MIDI Track',
'application/json': 'JSON Data',
'application/xml': 'XML Data',
'application/x-bittorrent': 'Torrent File',
'application/x-zip-compressed': 'Compressed ZIP Archive',
'application/x-x509-ca-cert': 'Certificate File',
'application/x-tar': 'Compressed TAR Archive',
'application/x-rar': 'Compressed RAR Archive',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'Workbook',
'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'Slideshow Presentation',
'application/msword': 'Microsoft Word Document',
'application/pdf': 'PDF Document',
'application/postscript': 'PostScript Document',
'application/epub+zip': 'EPUB Document',
'message/rfc822': 'Email Message',
'video/mp4': 'MP4 Video',
} as const;

const EXTENSION_DESCRIPTIONS = {
'rar': 'Compressed RAR Archive',
'7z': 'Compressed 7-Zip Archive',
'psd': 'Adobe Photoshop Document',
'dmg': 'Disk Image',
'fb2k-component': 'foobar2000 Component',
} as const;

export const getMimeTypeDescription = (type?: string, filename?: string) => {
if (typeof (type as unknown) !== 'string') {
return '';
}

if (type === 'application/octet-stream' || type === '') {
if (typeof filename === 'string' && filename.includes('.')) {
const extension = filename.slice(filename.lastIndexOf('.') + '.'.length).toLowerCase();
const {
[extension as keyof typeof EXTENSION_DESCRIPTIONS]: extensionDescription = `${extension.toUpperCase()} File`,
} = EXTENSION_DESCRIPTIONS;

return extensionDescription;
}
return `${type} File`;
}

const {
[type as keyof typeof MIME_TYPE_DESCRIPTIONS]: description = type,
} = MIME_TYPE_DESCRIPTIONS;

return description;
}

export enum ContentType {
TEXT = 'text',
AUDIO = 'audio',
VIDEO = 'video',
IMAGE = 'image',
BINARY = 'binary',
}

export const getContentType = (mimeType?: string, filename?: string) => {
let effectiveMimeType: string;
if (typeof mimeType !== 'string') {
if (typeof filename !== 'string') {
return ContentType.BINARY;
}
const lookupMimeType = mimeTypes.lookup(filename);

if (typeof lookupMimeType !== 'string') {
return ContentType.BINARY;
}

effectiveMimeType = lookupMimeType;
} else {
effectiveMimeType = mimeType;
}

if (
effectiveMimeType === 'application/json'
|| effectiveMimeType === 'application/xml'
|| effectiveMimeType.startsWith('text/')
) {
return ContentType.TEXT;
}

if (effectiveMimeType.startsWith('video/')) {
return ContentType.VIDEO;
}

if (effectiveMimeType.startsWith('audio/')) {
return ContentType.AUDIO;
}

if (effectiveMimeType.startsWith('image/')) {
return ContentType.IMAGE;
}

return ContentType.BINARY;
}

export const readAsDataURL = (blob: Partial<Blob>) => new Promise<string>((resolve, reject) => {
// TODO when to revoke these URLs
// return URL.createObjectURL(blob as Blob);

packages/web-kitchensink-reactnext/src/utils/numeral.ts → showcases/web-kitchensink-reactnext/src/utils/numeral.ts Visa fil


packages/web-kitchensink-reactnext/tailwind.config.js → showcases/web-kitchensink-reactnext/tailwind.config.js Visa fil


packages/web-kitchensink-reactnext/tsconfig.json → showcases/web-kitchensink-reactnext/tsconfig.json Visa fil


Laddar…
Avbryt
Spara