Internal cleanup
This commit is contained in:
@@ -4,11 +4,10 @@ import { FiMessageCircle, FiSettings } from 'react-icons/fi';
|
||||
import { RiMindMap, RiRoadMapLine } from 'react-icons/ri';
|
||||
import { VscExtensions } from 'react-icons/vsc';
|
||||
|
||||
import { toggleMobileNav } from '@app/core/slices/appSlice';
|
||||
import { useAppDispatch } from '@app/hooks/useAppDispatch';
|
||||
import { NavLinkButton } from '@components/layout/Sidebar/NavLinkButton';
|
||||
import { routes, useRoute } from '@core/router';
|
||||
|
||||
import { NavLinkButton } from './NavLinkButton';
|
||||
import { toggleMobileNav } from '@core/slices/appSlice';
|
||||
import { useAppDispatch } from '@hooks/useAppDispatch';
|
||||
|
||||
export interface ButtonNavProps {
|
||||
toggleSettingsOpen: () => void;
|
||||
|
||||
@@ -3,9 +3,12 @@ import React from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { FiSave } from 'react-icons/fi';
|
||||
|
||||
import { IconButton } from '@components/generic/button/IconButton';
|
||||
import { Checkbox } from '@components/generic/form/Checkbox';
|
||||
import { Input } from '@components/generic/form/Input';
|
||||
import { Select } from '@components/generic/form/Select';
|
||||
import { connection } from '@core/connection';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import { Checkbox, IconButton, Input, Select } from '@meshtastic/components';
|
||||
import { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export const Channels = (): JSX.Element => {
|
||||
|
||||
@@ -15,22 +15,21 @@ import {
|
||||
FiZap,
|
||||
} from 'react-icons/fi';
|
||||
|
||||
import { CollapsibleSection } from '@app/components/layout/Sidebar/sections/CollapsibleSection';
|
||||
import { ExternalSection } from '@app/components/layout/Sidebar/sections/ExternalSection';
|
||||
import { SidebarOverlay } from '@app/components/layout/Sidebar/sections/SidebarOverlay';
|
||||
import { Channels } from '@app/components/layout/Sidebar/Settings/Channels';
|
||||
import { ExternalNotificationsSettingsPlanel } from '@app/components/layout/Sidebar/Settings/plugins/panels/ExternalNotifications/SettingsPlanel';
|
||||
import { RangeTestSettingsPanel } from '@app/components/layout/Sidebar/Settings/plugins/panels/RangeTest/SettingsPanel';
|
||||
import { SerialSettingsPanel } from '@app/components/layout/Sidebar/Settings/plugins/panels/Serial/SettingsPanel';
|
||||
import { StoreForwardSettingsPanel } from '@app/components/layout/Sidebar/Settings/plugins/panels/StoreForward/SettingsPanel';
|
||||
import { Position } from '@app/components/layout/Sidebar/Settings/Position';
|
||||
import { Power } from '@app/components/layout/Sidebar/Settings/Power';
|
||||
import { Radio } from '@app/components/layout/Sidebar/Settings/Radio';
|
||||
import { User } from '@app/components/layout/Sidebar/Settings/User';
|
||||
import { WiFi } from '@app/components/layout/Sidebar/Settings/WiFi';
|
||||
|
||||
import { Interface } from './Interface';
|
||||
import { ChannelsGroup } from './radio/channels/panels/ChannelsGroup';
|
||||
import { CollapsibleSection } from '@components/generic/Sidebar/CollapsibleSection';
|
||||
import { ExternalSection } from '@components/generic/Sidebar/ExternalSection';
|
||||
import { SidebarOverlay } from '@components/generic/Sidebar/SidebarOverlay';
|
||||
import { Channels } from '@components/layout/Sidebar/Settings/Channels';
|
||||
import { ChannelsGroup } from '@components/layout/Sidebar/Settings/channels/ChannelsGroup';
|
||||
import { Interface } from '@components/layout/Sidebar/Settings/Interface';
|
||||
import { ExternalNotificationsSettingsPlanel } from '@components/layout/Sidebar/Settings/plugins/ExternalNotifications';
|
||||
import { RangeTestSettingsPanel } from '@components/layout/Sidebar/Settings/plugins/RangeTest';
|
||||
import { SerialSettingsPanel } from '@components/layout/Sidebar/Settings/plugins/Serial';
|
||||
import { StoreForwardSettingsPanel } from '@components/layout/Sidebar/Settings/plugins/StoreForward';
|
||||
import { Position } from '@components/layout/Sidebar/Settings/Position';
|
||||
import { Power } from '@components/layout/Sidebar/Settings/Power';
|
||||
import { Radio } from '@components/layout/Sidebar/Settings/Radio';
|
||||
import { User } from '@components/layout/Sidebar/Settings/User';
|
||||
import { WiFi } from '@components/layout/Sidebar/Settings/WiFi';
|
||||
|
||||
export interface SettingsProps {
|
||||
open: boolean;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type React from 'react';
|
||||
|
||||
import { Select } from '@meshtastic/components';
|
||||
import { Select } from '@components/generic/form/Select';
|
||||
|
||||
export const Interface = (): JSX.Element => {
|
||||
return (
|
||||
|
||||
@@ -4,11 +4,14 @@ import { Controller, useForm } from 'react-hook-form';
|
||||
import { FiSave } from 'react-icons/fi';
|
||||
import { MultiSelect } from 'react-multi-select-component';
|
||||
|
||||
import { bitwiseEncode } from '@app/core/utils/bitwise';
|
||||
import { IconButton } from '@components/generic/button/IconButton';
|
||||
import { Checkbox } from '@components/generic/form/Checkbox';
|
||||
import { Input } from '@components/generic/form/Input';
|
||||
import { Label } from '@components/generic/form/Label';
|
||||
import { Select } from '@components/generic/form/Select';
|
||||
import { connection } from '@core/connection';
|
||||
import { bitwiseEncode } from '@core/utils/bitwise';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import { Checkbox, IconButton, Input, Select } from '@meshtastic/components';
|
||||
import { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export const Position = (): JSX.Element => {
|
||||
|
||||
@@ -3,9 +3,11 @@ import React from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { FiSave } from 'react-icons/fi';
|
||||
|
||||
import { IconButton } from '@components/generic/button/IconButton';
|
||||
import { Checkbox } from '@components/generic/form/Checkbox';
|
||||
import { Select } from '@components/generic/form/Select';
|
||||
import { connection } from '@core/connection';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import { Checkbox, IconButton, Select } from '@meshtastic/components';
|
||||
import { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export const Power = (): JSX.Element => {
|
||||
|
||||
@@ -3,9 +3,11 @@ import React from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { FiSave } from 'react-icons/fi';
|
||||
|
||||
import { IconButton } from '@components/generic/button/IconButton';
|
||||
import { Checkbox } from '@components/generic/form/Checkbox';
|
||||
import { Select } from '@components/generic/form/Select';
|
||||
import { connection } from '@core/connection';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import { Checkbox, IconButton, Select } from '@meshtastic/components';
|
||||
import { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export const Radio = (): JSX.Element => {
|
||||
|
||||
@@ -4,9 +4,12 @@ import { useForm } from 'react-hook-form';
|
||||
import { FiSave } from 'react-icons/fi';
|
||||
import { base16 } from 'rfc4648';
|
||||
|
||||
import { IconButton } from '@components/generic/button/IconButton';
|
||||
import { Checkbox } from '@components/generic/form/Checkbox';
|
||||
import { Input } from '@components/generic/form/Input';
|
||||
import { Select } from '@components/generic/form/Select';
|
||||
import { connection } from '@core/connection';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import { Checkbox, IconButton, Input, Select } from '@meshtastic/components';
|
||||
import { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export const User = (): JSX.Element => {
|
||||
|
||||
@@ -3,9 +3,11 @@ import React from 'react';
|
||||
import { useForm, useWatch } from 'react-hook-form';
|
||||
import { FiSave } from 'react-icons/fi';
|
||||
|
||||
import { IconButton } from '@components/generic/button/IconButton';
|
||||
import { Checkbox } from '@components/generic/form/Checkbox';
|
||||
import { Input } from '@components/generic/form/Input';
|
||||
import { connection } from '@core/connection';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import { Checkbox, IconButton, Input } from '@meshtastic/components';
|
||||
import type { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export const WiFi = (): JSX.Element => {
|
||||
|
||||
+6
-3
@@ -5,9 +5,12 @@ import { useForm } from 'react-hook-form';
|
||||
import { FiSave } from 'react-icons/fi';
|
||||
import { MdRefresh, MdVisibility, MdVisibilityOff } from 'react-icons/md';
|
||||
|
||||
import { Form } from '@app/components/generic/form/Form';
|
||||
import { connection } from '@app/core/connection';
|
||||
import { Checkbox, IconButton, Input, Select } from '@meshtastic/components';
|
||||
import { IconButton } from '@components/generic/button/IconButton';
|
||||
import { Checkbox } from '@components/generic/form/Checkbox';
|
||||
import { Form } from '@components/generic/form/Form';
|
||||
import { Input } from '@components/generic/form/Input';
|
||||
import { Select } from '@components/generic/form/Select';
|
||||
import { connection } from '@core/connection';
|
||||
import { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export interface SettingsPanelProps {
|
||||
+4
-5
@@ -3,13 +3,12 @@ import type React from 'react';
|
||||
import { FaQrcode } from 'react-icons/fa';
|
||||
import { FiCode, FiSave } from 'react-icons/fi';
|
||||
|
||||
import { CollapsibleSection } from '@app/components/layout/Sidebar/sections/CollapsibleSection';
|
||||
import { useAppSelector } from '@app/hooks/useAppSelector';
|
||||
import { IconButton } from '@meshtastic/components';
|
||||
import { IconButton } from '@components/generic/button/IconButton';
|
||||
import { CollapsibleSection } from '@components/generic/Sidebar/CollapsibleSection';
|
||||
import { SettingsPanel } from '@components/layout/Sidebar/Settings/channels/Channels';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
import { SettingsPanel } from './SettingsPanel';
|
||||
|
||||
export const ChannelsGroup = (): JSX.Element => {
|
||||
const channels = useAppSelector((state) => state.meshtastic.radio.channels);
|
||||
|
||||
+6
-4
@@ -3,10 +3,12 @@ import React from 'react';
|
||||
import { useForm, useWatch } from 'react-hook-form';
|
||||
import { FiSave } from 'react-icons/fi';
|
||||
|
||||
import { Form } from '@app/components/generic/form/Form';
|
||||
import { connection } from '@app/core/connection';
|
||||
import { useAppSelector } from '@app/hooks/useAppSelector';
|
||||
import { Checkbox, IconButton, Input } from '@meshtastic/components';
|
||||
import { IconButton } from '@components/generic/button/IconButton';
|
||||
import { Checkbox } from '@components/generic/form/Checkbox';
|
||||
import { Form } from '@components/generic/form/Form';
|
||||
import { Input } from '@components/generic/form/Input';
|
||||
import { connection } from '@core/connection';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import type { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export const ExternalNotificationsSettingsPlanel = (): JSX.Element => {
|
||||
+6
-4
@@ -3,10 +3,12 @@ import React from 'react';
|
||||
import { useForm, useWatch } from 'react-hook-form';
|
||||
import { FiSave } from 'react-icons/fi';
|
||||
|
||||
import { Form } from '@app/components/generic/form/Form';
|
||||
import { connection } from '@app/core/connection';
|
||||
import { useAppSelector } from '@app/hooks/useAppSelector';
|
||||
import { Checkbox, IconButton, Input } from '@meshtastic/components';
|
||||
import { IconButton } from '@components/generic/button/IconButton';
|
||||
import { Checkbox } from '@components/generic/form/Checkbox';
|
||||
import { Form } from '@components/generic/form/Form';
|
||||
import { Input } from '@components/generic/form/Input';
|
||||
import { connection } from '@core/connection';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import type { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export const RangeTestSettingsPanel = (): JSX.Element => {
|
||||
+6
-4
@@ -3,10 +3,12 @@ import React from 'react';
|
||||
import { useForm, useWatch } from 'react-hook-form';
|
||||
import { FiSave } from 'react-icons/fi';
|
||||
|
||||
import { Form } from '@app/components/generic/form/Form';
|
||||
import { connection } from '@app/core/connection';
|
||||
import { useAppSelector } from '@app/hooks/useAppSelector';
|
||||
import { Checkbox, IconButton, Input } from '@meshtastic/components';
|
||||
import { IconButton } from '@components/generic/button/IconButton';
|
||||
import { Checkbox } from '@components/generic/form/Checkbox';
|
||||
import { Form } from '@components/generic/form/Form';
|
||||
import { Input } from '@components/generic/form/Input';
|
||||
import { connection } from '@core/connection';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import type { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export const SerialSettingsPanel = (): JSX.Element => {
|
||||
+6
-4
@@ -3,10 +3,12 @@ import React from 'react';
|
||||
import { useForm, useWatch } from 'react-hook-form';
|
||||
import { FiSave } from 'react-icons/fi';
|
||||
|
||||
import { Form } from '@app/components/generic/form/Form';
|
||||
import { connection } from '@app/core/connection';
|
||||
import { useAppSelector } from '@app/hooks/useAppSelector';
|
||||
import { Checkbox, IconButton, Input } from '@meshtastic/components';
|
||||
import { IconButton } from '@components/generic/button/IconButton';
|
||||
import { Checkbox } from '@components/generic/form/Checkbox';
|
||||
import { Form } from '@components/generic/form/Form';
|
||||
import { Input } from '@components/generic/form/Input';
|
||||
import { connection } from '@core/connection';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import type { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export const StoreForwardSettingsPanel = (): JSX.Element => {
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
import type React from 'react';
|
||||
|
||||
import JSONPretty from 'react-json-pretty';
|
||||
|
||||
import { useAppSelector } from '@app/hooks/useAppSelector';
|
||||
import { CopyButton } from '@components/menu/buttons/CopyButton';
|
||||
|
||||
export const ExternalNotificationsDebugPanel = (): JSX.Element => {
|
||||
const preferences = useAppSelector(
|
||||
(state) => state.meshtastic.radio.preferences,
|
||||
);
|
||||
|
||||
const debugData = {
|
||||
extNotificationPluginActive: preferences.extNotificationPluginActive,
|
||||
extNotificationPluginAlertBell: preferences.extNotificationPluginAlertBell,
|
||||
extNotificationPluginAlertMessage:
|
||||
preferences.extNotificationPluginAlertMessage,
|
||||
extNotificationPluginEnabled: preferences.extNotificationPluginEnabled,
|
||||
extNotificationPluginOutput: preferences.extNotificationPluginOutput,
|
||||
extNotificationPluginOutputMs: preferences.extNotificationPluginOutputMs,
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="fixed right-0 m-2">
|
||||
<CopyButton data={JSON.stringify(debugData)} />
|
||||
</div>
|
||||
<JSONPretty className="max-w-sm" data={debugData} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,27 +0,0 @@
|
||||
import type React from 'react';
|
||||
|
||||
import JSONPretty from 'react-json-pretty';
|
||||
|
||||
import { useAppSelector } from '@app/hooks/useAppSelector';
|
||||
import { CopyButton } from '@components/menu/buttons/CopyButton';
|
||||
|
||||
export const RangeTestDebugPanel = (): JSX.Element => {
|
||||
const preferences = useAppSelector(
|
||||
(state) => state.meshtastic.radio.preferences,
|
||||
);
|
||||
|
||||
const debugData = {
|
||||
rangeTestPluginEnabled: preferences.rangeTestPluginEnabled,
|
||||
rangeTestPluginSave: preferences.rangeTestPluginSave,
|
||||
rangeTestPluginSender: preferences.rangeTestPluginSender,
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="fixed right-0 m-2">
|
||||
<CopyButton data={JSON.stringify(debugData)} />
|
||||
</div>
|
||||
<JSONPretty className="max-w-sm" data={debugData} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,30 +0,0 @@
|
||||
import type React from 'react';
|
||||
|
||||
import JSONPretty from 'react-json-pretty';
|
||||
|
||||
import { useAppSelector } from '@app/hooks/useAppSelector';
|
||||
import { CopyButton } from '@components/menu/buttons/CopyButton';
|
||||
|
||||
export const SerialDebugPanel = (): JSX.Element => {
|
||||
const preferences = useAppSelector(
|
||||
(state) => state.meshtastic.radio.preferences,
|
||||
);
|
||||
|
||||
const debugData = {
|
||||
serialpluginEnabled: preferences.serialpluginEnabled,
|
||||
serialpluginEcho: preferences.serialpluginEcho,
|
||||
serialpluginMode: preferences.serialpluginMode,
|
||||
serialpluginRxd: preferences.serialpluginRxd,
|
||||
serialpluginTxd: preferences.serialpluginTxd,
|
||||
serialpluginTimeout: preferences.serialpluginTimeout,
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="fixed right-0 m-2">
|
||||
<CopyButton data={JSON.stringify(debugData)} />
|
||||
</div>
|
||||
<JSONPretty className="max-w-sm" data={debugData} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
import type React from 'react';
|
||||
|
||||
import JSONPretty from 'react-json-pretty';
|
||||
|
||||
import { useAppSelector } from '@app/hooks/useAppSelector';
|
||||
import { CopyButton } from '@components/menu/buttons/CopyButton';
|
||||
|
||||
export const StoreForwardDebugPanel = (): JSX.Element => {
|
||||
const preferences = useAppSelector(
|
||||
(state) => state.meshtastic.radio.preferences,
|
||||
);
|
||||
|
||||
const debugData = {
|
||||
storeForwardPluginEnabled: preferences.storeForwardPluginEnabled,
|
||||
storeForwardPluginHeartbeat: preferences.storeForwardPluginHeartbeat,
|
||||
storeForwardPluginRecords: preferences.storeForwardPluginRecords,
|
||||
storeForwardPluginHistoryReturnMax:
|
||||
preferences.storeForwardPluginHistoryReturnMax,
|
||||
storeForwardPluginHistoryReturnWindow:
|
||||
preferences.storeForwardPluginHistoryReturnWindow,
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="fixed right-0 m-2">
|
||||
<CopyButton data={JSON.stringify(debugData)} />
|
||||
</div>
|
||||
<JSONPretty className="max-w-sm" data={debugData} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
import type React from 'react';
|
||||
|
||||
import JSONPretty from 'react-json-pretty';
|
||||
|
||||
import { CopyButton } from '@components/menu/buttons/CopyButton';
|
||||
import type { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export interface DebugPanelProps {
|
||||
channel: Protobuf.Channel;
|
||||
}
|
||||
|
||||
export const DebugPanel = ({ channel }: DebugPanelProps): JSX.Element => {
|
||||
return (
|
||||
<>
|
||||
<div className="fixed right-0 m-2">
|
||||
<CopyButton data={JSON.stringify(channel)} />
|
||||
</div>
|
||||
<JSONPretty className="max-w-sm" data={channel} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,20 +0,0 @@
|
||||
import type React from 'react';
|
||||
|
||||
import QRCode from 'react-qr-code';
|
||||
|
||||
import type { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
|
||||
export interface QRCodePanelProps {
|
||||
channel: Protobuf.Channel;
|
||||
}
|
||||
|
||||
export const QRCodePanel = ({ channel }: QRCodePanelProps): JSX.Element => {
|
||||
return (
|
||||
<div className="m-auto">
|
||||
<QRCode
|
||||
className="rounded-md"
|
||||
value={`https://www.meshtastic.org/d/#${channel.index}`}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,9 +1,8 @@
|
||||
import React from 'react';
|
||||
|
||||
import { useAppSelector } from '@app/hooks/useAppSelector';
|
||||
|
||||
import { ButtonNav } from './ButtonNav';
|
||||
import { Settings } from './Settings/Index';
|
||||
import { ButtonNav } from '@components/layout/Sidebar/ButtonNav';
|
||||
import { Settings } from '@components/layout/Sidebar/Settings/Index';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
|
||||
export interface SidebarProps {
|
||||
children: React.ReactNode;
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { AnimatePresence, m } from 'framer-motion';
|
||||
import { FiArrowUp } from 'react-icons/fi';
|
||||
|
||||
export interface CollapsibleSectionProps {
|
||||
title: string;
|
||||
icon?: JSX.Element;
|
||||
actions?: JSX.Element;
|
||||
children: JSX.Element;
|
||||
}
|
||||
|
||||
export const CollapsibleSection = ({
|
||||
title,
|
||||
icon,
|
||||
actions,
|
||||
children,
|
||||
}: CollapsibleSectionProps): JSX.Element => {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const toggleOpen = (): void => setOpen(!open);
|
||||
return (
|
||||
<m.div>
|
||||
<m.div
|
||||
layout
|
||||
className="w-full cursor-pointer select-none overflow-hidden dark:bg-secondaryDark dark:text-gray-400"
|
||||
>
|
||||
<m.div
|
||||
layout
|
||||
onClick={toggleOpen}
|
||||
whileHover={{ scale: 1.01 }}
|
||||
whileTap={{ scale: 0.99 }}
|
||||
className="flex justify-between gap-2 border-b border-gray-300 p-2 text-sm font-medium dark:border-primaryDark"
|
||||
>
|
||||
<m.div className="flex gap-2 ">
|
||||
<m.div className="my-auto">{icon}</m.div>
|
||||
{title}
|
||||
</m.div>
|
||||
<m.div
|
||||
animate={open ? 'open' : 'closed'}
|
||||
initial={{ rotate: 180 }}
|
||||
variants={{
|
||||
open: { rotate: 0 },
|
||||
closed: { rotate: 180 },
|
||||
}}
|
||||
className="my-auto"
|
||||
>
|
||||
<FiArrowUp />
|
||||
</m.div>
|
||||
</m.div>
|
||||
</m.div>
|
||||
<AnimatePresence>
|
||||
{open && (
|
||||
<>
|
||||
{actions && (
|
||||
<m.div className="flex justify-end gap-1 rounded-b-md border-x border-b p-1 dark:border-gray-600">
|
||||
{actions}
|
||||
</m.div>
|
||||
)}
|
||||
<m.div
|
||||
className="p-2"
|
||||
layout
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
>
|
||||
{children}
|
||||
</m.div>
|
||||
</>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</m.div>
|
||||
);
|
||||
};
|
||||
@@ -1,47 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { m } from 'framer-motion';
|
||||
import { FiExternalLink } from 'react-icons/fi';
|
||||
|
||||
export interface ExternalSectionProps {
|
||||
title: string;
|
||||
icon?: JSX.Element;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
export const ExternalSection = ({
|
||||
title,
|
||||
icon,
|
||||
onClick,
|
||||
}: ExternalSectionProps): JSX.Element => {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const toggleOpen = (): void => setOpen(!open);
|
||||
return (
|
||||
<m.div
|
||||
onClick={(): void => {
|
||||
onClick();
|
||||
}}
|
||||
>
|
||||
<m.div
|
||||
layout
|
||||
className="w-full cursor-pointer select-none overflow-hidden dark:bg-secondaryDark dark:text-gray-400"
|
||||
>
|
||||
<m.div
|
||||
layout
|
||||
onClick={toggleOpen}
|
||||
whileHover={{ scale: 1.01 }}
|
||||
whileTap={{ scale: 0.99 }}
|
||||
className="flex justify-between gap-2 border-b border-gray-300 p-2 text-sm font-medium dark:border-primaryDark"
|
||||
>
|
||||
<m.div className="flex gap-2 ">
|
||||
<m.div className="my-auto">{icon}</m.div>
|
||||
{title}
|
||||
</m.div>
|
||||
<m.div className="my-auto">
|
||||
<FiExternalLink />
|
||||
</m.div>
|
||||
</m.div>
|
||||
</m.div>
|
||||
</m.div>
|
||||
);
|
||||
};
|
||||
@@ -1,55 +0,0 @@
|
||||
import type React from 'react';
|
||||
|
||||
import { AnimatePresence, AnimateSharedLayout, m } from 'framer-motion';
|
||||
import { FiArrowLeft } from 'react-icons/fi';
|
||||
|
||||
import { IconButton } from '@meshtastic/components';
|
||||
|
||||
export interface SidebarOverlayProps {
|
||||
title: string;
|
||||
open: boolean;
|
||||
close: () => void;
|
||||
direction: 'x' | 'y';
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const SidebarOverlay = ({
|
||||
title,
|
||||
open,
|
||||
close,
|
||||
direction,
|
||||
children,
|
||||
}: SidebarOverlayProps): JSX.Element => {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{open && (
|
||||
<m.div
|
||||
className="absolute z-30 flex h-full w-full flex-col bg-gray-100 dark:bg-primaryDark"
|
||||
animate={direction === 'x' ? { translateX: 0 } : { translateY: 0 }}
|
||||
initial={
|
||||
direction === 'x' ? { translateX: '-100%' } : { translateY: '100%' }
|
||||
}
|
||||
exit={
|
||||
direction === 'x' ? { translateX: '-100%' } : { translateY: '100%' }
|
||||
}
|
||||
transition={{ type: 'just' }}
|
||||
>
|
||||
<AnimateSharedLayout>
|
||||
<div className="flex gap-2 border-b border-gray-300 p-2 dark:border-gray-600">
|
||||
<IconButton
|
||||
onClick={(): void => {
|
||||
close();
|
||||
}}
|
||||
icon={<FiArrowLeft />}
|
||||
/>
|
||||
<div className="my-auto text-lg font-medium dark:text-white">
|
||||
{title}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-grow overflow-y-auto">{children}</div>
|
||||
</AnimateSharedLayout>
|
||||
</m.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user