Skip to content

Commit

Permalink
feat(extension-file): first version (#1031)
Browse files Browse the repository at this point in the history
  • Loading branch information
ocavue committed Aug 10, 2021
1 parent ab49c9e commit fccb1a6
Show file tree
Hide file tree
Showing 34 changed files with 1,702 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .changeset/big-pillows-pretend.md
@@ -0,0 +1,6 @@
---
'@remirror/styles': minor
'@remirror/theme': minor
---

Add styles for `@remirror/extension-file`.
5 changes: 5 additions & 0 deletions .changeset/brown-meals-study.md
@@ -0,0 +1,5 @@
---
'@remirror/extension-react-component': patch
---

Ignore selection mutations for unselectable nodes.
5 changes: 5 additions & 0 deletions .changeset/hot-donuts-film.md
@@ -0,0 +1,5 @@
---
'@remirror/extension-file': minor
---

Add the first version of `@remirror/extension-file`.
153 changes: 153 additions & 0 deletions packages/remirror__extension-file/__stories__/file.stories.tsx
@@ -0,0 +1,153 @@
import 'remirror/styles/extension-file.css';

import React, { useCallback, useEffect } from 'react';
import { ProsemirrorDevTools } from '@remirror/dev';
import { Remirror, ThemeProvider, useCommands, useRemirror } from '@remirror/react';

import { FileExtension } from '../src';
import { createBaseuploadFileUploader } from '../src/file-uploaders/bashupload-file-uploader';
import { createObjectUrlFileUploader } from '../src/file-uploaders/object-url-file-uploader';
import { createSlowFileUploader } from '../src/file-uploaders/slow-file-uploader';

export default { title: 'File extension' };

export const Default = (): JSX.Element => {
const extensions = useCallback(() => [new FileExtension({})], []);
const { manager, state } = useRemirror({ extensions, content, stringHandler: 'html' });

return (
<>
<p>
Default Implementation. Uses <code>FileReader.readAsDataURL</code> under the hood.
</p>
<ThemeProvider>
<Remirror manager={manager} initialContent={state} autoRender>
<UploadFileButton />
<ProsemirrorDevTools />
</Remirror>
</ThemeProvider>
</>
);
};

Default.args = {
autoLink: true,
openLinkOnClick: true,
};

export const WithObjectUrl = (): JSX.Element => {
const extensions = useCallback(
() => [new FileExtension({ uploadFileHandler: createObjectUrlFileUploader })],
[],
);
const { manager, state } = useRemirror({ extensions, content, stringHandler: 'html' });

return (
<>
<p>
Uses <code>URL.createObjectUrl</code> under the hood.
</p>
<ThemeProvider>
<Remirror manager={manager} initialContent={state} autoRender>
<UploadFileButton />
<ProsemirrorDevTools />
</Remirror>
</ThemeProvider>
</>
);
};

export const WithBashupload = (): JSX.Element => {
const extensions = useCallback(
() => [new FileExtension({ uploadFileHandler: createBaseuploadFileUploader })],
[],
);
const { manager, state } = useRemirror({ extensions, content, stringHandler: 'html' });

return (
<>
<p>
Actually upload the file to <a href='https://bashupload.com/'>https://bashupload.com/</a>.{' '}
bashupload is an open-source project created by IO-Technologies. Star it on{' '}
<a href='https://github.com/IO-Technologies/bashupload'>GitHub</a>.
</p>
<ThemeProvider>
<Remirror manager={manager} initialContent={state} autoRender>
<UploadFileButton />
<ProsemirrorDevTools />
</Remirror>
</ThemeProvider>
</>
);
};

export const UploadProgress = (): JSX.Element => {
const extensions = useCallback(
() => [new FileExtension({ uploadFileHandler: createSlowFileUploader })],
[],
);
const { manager, state } = useRemirror({ extensions, content, stringHandler: 'html' });

return (
<>
<p>
An example with slow uploading speed. You can see the upload progress and an abort button in
this example.
</p>
<ThemeProvider>
<Remirror manager={manager} initialContent={state} autoRender>
<UploadFileButton />
<ProsemirrorDevTools />
</Remirror>
</ThemeProvider>
</>
);
};

function useFileDialog() {
const [files, setFiles] = React.useState<FileList | null>(null);

const openFileDialog = () => {
const input = document.createElement('input');
input.type = 'file';
input.multiple = true;

input.addEventListener('change', (event: Event) => {
const { files } = event.target as HTMLInputElement;
setFiles(files);
});

input.click();
};

return { files, openFileDialog };
}

function useInsertFile() {
const { files, openFileDialog } = useFileDialog();
const { uploadFiles } = useCommands();

useEffect(() => {
if (files) {
const fileArray: File[] = [];

for (const file of files) {
fileArray.push(file);
}

uploadFiles(fileArray);
}
}, [files, uploadFiles]);

return { openFileDialog };
}

const UploadFileButton: React.FC = () => {
const { openFileDialog } = useInsertFile();
return <button onClick={openFileDialog}>Upload file</button>;
};

const html = String.raw; // Just for better editor support
const content = html`<p>
Drag and drop one or multiple non-image files into the editor or click the button at the bottom.
</p>`;
59 changes: 59 additions & 0 deletions packages/remirror__extension-file/__stories__/tsconfig.json
@@ -0,0 +1,59 @@
{
"__AUTO_GENERATED__": [
"To update the configuration edit the following field.",
"`package.json > @remirror > tsconfigs > '__stories__'`",
"",
"Then run: `pnpm -w generate:ts`"
],
"extends": "../../../support/tsconfig.base.json",
"compilerOptions": {
"types": [],
"declaration": false,
"noEmit": true,
"skipLibCheck": true,
"importsNotUsedAsValues": "remove",
"paths": {
"react": [
"../../../node_modules/.pnpm/@types+react@17.0.14/node_modules/@types/react/index.d.ts"
],
"react/jsx-dev-runtime": [
"../../../node_modules/.pnpm/@types+react@17.0.14/node_modules/@types/react/jsx-dev-runtime.d.ts"
],
"react/jsx-runtime": [
"../../../node_modules/.pnpm/@types+react@17.0.14/node_modules/@types/react/jsx-runtime.d.ts"
],
"react-dom": [
"../../../node_modules/.pnpm/@types+react-dom@17.0.9/node_modules/@types/react-dom/index.d.ts"
],
"reakit": [
"../../../node_modules/.pnpm/reakit@1.3.8_react-dom@17.0.2+react@17.0.2/node_modules/reakit/ts/index.d.ts"
],
"@remirror/react": ["../../remirror__react/src/index.ts"],
"@storybook/react": [
"../../../node_modules/.pnpm/@storybook+react@6.3.4_dfad392d5450b8683a621f3ec486af19/node_modules/@storybook/react/types-6-0.d.ts"
],
"@remirror/dev": ["../../remirror__dev/src/index.ts"]
}
},
"include": ["./"],
"references": [
{
"path": "../../testing/src"
},
{
"path": "../../remirror/src"
},
{
"path": "../../remirror__core/src"
},
{
"path": "../../remirror__react/src"
},
{
"path": "../../remirror__react-components/src"
},
{
"path": "../../remirror__theme/src"
}
]
}
@@ -0,0 +1,5 @@
import { extensionValidityTest } from 'jest-remirror';

import { FileExtension } from '../';

extensionValidityTest(FileExtension);
47 changes: 47 additions & 0 deletions packages/remirror__extension-file/__tests__/tsconfig.json
@@ -0,0 +1,47 @@
{
"__AUTO_GENERATED__": [
"To update the configuration edit the following field.",
"`package.json > @remirror > tsconfigs > '__tests__'`",
"",
"Then run: `pnpm -w generate:ts`"
],
"extends": "../../../support/tsconfig.base.json",
"compilerOptions": {
"types": [
"jest",
"jest-extended",
"jest-axe",
"@testing-library/jest-dom",
"snapshot-diff",
"node"
],
"declaration": false,
"noEmit": true,
"skipLibCheck": true,
"importsNotUsedAsValues": "remove"
},
"include": ["./"],
"references": [
{
"path": "../src"
},
{
"path": "../../testing/src"
},
{
"path": "../../remirror/src"
},
{
"path": "../../remirror__core/src"
},
{
"path": "../../remirror__react/src"
},
{
"path": "../../remirror__react-components/src"
},
{
"path": "../../remirror__theme/src"
}
]
}
81 changes: 81 additions & 0 deletions packages/remirror__extension-file/package.json
@@ -0,0 +1,81 @@
{
"name": "@remirror/extension-file",
"version": "0.1.0-beta.0",
"description": "",
"keywords": [
"remirror",
"extension",
"text-editor"
],
"homepage": "https://github.com/remirror/remirror/tree/HEAD/packages/remirror__extension-file",
"repository": "https://github.com/remirror/remirror/tree/HEAD/packages/remirror__extension-file",
"license": "MIT",
"contributors": [
"Ocavue <ocavue@gmail.com>"
],
"sideEffects": false,
"exports": {
".": {
"import": "./dist/remirror-extension-file.esm.js",
"require": "./dist/remirror-extension-file.cjs.js",
"browser": "./dist/remirror-extension-file.browser.esm.js",
"types": "./dist/remirror-extension-file.cjs.d.ts",
"default": "./dist/remirror-extension-file.esm.js"
},
"./package.json": "./package.json",
"./types/*": "./dist/declarations/src/*.d.ts"
},
"main": "dist/remirror-extension-file.cjs.js",
"module": "dist/remirror-extension-file.esm.js",
"browser": {
"./dist/remirror-extension-file.cjs.js": "./dist/remirror-extension-file.browser.cjs.js",
"./dist/remirror-extension-file.esm.js": "./dist/remirror-extension-file.browser.esm.js"
},
"types": "dist/remirror-extension-file.cjs.d.ts",
"files": [
"dist"
],
"dependencies": {
"@babel/runtime": "^7.13.10",
"@remirror/core": "^1.0.0",
"@remirror/react": "^1.0.0",
"@remirror/react-components": "^1.0.2",
"@remirror/theme": "^1.0.1",
"nanoevents": "^5.1.13"
},
"devDependencies": {
"@remirror/pm": "^1.0.0",
"@types/react": "^17.0.14",
"@types/react-dom": "^17.0.9",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"peerDependencies": {
"@remirror/pm": "^1.0.0",
"@types/react": "^16.14.0 || ^17",
"@types/react-dom": "^16.9.0 || ^17",
"react": "^16.14.0 || ^17",
"react-dom": "^16.14.0 || ^17"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
},
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
},
"publishConfig": {
"access": "public"
},
"@remirror": {
"sizeLimit": "30 KB"
},
"rn:dev": "src/index.ts"
}
1 change: 1 addition & 0 deletions packages/remirror__extension-file/readme.md
@@ -0,0 +1 @@
# @remirror/extension-file

1 comment on commit fccb1a6

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Published on https://remirror.io as production
🚀 Deployed on https://611217bc78ae28cc4b5d4ad5--remirror.netlify.app

Please sign in to comment.