mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-06 08:24:46 +00:00
feat(plugin): let users select a sidebar view
An exclusive view replaces the sidebar content while the host retains navigation, callouts, and footer. The device remembers the selection, unavailable views fall back to the default, and throwing views provide recovery. Device-scoped plugin settings persist locally with schema validation and revision conflicts. Web E2E and Android tablet QA cover selection, preserved chrome, disabled-view fallback, and error recovery.
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
import { useCallback, useMemo } from "react";
|
||||
import {
|
||||
useWorkspace,
|
||||
useWorkspaces,
|
||||
type WorkspaceRef,
|
||||
type PluginSidebarViewProps,
|
||||
} from "@getpaseo/plugin/client";
|
||||
import { Pressable, ScrollView, Text } from "react-native";
|
||||
|
||||
function WorkspaceRow({
|
||||
reference,
|
||||
view,
|
||||
}: {
|
||||
reference: WorkspaceRef;
|
||||
view: PluginSidebarViewProps;
|
||||
}) {
|
||||
const workspace = useWorkspace(reference);
|
||||
const open = useCallback(
|
||||
() => view.navigation.openWorkspace(reference),
|
||||
[view.navigation, reference],
|
||||
);
|
||||
const textStyle = useMemo(
|
||||
() => ({ color: view.theme.colors.foreground, fontSize: 12, lineHeight: 16 }),
|
||||
[view.theme],
|
||||
);
|
||||
const labelStyle = useMemo(
|
||||
() => ({ color: view.theme.colors.foregroundMuted, fontSize: 11 }),
|
||||
[view.theme],
|
||||
);
|
||||
if (!workspace) return null;
|
||||
return (
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`Open ${workspace.name}`}
|
||||
onPress={open}
|
||||
style={rowStyle}
|
||||
>
|
||||
<Text style={textStyle}>{workspace.title ?? workspace.name}</Text>
|
||||
<Text style={labelStyle}>{workspace.indicatorLabel}</Text>
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
export function Workspaces(view: PluginSidebarViewProps) {
|
||||
const workspaces = useWorkspaces({ orderBy: "name" });
|
||||
return (
|
||||
<ScrollView>
|
||||
{workspaces.map((reference) => (
|
||||
<WorkspaceRow key={reference.key} reference={reference} view={view} />
|
||||
))}
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
const rowStyle = { minHeight: 28, paddingHorizontal: 12, justifyContent: "center" } as const;
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { PluginClientContext } from "@getpaseo/plugin/client";
|
||||
import { Workspaces } from "./client/workspaces";
|
||||
|
||||
export default function contribute(client: PluginClientContext) {
|
||||
return client.addSidebarView({
|
||||
id: "workspaces",
|
||||
title: "Example workspaces",
|
||||
Component: Workspaces,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"id": "sidebar-views",
|
||||
"requirements": { "paseo": ">=0.16.0" }
|
||||
}
|
||||
Reference in New Issue
Block a user