> ## 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.

# Controls

> Modifiers that style buttons, pickers, and other controls

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 modifiers configure the visual presentation of interactive controls. `controlSize` scales buttons, progress views, and similar components across a discrete set of sizes; `pickerStyle` switches a `Picker` between segmented, wheel, menu, and other layouts; `buttonStyle` applies a fully custom rendering to a `Button` via `defineButtonStyle`.

Apply these modifiers to a single control or to a container — `controlSize` and `buttonStyle` propagate to descendant controls in the hierarchy.

## controlSize

Sets the size for controls like buttons and progress views.

```typescript theme={null}
.controlSize(size: "mini" | "small" | "regular" | "large" | "extraLarge")
```

<ParamField path="size" type="&#x22;mini&#x22; | &#x22;small&#x22; | &#x22;regular&#x22; | &#x22;large&#x22; | &#x22;extraLarge&#x22;" required>
  The control size to apply. Affects the visual size and padding of supported controls.
</ParamField>

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

**Small progress view**

```typescript theme={null}
ProgressView()
    .controlSize("small")
```

**Large control group**

```typescript theme={null}
VStack([
    Button("Submit", () => submit()),
    ProgressView({ value: 0.5 })
])
    .controlSize("large")
```

**Mini spinner**

```typescript theme={null}
ProgressView()
    .controlSize("mini")
```

## pickerStyle

Sets the display style for a Picker component.

```typescript theme={null}
.pickerStyle(style: PickerStyle): Component
```

<ParamField path="style" type="PickerStyle" required>
  The visual style for the picker. See [PickerStyle](/bindjs/types/PickerStyle).

  Options: `"automatic"`, `"segmented"`, `"inline"`, `"menu"`, `"navigationlink"`, `"palette"`, `"radiogroup"`, `"wheel"`.
</ParamField>

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

**Segmented picker**

```typescript theme={null}
const body = () => {
    const [size, setSize] = useState("m")
    return Picker("Size", { value: size, setValue: setSize }, [
        Text("S").tag("s"),
        Text("M").tag("m"),
        Text("L").tag("l"),
    ]).pickerStyle("segmented")
}
```

**Wheel picker**

```typescript theme={null}
const body = () => {
    const [selection, setSelection] = useState("a")
    return Picker("Option", { value: selection, setValue: setSelection }, [
        Text("Alpha").tag("a"),
        Text("Beta").tag("b"),
        Text("Gamma").tag("g"),
    ]).pickerStyle("wheel")
}
```

**Menu picker**

```typescript theme={null}
const body = () => {
    const [color, setColor] = useState("red")
    return Picker("Color", { value: color, setValue: setColor }, [
        Text("Red").tag("red"),
        Text("Green").tag("green"),
        Text("Blue").tag("blue"),
    ]).pickerStyle("menu")
}
```

## buttonStyle

Applies a custom button style to a Button component.

```typescript theme={null}
.buttonStyle(style: ButtonStyleComponent)
```

<ParamField path="style" type="ButtonStyleComponent" required>
  A custom button style component created with `defineButtonStyle`. The style controls how the button renders in its various states (normal, pressed).
</ParamField>

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

**Apply a custom button style**

```typescript theme={null}
Button("Tap me", () => handleTap())
    .buttonStyle(
        defineButtonStyle((config) =>
            Text(config.label)
                .padding(12)
                .background(
                    config.isPressed
                        ? Color("gray")
                        : Color("blue")
                )
                .foregroundStyle(Color("white"))
                .cornerRadius(8)
        )
    )
```

## See also

* [Button](/bindjs/components/Button) — interactive button control
* [Picker](/bindjs/components/Picker) — selection control
* [ProgressView](/bindjs/components/ProgressView) — progress indicator
* [disabled](/bindjs/modifiers/disabled) — disable interaction on a control
* [PickerStyle](/bindjs/types/PickerStyle) — picker style values
