mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-03-01 12:44:17 +00:00
merged main
This commit is contained in:
commit
4f768fe2dc
@ -70,3 +70,7 @@ Tags, colors and clusters help to retain the overview.
|
||||
<a href="https://opencollective.com/utopia-project">
|
||||
<img width="300" src="https://opencollective.com/utopia-project/donate/button@2x.png?color=blue" />
|
||||
</a>
|
||||
|
||||
---
|
||||
|
||||
This project is tested with BrowserStack
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "utopia-ui",
|
||||
"version": "3.0.80",
|
||||
"version": "3.0.81",
|
||||
"description": "Reuseable React Components to build mapping apps for real life communities and networks",
|
||||
"repository": "https://github.com/utopia-os/utopia-ui",
|
||||
"homepage": "https://utopia-os.org/",
|
||||
|
||||
@ -13,15 +13,17 @@ export function AppShell({
|
||||
appName,
|
||||
children,
|
||||
assetsApi,
|
||||
embedded,
|
||||
}: {
|
||||
appName: string
|
||||
children: React.ReactNode
|
||||
assetsApi: AssetsApi
|
||||
embedded?: boolean
|
||||
}) {
|
||||
return (
|
||||
<ContextWrapper>
|
||||
<div className='tw:flex tw:flex-col tw:h-full'>
|
||||
<SetAppState assetsApi={assetsApi} />
|
||||
<SetAppState assetsApi={assetsApi} embedded={embedded} />
|
||||
<NavBar appName={appName}></NavBar>
|
||||
<div id='app-content' className='tw:flex'>
|
||||
{children}
|
||||
|
||||
@ -12,8 +12,7 @@ export function Content({ children }: ContentProps) {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${appState.sideBarOpen && !appState.sideBarSlim ? 'tw:ml-48' : appState.sideBarOpen && appState.sideBarSlim ? 'tw:ml-14' : ''} tw:flex tw:flex-col tw:w-full tw:h-full tw:bg-base-200 tw:relative tw:transition-all tw:duration-300`}
|
||||
>
|
||||
className={`${appState.sideBarOpen && !appState.sideBarSlim ? 'tw:ml-48' : appState.sideBarOpen && appState.sideBarSlim ? 'tw:ml-14' : ''} tw:w-full tw:h-full tw:bg-base-200 tw:relative tw:transition-all tw:duration-300`} >
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import Bars3Icon from '@heroicons/react/16/solid/Bars3Icon'
|
||||
import QuestionMarkIcon from '@heroicons/react/24/outline/QuestionMarkCircleIcon'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { Link, useLocation } from 'react-router-dom'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
import { ThemeControl } from '#components/Templates/ThemeControl'
|
||||
|
||||
@ -18,20 +18,12 @@ export default function NavBar({ appName }: { appName: string }) {
|
||||
|
||||
const nameRef = useRef<HTMLHeadingElement>(null)
|
||||
const [nameWidth, setNameWidth] = useState<number>(0)
|
||||
const location = useLocation()
|
||||
const [showNav, setShowNav] = useState<boolean>(false)
|
||||
|
||||
useEffect(() => {
|
||||
showNav && nameRef.current && setNameWidth(nameRef.current.scrollWidth)
|
||||
}, [nameRef, appName, showNav])
|
||||
!appState.embedded && nameRef.current && setNameWidth(nameRef.current.scrollWidth)
|
||||
}, [nameRef, appName, appState.embedded])
|
||||
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(location.search)
|
||||
const embedded = params.get('embedded')
|
||||
embedded !== 'true' && setShowNav(true)
|
||||
}, [location])
|
||||
|
||||
if (showNav) {
|
||||
if (!appState.embedded) {
|
||||
return (
|
||||
<>
|
||||
<div className='tw:navbar tw:bg-base-100 tw:z-9998 tw:shadow-xl tw:relative tw:p-0'>
|
||||
|
||||
@ -4,13 +4,22 @@ import { useSetAppState } from './hooks/useAppState'
|
||||
|
||||
import type { AssetsApi } from '#types/AssetsApi'
|
||||
|
||||
export const SetAppState = ({ assetsApi }: { assetsApi: AssetsApi }) => {
|
||||
export const SetAppState = ({
|
||||
assetsApi,
|
||||
embedded,
|
||||
}: {
|
||||
assetsApi: AssetsApi
|
||||
embedded?: boolean
|
||||
}) => {
|
||||
const setAppState = useSetAppState()
|
||||
|
||||
useEffect(() => {
|
||||
setAppState({ assetsApi })
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [assetsApi])
|
||||
}, [assetsApi, setAppState])
|
||||
|
||||
useEffect(() => {
|
||||
setAppState({ embedded })
|
||||
}, [embedded, setAppState])
|
||||
|
||||
return <></>
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import ChevronRightIcon from '@heroicons/react/24/outline/ChevronRightIcon'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { NavLink, useLocation } from 'react-router-dom'
|
||||
|
||||
import { useAppState, useSetAppState } from './hooks/useAppState'
|
||||
@ -19,14 +18,6 @@ export interface Route {
|
||||
export function SideBar({ routes, bottomRoutes }: { routes: Route[]; bottomRoutes?: Route[] }) {
|
||||
const location = useLocation()
|
||||
|
||||
const [embedded, setEmbedded] = useState<boolean>(true)
|
||||
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(location.search)
|
||||
const embedded = params.get('embedded')
|
||||
embedded !== 'true' && setEmbedded(false)
|
||||
}, [location])
|
||||
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
|
||||
const appState = useAppState()
|
||||
@ -45,12 +36,12 @@ export function SideBar({ routes, bottomRoutes }: { routes: Route[]; bottomRoute
|
||||
id='sidenav'
|
||||
className={`${appState.sideBarOpen ? 'tw:translate-x-0' : 'tw:-translate-x-full'}
|
||||
${appState.sideBarSlim ? 'tw:w-14' : 'tw:w-48'}
|
||||
${embedded ? 'tw:mt-5.5 tw:h-[calc(100dvh-22px)]' : 'tw:mt-16 tw:h-[calc(100dvh-64px)]'}
|
||||
${appState.embedded ? 'tw:mt-5.5 tw:h-[calc(100dvh-22px)]' : 'tw:mt-16 tw:h-[calc(100dvh-64px)]'}
|
||||
tw:fixed tw:left-0 tw:transition-all tw:duration-300 tw:top-0 tw:z-10035
|
||||
tw:overflow-hidden tw:shadow-xl tw:dark:bg-zinc-800`}
|
||||
>
|
||||
<div
|
||||
className={`tw:flex tw:flex-col ${embedded ? 'tw:h-full' : 'tw:h-[calc(100dvh-64px)]'}`}
|
||||
className={`tw:flex tw:flex-col ${appState.embedded ? 'tw:h-full' : 'tw:h-[calc(100dvh-64px)]'}`}
|
||||
>
|
||||
<ul className='tw:menu tw:w-full tw:bg-base-100 tw:text-base-content tw:p-0'>
|
||||
{routes.map((route, k) => {
|
||||
|
||||
@ -9,6 +9,7 @@ interface AppState {
|
||||
sideBarOpen: boolean
|
||||
sideBarSlim: boolean
|
||||
showThemeControl: boolean
|
||||
embedded: boolean
|
||||
}
|
||||
|
||||
type UseAppManagerResult = ReturnType<typeof useAppManager>
|
||||
@ -18,6 +19,7 @@ const initialAppState: AppState = {
|
||||
sideBarOpen: false,
|
||||
sideBarSlim: false,
|
||||
showThemeControl: false,
|
||||
embedded: false,
|
||||
}
|
||||
|
||||
const AppContext = createContext<UseAppManagerResult>({
|
||||
|
||||
@ -14,11 +14,12 @@ import FlagIcon from '@heroicons/react/24/outline/FlagIcon'
|
||||
import MagnifyingGlassIcon from '@heroicons/react/24/outline/MagnifyingGlassIcon'
|
||||
import axios from 'axios'
|
||||
import { LatLng, LatLngBounds, marker } from 'leaflet'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useRef, useState } from 'react'
|
||||
import SVG from 'react-inlinesvg'
|
||||
import { useMap, useMapEvents } from 'react-leaflet'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { useAppState } from '#components/AppShell/hooks/useAppState'
|
||||
import { useDebounce } from '#components/Map/hooks/useDebounce'
|
||||
import { useAddFilterTag } from '#components/Map/hooks/useFilter'
|
||||
import { useItems } from '#components/Map/hooks/useItems'
|
||||
@ -48,6 +49,7 @@ export const SearchControl = () => {
|
||||
const items = useItems()
|
||||
const leafletRefs = useLeafletRefs()
|
||||
const addFilterTag = useAddFilterTag()
|
||||
const appState = useAppState()
|
||||
|
||||
useMapEvents({
|
||||
popupopen: () => {
|
||||
@ -97,21 +99,13 @@ export const SearchControl = () => {
|
||||
}
|
||||
|
||||
const searchInput = useRef<HTMLInputElement>(null)
|
||||
const [embedded, setEmbedded] = useState<boolean>(true)
|
||||
|
||||
const location = useLocation()
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(location.search)
|
||||
const embedded = params.get('embedded')
|
||||
embedded !== 'true' && setEmbedded(false)
|
||||
}, [location])
|
||||
|
||||
return (
|
||||
<>
|
||||
{!(windowDimensions.height < 500 && popupOpen && hideSuggestions) && (
|
||||
<div className='tw:w-[calc(100vw-2rem)] tw:max-w-[22rem] '>
|
||||
<div className='tw:flex tw:flex-row'>
|
||||
{embedded && <SidebarControl />}
|
||||
{appState.embedded && <SidebarControl />}
|
||||
<div className='tw:relative tw:shrink tw:max-w-69 tw:w-full'>
|
||||
<input
|
||||
type='text'
|
||||
|
||||
@ -194,7 +194,7 @@ export function UtopiaMapInner({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`tw:h-full ${selectNewItemPosition != null ? 'crosshair-cursor-enabled' : undefined}`}
|
||||
className={`tw:h-full ${selectNewItemPosition != null ? 'crosshair-cursor-enabled' : ''}`}
|
||||
>
|
||||
<Outlet />
|
||||
<Control position='topLeft' zIndex='1000' absolute>
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
"module": "esnext",
|
||||
"target": "ESNext",
|
||||
"lib": ["es6", "dom","es2015", "es2016", "es2017", "es2020"],
|
||||
"sourceMap": true,
|
||||
"sourceMap": false,
|
||||
"allowJs": false,
|
||||
"jsx": "react-jsx",
|
||||
"moduleResolution": "node",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user