diff --git a/spell-check/configure-spellcheck/.gitignore b/spell-check/configure-spellcheck/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/spell-check/configure-spellcheck/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/spell-check/configure-spellcheck/README.md b/spell-check/configure-spellcheck/README.md new file mode 100644 index 0000000..7dbf7eb --- /dev/null +++ b/spell-check/configure-spellcheck/README.md @@ -0,0 +1,73 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs) +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) + +## React Compiler + +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + + // Remove tseslint.configs.recommended and replace with this + tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + tseslint.configs.stylisticTypeChecked, + + // Other configs... + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` + +You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x' +import reactDom from 'eslint-plugin-react-dom' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + // Enable lint rules for React + reactX.configs['recommended-typescript'], + // Enable lint rules for React DOM + reactDom.configs.recommended, + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` diff --git a/spell-check/configure-spellcheck/eslint.config.js b/spell-check/configure-spellcheck/eslint.config.js new file mode 100644 index 0000000..ef614d2 --- /dev/null +++ b/spell-check/configure-spellcheck/eslint.config.js @@ -0,0 +1,22 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, + ], + languageOptions: { + globals: globals.browser, + }, + }, +]) diff --git a/spell-check/configure-spellcheck/index.html b/spell-check/configure-spellcheck/index.html new file mode 100644 index 0000000..cc2f11e --- /dev/null +++ b/spell-check/configure-spellcheck/index.html @@ -0,0 +1,13 @@ + + + + + + + spellcheck + + +
+ + + diff --git a/spell-check/configure-spellcheck/package.json b/spell-check/configure-spellcheck/package.json new file mode 100644 index 0000000..b8dbb81 --- /dev/null +++ b/spell-check/configure-spellcheck/package.json @@ -0,0 +1,31 @@ +{ + "name": "spellcheck", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@syncfusion/ej2-react-documenteditor": "^33.2.11", + "react": "^19.2.6", + "react-dom": "^19.2.6" + }, + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/node": "^24.12.3", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^10.3.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.6.0", + "typescript": "~6.0.2", + "typescript-eslint": "^8.59.2", + "vite": "^8.0.12" + } +} diff --git a/spell-check/configure-spellcheck/public/favicon.svg b/spell-check/configure-spellcheck/public/favicon.svg new file mode 100644 index 0000000..6893eb1 --- /dev/null +++ b/spell-check/configure-spellcheck/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/spell-check/configure-spellcheck/public/icons.svg b/spell-check/configure-spellcheck/public/icons.svg new file mode 100644 index 0000000..e952219 --- /dev/null +++ b/spell-check/configure-spellcheck/public/icons.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spell-check/configure-spellcheck/src/App.css b/spell-check/configure-spellcheck/src/App.css new file mode 100644 index 0000000..f90339d --- /dev/null +++ b/spell-check/configure-spellcheck/src/App.css @@ -0,0 +1,184 @@ +.counter { + font-size: 16px; + padding: 5px 10px; + border-radius: 5px; + color: var(--accent); + background: var(--accent-bg); + border: 2px solid transparent; + transition: border-color 0.3s; + margin-bottom: 24px; + + &:hover { + border-color: var(--accent-border); + } + &:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + } +} + +.hero { + position: relative; + + .base, + .framework, + .vite { + inset-inline: 0; + margin: 0 auto; + } + + .base { + width: 170px; + position: relative; + z-index: 0; + } + + .framework, + .vite { + position: absolute; + } + + .framework { + z-index: 1; + top: 34px; + height: 28px; + transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg) + scale(1.4); + } + + .vite { + z-index: 0; + top: 107px; + height: 26px; + width: auto; + transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg) + scale(0.8); + } +} + +#center { + display: flex; + flex-direction: column; + gap: 25px; + place-content: center; + place-items: center; + flex-grow: 1; + + @media (max-width: 1024px) { + padding: 32px 20px 24px; + gap: 18px; + } +} + +#next-steps { + display: flex; + border-top: 1px solid var(--border); + text-align: left; + + & > div { + flex: 1 1 0; + padding: 32px; + @media (max-width: 1024px) { + padding: 24px 20px; + } + } + + .icon { + margin-bottom: 16px; + width: 22px; + height: 22px; + } + + @media (max-width: 1024px) { + flex-direction: column; + text-align: center; + } +} + +#docs { + border-right: 1px solid var(--border); + + @media (max-width: 1024px) { + border-right: none; + border-bottom: 1px solid var(--border); + } +} + +#next-steps ul { + list-style: none; + padding: 0; + display: flex; + gap: 8px; + margin: 32px 0 0; + + .logo { + height: 18px; + } + + a { + color: var(--text-h); + font-size: 16px; + border-radius: 6px; + background: var(--social-bg); + display: flex; + padding: 6px 12px; + align-items: center; + gap: 8px; + text-decoration: none; + transition: box-shadow 0.3s; + + &:hover { + box-shadow: var(--shadow); + } + .button-icon { + height: 18px; + width: 18px; + } + } + + @media (max-width: 1024px) { + margin-top: 20px; + flex-wrap: wrap; + justify-content: center; + + li { + flex: 1 1 calc(50% - 8px); + } + + a { + width: 100%; + justify-content: center; + box-sizing: border-box; + } + } +} + +#spacer { + height: 88px; + border-top: 1px solid var(--border); + @media (max-width: 1024px) { + height: 48px; + } +} + +.ticks { + position: relative; + width: 100%; + + &::before, + &::after { + content: ''; + position: absolute; + top: -4.5px; + border: 5px solid transparent; + } + + &::before { + left: 0; + border-left-color: var(--border); + } + &::after { + right: 0; + border-right-color: var(--border); + } +} diff --git a/spell-check/configure-spellcheck/src/App.tsx b/spell-check/configure-spellcheck/src/App.tsx new file mode 100644 index 0000000..58e3e37 --- /dev/null +++ b/spell-check/configure-spellcheck/src/App.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; + +import { DocumentEditorContainerComponent, Toolbar } from '@syncfusion/ej2-react-documenteditor'; + +DocumentEditorContainerComponent.Inject(Toolbar); + +function App() { + const containerRef = React.useRef(null); + + React.useEffect(() => { + if (containerRef.current) { + // Accessing spell checker + let spellChecker = (containerRef.current as DocumentEditorContainerComponent).documentEditor.spellChecker; + // Set language id to map dictionary in server side + spellChecker.languageID = 1033; + spellChecker.removeUnderline = false; + // Allow suggestion for misspelled word + spellChecker.allowSpellCheckAndSuggestion = true; + } + }, []); + + return ( + + ); +} +export default App; diff --git a/spell-check/configure-spellcheck/src/assets/hero.png b/spell-check/configure-spellcheck/src/assets/hero.png new file mode 100644 index 0000000..02251f4 Binary files /dev/null and b/spell-check/configure-spellcheck/src/assets/hero.png differ diff --git a/spell-check/configure-spellcheck/src/assets/react.svg b/spell-check/configure-spellcheck/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/spell-check/configure-spellcheck/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/spell-check/configure-spellcheck/src/assets/vite.svg b/spell-check/configure-spellcheck/src/assets/vite.svg new file mode 100644 index 0000000..5101b67 --- /dev/null +++ b/spell-check/configure-spellcheck/src/assets/vite.svg @@ -0,0 +1 @@ +Vite diff --git a/spell-check/configure-spellcheck/src/index.css b/spell-check/configure-spellcheck/src/index.css new file mode 100644 index 0000000..b351054 --- /dev/null +++ b/spell-check/configure-spellcheck/src/index.css @@ -0,0 +1,9 @@ +@import '../node_modules/@syncfusion/ej2-base/styles/tailwind3.css'; +@import '../node_modules/@syncfusion/ej2-buttons/styles/tailwind3.css'; +@import '../node_modules/@syncfusion/ej2-inputs/styles/tailwind3.css'; +@import '../node_modules/@syncfusion/ej2-popups/styles/tailwind3.css'; +@import '../node_modules/@syncfusion/ej2-lists/styles/tailwind3.css'; +@import '../node_modules/@syncfusion/ej2-navigations/styles/tailwind3.css'; +@import '../node_modules/@syncfusion/ej2-splitbuttons/styles/tailwind3.css'; +@import '../node_modules/@syncfusion/ej2-dropdowns/styles/tailwind3.css'; +@import '../node_modules/@syncfusion/ej2-react-documenteditor/styles/tailwind3.css'; \ No newline at end of file diff --git a/spell-check/configure-spellcheck/src/main.tsx b/spell-check/configure-spellcheck/src/main.tsx new file mode 100644 index 0000000..bef5202 --- /dev/null +++ b/spell-check/configure-spellcheck/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.tsx' + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/spell-check/configure-spellcheck/tsconfig.app.json b/spell-check/configure-spellcheck/tsconfig.app.json new file mode 100644 index 0000000..7f42e5f --- /dev/null +++ b/spell-check/configure-spellcheck/tsconfig.app.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "es2023", + "lib": ["ES2023", "DOM"], + "module": "esnext", + "types": ["vite/client"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/spell-check/configure-spellcheck/tsconfig.json b/spell-check/configure-spellcheck/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/spell-check/configure-spellcheck/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/spell-check/configure-spellcheck/tsconfig.node.json b/spell-check/configure-spellcheck/tsconfig.node.json new file mode 100644 index 0000000..d3c52ea --- /dev/null +++ b/spell-check/configure-spellcheck/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "es2023", + "lib": ["ES2023"], + "module": "esnext", + "types": ["node"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["vite.config.ts"] +} diff --git a/spell-check/configure-spellcheck/vite.config.ts b/spell-check/configure-spellcheck/vite.config.ts new file mode 100644 index 0000000..8b0f57b --- /dev/null +++ b/spell-check/configure-spellcheck/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +})