diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 3c3629e6..00000000 --- a/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/.gitignore b/.gitignore index 596a670b..ce7f03b3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,6 @@ logs .idea /lib/ node_modules +demo/node_modules /.vscode/ ts-build/ diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index d8f8d469..00000000 --- a/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -docs diff --git a/cypress.json b/cypress.json deleted file mode 100644 index 0967ef42..00000000 --- a/cypress.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json deleted file mode 100644 index da18d935..00000000 --- a/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} \ No newline at end of file diff --git a/cypress/integration/keyboard-commands.ts b/cypress/integration/keyboard-commands.ts deleted file mode 100644 index 9a925404..00000000 --- a/cypress/integration/keyboard-commands.ts +++ /dev/null @@ -1,19 +0,0 @@ -context("Keyboard commands", () => { - beforeEach(() => { - cy.visit("http://localhost:4000"); - }); - it("bold", () => { - cy.get(".mde-text") - .type("{selectall}{backspace}") - .type("nice") - .type("{ctrl}b") - .should("have.value", "**nice**"); - }); - it("italic", () => { - cy.get(".mde-text") - .type("{selectall}{backspace}") - .type("nice") - .type("{ctrl}i") - .should("have.value", "*nice*"); - }); -}); diff --git a/cypress/integration/mentions.ts b/cypress/integration/mentions.ts deleted file mode 100644 index 7264ced8..00000000 --- a/cypress/integration/mentions.ts +++ /dev/null @@ -1,64 +0,0 @@ -const DELAY = 500; - -context("Suggestions", () => { - beforeEach(() => { - cy.visit("http://localhost:4000"); - }); - it("'@' should display the suggestions box", () => { - cy.get(".mde-suggestions").should("not.exist"); - cy.get(".mde-text") - .type("{selectall}{backspace}") - .type("@"); - cy.get(".mde-suggestions").should("exist"); - cy.get(".mde-suggestions") - .find("li") - .should("have.length", 4); - }); - it("'@' + 'an' should display 2 elements ", () => { - cy.get(".mde-suggestions").should("not.exist"); - cy.get(".mde-text") - .type("{selectall}{backspace}") - .type("@an"); - cy.get(".mde-suggestions").should("exist"); - cy.get(".mde-suggestions") - .find("li") - .should("have.length", 2); - }); - it("'@' + 'an' + 2x backspace should display 4 elements", () => { - cy.get(".mde-suggestions").should("not.exist"); - cy.get(".mde-text") - .type("{selectall}{backspace}") - .type("@an") - .type("{backspace}{backspace}"); - cy.get(".mde-suggestions").should("exist"); - cy.get(".mde-suggestions") - .find("li") - .should("have.length", 4); - }); - it("'@ + Enter' should select the first suggestion", () => { - cy.get(".mde-text") - .type("{selectall}{backspace}") - .type("@") - .wait(DELAY) - .type("{enter}") - .should("have.value", "@andre "); - }); - it("'@ + Arrow down + Enter' should select the first suggestion", () => { - cy.get(".mde-text") - .type("{selectall}{backspace}") - .type("@") - .wait(DELAY) - .type("{downArrow}") - .type("{enter}") - .should("have.value", "@angela "); - }); - it("'@ + 4x Arrow down + Enter' should cycle and select the first suggestion", () => { - cy.get(".mde-text") - .type("{selectall}{backspace}") - .type("@") - .wait(DELAY) - .type("{downArrow}{downArrow}{downArrow}{downArrow}") - .type("{enter}") - .should("have.value", "@andre "); - }); -}); diff --git a/cypress/integration/toolbar.ts b/cypress/integration/toolbar.ts deleted file mode 100644 index 7e262180..00000000 --- a/cypress/integration/toolbar.ts +++ /dev/null @@ -1,41 +0,0 @@ -context("Toolbar", () => { - beforeEach(() => { - cy.visit("http://localhost:4000"); - }); - it("bold", () => { - cy.get(".mde-text").type("{selectall}{backspace}").type("react-mde"); - - cy.get('button[data-name="bold"]').click(); - cy.get(".mde-text").should("have.value", "**react-mde**"); - }); - it("italic", () => { - cy.get(".mde-text").type("{selectall}{backspace}").type("react-mde"); - - cy.get('button[data-name="italic"]').click(); - cy.get(".mde-text").should("have.value", "*react-mde*"); - }); - it("strikethrough", () => { - cy.get(".mde-text").type("{selectall}{backspace}").type("react-mde"); - - cy.get('button[data-name="strikethrough"]').click(); - cy.get(".mde-text").should("have.value", "~~react-mde~~"); - }); - it("link", () => { - cy.get(".mde-text").type("{selectall}{backspace}").type("react-mde"); - - cy.get('button[data-name="link"]').click(); - cy.get(".mde-text").should("have.value", "[react-mde](url)"); - }); - it("quote", () => { - cy.get(".mde-text").type("{selectall}{backspace}").type("react-mde"); - - cy.get('button[data-name="quote"]').click(); - cy.get(".mde-text").should("have.value", "> react-mde"); - }); - it("image", () => { - cy.get(".mde-text").type("{selectall}{backspace}").type("react-mde"); - - cy.get('button[data-name="image"]').click(); - cy.get(".mde-text").should("have.value", "![](react-mde)"); - }); -}); diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js deleted file mode 100644 index 68aae934..00000000 --- a/cypress/plugins/index.js +++ /dev/null @@ -1,8 +0,0 @@ -var wp = require("@cypress/webpack-preprocessor"); - -module.exports = function(on) { - var options = { - webpackOptions: require("../webpack.config.js") - }; - on("file:preprocessor", wp(options)); -}; diff --git a/cypress/support/commands.js b/cypress/support/commands.js deleted file mode 100644 index ca4d256f..00000000 --- a/cypress/support/commands.js +++ /dev/null @@ -1,25 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add("login", (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/cypress/support/index.js b/cypress/support/index.js deleted file mode 100644 index d68db96d..00000000 --- a/cypress/support/index.js +++ /dev/null @@ -1,20 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands' - -// Alternatively you can use CommonJS syntax: -// require('./commands') diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json deleted file mode 100644 index 9d5fdf48..00000000 --- a/cypress/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "strict": true, - "target": "es5", - "lib": ["es5", "dom"], - "types": ["cypress", "node"] - }, - "include": ["**/*.ts"] -} diff --git a/cypress/tsconfig.plugins.json b/cypress/tsconfig.plugins.json deleted file mode 100644 index f7954d61..00000000 --- a/cypress/tsconfig.plugins.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "strict": true, - "target": "es5", - "lib": ["es5", "dom"], - "types": ["cypress", "node"], - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "jsx": "react", - "esModuleInterop": true, - "emitDecoratorMetadata": true - }, - "include": ["plugins/**/*.ts"] -} diff --git a/cypress/webpack.config.js b/cypress/webpack.config.js deleted file mode 100644 index 89bdb23c..00000000 --- a/cypress/webpack.config.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - mode: "development", - resolve: { - extensions: [".ts", ".js"] - }, - module: { - rules: [ - { - test: /\.ts$/, - exclude: [/node_modules/], - use: [ - { - loader: "awesome-typescript-loader", - options: { - // skip typechecking for speed - transpileOnly: true - } - } - ] - } - ] - } -}; diff --git a/demo/App.tsx b/demo/App.tsx deleted file mode 100644 index d71433fa..00000000 --- a/demo/App.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import * as React from "react"; -import ReactMde from "../src"; -import * as Showdown from "showdown"; -import { SaveImageHandler, Suggestion } from "../src/types"; - -export interface AppState { - value: string; - tab: "write" | "preview"; -} - -export class App extends React.Component<{}, AppState> { - converter: Showdown.Converter; - - constructor(props) { - super(props); - this.state = { - value: "**Hello world!!!**", - tab: "write" - }; - this.converter = new Showdown.Converter({ - tables: true, - simplifiedAutoLink: true, - strikethrough: true, - tasklists: true - }); - } - - handleValueChange = (value: string) => { - this.setState({ value }); - }; - - handleTabChange = (tab: "write" | "preview") => { - this.setState({ tab }); - }; - - loadSuggestions = async (text: string) => { - return new Promise((accept, reject) => { - setTimeout(() => { - const suggestions: Suggestion[] = [ - { - preview: "Andre", - value: "@andre" - }, - { - preview: "Angela", - value: "@angela" - }, - { - preview: "David", - value: "@david" - }, - { - preview: "Louise", - value: "@louise" - } - ].filter(i => i.preview.toLowerCase().includes(text.toLowerCase())); - accept(suggestions); - }, 250); - }); - }; - - render() { - const save: SaveImageHandler = async function*(data: ArrayBuffer, file: Blob) { - // Promise that waits for "time" milliseconds - const wait = function(time: number) { - return new Promise((a, r) => { - setTimeout(() => a(), time); - }); - }; - - // Upload "data" to your server - // Use XMLHttpRequest.send to send a FormData object containing - // "data" - // Check this question: https://stackoverflow.com/questions/18055422/how-to-receive-php-image-data-over-copy-n-paste-javascript-with-xmlhttprequest - - await wait(2000); - // yields the URL that should be inserted in the markdown - yield "https://picsum.photos/300"; - await wait(2000); - - // returns true meaning that the save was successful - return true; - }; - - return ( -
- - Promise.resolve(this.converter.makeHtml(markdown)) - } - selectedTab={this.state.tab} - loadSuggestions={this.loadSuggestions} - suggestionTriggerCharacters={["@"]} - suggestionsAutoplace={true} - paste={{ - saveImage: save - }} - /> -
- ); - } -} diff --git a/demo/client.tsx b/demo/client.tsx deleted file mode 100644 index 44ab3aed..00000000 --- a/demo/client.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import * as React from "react"; -import { render } from "react-dom"; -import { App } from "./App"; - -import "../node_modules/normalize.css/normalize.css"; -import "../src/styles/react-mde-all.scss"; -import "./styles/demo.scss"; -import "./styles/variables.scss"; - -render(, document.getElementById("#app_container")); diff --git a/demo/index.html b/demo/index.html deleted file mode 100644 index a15d48d0..00000000 --- a/demo/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - react-mde - - - - - - -
-
-
- - - - \ No newline at end of file diff --git a/demo/index.prod.html b/demo/index.prod.html deleted file mode 100644 index 3c873967..00000000 --- a/demo/index.prod.html +++ /dev/null @@ -1,27 +0,0 @@ - - - react-mde - - - - - - -
-
-
- - - - \ No newline at end of file diff --git a/demo/index.tsx b/demo/index.tsx new file mode 100644 index 00000000..c1d80d36 --- /dev/null +++ b/demo/index.tsx @@ -0,0 +1,56 @@ +import * as React from "react"; +import ReactDOM from "react-dom"; +import { + Box, + Button, + ChakraProvider, + HStack, + Textarea +} from "@chakra-ui/react"; +import { useTextAreaMarkdownEditor } from "../src/hooks/use-markdown-editor"; +import { faBold, faItalic } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; + +export type DemoProps = {}; + +export const Demo: React.FunctionComponent = props => { + const { ref, commandController } = useTextAreaMarkdownEditor(); + + return ( + + + + + + +