feat: Epic Modal + Window titlebar
This commit is contained in:
parent
07a73c6270
commit
6fdea8c033
15 changed files with 207 additions and 32 deletions
|
|
@ -12,8 +12,10 @@
|
|||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solidjs/router": "^0.13.0",
|
||||
"@tauri-apps/api": "2.0.0-beta.5",
|
||||
"@tauri-apps/plugin-shell": "2.0.0-beta.2",
|
||||
"@untitled-theme/icons-solid": "^0.6.0",
|
||||
"solid-js": "^1.7.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -27,6 +29,7 @@
|
|||
"eslint-config-airbnb-typescript": "^18.0.0",
|
||||
"eslint-plugin-solid": "^0.13.1",
|
||||
"postcss": "^8.4.35",
|
||||
"postcss-easings": "^4.0.0",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^5.0.0",
|
||||
|
|
|
|||
35
pnpm-lock.yaml
generated
35
pnpm-lock.yaml
generated
|
|
@ -5,12 +5,18 @@ settings:
|
|||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
'@solidjs/router':
|
||||
specifier: ^0.13.0
|
||||
version: 0.13.0(solid-js@1.8.15)
|
||||
'@tauri-apps/api':
|
||||
specifier: 2.0.0-beta.5
|
||||
version: 2.0.0-beta.5
|
||||
'@tauri-apps/plugin-shell':
|
||||
specifier: 2.0.0-beta.2
|
||||
version: 2.0.0-beta.2
|
||||
'@untitled-theme/icons-solid':
|
||||
specifier: ^0.6.0
|
||||
version: 0.6.0(solid-js@1.8.15)
|
||||
solid-js:
|
||||
specifier: ^1.7.8
|
||||
version: 1.8.15
|
||||
|
|
@ -46,6 +52,9 @@ devDependencies:
|
|||
postcss:
|
||||
specifier: ^8.4.35
|
||||
version: 8.4.35
|
||||
postcss-easings:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0(postcss@8.4.35)
|
||||
tailwindcss:
|
||||
specifier: ^3.4.1
|
||||
version: 3.4.1
|
||||
|
|
@ -757,6 +766,14 @@ packages:
|
|||
eslint-plugin-prettier: 5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5)
|
||||
dev: true
|
||||
|
||||
/@solidjs/router@0.13.0(solid-js@1.8.15):
|
||||
resolution: {integrity: sha512-YHLbFv9J53+iG4yVrh0vVdYiyXPTk892UyZ1jiMPsUXn2dYkX4552N+8SjvlKWWsmNmYxaoefM6jZn1YtVIUUg==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.8.6
|
||||
dependencies:
|
||||
solid-js: 1.8.15
|
||||
dev: false
|
||||
|
||||
/@stylistic/eslint-plugin-js@1.7.0(eslint@8.57.0):
|
||||
resolution: {integrity: sha512-PN6On/+or63FGnhhMKSQfYcWutRlzOiYlVdLM6yN7lquoBTqUJHYnl4TA4MHwiAt46X5gRxDr1+xPZ1lOLcL+Q==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
|
|
@ -1221,6 +1238,14 @@ packages:
|
|||
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
||||
dev: true
|
||||
|
||||
/@untitled-theme/icons-solid@0.6.0(solid-js@1.8.15):
|
||||
resolution: {integrity: sha512-8GBeDzNaBYPYg0FvWNtk2Xjx6Vg1Dgj2egalR1OaZQAEynbr4BzE+QjAb0XjKbxFpEdBxRC1gAOpdAr6uLrxUg==}
|
||||
peerDependencies:
|
||||
solid-js: '>=1.8.15'
|
||||
dependencies:
|
||||
solid-js: 1.8.15
|
||||
dev: false
|
||||
|
||||
/acorn-jsx@5.3.2(acorn@8.11.3):
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
|
|
@ -2898,6 +2923,16 @@ packages:
|
|||
engines: {node: '>= 0.4'}
|
||||
dev: true
|
||||
|
||||
/postcss-easings@4.0.0(postcss@8.4.35):
|
||||
resolution: {integrity: sha512-KNpwHA3mTnf0UWcdwahQDaz7DDJ6QteVwdlLff98se854p6pyQW9iofwrD05vtlp33AAAxuUGCOhYwERRJGy6Q==}
|
||||
engines: {node: '>=16.0'}
|
||||
peerDependencies:
|
||||
postcss: ^8.1.0
|
||||
dependencies:
|
||||
postcss: 8.4.35
|
||||
postcss-value-parser: 4.2.0
|
||||
dev: true
|
||||
|
||||
/postcss-import@15.1.0(postcss@8.4.35):
|
||||
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import postcssEasings from 'postcss-easings';
|
||||
import tailwind from 'tailwindcss';
|
||||
import autoprefixer from 'autoprefixer';
|
||||
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
plugins: [
|
||||
tailwind,
|
||||
autoprefixer,
|
||||
postcssEasings,
|
||||
],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "migrated",
|
||||
"description": "permissions that were migrated from v1",
|
||||
"local": true,
|
||||
|
|
@ -6,15 +7,8 @@
|
|||
"main"
|
||||
],
|
||||
"permissions": [
|
||||
"path:default",
|
||||
"event:default",
|
||||
"window:default",
|
||||
"app:default",
|
||||
"resources:default",
|
||||
"menu:default",
|
||||
"tray:default",
|
||||
"shell:allow-open",
|
||||
|
||||
"auth:default"
|
||||
"window:allow-close",
|
||||
"window:allow-minimize",
|
||||
"window:allow-start-dragging"
|
||||
]
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
{"migrated":{"identifier":"migrated","description":"permissions that were migrated from v1","local":true,"windows":["main"],"permissions":["path:default","event:default","window:default","app:default","resources:default","menu:default","tray:default","shell:allow-open","auth:default"]}}
|
||||
{"migrated":{"identifier":"migrated","description":"permissions that were migrated from v1","local":true,"windows":["main"],"permissions":["window:allow-close","window:allow-minimize","window:allow-start-dragging"]}}
|
||||
|
|
@ -21,14 +21,20 @@
|
|||
"identifier": "com.tauri.dev",
|
||||
"plugins": {},
|
||||
"app": {
|
||||
"withGlobalTauri": true,
|
||||
"security": {
|
||||
"csp": null
|
||||
"csp": null,
|
||||
"capabilities": []
|
||||
},
|
||||
"windows": [
|
||||
{
|
||||
"title": "polyfrost-launcher",
|
||||
"width": 1200,
|
||||
"height": 800
|
||||
"width": 1280,
|
||||
"height": 800,
|
||||
"resizable": false,
|
||||
"center": true,
|
||||
"decorations": false,
|
||||
"shadow": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
import auth from './bridge/auth';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<button onClick={() => auth.loginMicrosoft()}>loginMicrosoft</button>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
|
@ -1 +0,0 @@
|
|||
import '@fontsource/poppins';
|
||||
|
|
@ -1,3 +1,8 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@tailwind utilities;
|
||||
|
||||
/* start lynith's native experience */
|
||||
* { user-select: none; }
|
||||
*:hover { cursor: default; }
|
||||
/* end lynith's native experience */
|
||||
|
|
@ -3,6 +3,12 @@ import { render } from 'solid-js/web';
|
|||
|
||||
import './assets/fonts/Poppins/index.css';
|
||||
import './globals.css';
|
||||
import App from './App';
|
||||
import { Route, Router } from '@solidjs/router';
|
||||
import App from './ui/App';
|
||||
import HomePage from './ui/pages/Home';
|
||||
|
||||
render(() => <App />, document.getElementById('root') as HTMLElement);
|
||||
render(() => (
|
||||
<Router root={App}>
|
||||
<Route component={HomePage} path={'/'} />
|
||||
</Router>
|
||||
), document.getElementById('root') as HTMLElement);
|
||||
|
|
|
|||
13
src/ui/App.tsx
Normal file
13
src/ui/App.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { ParentProps } from 'solid-js';
|
||||
import WindowFrame from './components/native/WindowFrame';
|
||||
|
||||
function App(props: ParentProps) {
|
||||
return (
|
||||
<main class='bg-bg-primary min-h-screen text-white'>
|
||||
<WindowFrame />
|
||||
{props.children}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
38
src/ui/components/native/WindowFrame.tsx
Normal file
38
src/ui/components/native/WindowFrame.tsx
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { Window } from '@tauri-apps/api/window';
|
||||
import { MinusIcon, XCloseIcon } from '@untitled-theme/icons-solid';
|
||||
import { JSX, createSignal } from 'solid-js';
|
||||
import Modal from '../overlay/Modal';
|
||||
|
||||
type ButtonProps = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
icon: (any: any) => JSX.Element,
|
||||
onClick: (event: MouseEvent) => void,
|
||||
danger?: boolean,
|
||||
};
|
||||
|
||||
function Button(props: ButtonProps) {
|
||||
return (
|
||||
<button class='flex items-center justify-center w-8 h-8 group' onClick={(e) => props.onClick(e)}>
|
||||
<div class='rounded-lg group-hover:bg-bg-primary p-1'>
|
||||
<props.icon class={`w-[18px] h-[18px] stroke-slate ${props.danger ? 'group-hover:stroke-danger' : 'group-hover:stroke-white'}`} />
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function WindowFrame() {
|
||||
const [isCloseModalVisible, setIsCloseModalVisible] = createSignal(false);
|
||||
|
||||
return (
|
||||
<div data-tauri-drag-region class="flex flex-row gap-2 justify-end items-center w-screen h-8 bg-bg-secondary pr-4">
|
||||
<Button icon={MinusIcon} onClick={() => Window.getCurrent().minimize()} />
|
||||
<Button icon={XCloseIcon} onClick={() => {
|
||||
setIsCloseModalVisible(!isCloseModalVisible());
|
||||
}} danger />
|
||||
|
||||
<Modal title='Close' visible={isCloseModalVisible} setVisible={setIsCloseModalVisible} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default WindowFrame;
|
||||
49
src/ui/components/overlay/Modal.tsx
Normal file
49
src/ui/components/overlay/Modal.tsx
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import {
|
||||
Accessor,
|
||||
ParentProps, Setter, Show, createEffect, createSignal,
|
||||
} from 'solid-js';
|
||||
import { Portal } from 'solid-js/web';
|
||||
|
||||
type ModalButton = {
|
||||
text: string,
|
||||
class?: string,
|
||||
onClick?: (event: MouseEvent) => void,
|
||||
};
|
||||
|
||||
type ModalProps = {
|
||||
title: string,
|
||||
visible: Accessor<boolean>,
|
||||
setVisible: Setter<boolean>,
|
||||
buttons?: ModalButton[],
|
||||
} & ParentProps;
|
||||
|
||||
function Modal(props: ModalProps) {
|
||||
const [animate, setAnimate] = createSignal('animate-fade-in');
|
||||
|
||||
function onBackdropClick() {
|
||||
setAnimate('animate-fade-out pointer-events-none');
|
||||
setTimeout(() => {
|
||||
props.setVisible(false);
|
||||
setAnimate('animate-fade-in pointer-events-auto');
|
||||
}, 150);
|
||||
}
|
||||
|
||||
return (
|
||||
<Show when={props.visible()}>
|
||||
<Portal>
|
||||
<div class={`fixed z-[1000] top-0 left-0 w-screen h-screen bg-black/50 backdrop-blur-md ${animate()}`}>
|
||||
<div class='absolute w-full h-full' onClick={() => onBackdropClick()} />
|
||||
|
||||
<div class='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'>
|
||||
<div class='bg-white p-4'>
|
||||
<h1>Hello World</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</Portal>
|
||||
</Show>
|
||||
);
|
||||
}
|
||||
|
||||
export default Modal;
|
||||
10
src/ui/pages/Home.tsx
Normal file
10
src/ui/pages/Home.tsx
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
function HomePage() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Home</h1>
|
||||
<p>Welcome to the home page</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default HomePage;
|
||||
|
|
@ -3,11 +3,31 @@ export default {
|
|||
content: ['./src/**/*.{js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
colors: {
|
||||
white: '#ffffff',
|
||||
black: '#000000',
|
||||
slate: '#9BA1A6',
|
||||
danger: '#E5484D',
|
||||
bg: {
|
||||
primary: '#11171C',
|
||||
secondary: '#192026',
|
||||
},
|
||||
},
|
||||
extend: {
|
||||
animation: {
|
||||
'fade-in': 'fadeIn 150ms easeOutExpo forwards',
|
||||
'fade-out': 'fadeOut 150ms easeOutExpo forwards',
|
||||
},
|
||||
|
||||
keyframes: {
|
||||
fadeIn: {
|
||||
'0%': { opacity: '0' },
|
||||
'100%': { opacity: '1' },
|
||||
},
|
||||
fadeOut: {
|
||||
'0%': { opacity: '1' },
|
||||
'100%': { opacity: '0' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue