commit
824e2ea9d5
35 changed files with 9142 additions and 0 deletions
@ -0,0 +1,9 @@ |
|||||||
|
root = true |
||||||
|
|
||||||
|
[*] |
||||||
|
charset = utf-8 |
||||||
|
indent_style = space |
||||||
|
indent_size = 2 |
||||||
|
end_of_line = lf |
||||||
|
insert_final_newline = true |
||||||
|
trim_trailing_whitespace = true |
||||||
@ -0,0 +1,14 @@ |
|||||||
|
module.exports = { |
||||||
|
extends: [ |
||||||
|
'eslint:recommended', |
||||||
|
'plugin:react/recommended', |
||||||
|
'plugin:react/jsx-runtime', |
||||||
|
'@electron-toolkit/eslint-config-ts/recommended', |
||||||
|
'@electron-toolkit/eslint-config-prettier' |
||||||
|
], |
||||||
|
rules: { |
||||||
|
'@typescript-eslint/explicit-function-return-type': 'off', |
||||||
|
'react/prop-types': 'off', |
||||||
|
'@typescript-eslint/no-explicit-any': 'off' |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
out |
||||||
|
dist |
||||||
|
pnpm-lock.yaml |
||||||
|
LICENSE.md |
||||||
|
tsconfig.json |
||||||
|
tsconfig.*.json |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
singleQuote: true |
||||||
|
semi: false |
||||||
|
printWidth: 100 |
||||||
|
trailingComma: none |
||||||
@ -0,0 +1,3 @@ |
|||||||
|
{ |
||||||
|
"recommendations": ["dbaeumer.vscode-eslint"] |
||||||
|
} |
||||||
@ -0,0 +1,39 @@ |
|||||||
|
{ |
||||||
|
"version": "0.2.0", |
||||||
|
"configurations": [ |
||||||
|
{ |
||||||
|
"name": "Debug Main Process", |
||||||
|
"type": "node", |
||||||
|
"request": "launch", |
||||||
|
"cwd": "${workspaceRoot}", |
||||||
|
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite", |
||||||
|
"windows": { |
||||||
|
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite.cmd" |
||||||
|
}, |
||||||
|
"runtimeArgs": ["--sourcemap"], |
||||||
|
"env": { |
||||||
|
"REMOTE_DEBUGGING_PORT": "9222" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"name": "Debug Renderer Process", |
||||||
|
"port": 9222, |
||||||
|
"request": "attach", |
||||||
|
"type": "chrome", |
||||||
|
"webRoot": "${workspaceFolder}/src/renderer", |
||||||
|
"timeout": 60000, |
||||||
|
"presentation": { |
||||||
|
"hidden": true |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"compounds": [ |
||||||
|
{ |
||||||
|
"name": "Debug All", |
||||||
|
"configurations": ["Debug Main Process", "Debug Renderer Process"], |
||||||
|
"presentation": { |
||||||
|
"order": 1 |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
{ |
||||||
|
"[typescript]": { |
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||||
|
}, |
||||||
|
"[javascript]": { |
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||||
|
}, |
||||||
|
"[json]": { |
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,21 @@ |
|||||||
|
MIT License |
||||||
|
|
||||||
|
Copyright (c) 2024 Cody Tseng |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
of this software and associated documentation files (the "Software"), to deal |
||||||
|
in the Software without restriction, including without limitation the rights |
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the Software is |
||||||
|
furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all |
||||||
|
copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
SOFTWARE. |
||||||
Binary file not shown.
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 35 KiB |
@ -0,0 +1,17 @@ |
|||||||
|
{ |
||||||
|
"$schema": "https://ui.shadcn.com/schema.json", |
||||||
|
"style": "default", |
||||||
|
"rsc": false, |
||||||
|
"tsx": true, |
||||||
|
"tailwind": { |
||||||
|
"config": "tailwind.config.js", |
||||||
|
"css": "src/renderer/src/assets/main.css", |
||||||
|
"baseColor": "slate", |
||||||
|
"cssVariables": true, |
||||||
|
"prefix": "" |
||||||
|
}, |
||||||
|
"aliases": { |
||||||
|
"components": "@renderer/components", |
||||||
|
"utils": "@renderer/lib/utils" |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,34 @@ |
|||||||
|
appId: com.jumble.app |
||||||
|
productName: jumble |
||||||
|
directories: |
||||||
|
buildResources: build |
||||||
|
files: |
||||||
|
- '!**/.vscode/*' |
||||||
|
- '!src/*' |
||||||
|
- '!electron.vite.config.{js,ts,mjs,cjs}' |
||||||
|
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}' |
||||||
|
- '!{.env,.env.*,.npmrc,pnpm-lock.yaml}' |
||||||
|
- '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}' |
||||||
|
asarUnpack: |
||||||
|
- resources/** |
||||||
|
win: |
||||||
|
executableName: jumble |
||||||
|
nsis: |
||||||
|
artifactName: ${name}-${version}-setup.${ext} |
||||||
|
shortcutName: ${productName} |
||||||
|
uninstallDisplayName: ${productName} |
||||||
|
createDesktopShortcut: always |
||||||
|
mac: |
||||||
|
notarize: false |
||||||
|
dmg: |
||||||
|
artifactName: ${name}-${version}.${ext} |
||||||
|
linux: |
||||||
|
target: |
||||||
|
- AppImage |
||||||
|
- snap |
||||||
|
- deb |
||||||
|
maintainer: codytseng |
||||||
|
category: Utility |
||||||
|
appImage: |
||||||
|
artifactName: ${name}-${version}.${ext} |
||||||
|
npmRebuild: false |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
import { resolve } from 'path' |
||||||
|
import { defineConfig, externalizeDepsPlugin } from 'electron-vite' |
||||||
|
import react from '@vitejs/plugin-react' |
||||||
|
|
||||||
|
export default defineConfig({ |
||||||
|
main: { |
||||||
|
plugins: [externalizeDepsPlugin()] |
||||||
|
}, |
||||||
|
preload: { |
||||||
|
plugins: [externalizeDepsPlugin()] |
||||||
|
}, |
||||||
|
renderer: { |
||||||
|
resolve: { |
||||||
|
alias: { |
||||||
|
'@renderer': resolve('src/renderer/src') |
||||||
|
} |
||||||
|
}, |
||||||
|
plugins: [react()] |
||||||
|
} |
||||||
|
}) |
||||||
@ -0,0 +1,59 @@ |
|||||||
|
{ |
||||||
|
"name": "jumble", |
||||||
|
"version": "0.0.1", |
||||||
|
"description": "Yet another Nostr desktop client", |
||||||
|
"main": "./out/main/index.js", |
||||||
|
"author": "codytseng", |
||||||
|
"license": "MIT", |
||||||
|
"repository": { |
||||||
|
"type": "git", |
||||||
|
"url": "git+https://github.com/CodyTseng/jumble" |
||||||
|
}, |
||||||
|
"homepage": "https://github.com/CodyTseng/jumble", |
||||||
|
"scripts": { |
||||||
|
"format": "prettier --write .", |
||||||
|
"lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix", |
||||||
|
"typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false", |
||||||
|
"typecheck:web": "tsc --noEmit -p tsconfig.web.json --composite false", |
||||||
|
"typecheck": "npm run typecheck:node && npm run typecheck:web", |
||||||
|
"start": "electron-vite preview", |
||||||
|
"dev": "electron-vite dev", |
||||||
|
"build": "npm run typecheck && electron-vite build", |
||||||
|
"postinstall": "electron-builder install-app-deps", |
||||||
|
"build:unpack": "npm run build && electron-builder --dir", |
||||||
|
"build:win": "npm run build && electron-builder --win", |
||||||
|
"build:mac": "electron-vite build && electron-builder --mac", |
||||||
|
"build:linux": "electron-vite build && electron-builder --linux" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"@electron-toolkit/preload": "^3.0.1", |
||||||
|
"@electron-toolkit/utils": "^3.0.0", |
||||||
|
"@radix-ui/react-slot": "^1.1.0", |
||||||
|
"class-variance-authority": "^0.7.0", |
||||||
|
"clsx": "^2.1.1", |
||||||
|
"lucide-react": "^0.453.0", |
||||||
|
"tailwind-merge": "^2.5.4", |
||||||
|
"tailwindcss-animate": "^1.0.7" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@electron-toolkit/eslint-config-prettier": "^2.0.0", |
||||||
|
"@electron-toolkit/eslint-config-ts": "^2.0.0", |
||||||
|
"@electron-toolkit/tsconfig": "^1.0.1", |
||||||
|
"@types/node": "^20.14.8", |
||||||
|
"@types/react": "^18.3.3", |
||||||
|
"@types/react-dom": "^18.3.0", |
||||||
|
"@vitejs/plugin-react": "^4.3.1", |
||||||
|
"autoprefixer": "^10.4.20", |
||||||
|
"electron": "^31.0.2", |
||||||
|
"electron-builder": "^24.13.3", |
||||||
|
"electron-vite": "^2.3.0", |
||||||
|
"eslint": "^8.57.0", |
||||||
|
"eslint-plugin-react": "^7.34.3", |
||||||
|
"prettier": "^3.3.2", |
||||||
|
"react": "^18.3.1", |
||||||
|
"react-dom": "^18.3.1", |
||||||
|
"tailwindcss": "^3.4.14", |
||||||
|
"typescript": "^5.5.2", |
||||||
|
"vite": "^5.3.1" |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,3 @@ |
|||||||
|
module.exports = { |
||||||
|
plugins: [require('tailwindcss'), require('autoprefixer')] |
||||||
|
} |
||||||
|
After Width: | Height: | Size: 35 KiB |
@ -0,0 +1,74 @@ |
|||||||
|
import { app, shell, BrowserWindow, ipcMain } from 'electron' |
||||||
|
import { join } from 'path' |
||||||
|
import { electronApp, optimizer, is } from '@electron-toolkit/utils' |
||||||
|
import icon from '../../resources/icon.png?asset' |
||||||
|
|
||||||
|
function createWindow(): void { |
||||||
|
// Create the browser window.
|
||||||
|
const mainWindow = new BrowserWindow({ |
||||||
|
width: 900, |
||||||
|
height: 670, |
||||||
|
show: false, |
||||||
|
autoHideMenuBar: true, |
||||||
|
...(process.platform === 'linux' ? { icon } : {}), |
||||||
|
webPreferences: { |
||||||
|
preload: join(__dirname, '../preload/index.js'), |
||||||
|
sandbox: false |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
mainWindow.on('ready-to-show', () => { |
||||||
|
mainWindow.show() |
||||||
|
}) |
||||||
|
|
||||||
|
mainWindow.webContents.setWindowOpenHandler((details) => { |
||||||
|
shell.openExternal(details.url) |
||||||
|
return { action: 'deny' } |
||||||
|
}) |
||||||
|
|
||||||
|
// HMR for renderer base on electron-vite cli.
|
||||||
|
// Load the remote URL for development or the local html file for production.
|
||||||
|
if (is.dev && process.env['ELECTRON_RENDERER_URL']) { |
||||||
|
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL']) |
||||||
|
} else { |
||||||
|
mainWindow.loadFile(join(__dirname, '../renderer/index.html')) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// This method will be called when Electron has finished
|
||||||
|
// initialization and is ready to create browser windows.
|
||||||
|
// Some APIs can only be used after this event occurs.
|
||||||
|
app.whenReady().then(() => { |
||||||
|
// Set app user model id for windows
|
||||||
|
electronApp.setAppUserModelId('com.electron') |
||||||
|
|
||||||
|
// Default open or close DevTools by F12 in development
|
||||||
|
// and ignore CommandOrControl + R in production.
|
||||||
|
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
|
||||||
|
app.on('browser-window-created', (_, window) => { |
||||||
|
optimizer.watchWindowShortcuts(window) |
||||||
|
}) |
||||||
|
|
||||||
|
// IPC test
|
||||||
|
ipcMain.on('ping', () => console.log('pong')) |
||||||
|
|
||||||
|
createWindow() |
||||||
|
|
||||||
|
app.on('activate', function () { |
||||||
|
// On macOS it's common to re-create a window in the app when the
|
||||||
|
// dock icon is clicked and there are no other windows open.
|
||||||
|
if (BrowserWindow.getAllWindows().length === 0) createWindow() |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
// Quit when all windows are closed, except on macOS. There, it's common
|
||||||
|
// for applications and their menu bar to stay active until the user quits
|
||||||
|
// explicitly with Cmd + Q.
|
||||||
|
app.on('window-all-closed', () => { |
||||||
|
if (process.platform !== 'darwin') { |
||||||
|
app.quit() |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
// In this file you can include the rest of your app"s specific main process
|
||||||
|
// code. You can also put them in separate files and require them here.
|
||||||
@ -0,0 +1,8 @@ |
|||||||
|
import { ElectronAPI } from '@electron-toolkit/preload' |
||||||
|
|
||||||
|
declare global { |
||||||
|
interface Window { |
||||||
|
electron: ElectronAPI |
||||||
|
api: unknown |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
import { contextBridge } from 'electron' |
||||||
|
import { electronAPI } from '@electron-toolkit/preload' |
||||||
|
|
||||||
|
// Custom APIs for renderer
|
||||||
|
const api = {} |
||||||
|
|
||||||
|
// Use `contextBridge` APIs to expose Electron APIs to
|
||||||
|
// renderer only if context isolation is enabled, otherwise
|
||||||
|
// just add to the DOM global.
|
||||||
|
if (process.contextIsolated) { |
||||||
|
try { |
||||||
|
contextBridge.exposeInMainWorld('electron', electronAPI) |
||||||
|
contextBridge.exposeInMainWorld('api', api) |
||||||
|
} catch (error) { |
||||||
|
console.error(error) |
||||||
|
} |
||||||
|
} else { |
||||||
|
// @ts-ignore (define in dts)
|
||||||
|
window.electron = electronAPI |
||||||
|
// @ts-ignore (define in dts)
|
||||||
|
window.api = api |
||||||
|
} |
||||||
@ -0,0 +1,17 @@ |
|||||||
|
<!doctype html> |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8" /> |
||||||
|
<title>Electron</title> |
||||||
|
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP --> |
||||||
|
<meta |
||||||
|
http-equiv="Content-Security-Policy" |
||||||
|
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:" |
||||||
|
/> |
||||||
|
</head> |
||||||
|
|
||||||
|
<body> |
||||||
|
<div id="root"></div> |
||||||
|
<script type="module" src="/src/main.tsx"></script> |
||||||
|
</body> |
||||||
|
</html> |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
function App(): JSX.Element { |
||||||
|
return <div>Hello</div> |
||||||
|
} |
||||||
|
|
||||||
|
export default App |
||||||
@ -0,0 +1,97 @@ |
|||||||
|
@tailwind base; |
||||||
|
@tailwind components; |
||||||
|
@tailwind utilities; |
||||||
|
|
||||||
|
@layer base { |
||||||
|
body { |
||||||
|
font-family: 'Inter', sans-serif; |
||||||
|
color: hsl(var(--foreground)); |
||||||
|
background-color: hsl(var(--background)); |
||||||
|
} |
||||||
|
|
||||||
|
.draggable { |
||||||
|
-webkit-app-region: drag; |
||||||
|
} |
||||||
|
|
||||||
|
.non-draggable { |
||||||
|
-webkit-app-region: no-drag; |
||||||
|
} |
||||||
|
|
||||||
|
:root { |
||||||
|
--background: 0 0% 100%; |
||||||
|
--foreground: 222.2 47.4% 11.2%; |
||||||
|
|
||||||
|
--muted: 210 40% 96.1%; |
||||||
|
--muted-foreground: 215.4 16.3% 46.9%; |
||||||
|
|
||||||
|
--popover: 0 0% 100%; |
||||||
|
--popover-foreground: 222.2 47.4% 11.2%; |
||||||
|
|
||||||
|
--border: 214.3 31.8% 91.4%; |
||||||
|
--input: 214.3 31.8% 91.4%; |
||||||
|
|
||||||
|
--card: 0 0% 100%; |
||||||
|
--card-foreground: 222.2 47.4% 11.2%; |
||||||
|
|
||||||
|
--primary: 222.2 47.4% 11.2%; |
||||||
|
--primary-foreground: 210 40% 98%; |
||||||
|
|
||||||
|
--secondary: 210 40% 96.1%; |
||||||
|
--secondary-foreground: 222.2 47.4% 11.2%; |
||||||
|
|
||||||
|
--accent: 210 40% 96.1%; |
||||||
|
--accent-foreground: 222.2 47.4% 11.2%; |
||||||
|
|
||||||
|
--destructive: 0 100% 50%; |
||||||
|
--destructive-foreground: 210 40% 98%; |
||||||
|
|
||||||
|
--ring: 215 20.2% 65.1%; |
||||||
|
|
||||||
|
--radius: 0.5rem; |
||||||
|
} |
||||||
|
|
||||||
|
.dark { |
||||||
|
--background: 224 71% 4%; |
||||||
|
--foreground: 213 31% 91%; |
||||||
|
|
||||||
|
--muted: 223 47% 11%; |
||||||
|
--muted-foreground: 215.4 16.3% 56.9%; |
||||||
|
|
||||||
|
--accent: 216 34% 17%; |
||||||
|
--accent-foreground: 210 40% 98%; |
||||||
|
|
||||||
|
--popover: 224 71% 4%; |
||||||
|
--popover-foreground: 215 20.2% 65.1%; |
||||||
|
|
||||||
|
--border: 216 34% 17%; |
||||||
|
--input: 216 34% 17%; |
||||||
|
|
||||||
|
--card: 224 71% 4%; |
||||||
|
--card-foreground: 213 31% 91%; |
||||||
|
|
||||||
|
--primary: 210 40% 98%; |
||||||
|
--primary-foreground: 222.2 47.4% 1.2%; |
||||||
|
|
||||||
|
--secondary: 222.2 47.4% 11.2%; |
||||||
|
--secondary-foreground: 210 40% 98%; |
||||||
|
|
||||||
|
--destructive: 0 63% 31%; |
||||||
|
--destructive-foreground: 210 40% 98%; |
||||||
|
|
||||||
|
--ring: 216 34% 17%; |
||||||
|
|
||||||
|
--radius: 0.5rem; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@layer base { |
||||||
|
* { |
||||||
|
@apply border-border; |
||||||
|
} |
||||||
|
body { |
||||||
|
@apply bg-background text-foreground; |
||||||
|
font-feature-settings: |
||||||
|
'rlig' 1, |
||||||
|
'calt' 1; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,56 @@ |
|||||||
|
import * as React from "react" |
||||||
|
import { Slot } from "@radix-ui/react-slot" |
||||||
|
import { cva, type VariantProps } from "class-variance-authority" |
||||||
|
|
||||||
|
import { cn } from "@renderer/lib/utils" |
||||||
|
|
||||||
|
const buttonVariants = cva( |
||||||
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", |
||||||
|
{ |
||||||
|
variants: { |
||||||
|
variant: { |
||||||
|
default: "bg-primary text-primary-foreground hover:bg-primary/90", |
||||||
|
destructive: |
||||||
|
"bg-destructive text-destructive-foreground hover:bg-destructive/90", |
||||||
|
outline: |
||||||
|
"border border-input bg-background hover:bg-accent hover:text-accent-foreground", |
||||||
|
secondary: |
||||||
|
"bg-secondary text-secondary-foreground hover:bg-secondary/80", |
||||||
|
ghost: "hover:bg-accent hover:text-accent-foreground", |
||||||
|
link: "text-primary underline-offset-4 hover:underline", |
||||||
|
}, |
||||||
|
size: { |
||||||
|
default: "h-10 px-4 py-2", |
||||||
|
sm: "h-9 rounded-md px-3", |
||||||
|
lg: "h-11 rounded-md px-8", |
||||||
|
icon: "h-10 w-10", |
||||||
|
}, |
||||||
|
}, |
||||||
|
defaultVariants: { |
||||||
|
variant: "default", |
||||||
|
size: "default", |
||||||
|
}, |
||||||
|
} |
||||||
|
) |
||||||
|
|
||||||
|
export interface ButtonProps |
||||||
|
extends React.ButtonHTMLAttributes<HTMLButtonElement>, |
||||||
|
VariantProps<typeof buttonVariants> { |
||||||
|
asChild?: boolean |
||||||
|
} |
||||||
|
|
||||||
|
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>( |
||||||
|
({ className, variant, size, asChild = false, ...props }, ref) => { |
||||||
|
const Comp = asChild ? Slot : "button" |
||||||
|
return ( |
||||||
|
<Comp |
||||||
|
className={cn(buttonVariants({ variant, size, className }))} |
||||||
|
ref={ref} |
||||||
|
{...props} |
||||||
|
/> |
||||||
|
) |
||||||
|
} |
||||||
|
) |
||||||
|
Button.displayName = "Button" |
||||||
|
|
||||||
|
export { Button, buttonVariants } |
||||||
@ -0,0 +1 @@ |
|||||||
|
/// <reference types="vite/client" />
|
||||||
@ -0,0 +1,6 @@ |
|||||||
|
import { clsx, type ClassValue } from 'clsx' |
||||||
|
import { twMerge } from 'tailwind-merge' |
||||||
|
|
||||||
|
export function cn(...inputs: ClassValue[]) { |
||||||
|
return twMerge(clsx(inputs)) |
||||||
|
} |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
import './assets/main.css' |
||||||
|
|
||||||
|
import React from 'react' |
||||||
|
import ReactDOM from 'react-dom/client' |
||||||
|
import App from './App' |
||||||
|
|
||||||
|
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( |
||||||
|
<React.StrictMode> |
||||||
|
<App /> |
||||||
|
</React.StrictMode> |
||||||
|
) |
||||||
@ -0,0 +1,53 @@ |
|||||||
|
/** @type {import('tailwindcss').Config} */ |
||||||
|
module.exports = { |
||||||
|
content: ['./src/renderer/**/*.{ts,tsx}'], |
||||||
|
prefix: '', |
||||||
|
theme: { |
||||||
|
container: { |
||||||
|
center: true, |
||||||
|
padding: '2rem', |
||||||
|
screens: { |
||||||
|
'2xl': '1400px' |
||||||
|
} |
||||||
|
}, |
||||||
|
extend: { |
||||||
|
keyframes: { |
||||||
|
'accordion-down': { |
||||||
|
from: { height: '0' }, |
||||||
|
to: { height: 'var(--radix-accordion-content-height)' } |
||||||
|
}, |
||||||
|
'accordion-up': { |
||||||
|
from: { height: 'var(--radix-accordion-content-height)' }, |
||||||
|
to: { height: '0' } |
||||||
|
} |
||||||
|
}, |
||||||
|
animation: { |
||||||
|
'accordion-down': 'accordion-down 0.2s ease-out', |
||||||
|
'accordion-up': 'accordion-up 0.2s ease-out' |
||||||
|
}, |
||||||
|
colors: { |
||||||
|
background: 'hsl(var(--background))', |
||||||
|
foreground: 'hsl(var(--foreground))', |
||||||
|
muted: 'hsl(var(--muted))', |
||||||
|
'muted-foreground': 'hsl(var(--muted-foreground))', |
||||||
|
card: 'hsl(var(--card))', |
||||||
|
'card-foreground': 'hsl(var(--card-foreground))', |
||||||
|
popover: 'hsl(var(--popover))', |
||||||
|
'popover-foreground': 'hsl(var(--popover-foreground))', |
||||||
|
border: 'hsl(var(--border))', |
||||||
|
input: 'hsl(var(--input))', |
||||||
|
primary: 'hsl(var(--primary))', |
||||||
|
'primary-foreground': 'hsl(var(--primary-foreground))', |
||||||
|
secondary: 'hsl(var(--secondary))', |
||||||
|
'secondary-foreground': 'hsl(var(--secondary-foreground))', |
||||||
|
accent: 'hsl(var(--accent))', |
||||||
|
'accent-foreground': 'hsl(var(--accent-foreground))', |
||||||
|
destructive: 'hsl(var(--destructive))', |
||||||
|
'destructive-foreground': 'hsl(var(--destructive-foreground))', |
||||||
|
ring: 'hsl(var(--ring))', |
||||||
|
highlight: 'hsl(var(--highlight))' |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
plugins: [require('tailwindcss-animate')] |
||||||
|
} |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
{ |
||||||
|
"compilerOptions": { |
||||||
|
"paths": { |
||||||
|
"@renderer/*": ["./src/renderer/src/*"], |
||||||
|
} |
||||||
|
}, |
||||||
|
"files": [], |
||||||
|
"references": [{ "path": "./tsconfig.node.json" }, { "path": "./tsconfig.web.json" }] |
||||||
|
} |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
{ |
||||||
|
"extends": "@electron-toolkit/tsconfig/tsconfig.node.json", |
||||||
|
"include": ["electron.vite.config.*", "src/main/**/*", "src/preload/**/*"], |
||||||
|
"compilerOptions": { |
||||||
|
"composite": true, |
||||||
|
"types": ["electron-vite/node"] |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,19 @@ |
|||||||
|
{ |
||||||
|
"extends": "@electron-toolkit/tsconfig/tsconfig.web.json", |
||||||
|
"include": [ |
||||||
|
"src/renderer/src/env.d.ts", |
||||||
|
"src/renderer/src/**/*", |
||||||
|
"src/renderer/src/**/*.tsx", |
||||||
|
"src/preload/*.d.ts" |
||||||
|
], |
||||||
|
"compilerOptions": { |
||||||
|
"composite": true, |
||||||
|
"jsx": "react-jsx", |
||||||
|
"baseUrl": ".", |
||||||
|
"paths": { |
||||||
|
"@renderer/*": [ |
||||||
|
"src/renderer/src/*" |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue