├── src ├── global.d.ts ├── main.ts ├── components │ └── react │ │ ├── Badges.tsx │ │ └── MyTable.tsx └── App.svelte ├── .gitignore ├── docs └── svelte.png ├── public ├── favicon.png ├── index.html └── global.css ├── CONTRIBUTING.md ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── tsconfig.json ├── LICENSE ├── README.md ├── package.json ├── rollup.config.js └── CODE_OF_CONDUCT.md /src/global.d.ts: -------------------------------------------------------------------------------- 1 | /// -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /public/build/ 3 | 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /docs/svelte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpinho/svelte-react-sample-app/HEAD/docs/svelte.png -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpinho/svelte-react-sample-app/HEAD/public/favicon.png -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import App from './App.svelte'; 2 | 3 | const app = new App({ 4 | target: document.body, 5 | }); 6 | 7 | export default app; -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Guidelines: 2 | 3 | - Submit a PR, have reviewed by another owner. 4 | - Ensure new features are covered by tests. 5 | - Update any relevant docs. 6 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Svelte app 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | 4 | "compilerOptions": { 5 | "target": "es5", 6 | "lib": [ 7 | "dom", 8 | "dom.iterable", 9 | "esnext" 10 | ], 11 | "allowJs": true, 12 | "skipLibCheck": true, 13 | "esModuleInterop": true, 14 | "allowSyntheticDefaultImports": true, 15 | "strict": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "module": "esnext", 18 | "moduleResolution": "node", 19 | "resolveJsonModule": true, 20 | "isolatedModules": true, 21 | "noEmit": true, 22 | "jsx": "react", 23 | }, 24 | "include": ["src/**/*"], 25 | "exclude": ["node_modules/*", "__sapper__/*", "public/*"] 26 | } -------------------------------------------------------------------------------- /src/components/react/Badges.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { makeStyles, Theme, createStyles, createTheme } from '@material-ui/core/styles'; 3 | 4 | import Badge from '@material-ui/core/Badge'; 5 | import MailIcon from '@material-ui/icons/Mail'; 6 | 7 | const useStyles = makeStyles((theme: Theme) => 8 | createStyles({ 9 | root: { 10 | '& > *': { 11 | margin: theme.spacing(1), 12 | }, 13 | }, 14 | }), 15 | ); 16 | 17 | export default function SimpleBadge() { 18 | const classes = useStyles(createTheme()); 19 | 20 | return ( 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 João Pinho 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /public/global.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | position: relative; 3 | width: 100%; 4 | height: 100%; 5 | } 6 | 7 | body { 8 | color: #333; 9 | margin: 0; 10 | padding: 8px; 11 | box-sizing: border-box; 12 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; 13 | } 14 | 15 | a { 16 | color: rgb(0,100,200); 17 | text-decoration: none; 18 | } 19 | 20 | a:hover { 21 | text-decoration: underline; 22 | } 23 | 24 | a:visited { 25 | color: rgb(0,80,160); 26 | } 27 | 28 | label { 29 | display: block; 30 | } 31 | 32 | input, button, select, textarea { 33 | font-family: inherit; 34 | font-size: inherit; 35 | -webkit-padding: 0.4em 0; 36 | padding: 0.4em; 37 | margin: 0 0 0.5em 0; 38 | box-sizing: border-box; 39 | border: 1px solid #ccc; 40 | border-radius: 2px; 41 | } 42 | 43 | input:disabled { 44 | color: #ccc; 45 | } 46 | 47 | button { 48 | color: #333; 49 | background-color: #f4f4f4; 50 | outline: none; 51 | } 52 | 53 | button:disabled { 54 | color: #999; 55 | } 56 | 57 | button:not(:disabled):active { 58 | background-color: #ddd; 59 | } 60 | 61 | button:focus { 62 | border-color: #666; 63 | } 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # svelte-react-kit sample app 2 | 3 | ![svelte-react-kit sample app](docs/svelte.png) 4 | 5 | This is just a sample app for the [svelte-react-kit](https://github.com/jpinho/svelte-react-kit) project. 6 | 7 | --- 8 | 9 | Use React components inside Svelte apps. 10 | 11 | This repo is the mirror of [RichHarris/react-svelte](https://github.com/Rich-Harris/react-svelte/blob/master/README.md) with some bonus given we also add MaterialUI to the mix here. 12 | 13 | ```svelte 14 | 18 | 19 | alert("hello world!")} 26 | /> 27 | 28 | 36 | ``` 37 | 38 | Check the live demo [here](https://svelte-react.surge.sh), and don't forget to see the [BlogPost: Using React Within Svelte Apps](https://jpepinho.medium.com/using-react-within-your-svelte-applications-3b1f2a75aefc). 39 | 40 | ## Usage 41 | 42 | Right now there is no npm package that you can install. 43 | To use this, simply copy/paste the `ReactAdapter` into your project and you are done. 44 | Additionally, you may want to copy the rollup and typescript configurations so that you can have React and Svelte living side-by-side. 45 | 46 | ## License 47 | 48 | [MIT](LICENSE) 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-react-sample", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "build": "rollup -c -m", 7 | "dev": "rollup -c -w", 8 | "start": "sirv public --no-clear", 9 | "check": "svelte-check --tsconfig ./tsconfig.json", 10 | "test": "jest src" 11 | }, 12 | "devDependencies": { 13 | "@babel/preset-react": "^7.14.5", 14 | "@rollup/plugin-commonjs": "^17.0.0", 15 | "@rollup/plugin-node-resolve": "^11.0.0", 16 | "@rollup/plugin-replace": "^2.4.2", 17 | "@rollup/plugin-typescript": "^8.0.0", 18 | "@testing-library/jest-dom": "^5.14.1", 19 | "@testing-library/svelte": "^3.0.3", 20 | "@tsconfig/svelte": "^2.0.0", 21 | "@types/react": "^17.0.4", 22 | "@types/react-dom": "^17.0.9", 23 | "git-scripts": "^0.4.3", 24 | "jest": "^26.0.0", 25 | "rollup": "^2.3.4", 26 | "rollup-plugin-css-only": "^3.1.0", 27 | "rollup-plugin-livereload": "^2.0.0", 28 | "rollup-plugin-svelte": "^7.0.0", 29 | "rollup-plugin-terser": "^7.0.0", 30 | "surge": "^0.23.0", 31 | "svelte": "^3.0.0", 32 | "svelte-check": "^2.0.0", 33 | "svelte-preprocess": "^4.0.0", 34 | "tslib": "^2.0.0", 35 | "typescript": "^4.0.0" 36 | }, 37 | "dependencies": { 38 | "@material-ui/core": "^4.12.1", 39 | "@material-ui/icons": "^4.11.2", 40 | "clsx": "^1.1.1", 41 | "react": "^17.0.2", 42 | "react-dom": "^17.0.2", 43 | "sirv-cli": "^1.0.12", 44 | "svelte-react-kit": "^0.1.2" 45 | }, 46 | "git": { 47 | "scripts": { 48 | "pre-push": "npm run build && surge --project ./public --domain svelte-react.surge.sh" 49 | } 50 | }, 51 | "jest": { 52 | "transform": { 53 | "^.+\\.svelte$": [ 54 | "svelte-jester", 55 | { 56 | "preprocess": true 57 | } 58 | ], 59 | "^.+\\.ts$": "ts-jest" 60 | }, 61 | "moduleFileExtensions": [ 62 | "js", 63 | "ts", 64 | "svelte" 65 | ] 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/App.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 |
13 |

React inside Svelte

14 |

with React Material UI!

15 | 16 | 17 | 18 |

A MUI React Button

19 | alert('Hello Fella!')} 26 | /> 27 | 28 |

An Outstanding Custom MUI React Table

29 | 30 | 31 |

Simple Badge

32 | 33 | 34 |

Multiple Badges with Children

35 | 36 |
37 | 38 | 85 | -------------------------------------------------------------------------------- /src/components/react/MyTable.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { makeStyles } from '@material-ui/core/styles'; 3 | import Table from '@material-ui/core/Table'; 4 | import TableBody from '@material-ui/core/TableBody'; 5 | import TableCell from '@material-ui/core/TableCell'; 6 | import TableContainer from '@material-ui/core/TableContainer'; 7 | import TableHead from '@material-ui/core/TableHead'; 8 | import TableRow from '@material-ui/core/TableRow'; 9 | import Paper from '@material-ui/core/Paper'; 10 | 11 | const useStyles = makeStyles({ 12 | table: { 13 | minWidth: 650, 14 | }, 15 | }); 16 | 17 | function createData(name: string, calories: number, fat: number, carbs: number, protein: number) { 18 | return { name, calories, fat, carbs, protein }; 19 | } 20 | 21 | const rows = [ 22 | createData('Frozen yoghurt', 159, 6.0, 24, 4.0), 23 | createData('Ice cream sandwich', 237, 9.0, 37, 4.3), 24 | createData('Eclair', 262, 16.0, 24, 6.0), 25 | createData('Cupcake', 305, 3.7, 67, 4.3), 26 | createData('Gingerbread', 356, 16.0, 49, 3.9), 27 | ]; 28 | 29 | export default function BasicTable() { 30 | const classes = useStyles(); 31 | 32 | return ( 33 | 34 | 35 | 36 | 37 | Dessert (100g serving) 38 | Calories 39 | Fat (g) 40 | Carbs (g) 41 | Protein (g) 42 | 43 | 44 | 45 | {rows.map((row) => ( 46 | 47 | 48 | {row.name} 49 | 50 | {row.calories} 51 | {row.fat} 52 | {row.carbs} 53 | {row.protein} 54 | 55 | ))} 56 | 57 |
58 |
59 | ); 60 | } 61 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import svelte from 'rollup-plugin-svelte'; 2 | import commonjs from '@rollup/plugin-commonjs'; 3 | import resolve from '@rollup/plugin-node-resolve'; 4 | import livereload from 'rollup-plugin-livereload'; 5 | import { terser } from 'rollup-plugin-terser'; 6 | import sveltePreprocess from 'svelte-preprocess'; 7 | import typescript from '@rollup/plugin-typescript'; 8 | import css from 'rollup-plugin-css-only'; 9 | import replace from '@rollup/plugin-replace'; 10 | 11 | const production = !process.env.ROLLUP_WATCH; 12 | 13 | function serve() { 14 | let server; 15 | 16 | function toExit() { 17 | if (server) server.kill(0); 18 | } 19 | 20 | return { 21 | writeBundle() { 22 | if (server) return; 23 | server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], { 24 | stdio: ['ignore', 'inherit', 'inherit'], 25 | shell: true 26 | }); 27 | 28 | process.on('SIGTERM', toExit); 29 | process.on('exit', toExit); 30 | } 31 | }; 32 | } 33 | 34 | export default { 35 | input: 'src/main.ts', 36 | output: { 37 | sourcemap: true, 38 | format: 'iife', 39 | name: 'app', 40 | file: 'public/build/bundle.js' 41 | }, 42 | plugins: [ 43 | replace({ 44 | 'process.env.NODE_ENV': JSON.stringify( 'development' ), 45 | preventAssignment: true 46 | }), 47 | svelte({ 48 | preprocess: sveltePreprocess({ sourceMap: !production }), 49 | compilerOptions: { 50 | // enable run-time checks when not in production 51 | dev: !production 52 | } 53 | }), 54 | // we'll extract any component CSS out into 55 | // a separate file - better for performance 56 | css({ output: 'bundle.css' }), 57 | 58 | // If you have external dependencies installed from 59 | // npm, you'll most likely need these plugins. In 60 | // some cases you'll need additional configuration - 61 | // consult the documentation for details: 62 | // https://github.com/rollup/plugins/tree/master/packages/commonjs 63 | resolve({ 64 | browser: true, 65 | dedupe: ['svelte', 'react', 'react-dom', '@material-ui/core'] 66 | }), 67 | commonjs(), 68 | typescript({ 69 | sourceMap: !production, 70 | inlineSources: !production 71 | }), 72 | 73 | // In dev mode, call `npm run start` once 74 | // the bundle has been generated 75 | !production && serve(), 76 | 77 | // Watch the `public` directory and refresh the 78 | // browser on changes when not in production 79 | !production && livereload('public'), 80 | 81 | // If we're building for production (npm run build 82 | // instead of npm run dev), minify 83 | production && terser() 84 | ], 85 | watch: { 86 | clearScreen: false 87 | } 88 | }; 89 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | email. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | --------------------------------------------------------------------------------