diff --git a/ui/src/components/entry/entry-panel.tsx b/ui/src/components/panels/entry-panel.tsx similarity index 100% rename from ui/src/components/entry/entry-panel.tsx rename to ui/src/components/panels/entry-panel.tsx diff --git a/ui/src/components/panels/list-panel.tsx b/ui/src/components/panels/list-panel.tsx new file mode 100644 index 00000000..85423d23 --- /dev/null +++ b/ui/src/components/panels/list-panel.tsx @@ -0,0 +1,131 @@ +import { createActiveElement } from '@solid-primitives/active-element'; +import { createElementBounds } from '@solid-primitives/bounds'; +import { useIsRouting } from '@solidjs/router'; +import { cx } from 'class-variance-authority'; +import { Match, Show, Switch, createEffect, createSignal } from 'solid-js'; +import { Portal } from 'solid-js/web'; +import { EntryList } from '~/components/entry/entry-list'; +import { FeedHeader } from '~/components/feed/feed-header'; +import { FeedInfo } from '~/components/feed/feed-info'; +import { FeedList } from '~/components/feed/feed-list'; +import { Panel } from '~/components/layout/panel'; +import { MenuFeeds } from '~/components/menus/menu-feeds'; +import { NavRow } from '~/components/nav/nav-row'; +import { NavViewSwitcher } from '~/components/nav/nav-view-switcher'; +import { useQueryState } from '~/hooks/use-query-state'; +import { useViewport } from '~/hooks/use-viewport'; + +export const ListPanel = () => { + const state = useQueryState(); + const viewport = useViewport(); + const isRouting = useIsRouting(); + + const [showFeedSelector, setShowFeedSelector] = createSignal(false); + const [allFeedsMenuOpen, setAllFeedsMenuOpen] = createSignal(false); + + const [container, setContainer] = createSignal(); + const containerBounds = createElementBounds(container); + + const viewingEntry = () => !!state.params.entry_uuid; + + const isMobile = () => viewport.lteBreakpoint('md'); + const showPanel = () => !isMobile() || (isMobile() && !viewingEntry()); + const showFeeds = () => viewport.lteBreakpoint('xl') && showFeedSelector(); + + const activeElement = createActiveElement(); + const containsActiveElement = () => container()?.contains(activeElement()); + + const handleSkipToContent = () => { + const el = container(); + if (!el) return; + + const focusable = el.querySelector('[tabindex="0"]') as HTMLElement | undefined; + focusable?.focus() || el.focus(); + }; + + createEffect(() => { + // Hide feed selector when routing + if (!isRouting()) return; + setShowFeedSelector(false); + }); + + createEffect(() => { + // Scroll to top of list whenever the feed URL changes + state.getFeedUrl(); + container()?.scrollTo({ top: 0, behavior: 'instant' }); + }); + + return ( + <> + + + + + +
+
+ +
+ + + + +
+ + {/* Showing single feed -- show feed info */} + + + + + {/* Showing all feeds -- create custom label */} + +
+ + +
+
+
+
+
+
+ + +
+ + + + + + + + + +
+
+
+ + ); +}; diff --git a/ui/src/routes/feed.tsx b/ui/src/routes/feed.tsx index cd52cc88..6161c3c5 100644 --- a/ui/src/routes/feed.tsx +++ b/ui/src/routes/feed.tsx @@ -1,21 +1,6 @@ -import { createActiveElement } from '@solid-primitives/active-element'; -import { createElementBounds } from '@solid-primitives/bounds'; -import { useIsRouting } from '@solidjs/router'; -import { cx } from 'class-variance-authority'; -import { Match, Show, Switch, createEffect, createSignal } from 'solid-js'; -import { Portal } from 'solid-js/web'; -import { EntryList } from '~/components/entry/entry-list'; -import { EntryPanel } from '~/components/entry/entry-panel'; -import { FeedHeader } from '~/components/feed/feed-header'; -import { FeedInfo } from '~/components/feed/feed-info'; -import { FeedList } from '~/components/feed/feed-list'; -import { Panel } from '~/components/layout/panel'; import { Sidebar } from '~/components/layout/sidebar'; -import { MenuFeeds } from '~/components/menus/menu-feeds'; -import { NavRow } from '~/components/nav/nav-row'; -import { NavViewSwitcher } from '~/components/nav/nav-view-switcher'; -import { useQueryState } from '~/hooks/use-query-state'; -import { useViewport } from '~/hooks/use-viewport'; +import { EntryPanel } from '~/components/panels/entry-panel'; +import { ListPanel } from '~/components/panels/list-panel'; export default () => ( <> @@ -27,118 +12,3 @@ export default () => ( ); - -const ListPanel = () => { - const state = useQueryState(); - const viewport = useViewport(); - const isRouting = useIsRouting(); - - const [showFeedSelector, setShowFeedSelector] = createSignal(false); - const [allFeedsMenuOpen, setAllFeedsMenuOpen] = createSignal(false); - - const [container, setContainer] = createSignal(); - const containerBounds = createElementBounds(container); - - const viewingEntry = () => !!state.params.entry_uuid; - - const isMobile = () => viewport.lteBreakpoint('md'); - const showPanel = () => !isMobile() || (isMobile() && !viewingEntry()); - const showFeeds = () => viewport.lteBreakpoint('xl') && showFeedSelector(); - - const activeElement = createActiveElement(); - const containsActiveElement = () => container()?.contains(activeElement()); - - const handleSkipToContent = () => { - const el = container(); - if (!el) return; - - const focusable = el.querySelector('[tabindex="0"]') as HTMLElement | undefined; - focusable?.focus() || el.focus(); - }; - - createEffect(() => { - // Hide feed selector when routing - if (!isRouting()) return; - setShowFeedSelector(false); - }); - - createEffect(() => { - // Scroll to top of list whenever the feed URL changes - state.getFeedUrl(); - container()?.scrollTo({ top: 0, behavior: 'instant' }); - }); - - return ( - <> - - - - - -
-
- -
- - - - -
- - {/* Showing single feed -- show feed info */} - - - - - {/* Showing all feeds -- create custom label */} - -
- - -
-
-
-
-
-
- - -
- - - - - - - - - -
-
-
- - ); -};