diff --git a/docs/static/appkit-ui/styles.gen.css b/docs/static/appkit-ui/styles.gen.css index a2192039d..5dbf7869a 100644 --- a/docs/static/appkit-ui/styles.gen.css +++ b/docs/static/appkit-ui/styles.gen.css @@ -3967,6 +3967,11 @@ flex-direction: row; } } + .sm\:items-center { + @media (width >= 40rem) { + align-items: center; + } + } .sm\:justify-end { @media (width >= 40rem) { justify-content: flex-end; @@ -3977,6 +3982,11 @@ gap: calc(var(--spacing) * 2.5); } } + .sm\:gap-6 { + @media (width >= 40rem) { + gap: calc(var(--spacing) * 6); + } + } .sm\:pr-2\.5 { @media (width >= 40rem) { padding-right: calc(var(--spacing) * 2.5); diff --git a/packages/appkit-ui/src/react/charts/options.ts b/packages/appkit-ui/src/react/charts/options.ts index 5146b4694..9f0d1ac66 100644 --- a/packages/appkit-ui/src/react/charts/options.ts +++ b/packages/appkit-ui/src/react/charts/options.ts @@ -270,6 +270,7 @@ export function buildCartesianOption( right: "10%", top: ctx.title ? "15%" : "10%", bottom: ctx.showLegend && hasMultipleSeries ? "20%" : "15%", + containLabel: true, }, xAxis: { type: isScatter ? "value" : isTimeSeries ? "time" : "category", diff --git a/packages/appkit-ui/src/react/hooks/index.ts b/packages/appkit-ui/src/react/hooks/index.ts index b1a5a1446..e272616d2 100644 --- a/packages/appkit-ui/src/react/hooks/index.ts +++ b/packages/appkit-ui/src/react/hooks/index.ts @@ -25,6 +25,7 @@ export { type UseChartDataResult, useChartData, } from "./use-chart-data"; +export { useIsMobile } from "./use-mobile"; export { usePluginClientConfig } from "./use-plugin-config"; export { type UseServingInvokeOptions, diff --git a/packages/appkit-ui/src/react/table/data-table.tsx b/packages/appkit-ui/src/react/table/data-table.tsx index 91e8a5ccc..2b7306d03 100644 --- a/packages/appkit-ui/src/react/table/data-table.tsx +++ b/packages/appkit-ui/src/react/table/data-table.tsx @@ -256,8 +256,9 @@ export function DataTable(props: DataTableProps) { -
-
+ {/* On mobile, flex-col-reverse places pagination buttons above the info row for easier thumb access */} +
+
{totalRows > 0 ? finalLabels.showing diff --git a/template/client/src/App.tsx b/template/client/src/App.tsx index d3cc4bc81..33d2312d4 100644 --- a/template/client/src/App.tsx +++ b/template/client/src/App.tsx @@ -1,10 +1,18 @@ import { createBrowserRouter, RouterProvider, NavLink, Outlet } from 'react-router'; +import { useState, useEffect } from 'react'; import { + Button, Card, CardContent, CardHeader, CardTitle, + Sheet, + SheetContent, + SheetHeader, + SheetTitle, + useIsMobile, } from '@databricks/appkit-ui/react'; +import { Menu } from 'lucide-react'; {{- if .plugins.agents}} import { AgentChat } from './pages/agents/AgentChat'; {{- end}} @@ -37,59 +45,98 @@ const navLinkClass = ({ isActive }: { isActive: boolean }) => : 'text-muted-foreground hover:bg-muted hover:text-foreground' }`; -function Layout() { +const mobileNavLinkClass = ({ isActive }: { isActive: boolean }) => + `block px-3 py-2 rounded-md text-sm font-medium transition-colors ${ + isActive + ? 'bg-primary text-primary-foreground' + : 'text-muted-foreground hover:bg-muted hover:text-foreground' + }`; + +type NavLinkClassFn = (props: { isActive: boolean }) => string; + +function NavLinks({ className, linkClass, onClick }: { className?: string; linkClass: NavLinkClassFn; onClick?: () => void }) { return ( -
-
-

{{.projectName}}

- + ); +} + +function Layout() { + const isMobile = useIsMobile(); + const [mobileNavOpen, setMobileNavOpen] = useState(false); + + // Close mobile nav when viewport crosses to desktop + useEffect(() => { + if (!isMobile) setMobileNavOpen(false); + }, [isMobile]); + + return ( +
+
+

{{.projectName}}

+ {/* Desktop nav — hidden below md breakpoint */} + + {/* Mobile nav — visible below md breakpoint */} +
+ + + + + Navigation + + setMobileNavOpen(false)} /> + + +
-
+
diff --git a/template/client/src/pages/agents/AgentChat.tsx b/template/client/src/pages/agents/AgentChat.tsx index a64855335..5d1e5758d 100644 --- a/template/client/src/pages/agents/AgentChat.tsx +++ b/template/client/src/pages/agents/AgentChat.tsx @@ -141,7 +141,7 @@ export function AgentChat() {

- +
-
+
{volumes.length > 1 && (