chore: move to biome

This commit is contained in:
2026-01-09 16:42:55 -08:00
parent 2544a7d606
commit 4c7cfe4136
25 changed files with 2146 additions and 11818 deletions

View File

@@ -1,5 +1,3 @@
{ {
"recommendations": [ "recommendations": ["Webnative.webnative"]
"Webnative.webnative"
]
} }

34
biome.json Normal file
View File

@@ -0,0 +1,34 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.11/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": false
},
"formatter": {
"enabled": true,
"indentStyle": "tab"
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}

1788
bun.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
import type { CapacitorConfig } from '@capacitor/cli'; import type { CapacitorConfig } from "@capacitor/cli";
const config: CapacitorConfig = { const config: CapacitorConfig = {
appId: 'io.ionic.starter', appId: "io.ionic.starter",
appName: 'mobile', appName: "mobile",
webDir: 'dist' webDir: "dist",
}; };
export default config; export default config;

View File

@@ -1,10 +1,10 @@
import { defineConfig } from "cypress"; import { defineConfig } from "cypress";
export default defineConfig({ export default defineConfig({
e2e: { e2e: {
baseUrl: "http://localhost:5173", baseUrl: "http://localhost:5173",
setupNodeEvents(on, config) { setupNodeEvents(on, config) {
// implement node event listeners here // implement node event listeners here
}, },
}, },
}); });

View File

@@ -1,6 +1,6 @@
describe('My First Test', () => { describe("My First Test", () => {
it('Visits the app root url', () => { it("Visits the app root url", () => {
cy.visit('/') cy.visit("/");
cy.contains('ion-content', 'Tab 1 page') cy.contains("ion-content", "Tab 1 page");
}) });
}) });

View File

@@ -1,5 +1,5 @@
{ {
"name": "Using fixtures to represent data", "name": "Using fixtures to represent data",
"email": "hello@cypress.io", "email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes" "body": "Fixtures are a great way to mock data for responses to routes"
} }

View File

@@ -34,4 +34,4 @@
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element> // visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// } // }
// } // }
// } // }

View File

@@ -14,7 +14,7 @@
// *********************************************************** // ***********************************************************
// Import commands.js using ES2015 syntax: // Import commands.js using ES2015 syntax:
import './commands' import "./commands";
// Alternatively you can use CommonJS syntax: // Alternatively you can use CommonJS syntax:
// require('./commands') // require('./commands')

View File

@@ -1,7 +1,7 @@
{ {
"name": "mobile", "name": "mobile",
"integrations": { "integrations": {
"capacitor": {} "capacitor": {}
}, },
"type": "react-vite" "type": "react-vite"
} }

11512
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,54 +1,50 @@
{ {
"name": "mobile", "name": "mobile",
"private": true, "private": true,
"version": "0.0.1", "version": "0.0.1",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "tsc && vite build", "build": "tsc && vite build",
"preview": "vite preview", "preview": "vite preview",
"test.e2e": "cypress run", "test.e2e": "cypress run",
"test.unit": "vitest", "test.unit": "vitest",
"lint": "eslint" "lint": "biome check --write"
}, },
"dependencies": { "dependencies": {
"@capacitor/app": "8.0.0", "@capacitor/app": "8.0.0",
"@capacitor/core": "8.0.0", "@capacitor/core": "8.0.0",
"@capacitor/haptics": "8.0.0", "@capacitor/haptics": "8.0.0",
"@capacitor/keyboard": "8.0.0", "@capacitor/keyboard": "8.0.0",
"@capacitor/status-bar": "8.0.0", "@capacitor/status-bar": "8.0.0",
"@ionic/react": "^8.5.0", "@ionic/react": "^8.5.0",
"@ionic/react-router": "^8.5.0", "@ionic/react-router": "^8.5.0",
"@types/react-router": "^5.1.20", "@types/react-router": "^5.1.20",
"@types/react-router-dom": "^5.3.3", "@types/react-router-dom": "^5.3.3",
"ionicons": "^7.4.0", "ionicons": "^7.4.0",
"react": "19.0.0", "react": "19.0.0",
"react-dom": "19.0.0", "react-dom": "19.0.0",
"react-router": "^5.3.4", "react-router": "^5.3.4",
"react-router-dom": "^5.3.4" "react-router-dom": "^5.3.4"
}, },
"devDependencies": { "devDependencies": {
"@capacitor/cli": "8.0.0", "@biomejs/biome": "2.3.11",
"@testing-library/dom": ">=7.21.4", "@capacitor/cli": "8.0.0",
"@testing-library/jest-dom": "^5.16.5", "@testing-library/dom": ">=7.21.4",
"@testing-library/react": "^16.2.0", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/user-event": "^14.4.3", "@testing-library/react": "^16.2.0",
"@types/react": "19.0.10", "@testing-library/user-event": "^14.4.3",
"@types/react-dom": "19.0.4", "@types/react": "19.0.10",
"@vitejs/plugin-legacy": "^5.0.0", "@types/react-dom": "19.0.4",
"@vitejs/plugin-react": "^4.0.1", "@vitejs/plugin-legacy": "^5.0.0",
"cypress": "^13.5.0", "@vitejs/plugin-react": "^4.0.1",
"eslint": "^9.20.1", "cypress": "^13.5.0",
"eslint-plugin-react": "^7.32.2", "globals": "^15.15.0",
"eslint-plugin-react-hooks": "^5.1.0", "jsdom": "^22.1.0",
"eslint-plugin-react-refresh": "^0.4.19", "terser": "^5.4.0",
"globals": "^15.15.0", "typescript": "~5.9.0",
"jsdom": "^22.1.0", "vite": "^5.0.0",
"terser": "^5.4.0", "vitest": "^0.34.6"
"typescript": "~5.9.0", },
"typescript-eslint": "^8.24.0", "description": "An Ionic project"
"vite": "^5.0.0",
"vitest": "^0.34.6"
},
"description": "An Ionic project"
} }

View File

@@ -1,21 +1,21 @@
{ {
"short_name": "Ionic App", "short_name": "Ionic App",
"name": "My Ionic App", "name": "My Ionic App",
"icons": [ "icons": [
{ {
"src": "assets/icon/favicon.png", "src": "assets/icon/favicon.png",
"sizes": "64x64 32x32 24x24 16x16", "sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon" "type": "image/x-icon"
}, },
{ {
"src": "assets/icon/icon.png", "src": "assets/icon/icon.png",
"type": "image/png", "type": "image/png",
"sizes": "512x512", "sizes": "512x512",
"purpose": "maskable" "purpose": "maskable"
} }
], ],
"start_url": ".", "start_url": ".",
"display": "standalone", "display": "standalone",
"theme_color": "#ffffff", "theme_color": "#ffffff",
"background_color": "#ffffff" "background_color": "#ffffff"
} }

View File

@@ -1,8 +1,8 @@
import React from 'react'; import { render } from "@testing-library/react";
import { render } from '@testing-library/react'; import React from "react";
import App from './App'; import App from "./App";
test('renders without crashing', () => { test("renders without crashing", () => {
const { baseElement } = render(<App />); const { baseElement } = render(<App />);
expect(baseElement).toBeDefined(); expect(baseElement).toBeDefined();
}); });

View File

@@ -1,35 +1,35 @@
import { Redirect, Route } from 'react-router-dom';
import { import {
IonApp, IonApp,
IonIcon, IonIcon,
IonLabel, IonLabel,
IonRouterOutlet, IonRouterOutlet,
IonTabBar, IonTabBar,
IonTabButton, IonTabButton,
IonTabs, IonTabs,
setupIonicReact setupIonicReact,
} from '@ionic/react'; } from "@ionic/react";
import { IonReactRouter } from '@ionic/react-router'; import { IonReactRouter } from "@ionic/react-router";
import { ellipse, square, triangle } from 'ionicons/icons'; import { ellipse, square, triangle } from "ionicons/icons";
import Tab1 from './pages/Tab1'; import { Redirect, Route } from "react-router-dom";
import Tab2 from './pages/Tab2'; import Tab1 from "./pages/Tab1";
import Tab3 from './pages/Tab3'; import Tab2 from "./pages/Tab2";
import Tab3 from "./pages/Tab3";
/* Core CSS required for Ionic components to work properly */ /* Core CSS required for Ionic components to work properly */
import '@ionic/react/css/core.css'; import "@ionic/react/css/core.css";
/* Basic CSS for apps built with Ionic */ /* Basic CSS for apps built with Ionic */
import '@ionic/react/css/normalize.css'; import "@ionic/react/css/normalize.css";
import '@ionic/react/css/structure.css'; import "@ionic/react/css/structure.css";
import '@ionic/react/css/typography.css'; import "@ionic/react/css/typography.css";
/* Optional CSS utils that can be commented out */ /* Optional CSS utils that can be commented out */
import '@ionic/react/css/padding.css'; import "@ionic/react/css/padding.css";
import '@ionic/react/css/float-elements.css'; import "@ionic/react/css/float-elements.css";
import '@ionic/react/css/text-alignment.css'; import "@ionic/react/css/text-alignment.css";
import '@ionic/react/css/text-transformation.css'; import "@ionic/react/css/text-transformation.css";
import '@ionic/react/css/flex-utils.css'; import "@ionic/react/css/flex-utils.css";
import '@ionic/react/css/display.css'; import "@ionic/react/css/display.css";
/** /**
* Ionic Dark Mode * Ionic Dark Mode
@@ -40,48 +40,48 @@ import '@ionic/react/css/display.css';
/* import '@ionic/react/css/palettes/dark.always.css'; */ /* import '@ionic/react/css/palettes/dark.always.css'; */
/* import '@ionic/react/css/palettes/dark.class.css'; */ /* import '@ionic/react/css/palettes/dark.class.css'; */
import '@ionic/react/css/palettes/dark.system.css'; import "@ionic/react/css/palettes/dark.system.css";
/* Theme variables */ /* Theme variables */
import './theme/variables.css'; import "./theme/variables.css";
setupIonicReact(); setupIonicReact();
const App: React.FC = () => ( const App: React.FC = () => (
<IonApp> <IonApp>
<IonReactRouter> <IonReactRouter>
<IonTabs> <IonTabs>
<IonRouterOutlet> <IonRouterOutlet>
<Route exact path="/tab1"> <Route exact path="/tab1">
<Tab1 /> <Tab1 />
</Route> </Route>
<Route exact path="/tab2"> <Route exact path="/tab2">
<Tab2 /> <Tab2 />
</Route> </Route>
<Route path="/tab3"> <Route path="/tab3">
<Tab3 /> <Tab3 />
</Route> </Route>
<Route exact path="/"> <Route exact path="/">
<Redirect to="/tab1" /> <Redirect to="/tab1" />
</Route> </Route>
</IonRouterOutlet> </IonRouterOutlet>
<IonTabBar slot="bottom"> <IonTabBar slot="bottom">
<IonTabButton tab="tab1" href="/tab1"> <IonTabButton tab="tab1" href="/tab1">
<IonIcon aria-hidden="true" icon={triangle} /> <IonIcon aria-hidden="true" icon={triangle} />
<IonLabel>Tab 1</IonLabel> <IonLabel>Tab 1</IonLabel>
</IonTabButton> </IonTabButton>
<IonTabButton tab="tab2" href="/tab2"> <IonTabButton tab="tab2" href="/tab2">
<IonIcon aria-hidden="true" icon={ellipse} /> <IonIcon aria-hidden="true" icon={ellipse} />
<IonLabel>Tab 2</IonLabel> <IonLabel>Tab 2</IonLabel>
</IonTabButton> </IonTabButton>
<IonTabButton tab="tab3" href="/tab3"> <IonTabButton tab="tab3" href="/tab3">
<IonIcon aria-hidden="true" icon={square} /> <IonIcon aria-hidden="true" icon={square} />
<IonLabel>Tab 3</IonLabel> <IonLabel>Tab 3</IonLabel>
</IonTabButton> </IonTabButton>
</IonTabBar> </IonTabBar>
</IonTabs> </IonTabs>
</IonReactRouter> </IonReactRouter>
</IonApp> </IonApp>
); );
export default App; export default App;

View File

@@ -1,24 +1,24 @@
.container { .container {
text-align: center; text-align: center;
position: absolute; position: absolute;
left: 0; left: 0;
right: 0; right: 0;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
} }
.container strong { .container strong {
font-size: 20px; font-size: 20px;
line-height: 26px; line-height: 26px;
} }
.container p { .container p {
font-size: 16px; font-size: 16px;
line-height: 22px; line-height: 22px;
color: #8c8c8c; color: #8c8c8c;
margin: 0; margin: 0;
} }
.container a { .container a {
text-decoration: none; text-decoration: none;
} }

View File

@@ -1,16 +1,25 @@
import './ExploreContainer.css'; import "./ExploreContainer.css";
interface ContainerProps { interface ContainerProps {
name: string; name: string;
} }
const ExploreContainer: React.FC<ContainerProps> = ({ name }) => { const ExploreContainer: React.FC<ContainerProps> = ({ name }) => {
return ( return (
<div className="container"> <div className="container">
<strong>{name}</strong> <strong>{name}</strong>
<p>Explore <a target="_blank" rel="noopener noreferrer" href="https://ionicframework.com/docs/components">UI Components</a></p> <p>
</div> Explore{" "}
); <a
target="_blank"
rel="noopener noreferrer"
href="https://ionicframework.com/docs/components"
>
UI Components
</a>
</p>
</div>
);
}; };
export default ExploreContainer; export default ExploreContainer;

View File

@@ -1,11 +1,11 @@
import React from 'react'; import React from "react";
import { createRoot } from 'react-dom/client'; import { createRoot } from "react-dom/client";
import App from './App'; import App from "./App";
const container = document.getElementById('root'); const container = document.getElementById("root");
const root = createRoot(container!); const root = createRoot(container!);
root.render( root.render(
<React.StrictMode> <React.StrictMode>
<App /> <App />
</React.StrictMode> </React.StrictMode>,
); );

View File

@@ -1,25 +1,31 @@
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react'; import {
import ExploreContainer from '../components/ExploreContainer'; IonContent,
import './Tab1.css'; IonHeader,
IonPage,
IonTitle,
IonToolbar,
} from "@ionic/react";
import ExploreContainer from "../components/ExploreContainer";
import "./Tab1.css";
const Tab1: React.FC = () => { const Tab1: React.FC = () => {
return ( return (
<IonPage> <IonPage>
<IonHeader> <IonHeader>
<IonToolbar> <IonToolbar>
<IonTitle>Tab 1</IonTitle> <IonTitle>Tab 1</IonTitle>
</IonToolbar> </IonToolbar>
</IonHeader> </IonHeader>
<IonContent fullscreen> <IonContent fullscreen>
<IonHeader collapse="condense"> <IonHeader collapse="condense">
<IonToolbar> <IonToolbar>
<IonTitle size="large">Tab 1</IonTitle> <IonTitle size="large">Tab 1</IonTitle>
</IonToolbar> </IonToolbar>
</IonHeader> </IonHeader>
<ExploreContainer name="Tab 1 page" /> <ExploreContainer name="Tab 1 page" />
</IonContent> </IonContent>
</IonPage> </IonPage>
); );
}; };
export default Tab1; export default Tab1;

View File

@@ -1,25 +1,31 @@
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react'; import {
import ExploreContainer from '../components/ExploreContainer'; IonContent,
import './Tab2.css'; IonHeader,
IonPage,
IonTitle,
IonToolbar,
} from "@ionic/react";
import ExploreContainer from "../components/ExploreContainer";
import "./Tab2.css";
const Tab2: React.FC = () => { const Tab2: React.FC = () => {
return ( return (
<IonPage> <IonPage>
<IonHeader> <IonHeader>
<IonToolbar> <IonToolbar>
<IonTitle>Tab 2</IonTitle> <IonTitle>Tab 2</IonTitle>
</IonToolbar> </IonToolbar>
</IonHeader> </IonHeader>
<IonContent fullscreen> <IonContent fullscreen>
<IonHeader collapse="condense"> <IonHeader collapse="condense">
<IonToolbar> <IonToolbar>
<IonTitle size="large">Tab 2</IonTitle> <IonTitle size="large">Tab 2</IonTitle>
</IonToolbar> </IonToolbar>
</IonHeader> </IonHeader>
<ExploreContainer name="Tab 2 page" /> <ExploreContainer name="Tab 2 page" />
</IonContent> </IonContent>
</IonPage> </IonPage>
); );
}; };
export default Tab2; export default Tab2;

View File

@@ -1,25 +1,31 @@
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react'; import {
import ExploreContainer from '../components/ExploreContainer'; IonContent,
import './Tab3.css'; IonHeader,
IonPage,
IonTitle,
IonToolbar,
} from "@ionic/react";
import ExploreContainer from "../components/ExploreContainer";
import "./Tab3.css";
const Tab3: React.FC = () => { const Tab3: React.FC = () => {
return ( return (
<IonPage> <IonPage>
<IonHeader> <IonHeader>
<IonToolbar> <IonToolbar>
<IonTitle>Tab 3</IonTitle> <IonTitle>Tab 3</IonTitle>
</IonToolbar> </IonToolbar>
</IonHeader> </IonHeader>
<IonContent fullscreen> <IonContent fullscreen>
<IonHeader collapse="condense"> <IonHeader collapse="condense">
<IonToolbar> <IonToolbar>
<IonTitle size="large">Tab 3</IonTitle> <IonTitle size="large">Tab 3</IonTitle>
</IonToolbar> </IonToolbar>
</IonHeader> </IonHeader>
<ExploreContainer name="Tab 3 page" /> <ExploreContainer name="Tab 3 page" />
</IonContent> </IonContent>
</IonPage> </IonPage>
); );
}; };
export default Tab3; export default Tab3;

View File

@@ -2,13 +2,13 @@
// allows you to do things like: // allows you to do things like:
// expect(element).toHaveTextContent(/react/i) // expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom // learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom/extend-expect'; import "@testing-library/jest-dom/extend-expect";
// Mock matchmedia // Mock matchmedia
window.matchMedia = window.matchMedia || function() { window.matchMedia =
return { window.matchMedia ||
matches: false, (() => ({
addListener: function() {}, matches: false,
removeListener: function() {} addListener: () => {},
}; removeListener: () => {},
}; }));

View File

@@ -1,21 +1,21 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "ESNext", "target": "ESNext",
"useDefineForClassFields": true, "useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"], "lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false, "allowJs": false,
"skipLibCheck": true, "skipLibCheck": true,
"esModuleInterop": false, "esModuleInterop": false,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"strict": true, "strict": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"module": "ESNext", "module": "ESNext",
"moduleResolution": "Node", "moduleResolution": "Node",
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"noEmit": true, "noEmit": true,
"jsx": "react-jsx" "jsx": "react-jsx"
}, },
"include": ["src"], "include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }] "references": [{ "path": "./tsconfig.node.json" }]
} }

View File

@@ -1,9 +1,9 @@
{ {
"compilerOptions": { "compilerOptions": {
"composite": true, "composite": true,
"module": "ESNext", "module": "ESNext",
"moduleResolution": "Node", "moduleResolution": "Node",
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true
}, },
"include": ["vite.config.ts"] "include": ["vite.config.ts"]
} }

View File

@@ -1,18 +1,15 @@
/// <reference types="vitest" /> /// <reference types="vitest" />
import legacy from '@vitejs/plugin-legacy' import legacy from "@vitejs/plugin-legacy";
import react from '@vitejs/plugin-react' import react from "@vitejs/plugin-react";
import { defineConfig } from 'vite' import { defineConfig } from "vite";
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [react(), legacy()],
react(), test: {
legacy() globals: true,
], environment: "jsdom",
test: { setupFiles: "./src/setupTests.ts",
globals: true, },
environment: 'jsdom', });
setupFiles: './src/setupTests.ts',
}
})