@@ -1,5 +1,7 @@
|
|||||||
# Next.js + Tailwind CSS + Capacitor for mobile app development
|
# Next.js + Tailwind CSS + Capacitor for mobile app development
|
||||||
|
|
||||||
|
*Note: this repo is in active development and not quite ready for production use!*
|
||||||
|
|
||||||
This repo is a starting point for building an iOS, Android, and Progressive Web App with Tailwind CSS, Next.js, and Capacitor. It comes with some pre-built components that can be customized using Tailwind classes, and provides the most important UI controls needed to build native mobile experiences (tabs, nav bars, modals, menus, etc).
|
This repo is a starting point for building an iOS, Android, and Progressive Web App with Tailwind CSS, Next.js, and Capacitor. It comes with some pre-built components that can be customized using Tailwind classes, and provides the most important UI controls needed to build native mobile experiences (tabs, nav bars, modals, menus, etc).
|
||||||
|
|
||||||
These components are baked into the starter and will be adopted into your project. This way you gain full control over the experience and can easily modify the look and feel of the components to match your design.
|
These components are baked into the starter and will be adopted into your project. This way you gain full control over the experience and can easily modify the look and feel of the components to match your design.
|
||||||
|
|||||||
+19
-16
@@ -7,23 +7,26 @@ const { DarkMode } = Plugins;
|
|||||||
const App = ({ children, className, ...props }) => {
|
const App = ({ children, className, ...props }) => {
|
||||||
const [darkMode, setDarkMode] = useState(false);
|
const [darkMode, setDarkMode] = useState(false);
|
||||||
|
|
||||||
useEffect(async() => {
|
useEffect(async () => {
|
||||||
let darkmodeConfig = await DarkMode.isDarkModeOn();
|
try {
|
||||||
setDarkMode(darkmodeConfig.isDarkModeOn);
|
let darkmodeConfig = await DarkMode.isDarkModeOn();
|
||||||
DarkMode.addListener("darkModeStateChanged", (state) => {
|
setDarkMode(darkmodeConfig.isDarkModeOn);
|
||||||
setDarkMode(state.isDarkModeOn);
|
DarkMode.addListener('darkModeStateChanged', state => {
|
||||||
});
|
setDarkMode(state.isDarkModeOn);
|
||||||
|
});
|
||||||
|
} catch (e) {}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (<div {...props} className={classNames(
|
return (
|
||||||
'flex h-screen flex-col',
|
<div
|
||||||
className,
|
{...props}
|
||||||
{
|
className={classNames('flex h-screen flex-col', className, {
|
||||||
'dark': darkMode
|
dark: darkMode,
|
||||||
}
|
})}
|
||||||
)}>
|
>
|
||||||
{children}
|
{children}
|
||||||
</div>);
|
</div>
|
||||||
}
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|||||||
+10
-8
@@ -1,6 +1,6 @@
|
|||||||
import { Plugins } from '@capacitor/core';
|
import { Plugins } from '@capacitor/core';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { useDrag } from 'react-use-gesture';
|
import { useDrag } from 'react-use-gesture';
|
||||||
|
|
||||||
@@ -13,20 +13,22 @@ const Menu = ({ open, onClose, children, className, ...props }) => {
|
|||||||
const [dragging, setDragging] = useState(false);
|
const [dragging, setDragging] = useState(false);
|
||||||
|
|
||||||
useEffect(async () => {
|
useEffect(async () => {
|
||||||
let darkmodeConfig = await DarkMode.isDarkModeOn();
|
try {
|
||||||
console.log({open, darkMode: darkmodeConfig.isDarkModeOn})
|
let darkmodeConfig = await DarkMode.isDarkModeOn();
|
||||||
Plugins.StatusBar.setStyle({
|
console.log({ open, darkMode: darkmodeConfig.isDarkModeOn });
|
||||||
style: open && !darkmodeConfig.isDarkModeOn ? 'LIGHT' : 'DARK',
|
Plugins.StatusBar.setStyle({
|
||||||
}).catch(() => {});
|
style: open && !darkmodeConfig.isDarkModeOn ? 'LIGHT' : 'DARK',
|
||||||
|
}).catch(() => {});
|
||||||
|
} catch (e) {}
|
||||||
}, [open]);
|
}, [open]);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useEffect(() => {
|
||||||
const rect = ref.current?.getBoundingClientRect();
|
const rect = ref.current?.getBoundingClientRect();
|
||||||
setRect(rect);
|
setRect(rect);
|
||||||
setX(-rect.width);
|
setX(-rect.width);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
setX(0);
|
setX(0);
|
||||||
} else if (rect) {
|
} else if (rect) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
import { useCallback, useContext, useEffect, useRef, useState } from 'react';
|
||||||
import { useDrag } from 'react-use-gesture';
|
import { useDrag } from 'react-use-gesture';
|
||||||
import Store from '../../store';
|
import Store from '../../store';
|
||||||
import { SafeAreaContext } from './SafeArea';
|
import { SafeAreaContext } from './SafeArea';
|
||||||
@@ -26,14 +26,14 @@ const Modal = ({ open, onClose, children }) => {
|
|||||||
}, [safeAreaTop, rect]);
|
}, [safeAreaTop, rect]);
|
||||||
|
|
||||||
// Get the layout rectangle for the modal
|
// Get the layout rectangle for the modal
|
||||||
useLayoutEffect(() => {
|
useEffect(() => {
|
||||||
const rect = ref.current?.getBoundingClientRect();
|
const rect = ref.current?.getBoundingClientRect();
|
||||||
setRect(rect);
|
setRect(rect);
|
||||||
_close();
|
_close();
|
||||||
}, [safeAreaTop]);
|
}, [safeAreaTop]);
|
||||||
|
|
||||||
// If open changes, open/close the modal
|
// If open changes, open/close the modal
|
||||||
useLayoutEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
_open();
|
_open();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user