├── .github
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── LICENSE
├── README.md
├── ionic
├── .gitignore
├── capacitor.config.json
├── ionic.config.json
├── package-lock.json
├── package.json
├── public
│ ├── assets
│ │ ├── icon
│ │ │ ├── favicon.png
│ │ │ └── icon.png
│ │ └── shapes.svg
│ ├── index.html
│ └── manifest.json
├── src
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── index.tsx
│ ├── pages
│ │ ├── Home.css
│ │ └── Home.tsx
│ ├── react-app-env.d.ts
│ ├── serviceWorker.ts
│ ├── setupTests.ts
│ └── theme
│ │ └── variables.css
└── tsconfig.json
├── material-ui
├── .gitignore
├── README.md
├── capacitor.config.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── preact
├── .gitignore
├── README.md
├── capacitor.config.json
├── package.json
├── public
│ └── index.html
└── src
│ ├── assets
│ ├── favicon.ico
│ └── icons
│ │ ├── android-chrome-192x192.png
│ │ ├── android-chrome-512x512.png
│ │ ├── apple-touch-icon.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ └── mstile-150x150.png
│ ├── components
│ ├── app.js
│ └── header
│ │ ├── index.js
│ │ └── style.css
│ ├── index.js
│ ├── manifest.json
│ ├── routes
│ ├── 404
│ │ ├── index.js
│ │ └── style.css
│ ├── camera
│ │ └── index.js
│ ├── geolocation
│ │ └── index.js
│ └── home
│ │ ├── index.js
│ │ └── style.css
│ └── style
│ └── index.css
├── svelte-framework7
├── .gitignore
├── README.md
├── assets-src
│ ├── apple-touch-icon.png
│ └── web-icon.png
├── babel.config.js
├── build
│ ├── build.js
│ └── webpack.config.js
├── capacitor.config.json
├── framework7.json
├── package-lock.json
├── package.json
├── postcss.config.js
└── src
│ ├── components
│ └── app.svelte
│ ├── css
│ ├── app.scss
│ └── icons.css
│ ├── fonts
│ ├── Framework7Icons-Regular.eot
│ ├── Framework7Icons-Regular.ttf
│ ├── Framework7Icons-Regular.woff
│ ├── Framework7Icons-Regular.woff2
│ ├── MaterialIcons-Regular.eot
│ ├── MaterialIcons-Regular.ttf
│ ├── MaterialIcons-Regular.woff
│ └── MaterialIcons-Regular.woff2
│ ├── index.html
│ ├── js
│ ├── app.js
│ └── routes.js
│ ├── pages
│ ├── 404.svelte
│ └── home.svelte
│ └── static
│ └── icons
│ ├── 128x128.png
│ ├── 144x144.png
│ ├── 152x152.png
│ ├── 192x192.png
│ ├── 256x256.png
│ ├── 512x512.png
│ ├── apple-touch-icon.png
│ └── favicon.png
└── vuejs-vuetify
├── .browserslistrc
├── .eslintrc.js
├── .gitignore
├── README.md
├── babel.config.js
├── capacitor.config.json
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── img
│ └── icons
│ │ ├── android-chrome-192x192.png
│ │ ├── android-chrome-512x512.png
│ │ ├── android-chrome-maskable-192x192.png
│ │ ├── android-chrome-maskable-512x512.png
│ │ ├── apple-touch-icon-120x120.png
│ │ ├── apple-touch-icon-152x152.png
│ │ ├── apple-touch-icon-180x180.png
│ │ ├── apple-touch-icon-60x60.png
│ │ ├── apple-touch-icon-76x76.png
│ │ ├── apple-touch-icon.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── msapplication-icon-144x144.png
│ │ ├── mstile-150x150.png
│ │ └── safari-pinned-tab.svg
├── index.html
└── robots.txt
├── src
├── App.vue
├── components
│ └── DeviceInfoCard.vue
├── main.ts
├── plugins
│ └── vuetify.ts
├── registerServiceWorker.ts
├── router
│ └── index.ts
├── shims-tsx.d.ts
├── shims-vue.d.ts
├── store
│ └── index.ts
└── views
│ └── Home.vue
├── tsconfig.json
└── vue.config.js
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
2 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | Contributor Code of Conduct
2 |
3 | As contributors and maintainers of this Capacitor Community project, we pledge to respect everyone who contributes by posting issues, updating documentation, submitting pull requests, providing feedback in comments, and any other activities.
4 |
5 | Communication through this repository must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
6 |
7 | We promise to extend courtesy and respect to everyone involved in this project regardless of gender, gender identity, sexual orientation, disability, age, race, ethnicity, religion, or level of experience. We expect anyone contributing to this Capacitor Community project to do the same.
8 |
9 | If any member of the community violates this code of conduct, the maintainers of this Capacitor Community and/or the Ionic project may take action, including but not limited to removing issues, comments, and PRs or blocking accounts as deemed appropriate.
10 |
11 | If you are subject to or witness unacceptable behavior, or have any other concerns, please contact the maintainer of this repository or email hi@ionicframework.com.
12 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
2 | # Contributing to this project
3 |
4 | Describe the steps a developer should go through in order to contribute to this project
5 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | dist
3 | .sourcemaps
4 | xcuserdata/
5 | node_modules/
6 | cli/dist/commands/copy.js
7 | Pods/
8 | test_project/
9 | *.map
10 | .DS_Store
11 | Podfile.lock
12 | example/www/
13 | example/electron/www/*
14 | example/electron/capacitor.config.json
15 | example/android/app/src/main/assets/public/*
16 | !example/android/app/src/main/assets/public/.gitkeep
17 | example/ios/IonicRunner/public/*
18 | !example/ios/IonicRunner/public/.gitkeep
19 | Build/*
20 | Index/
21 | .*.sw*
22 | site/www
23 | android-template.iml
24 | !/build/.npmkeep
25 | lerna-debug.log
26 | capacitor-ios/
27 | local.properties
28 | contents.xcworkspacedata
29 | .stencil/
30 | android-template/.gradle/
31 | android-template/app/app.iml
32 | /site/.env
33 | /site/.firebase
34 | .gradle/
35 | .settings/
36 | .project
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) COPYRIGHT_YEAR COPYRIGHT_HOLDER
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Capacitor Examples
2 |
3 | Capacitor works with any web technology to enable web developers to deploy their web apps natively to iOS and Android, and the web as a Progressive Web App.
4 |
5 | Capacitor drops into any new or existing web app. To see how to use Capacitor with your frontend tooling of choice, check out the examples in this repo.
6 |
7 | ## How to Run
8 |
9 | 1. Change into the UI Framework directory of choice, then run `npm install`.
10 | 2. Build the web app: `npm run build`.
11 | 3. Add a native platform: `npx cap add android` or `npx cap add ios`.
12 | 4. Copy the built web app into the native platform: `npx cap copy`.
13 | 5. Open the native IDE and run the app: `npx cap open android` or `npx cap open ios`.
14 |
15 | > Normally the top-level `android` and `ios` native project folders are committed to source control. They are excluded here to avoid bloating this repository.
16 |
--------------------------------------------------------------------------------
/ionic/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # capacitor
4 | android/
5 | ios/
6 |
7 | # dependencies
8 | /node_modules
9 | /.pnp
10 | .pnp.js
11 |
12 | # testing
13 | /coverage
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | .env.local
21 | .env.development.local
22 | .env.test.local
23 | .env.production.local
24 | .vscode
25 |
26 | npm-debug.log*
27 | yarn-debug.log*
28 | yarn-error.log*
29 |
--------------------------------------------------------------------------------
/ionic/capacitor.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "appId": "com.capacitorjs.examples.ionic",
3 | "appName": "cap-ionic",
4 | "bundledWebRuntime": false,
5 | "npmClient": "npm",
6 | "webDir": "build",
7 | "plugins": {
8 | "SplashScreen": {
9 | "launchShowDuration": 0
10 | }
11 | },
12 | "cordova": {}
13 | }
14 |
--------------------------------------------------------------------------------
/ionic/ionic.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ionic",
3 | "integrations": {
4 | "capacitor": {}
5 | },
6 | "type": "react"
7 | }
8 |
--------------------------------------------------------------------------------
/ionic/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ionic",
3 | "version": "0.0.1",
4 | "private": true,
5 | "dependencies": {
6 | "@capacitor/core": "^2.1.2",
7 | "@ionic/react": "^5.0.7",
8 | "@ionic/react-router": "^5.0.7",
9 | "@testing-library/jest-dom": "^4.2.4",
10 | "@testing-library/react": "^9.4.0",
11 | "@testing-library/user-event": "^8.0.3",
12 | "@types/jest": "^24.0.25",
13 | "@types/node": "^12.12.24",
14 | "@types/react": "^16.9.17",
15 | "@types/react-dom": "^16.9.4",
16 | "@types/react-router": "^5.1.4",
17 | "@types/react-router-dom": "^5.1.3",
18 | "ionicons": "^5.0.0",
19 | "react": "^16.13.0",
20 | "react-dom": "^16.13.0",
21 | "react-router": "^5.1.2",
22 | "react-router-dom": "^5.1.2",
23 | "react-scripts": "3.4.1",
24 | "typescript": "3.8.3"
25 | },
26 | "scripts": {
27 | "start": "react-scripts start",
28 | "build": "react-scripts build",
29 | "test": "react-scripts test",
30 | "eject": "react-scripts eject"
31 | },
32 | "eslintConfig": {
33 | "extends": "react-app"
34 | },
35 | "browserslist": {
36 | "production": [
37 | ">0.2%",
38 | "not dead",
39 | "not op_mini all"
40 | ],
41 | "development": [
42 | "last 1 chrome version",
43 | "last 1 firefox version",
44 | "last 1 safari version"
45 | ]
46 | },
47 | "devDependencies": {
48 | "@capacitor/cli": "^2.1.2"
49 | },
50 | "description": "An Ionic project"
51 | }
52 |
--------------------------------------------------------------------------------
/ionic/public/assets/icon/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/capacitor-community/examples/6e703917d3343661bedbea54047faef364a11a18/ionic/public/assets/icon/favicon.png
--------------------------------------------------------------------------------
/ionic/public/assets/icon/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/capacitor-community/examples/6e703917d3343661bedbea54047faef364a11a18/ionic/public/assets/icon/icon.png
--------------------------------------------------------------------------------
/ionic/public/assets/shapes.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ionic/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Ionic App
6 |
7 |
8 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ionic/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Ionic App",
3 | "name": "My Ionic App",
4 | "icons": [
5 | {
6 | "src": "assets/icon/favicon.png",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "assets/icon/icon.png",
12 | "type": "image/png",
13 | "sizes": "512x512",
14 | "purpose": "maskable"
15 | }
16 | ],
17 | "start_url": ".",
18 | "display": "standalone",
19 | "theme_color": "#ffffff",
20 | "background_color": "#ffffff"
21 | }
22 |
--------------------------------------------------------------------------------
/ionic/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders without crashing', () => {
6 | const { baseElement } = render();
7 | expect(baseElement).toBeDefined();
8 | });
9 |
--------------------------------------------------------------------------------
/ionic/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Redirect, Route } from 'react-router-dom';
3 | import { IonApp, IonRouterOutlet } from '@ionic/react';
4 | import { IonReactRouter } from '@ionic/react-router';
5 | import Home from './pages/Home';
6 |
7 | /* Core CSS required for Ionic components to work properly */
8 | import '@ionic/react/css/core.css';
9 |
10 | /* Basic CSS for apps built with Ionic */
11 | import '@ionic/react/css/normalize.css';
12 | import '@ionic/react/css/structure.css';
13 | import '@ionic/react/css/typography.css';
14 |
15 | /* Optional CSS utils that can be commented out */
16 | import '@ionic/react/css/padding.css';
17 | import '@ionic/react/css/float-elements.css';
18 | import '@ionic/react/css/text-alignment.css';
19 | import '@ionic/react/css/text-transformation.css';
20 | import '@ionic/react/css/flex-utils.css';
21 | import '@ionic/react/css/display.css';
22 |
23 | /* Theme variables */
24 | import './theme/variables.css';
25 |
26 | const App: React.FC = () => (
27 |
28 |
29 |
30 |
31 | } />
32 |
33 |
34 |
35 | );
36 |
37 | export default App;
38 |
--------------------------------------------------------------------------------
/ionic/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 | import * as serviceWorker from './serviceWorker';
5 |
6 | ReactDOM.render(, document.getElementById('root'));
7 |
8 | // If you want your app to work offline and load faster, you can change
9 | // unregister() to register() below. Note this comes with some pitfalls.
10 | // Learn more about service workers: https://bit.ly/CRA-PWA
11 | serviceWorker.unregister();
12 |
--------------------------------------------------------------------------------
/ionic/src/pages/Home.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/capacitor-community/examples/6e703917d3343661bedbea54047faef364a11a18/ionic/src/pages/Home.css
--------------------------------------------------------------------------------
/ionic/src/pages/Home.tsx:
--------------------------------------------------------------------------------
1 | import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonButton, IonIcon } from '@ionic/react';
2 | import React, { useEffect, useState } from 'react';
3 | import { shareSocialOutline } from 'ionicons/icons';
4 |
5 | import { Plugins, DeviceInfo } from '@capacitor/core';
6 |
7 | import './Home.css';
8 |
9 | const Home: React.FC = () => {
10 | const [deviceInfo, setDeviceInfo] = useState(null);
11 |
12 | const shareTweet = async () => {
13 | const { Share } = Plugins;
14 |
15 | const share = await Share.share({
16 | title: 'Share Capacitor',
17 | text: 'I deployed an Ionic React web app as a native mobile app using @capacitorjs in minutes!',
18 | url: 'https://capacitorjs.com',
19 | });
20 | }
21 |
22 | useEffect(() => {
23 | const getDeviceInfo = async () => {
24 | const { Device } = Plugins;
25 |
26 | setDeviceInfo(await Device.getInfo());
27 | };
28 |
29 | getDeviceInfo();
30 | }, []);
31 |
32 | return (
33 |
34 |
35 |
36 | Capacitor Example
37 |
38 |
39 |
40 |
41 |
42 | Capacitor Ionic Example
43 |
44 |
45 | shareTweet()}>
46 |
47 | Share This
48 |
49 |
50 |
Device Info:
51 |
52 | {deviceInfo ? (
53 | JSON.stringify(deviceInfo, null, 2)
54 | ) : null}
55 |
56 |
57 |
58 |
59 | );
60 | };
61 |
62 | export default Home;
63 |
--------------------------------------------------------------------------------
/ionic/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/ionic/src/serviceWorker.ts:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.0/8 are considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | type Config = {
24 | onSuccess?: (registration: ServiceWorkerRegistration) => void;
25 | onUpdate?: (registration: ServiceWorkerRegistration) => void;
26 | };
27 |
28 | export function register(config?: Config) {
29 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
30 | // The URL constructor is available in all browsers that support SW.
31 | const publicUrl = new URL(
32 | process.env.PUBLIC_URL,
33 | window.location.href
34 | );
35 | if (publicUrl.origin !== window.location.origin) {
36 | // Our service worker won't work if PUBLIC_URL is on a different origin
37 | // from what our page is served on. This might happen if a CDN is used to
38 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
39 | return;
40 | }
41 |
42 | window.addEventListener('load', () => {
43 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
44 |
45 | if (isLocalhost) {
46 | // This is running on localhost. Let's check if a service worker still exists or not.
47 | checkValidServiceWorker(swUrl, config);
48 |
49 | // Add some additional logging to localhost, pointing developers to the
50 | // service worker/PWA documentation.
51 | navigator.serviceWorker.ready.then(() => {
52 | console.log(
53 | 'This web app is being served cache-first by a service ' +
54 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
55 | );
56 | });
57 | } else {
58 | // Is not localhost. Just register service worker
59 | registerValidSW(swUrl, config);
60 | }
61 | });
62 | }
63 | }
64 |
65 | function registerValidSW(swUrl: string, config?: Config) {
66 | navigator.serviceWorker
67 | .register(swUrl)
68 | .then(registration => {
69 | registration.onupdatefound = () => {
70 | const installingWorker = registration.installing;
71 | if (installingWorker == null) {
72 | return;
73 | }
74 | installingWorker.onstatechange = () => {
75 | if (installingWorker.state === 'installed') {
76 | if (navigator.serviceWorker.controller) {
77 | // At this point, the updated precached content has been fetched,
78 | // but the previous service worker will still serve the older
79 | // content until all client tabs are closed.
80 | console.log(
81 | 'New content is available and will be used when all ' +
82 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
83 | );
84 |
85 | // Execute callback
86 | if (config && config.onUpdate) {
87 | config.onUpdate(registration);
88 | }
89 | } else {
90 | // At this point, everything has been precached.
91 | // It's the perfect time to display a
92 | // "Content is cached for offline use." message.
93 | console.log('Content is cached for offline use.');
94 |
95 | // Execute callback
96 | if (config && config.onSuccess) {
97 | config.onSuccess(registration);
98 | }
99 | }
100 | }
101 | };
102 | };
103 | })
104 | .catch(error => {
105 | console.error('Error during service worker registration:', error);
106 | });
107 | }
108 |
109 | function checkValidServiceWorker(swUrl: string, config?: Config) {
110 | // Check if the service worker can be found. If it can't reload the page.
111 | fetch(swUrl, {
112 | headers: { 'Service-Worker': 'script' }
113 | })
114 | .then(response => {
115 | // Ensure service worker exists, and that we really are getting a JS file.
116 | const contentType = response.headers.get('content-type');
117 | if (
118 | response.status === 404 ||
119 | (contentType != null && contentType.indexOf('javascript') === -1)
120 | ) {
121 | // No service worker found. Probably a different app. Reload the page.
122 | navigator.serviceWorker.ready.then(registration => {
123 | registration.unregister().then(() => {
124 | window.location.reload();
125 | });
126 | });
127 | } else {
128 | // Service worker found. Proceed as normal.
129 | registerValidSW(swUrl, config);
130 | }
131 | })
132 | .catch(() => {
133 | console.log(
134 | 'No internet connection found. App is running in offline mode.'
135 | );
136 | });
137 | }
138 |
139 | export function unregister() {
140 | if ('serviceWorker' in navigator) {
141 | navigator.serviceWorker.ready.then(registration => {
142 | registration.unregister();
143 | });
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/ionic/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/ionic/src/theme/variables.css:
--------------------------------------------------------------------------------
1 | /* Ionic Variables and Theming. For more info, please see:
2 | http://ionicframework.com/docs/theming/ */
3 |
4 | /** Ionic CSS Variables **/
5 | :root {
6 | /** primary **/
7 | --ion-color-primary: #3880ff;
8 | --ion-color-primary-rgb: 56, 128, 255;
9 | --ion-color-primary-contrast: #ffffff;
10 | --ion-color-primary-contrast-rgb: 255, 255, 255;
11 | --ion-color-primary-shade: #3171e0;
12 | --ion-color-primary-tint: #4c8dff;
13 |
14 | /** secondary **/
15 | --ion-color-secondary: #3dc2ff;
16 | --ion-color-secondary-rgb: 61, 194, 255;
17 | --ion-color-secondary-contrast: #ffffff;
18 | --ion-color-secondary-contrast-rgb: 255, 255, 255;
19 | --ion-color-secondary-shade: #36abe0;
20 | --ion-color-secondary-tint: #50c8ff;
21 |
22 | /** tertiary **/
23 | --ion-color-tertiary: #5260ff;
24 | --ion-color-tertiary-rgb: 82, 96, 255;
25 | --ion-color-tertiary-contrast: #ffffff;
26 | --ion-color-tertiary-contrast-rgb: 255, 255, 255;
27 | --ion-color-tertiary-shade: #4854e0;
28 | --ion-color-tertiary-tint: #6370ff;
29 |
30 | /** success **/
31 | --ion-color-success: #2dd36f;
32 | --ion-color-success-rgb: 45, 211, 111;
33 | --ion-color-success-contrast: #ffffff;
34 | --ion-color-success-contrast-rgb: 255, 255, 255;
35 | --ion-color-success-shade: #28ba62;
36 | --ion-color-success-tint: #42d77d;
37 |
38 | /** warning **/
39 | --ion-color-warning: #ffc409;
40 | --ion-color-warning-rgb: 255, 196, 9;
41 | --ion-color-warning-contrast: #000000;
42 | --ion-color-warning-contrast-rgb: 0, 0, 0;
43 | --ion-color-warning-shade: #e0ac08;
44 | --ion-color-warning-tint: #ffca22;
45 |
46 | /** danger **/
47 | --ion-color-danger: #eb445a;
48 | --ion-color-danger-rgb: 235, 68, 90;
49 | --ion-color-danger-contrast: #ffffff;
50 | --ion-color-danger-contrast-rgb: 255, 255, 255;
51 | --ion-color-danger-shade: #cf3c4f;
52 | --ion-color-danger-tint: #ed576b;
53 |
54 | /** dark **/
55 | --ion-color-dark: #222428;
56 | --ion-color-dark-rgb: 34, 36, 40;
57 | --ion-color-dark-contrast: #ffffff;
58 | --ion-color-dark-contrast-rgb: 255, 255, 255;
59 | --ion-color-dark-shade: #1e2023;
60 | --ion-color-dark-tint: #383a3e;
61 |
62 | /** medium **/
63 | --ion-color-medium: #92949c;
64 | --ion-color-medium-rgb: 146, 148, 156;
65 | --ion-color-medium-contrast: #ffffff;
66 | --ion-color-medium-contrast-rgb: 255, 255, 255;
67 | --ion-color-medium-shade: #808289;
68 | --ion-color-medium-tint: #9d9fa6;
69 |
70 | /** light **/
71 | --ion-color-light: #f4f5f8;
72 | --ion-color-light-rgb: 244, 245, 248;
73 | --ion-color-light-contrast: #000000;
74 | --ion-color-light-contrast-rgb: 0, 0, 0;
75 | --ion-color-light-shade: #d7d8da;
76 | --ion-color-light-tint: #f5f6f9;
77 | }
78 |
79 | @media (prefers-color-scheme: dark) {
80 | /*
81 | * Dark Colors
82 | * -------------------------------------------
83 | */
84 |
85 | body {
86 | --ion-color-primary: #428cff;
87 | --ion-color-primary-rgb: 66,140,255;
88 | --ion-color-primary-contrast: #ffffff;
89 | --ion-color-primary-contrast-rgb: 255,255,255;
90 | --ion-color-primary-shade: #3a7be0;
91 | --ion-color-primary-tint: #5598ff;
92 |
93 | --ion-color-secondary: #50c8ff;
94 | --ion-color-secondary-rgb: 80,200,255;
95 | --ion-color-secondary-contrast: #ffffff;
96 | --ion-color-secondary-contrast-rgb: 255,255,255;
97 | --ion-color-secondary-shade: #46b0e0;
98 | --ion-color-secondary-tint: #62ceff;
99 |
100 | --ion-color-tertiary: #6a64ff;
101 | --ion-color-tertiary-rgb: 106,100,255;
102 | --ion-color-tertiary-contrast: #ffffff;
103 | --ion-color-tertiary-contrast-rgb: 255,255,255;
104 | --ion-color-tertiary-shade: #5d58e0;
105 | --ion-color-tertiary-tint: #7974ff;
106 |
107 | --ion-color-success: #2fdf75;
108 | --ion-color-success-rgb: 47,223,117;
109 | --ion-color-success-contrast: #000000;
110 | --ion-color-success-contrast-rgb: 0,0,0;
111 | --ion-color-success-shade: #29c467;
112 | --ion-color-success-tint: #44e283;
113 |
114 | --ion-color-warning: #ffd534;
115 | --ion-color-warning-rgb: 255,213,52;
116 | --ion-color-warning-contrast: #000000;
117 | --ion-color-warning-contrast-rgb: 0,0,0;
118 | --ion-color-warning-shade: #e0bb2e;
119 | --ion-color-warning-tint: #ffd948;
120 |
121 | --ion-color-danger: #ff4961;
122 | --ion-color-danger-rgb: 255,73,97;
123 | --ion-color-danger-contrast: #ffffff;
124 | --ion-color-danger-contrast-rgb: 255,255,255;
125 | --ion-color-danger-shade: #e04055;
126 | --ion-color-danger-tint: #ff5b71;
127 |
128 | --ion-color-dark: #f4f5f8;
129 | --ion-color-dark-rgb: 244,245,248;
130 | --ion-color-dark-contrast: #000000;
131 | --ion-color-dark-contrast-rgb: 0,0,0;
132 | --ion-color-dark-shade: #d7d8da;
133 | --ion-color-dark-tint: #f5f6f9;
134 |
135 | --ion-color-medium: #989aa2;
136 | --ion-color-medium-rgb: 152,154,162;
137 | --ion-color-medium-contrast: #000000;
138 | --ion-color-medium-contrast-rgb: 0,0,0;
139 | --ion-color-medium-shade: #86888f;
140 | --ion-color-medium-tint: #a2a4ab;
141 |
142 | --ion-color-light: #222428;
143 | --ion-color-light-rgb: 34,36,40;
144 | --ion-color-light-contrast: #ffffff;
145 | --ion-color-light-contrast-rgb: 255,255,255;
146 | --ion-color-light-shade: #1e2023;
147 | --ion-color-light-tint: #383a3e;
148 | }
149 |
150 | /*
151 | * iOS Dark Theme
152 | * -------------------------------------------
153 | */
154 |
155 | .ios body {
156 | --ion-background-color: #000000;
157 | --ion-background-color-rgb: 0,0,0;
158 |
159 | --ion-text-color: #ffffff;
160 | --ion-text-color-rgb: 255,255,255;
161 |
162 | --ion-color-step-50: #0d0d0d;
163 | --ion-color-step-100: #1a1a1a;
164 | --ion-color-step-150: #262626;
165 | --ion-color-step-200: #333333;
166 | --ion-color-step-250: #404040;
167 | --ion-color-step-300: #4d4d4d;
168 | --ion-color-step-350: #595959;
169 | --ion-color-step-400: #666666;
170 | --ion-color-step-450: #737373;
171 | --ion-color-step-500: #808080;
172 | --ion-color-step-550: #8c8c8c;
173 | --ion-color-step-600: #999999;
174 | --ion-color-step-650: #a6a6a6;
175 | --ion-color-step-700: #b3b3b3;
176 | --ion-color-step-750: #bfbfbf;
177 | --ion-color-step-800: #cccccc;
178 | --ion-color-step-850: #d9d9d9;
179 | --ion-color-step-900: #e6e6e6;
180 | --ion-color-step-950: #f2f2f2;
181 |
182 | --ion-toolbar-background: #0d0d0d;
183 |
184 | --ion-item-background: #000000;
185 | }
186 |
187 |
188 | /*
189 | * Material Design Dark Theme
190 | * -------------------------------------------
191 | */
192 |
193 | .md body {
194 | --ion-background-color: #121212;
195 | --ion-background-color-rgb: 18,18,18;
196 |
197 | --ion-text-color: #ffffff;
198 | --ion-text-color-rgb: 255,255,255;
199 |
200 | --ion-border-color: #222222;
201 |
202 | --ion-color-step-50: #1e1e1e;
203 | --ion-color-step-100: #2a2a2a;
204 | --ion-color-step-150: #363636;
205 | --ion-color-step-200: #414141;
206 | --ion-color-step-250: #4d4d4d;
207 | --ion-color-step-300: #595959;
208 | --ion-color-step-350: #656565;
209 | --ion-color-step-400: #717171;
210 | --ion-color-step-450: #7d7d7d;
211 | --ion-color-step-500: #898989;
212 | --ion-color-step-550: #949494;
213 | --ion-color-step-600: #a0a0a0;
214 | --ion-color-step-650: #acacac;
215 | --ion-color-step-700: #b8b8b8;
216 | --ion-color-step-750: #c4c4c4;
217 | --ion-color-step-800: #d0d0d0;
218 | --ion-color-step-850: #dbdbdb;
219 | --ion-color-step-900: #e7e7e7;
220 | --ion-color-step-950: #f3f3f3;
221 |
222 | --ion-item-background: #1e1e1e;
223 |
224 | --ion-toolbar-background: #1f1f1f;
225 |
226 | --ion-tab-bar-background: #1f1f1f;
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/ionic/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "noEmit": true,
20 | "jsx": "react"
21 | },
22 | "include": [
23 | "src"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/material-ui/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # capacitor
4 | android/
5 | ios/
6 |
7 | # dependencies
8 | /node_modules
9 | /.pnp
10 | .pnp.js
11 |
12 | # testing
13 | /coverage
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | .env.local
21 | .env.development.local
22 | .env.test.local
23 | .env.production.local
24 |
25 | npm-debug.log*
26 | yarn-debug.log*
27 | yarn-error.log*
28 |
--------------------------------------------------------------------------------
/material-ui/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
2 |
3 | ## Available Scripts
4 |
5 | In the project directory, you can run:
6 |
7 | ### `yarn start`
8 |
9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
11 |
12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console.
14 |
15 | ### `yarn test`
16 |
17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
19 |
20 | ### `yarn build`
21 |
22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance.
24 |
25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed!
27 |
28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
29 |
30 | ### `yarn eject`
31 |
32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
33 |
34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
35 |
36 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
37 |
38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
39 |
40 | ## Learn More
41 |
42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
43 |
44 | To learn React, check out the [React documentation](https://reactjs.org/).
45 |
46 | ### Code Splitting
47 |
48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
49 |
50 | ### Analyzing the Bundle Size
51 |
52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
53 |
54 | ### Making a Progressive Web App
55 |
56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
57 |
58 | ### Advanced Configuration
59 |
60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
61 |
62 | ### Deployment
63 |
64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
65 |
66 | ### `yarn build` fails to minify
67 |
68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
69 |
--------------------------------------------------------------------------------
/material-ui/capacitor.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "appId": "com.capacitorjs.examples.materialui",
3 | "appName": "cap-materialui",
4 | "bundledWebRuntime": false,
5 | "npmClient": "yarn",
6 | "webDir": "build",
7 | "plugins": {
8 | "SplashScreen": {
9 | "launchShowDuration": 0
10 | }
11 | },
12 | "cordova": {}
13 | }
14 |
--------------------------------------------------------------------------------
/material-ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "material-ui",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@capacitor/cli": "^2.1.2",
7 | "@capacitor/core": "^2.1.2",
8 | "@ionic/pwa-elements": "^2.0.2",
9 | "@material-ui/core": "^4.10.1",
10 | "@material-ui/icons": "^4.9.1",
11 | "@testing-library/jest-dom": "^4.2.4",
12 | "@testing-library/react": "^9.3.2",
13 | "@testing-library/user-event": "^7.1.2",
14 | "react": "^16.13.1",
15 | "react-dom": "^16.13.1",
16 | "react-scripts": "3.4.1"
17 | },
18 | "scripts": {
19 | "start": "react-scripts start",
20 | "build": "react-scripts build",
21 | "test": "react-scripts test",
22 | "eject": "react-scripts eject"
23 | },
24 | "eslintConfig": {
25 | "extends": "react-app"
26 | },
27 | "browserslist": {
28 | "production": [
29 | ">0.2%",
30 | "not dead",
31 | "not op_mini all"
32 | ],
33 | "development": [
34 | "last 1 chrome version",
35 | "last 1 firefox version",
36 | "last 1 safari version"
37 | ]
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/material-ui/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/capacitor-community/examples/6e703917d3343661bedbea54047faef364a11a18/material-ui/public/favicon.ico
--------------------------------------------------------------------------------
/material-ui/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
18 |
19 |
28 | React App
29 |
30 |
31 |
32 |
33 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/material-ui/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/capacitor-community/examples/6e703917d3343661bedbea54047faef364a11a18/material-ui/public/logo192.png
--------------------------------------------------------------------------------
/material-ui/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/capacitor-community/examples/6e703917d3343661bedbea54047faef364a11a18/material-ui/public/logo512.png
--------------------------------------------------------------------------------
/material-ui/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/material-ui/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/material-ui/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/material-ui/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useCallback, useState, useEffect } from 'react';
2 | import './App.css';
3 |
4 | import { createMuiTheme, makeStyles, ThemeProvider } from '@material-ui/core/styles';
5 | import { deepOrange } from '@material-ui/core/colors';
6 |
7 | import AppBar from '@material-ui/core/AppBar';
8 | import Box from '@material-ui/core/Box';
9 | import Toolbar from '@material-ui/core/Toolbar';
10 | import Typography from '@material-ui/core/Typography';
11 | import Button from '@material-ui/core/Button';
12 | import IconButton from '@material-ui/core/IconButton';
13 | import Table from '@material-ui/core/Table';
14 | import TableBody from '@material-ui/core/TableBody';
15 | import TableCell from '@material-ui/core/TableCell';
16 | import TableContainer from '@material-ui/core/TableContainer';
17 | import TableHead from '@material-ui/core/TableHead';
18 | import TableRow from '@material-ui/core/TableRow';
19 | import Paper from '@material-ui/core/Paper';
20 |
21 | import MenuIcon from '@material-ui/icons/Menu';
22 | import ShareIcon from '@material-ui/icons/Share';
23 | import CameraAltIcon from '@material-ui/icons/CameraAlt';
24 |
25 | import { Plugins } from '@capacitor/core';
26 |
27 | const theme = createMuiTheme({
28 | palette: {
29 | primary: deepOrange,
30 | },
31 | });
32 | const useStyles = makeStyles((theme) => ({
33 | root: {
34 | flexGrow: 1,
35 | },
36 | menuButton: {
37 | marginRight: theme.spacing(2),
38 | },
39 | title: {
40 | flexGrow: 1,
41 | },
42 | tableDiv: {
43 | margin: 20
44 | },
45 | button: {
46 | margin: 10
47 | }
48 | }));
49 |
50 | function App() {
51 | const classes = useStyles();
52 |
53 | const [photo, setPhoto] = useState(null);
54 |
55 | const takePhoto = useCallback(async () => {
56 | const { Camera } = Plugins;
57 |
58 | const photo = await Camera.getPhoto({
59 | resultType: 'Base64'
60 | });
61 |
62 | console.log('Got photo', photo);
63 |
64 | setPhoto(photo);
65 | }, []);
66 |
67 | const shareCapacitor = async () => {
68 | const { Share } = Plugins;
69 |
70 | await Share.share({
71 | title: 'Share Capacitor',
72 | text: 'I deployed a Material-UI web app as a native mobile app using @capacitorjs in minutes! \r\n\r\nTry it yourself here:',
73 | url: 'https://capacitorjs.com',
74 | });
75 | }
76 |
77 | const [deviceInfo, setDeviceInfo] = useState(null);
78 |
79 | useEffect(() => {
80 | const getDeviceInfo = async () => {
81 | const { Device } = Plugins;
82 |
83 | setDeviceInfo(await Device.getInfo());
84 | };
85 |
86 | getDeviceInfo();
87 | }, []);
88 |
89 | return (
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | Capacitor Material-UI Demo
98 |
99 |
100 |
101 |
102 |
103 | } variant="contained" color="secondary">Take Photo
104 |
105 | } variant="contained" color="primary" >Share this app
106 |
107 |
108 |
109 | {photo &&
}
110 |
111 |
112 |
113 |
Device Info:
114 | {deviceInfo ? (
115 |
116 |
117 |
118 |
119 | Name
120 | Value
121 |
122 |
123 |
124 | {Object.keys(deviceInfo).map((key) => (
125 |
126 |
127 | {key}
128 |
129 | {deviceInfo[key].toString() || 'Not available'}
130 |
131 | ))}
132 |
133 |
134 |
135 | ) : null }
136 |
137 |
138 |
139 | );
140 | }
141 |
142 | export default App;
143 |
--------------------------------------------------------------------------------
/material-ui/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/material-ui/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/material-ui/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 | import { defineCustomElements } from '@ionic/pwa-elements/loader';
7 |
8 | ReactDOM.render(
9 |
10 |
11 | ,
12 | document.getElementById('root')
13 | );
14 |
15 | defineCustomElements(window);
16 |
17 | // If you want your app to work offline and load faster, you can change
18 | // unregister() to register() below. Note this comes with some pitfalls.
19 | // Learn more about service workers: https://bit.ly/CRA-PWA
20 | serviceWorker.unregister();
21 |
--------------------------------------------------------------------------------
/material-ui/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/material-ui/src/serviceWorker.js:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.0/8 are considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | export function register(config) {
24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
25 | // The URL constructor is available in all browsers that support SW.
26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
27 | if (publicUrl.origin !== window.location.origin) {
28 | // Our service worker won't work if PUBLIC_URL is on a different origin
29 | // from what our page is served on. This might happen if a CDN is used to
30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
31 | return;
32 | }
33 |
34 | window.addEventListener('load', () => {
35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
36 |
37 | if (isLocalhost) {
38 | // This is running on localhost. Let's check if a service worker still exists or not.
39 | checkValidServiceWorker(swUrl, config);
40 |
41 | // Add some additional logging to localhost, pointing developers to the
42 | // service worker/PWA documentation.
43 | navigator.serviceWorker.ready.then(() => {
44 | console.log(
45 | 'This web app is being served cache-first by a service ' +
46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
47 | );
48 | });
49 | } else {
50 | // Is not localhost. Just register service worker
51 | registerValidSW(swUrl, config);
52 | }
53 | });
54 | }
55 | }
56 |
57 | function registerValidSW(swUrl, config) {
58 | navigator.serviceWorker
59 | .register(swUrl)
60 | .then(registration => {
61 | registration.onupdatefound = () => {
62 | const installingWorker = registration.installing;
63 | if (installingWorker == null) {
64 | return;
65 | }
66 | installingWorker.onstatechange = () => {
67 | if (installingWorker.state === 'installed') {
68 | if (navigator.serviceWorker.controller) {
69 | // At this point, the updated precached content has been fetched,
70 | // but the previous service worker will still serve the older
71 | // content until all client tabs are closed.
72 | console.log(
73 | 'New content is available and will be used when all ' +
74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
75 | );
76 |
77 | // Execute callback
78 | if (config && config.onUpdate) {
79 | config.onUpdate(registration);
80 | }
81 | } else {
82 | // At this point, everything has been precached.
83 | // It's the perfect time to display a
84 | // "Content is cached for offline use." message.
85 | console.log('Content is cached for offline use.');
86 |
87 | // Execute callback
88 | if (config && config.onSuccess) {
89 | config.onSuccess(registration);
90 | }
91 | }
92 | }
93 | };
94 | };
95 | })
96 | .catch(error => {
97 | console.error('Error during service worker registration:', error);
98 | });
99 | }
100 |
101 | function checkValidServiceWorker(swUrl, config) {
102 | // Check if the service worker can be found. If it can't reload the page.
103 | fetch(swUrl, {
104 | headers: { 'Service-Worker': 'script' },
105 | })
106 | .then(response => {
107 | // Ensure service worker exists, and that we really are getting a JS file.
108 | const contentType = response.headers.get('content-type');
109 | if (
110 | response.status === 404 ||
111 | (contentType != null && contentType.indexOf('javascript') === -1)
112 | ) {
113 | // No service worker found. Probably a different app. Reload the page.
114 | navigator.serviceWorker.ready.then(registration => {
115 | registration.unregister().then(() => {
116 | window.location.reload();
117 | });
118 | });
119 | } else {
120 | // Service worker found. Proceed as normal.
121 | registerValidSW(swUrl, config);
122 | }
123 | })
124 | .catch(() => {
125 | console.log(
126 | 'No internet connection found. App is running in offline mode.'
127 | );
128 | });
129 | }
130 |
131 | export function unregister() {
132 | if ('serviceWorker' in navigator) {
133 | navigator.serviceWorker.ready
134 | .then(registration => {
135 | registration.unregister();
136 | })
137 | .catch(error => {
138 | console.error(error.message);
139 | });
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/material-ui/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/preact/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | build
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | .DS_Store
61 |
62 | # lock files
63 | yarn.lock
64 | package-lock.json
65 |
--------------------------------------------------------------------------------
/preact/README.md:
--------------------------------------------------------------------------------
1 | # Preact + Material UI + Capacitor
2 |
3 | An example app using [Preact](https://preactjs.com) and [Capacitor](https://capacitorjs.com) for building high quality PWAs and native iOS/Android app. This brings together the ease of building apps with Preact with the ease of making native apps from Capacitor. For more information on both Preact and Capacitor, please see their docs.
4 |
5 | - [Preact](https://preactjs.com)
6 | - [Capacitor](https://capacitorjs.com)
7 |
8 |
9 | ## Install Capacitor
10 |
11 | If you have an existing Preact app, you can install Capacitor with the following command
12 |
13 | ```bash
14 | npm install @capacitor/core @capacitor/cli
15 | npx cap init [name] [id] --webDir=build
16 | ```
17 |
18 | ## Build the Web App
19 |
20 | Build a production version of your app to be deployed to the native platform
21 |
22 | ```bash
23 | npm run build
24 | ```
25 |
26 | ## Install the native platforms you want to target
27 |
28 | ```
29 | npx cap add android
30 | npx cap add ios
31 | ```
32 |
33 | ## Call native functionality
34 |
35 | ``` javascript
36 | import { h } from 'preact';
37 | import { useState } from 'preact/hooks';
38 |
39 | import { Plugins } from '@capacitor/core';
40 |
41 | export default function GeolocationPage() {
42 |
43 | const [loc, setLoc] = useState(null);
44 |
45 | const getCurrentPosition = async () => {
46 | const { Geolocation } = Plugins;
47 | const coordinates = await Geolocation.getCurrentPosition();
48 | setLoc(coordinates);
49 | };
50 |
51 | return (
52 |
53 |
Geolocation
54 |
Your location is:
55 |
Latitude: {loc?.coords.latitude}
56 |
Longitude: {loc?.coords.longitude}
57 |
58 |
61 |
62 | );
63 | }
64 | ```
65 |
66 | For more examples of Capacitor APIs, check out the [Capacitor Docs](https://capacitorjs.com/docs) and the [Plugin API docs](https://capacitorjs.com/docs/apis)
67 |
--------------------------------------------------------------------------------
/preact/capacitor.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "appId": "com.example.app",
3 | "appName": "preact-example",
4 | "bundledWebRuntime": false,
5 | "npmClient": "npm",
6 | "webDir": "build",
7 | "plugins": {
8 | "SplashScreen": {
9 | "launchShowDuration": 0
10 | }
11 | },
12 | "cordova": {}
13 | }
14 |
--------------------------------------------------------------------------------
/preact/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "preact-example",
4 | "version": "0.0.0",
5 | "license": "MIT",
6 | "scripts": {
7 | "build": "preact build --template public/index.html --no-prerender",
8 | "serve": "preact serve",
9 | "dev": "preact watch"
10 | },
11 | "devDependencies": {
12 | "preact-cli": "^3.0.0-rc.18"
13 | },
14 | "dependencies": {
15 | "@capacitor/cli": "^2.2.1",
16 | "@capacitor/core": "^2.2.1",
17 | "@capacitor/ios": "^2.2.1",
18 | "@ionic/pwa-elements": "^3.0.0",
19 | "preact": "^10.4.6",
20 | "preact-compat": "^3.19.0",
21 | "preact-material-components": "^1.6.1",
22 | "preact-render-to-string": "^5.1.10",
23 | "preact-router": "^3.2.1"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/preact/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <% preact.title %>
6 |
10 |
11 |
12 |
13 | <% preact.headEnd %>
14 |
15 |
16 | <% preact.bodyEnd %>
17 |
18 |
19 |