> ## Documentation Index
> Fetch the complete documentation index at: https://docs.metabind.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Toolbar

> Modifiers for populating and controlling the visibility of system toolbars

export const PlatformStatuses = ({statuses}) => {
  const StatusBadge = ({status, label}) => {
    const styles = {
      green: {
        backgroundColor: '#dcfce7',
        color: '#166534'
      },
      orange: {
        backgroundColor: '#fed7aa',
        color: '#9a3412'
      },
      red: {
        backgroundColor: '#fecaca',
        color: '#991b1b'
      },
      gray: {
        backgroundColor: '#f3f4f6',
        color: '#4b5563'
      }
    };
    const baseStyle = {
      display: 'inline-flex',
      alignItems: 'center',
      padding: '0.125rem 0.625rem',
      borderRadius: '9999px',
      fontSize: '0.875rem',
      fontWeight: '500'
    };
    const colorStyle = styles[status] || styles.green;
    return <span style={{
      ...baseStyle,
      ...colorStyle
    }}>
        {label || status}
      </span>;
  };
  const STATUS_CONFIG = {
    supported: {
      label: "Supported",
      color: "green"
    },
    partial: {
      label: "Partial",
      color: "orange"
    },
    "not-implemented": {
      label: "Not Implemented",
      color: "gray"
    }
  };
  const renderCard = (platform, value) => {
    if (!value) return null;
    const {status, note} = typeof value === "string" ? {
      status: value
    } : value;
    const config = STATUS_CONFIG[status];
    if (!config) return null;
    const titleMap = {
      ios: "SwiftUI",
      android: "Jetpack Compose",
      web: "Web"
    };
    return <Card key={platform} title={titleMap[platform] || platform}>
          <StatusBadge status={config.color} label={config.label} />
          {note && <div style={{
      marginTop: '0.5rem',
      fontSize: '0.875rem',
      color: '#6b7280'
    }}>
              {note}
            </div>}
      </Card>;
  };
  if (statuses == null) {
    return null;
  }
  return <Columns cols="3">
      {Object.entries(statuses).map(([platform, value]) => renderCard(platform, value))}
    </Columns>;
};

export const ComposeJS = ({code, name, height}) => {
  const encodedCode = useMemo(() => {
    if (!code) return "";
    try {
      return btoa(code);
    } catch (e) {
      console.error("Failed to encode code", e);
      return "";
    }
  }, [code]);
  if (!encodedCode) {
    return null;
  }
  return <iframe src={`https://www.metabind.ai/embed?code=${encodedCode}&name=${name ?? 'Example'}`} loading="lazy" style={{
    width: "100%",
    height: height || '350px',
    border: "1px solid #e5e7eb",
    borderRadius: "var(--rounded-2xl,1rem)",
    overflow: "hidden"
  }} title="ComposeJS Preview" />;
};

These iOS-only modifiers manage system toolbars — the navigation bar, tab bar, and bottom bar — typically inside a [NavigationStack](/bindjs/components/NavigationStack). Use `toolbar` to populate items and `toolbarVisibility` to show or hide whole bars.

Pair `toolbar` with [ToolbarItem](/bindjs/components/ToolbarItem) for individually-placed items or [ToolbarItemGroup](/bindjs/components/ToolbarItemGroup) when several items share a placement.

## toolbar

Populates the toolbar with items, typically used inside a `NavigationStack`.

```typescript theme={null}
.toolbar(content: ToolbarItem | ToolbarItemGroup | Group | (ToolbarItem | ToolbarItemGroup)[]): Component;
```

<ParamField path="content" type="ToolbarItem | ToolbarItemGroup | Group | (ToolbarItem | ToolbarItemGroup)[]" required>
  The toolbar content. Can be a single item, a group, or an array of items.
</ParamField>

<PlatformStatuses
  statuses={{
ios: { status: "supported" },
android: "not-implemented",
web: "not-implemented",
}}
/>

**Single toolbar item**

```typescript theme={null}
VStack([Text("Content")])
    .toolbar(
        ToolbarItem({ placement: "topBarTrailing" }, [
            Button("Save", () => handleSave())
        ])
    )
```

**Multiple toolbar items**

```typescript theme={null}
VStack([Text("Content")])
    .toolbar([
        ToolbarItem({ placement: "topBarLeading" }, [
            Button("Cancel", () => {})
        ]),
        ToolbarItem({ placement: "topBarTrailing" }, [
            Button("Done", () => {})
        ])
    ])
```

**Toolbar item group**

```typescript theme={null}
VStack([Text("Content")])
    .toolbar(
        ToolbarItemGroup({ placement: "bottomBar" }, [
            Button("Action 1", () => {}),
            Spacer(),
            Button("Action 2", () => {})
        ])
    )
```

**Using Group for mixed placements**

```typescript theme={null}
VStack([Text("Content")])
    .toolbar(
        Group([
            ToolbarItem({ placement: "topBarLeading" }, [
                Button("Back", () => {})
            ]),
            ToolbarItemGroup({ placement: "topBarTrailing" }, [
                Button("Edit", () => {}),
                Button("Share", () => {})
            ])
        ])
    )
```

**In a NavigationStack**

```typescript theme={null}
NavigationStack([
    VStack([Text("Main content")])
        .navigationTitle("My App")
        .toolbar(
            ToolbarItem({ placement: "topBarTrailing" }, [
                Menu({ label: Image({ systemName: "ellipsis.circle" }) }, [
                    Button("Settings", () => {}),
                    Button("Help", () => {})
                ])
            ])
        )
])
```

<Note>
  Typically used inside a [NavigationStack](/bindjs/components/NavigationStack) to place items in the navigation bar. Use [ToolbarItem](/bindjs/components/ToolbarItem) for individually-placed items and [ToolbarItemGroup](/bindjs/components/ToolbarItemGroup) when multiple items share the same placement.
</Note>

## toolbarVisibility

Controls the visibility of system toolbars.

```typescript theme={null}
.toolbarVisibility(
    visibility: "visible" | "hidden" | "automatic",
    bars?: ToolbarBarPlacement | ToolbarBarPlacement[]
): Component
```

<ParamField path="visibility" type="&#x22;visible&#x22; | &#x22;hidden&#x22; | &#x22;automatic&#x22;" required>
  Whether the toolbar is visible, hidden, or determined automatically by the system.
</ParamField>

<ParamField path="bars" type="ToolbarBarPlacement | ToolbarBarPlacement[]" optional>
  Which toolbars to affect (e.g., `"navigationBar"`, `"tabBar"`, `"bottomBar"`). When omitted, applies to all toolbars.
</ParamField>

<PlatformStatuses
  statuses={{
ios: { status: "supported" },
android: "not-implemented",
web: "not-implemented",
}}
/>

**Hide navigation bar**

```typescript theme={null}
ScrollView([
    ForEach(items, (item) =>
        Text(item.name).padding(12)
    )
]).toolbarVisibility("hidden", "navigationBar")
```

**Hide tab bar**

```typescript theme={null}
VStack([
    Text("Full screen content")
]).toolbarVisibility("hidden", "tabBar")
```

**Hide all toolbars**

```typescript theme={null}
Image({ url: "photo.jpg" })
    .resizable()
    .scaledToFill()
    .ignoresSafeArea()
    .toolbarVisibility("hidden")
```

**Hide multiple specific bars**

```typescript theme={null}
VStack([
    Text("Immersive view")
]).toolbarVisibility("hidden", ["navigationBar", "tabBar"])
```

## See also

* [ToolbarItem](/bindjs/components/ToolbarItem) — single toolbar item
* [ToolbarItemGroup](/bindjs/components/ToolbarItemGroup) — grouped toolbar items
* [Navigation chrome](/bindjs/modifiers/navigation-chrome) — title and back button modifiers
* [NavigationStack](/bindjs/components/NavigationStack) — navigation container
* [ToolbarItemPlacement](/bindjs/types/ToolbarItemPlacement) — placement options
