> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# ChatPermissions

The settings button in the chat composer that lists which Wally tools may run without asking first in this conversation. Each row is a switch and takes effect the moment it is flipped — there is no Save, and the popover stays open so several tools can be changed in one go. The app owns the list and its order: enabled tools first, then a `Separator` and the disabled ones.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/ChatPermissions) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/ai-chatpermissions--overview)

```tsx
import { useState } from 'react';
import { ChatPermissions, ChatPermissionsContent, ChatPermissionsItem, type ChatPermissionsItemCheckedChangeDetails, ChatPermissionsTrigger } from '@wallarm-org/design-system/ChatPermissions';
import { Separator } from '@wallarm-org/design-system/Separator';

export const AllOn = () => {
  const [allowed, setAllowed] = useState<Record<string, boolean>>({
    propose_add_to_denylist: true,
    search_attacks: true,
    get_api_inventory: true,
    create_rule: true,
  });
  const enabled = TOOLS.filter(tool => allowed[tool.name]);
  const disabled = TOOLS.filter(tool => !allowed[tool.name]);

  const handleCheckedChange = ({ checked, name }: ChatPermissionsItemCheckedChangeDetails) => {
    setAllowed(prev => ({ ...prev, [name]: checked }));
  };

  return (
    <div className='flex h-[360px] w-[400px] items-end'>
      <ChatPermissions data-testid='permissions'>
        <ChatPermissionsTrigger />
        <ChatPermissionsContent>
          {enabled.map(tool => (
            <ChatPermissionsItem
              key={tool.name}
              name={tool.name}
              data-testid={`permission-${tool.name}`}
              title={tool.name}
              description={tool.description}
              checked
              onCheckedChange={handleCheckedChange}
            />
          ))}
          {enabled.length > 0 && disabled.length > 0 && <Separator spacing={4} />}
          {disabled.map(tool => (
            <ChatPermissionsItem
              key={tool.name}
              name={tool.name}
              data-testid={`permission-${tool.name}`}
              title={tool.name}
              description={tool.description}
              checked={false}
              onCheckedChange={handleCheckedChange}
            />
          ))}
        </ChatPermissionsContent>
      </ChatPermissions>
    </div>
  );
};
```

## Usage

```tsx
import { ChatPermissions, ChatPermissionsContent, ChatPermissionsItem, type ChatPermissionsItemCheckedChangeDetails, ChatPermissionsTrigger } from '@wallarm-org/design-system/ChatPermissions';
import { Separator } from '@wallarm-org/design-system/Separator';
```

## Examples

### Some off

Two tools switched off sit below a separator. The order is decided by the app, not the component.

```tsx
import { useState } from 'react';
import { ChatPermissions, ChatPermissionsContent, ChatPermissionsItem, type ChatPermissionsItemCheckedChangeDetails, ChatPermissionsTrigger } from '@wallarm-org/design-system/ChatPermissions';
import { Separator } from '@wallarm-org/design-system/Separator';

export const SomeOff = () => {
  const [allowed, setAllowed] = useState<Record<string, boolean>>({
    propose_add_to_denylist: true,
    search_attacks: true,
    get_api_inventory: false,
    create_rule: false,
  });
  const enabled = TOOLS.filter(tool => allowed[tool.name]);
  const disabled = TOOLS.filter(tool => !allowed[tool.name]);

  const handleCheckedChange = ({ checked, name }: ChatPermissionsItemCheckedChangeDetails) => {
    setAllowed(prev => ({ ...prev, [name]: checked }));
  };

  return (
    <div className='flex h-[360px] w-[400px] items-end'>
      <ChatPermissions data-testid='permissions'>
        <ChatPermissionsTrigger />
        <ChatPermissionsContent>
          {enabled.map(tool => (
            <ChatPermissionsItem
              key={tool.name}
              name={tool.name}
              data-testid={`permission-${tool.name}`}
              title={tool.name}
              description={tool.description}
              checked
              onCheckedChange={handleCheckedChange}
            />
          ))}
          {enabled.length > 0 && disabled.length > 0 && <Separator spacing={4} />}
          {disabled.map(tool => (
            <ChatPermissionsItem
              key={tool.name}
              name={tool.name}
              data-testid={`permission-${tool.name}`}
              title={tool.name}
              description={tool.description}
              checked={false}
              onCheckedChange={handleCheckedChange}
            />
          ))}
        </ChatPermissionsContent>
      </ChatPermissions>
    </div>
  );
};
```

### Analytics

`data-analytics-id` lands on the real trigger `<button>` and on each switch row's `<label>`, so
a click anywhere on the row resolves to the row's id.

```tsx
import { useState } from 'react';
import { ChatPermissions, ChatPermissionsContent, ChatPermissionsItem, type ChatPermissionsItemCheckedChangeDetails, ChatPermissionsTrigger } from '@wallarm-org/design-system/ChatPermissions';

export const Analytics = () => {
  const [checked, setChecked] = useState(true);

  const handleCheckedChange = (details: ChatPermissionsItemCheckedChangeDetails) => {
    setChecked(details.checked);
  };

  return (
    <div className='flex h-[360px] w-[400px] items-end'>
      <ChatPermissions data-testid='permissions'>
        <ChatPermissionsTrigger data-analytics-id='CHAT_PERMISSIONS_OPEN' />
        <ChatPermissionsContent>
          <ChatPermissionsItem
            name='search_attacks'
            data-testid='permission-search_attacks'
            data-analytics-id='CHAT_PERMISSION_TOGGLE'
            data-analytics-props='{"tool":"search_attacks"}'
            title='search_attacks'
            description='Search detected attacks and incidents'
            checked={checked}
            onCheckedChange={handleCheckedChange}
          />
        </ChatPermissionsContent>
      </ChatPermissions>
    </div>
  );
};
```

## Props

| Prop         | Type                                     | Default | Description |
| ------------ | ---------------------------------------- | ------- | ----------- |
| open         | `boolean \| undefined`                   |         |             |
| onOpenChange | `((open: boolean) => void) \| undefined` |         |             |
| data-testid  | `string \| undefined`                    |         |             |

### ChatPermissionsContent

| Prop           | Type                                                 | Default                               | Description                                                                                  |
| -------------- | ---------------------------------------------------- | ------------------------------------- | -------------------------------------------------------------------------------------------- |
| label          | `ReactNode`                                          | `Always allowed in this conversation` | Heading above the tool rows; also names the dialog. Pass `null`, `false` or `''` to hide it. |
| title          | `string \| undefined`                                |                                       |                                                                                              |
| defaultChecked | `boolean \| undefined`                               |                                       |                                                                                              |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |                                       |                                                                                              |
| autoFocus      | `boolean \| undefined`                               |                                       |                                                                                              |
| tabIndex       | `number \| undefined`                                |                                       |                                                                                              |
| rel            | `string \| undefined`                                |                                       |                                                                                              |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |                                       |                                                                                              |
| data-testid    | `string \| undefined`                                |                                       |                                                                                              |
| minHeight      | `PopoverSizeDimension \| undefined`                  |                                       |                                                                                              |
| maxHeight      | `PopoverSizeDimension \| undefined`                  |                                       |                                                                                              |

### ChatPermissionsItem

| Prop            | Type                                                 | Default | Description                                                                                         |
| --------------- | ---------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| name \*         | `string`                                             |         | Machine name of the tool, e.g. `propose_add_to_denylist`; echoed back in `onCheckedChange`.         |
| title \*        | `ReactNode`                                          |         | Visible tool name.                                                                                  |
| description     | `ReactNode`                                          |         |                                                                                                     |
| onCheckedChange | `complex`                                            |         |                                                                                                     |
| label           | `string \| undefined`                                |         | Specifies the localized strings that identifies the accessibility elements and their states         |
| defaultChecked  | `boolean \| undefined`                               |         |                                                                                                     |
| defaultValue    | `string \| number \| readonly string[] \| undefined` |         |                                                                                                     |
| autoFocus       | `boolean \| undefined`                               |         |                                                                                                     |
| id              | `string \| undefined`                                |         |                                                                                                     |
| tabIndex        | `number \| undefined`                                |         |                                                                                                     |
| rel             | `string \| undefined`                                |         |                                                                                                     |
| onChange        | `ChangeEventHandler<T, Element> \| undefined`        |         |                                                                                                     |
| disabled        | `boolean \| undefined`                               |         | Whether the switch is disabled.                                                                     |
| value           | `string \| number \| undefined`                      |         | The value of switch input. Useful for form submission.                                              |
| asChild         | `boolean \| undefined`                               |         | Use the provided child element as the default rendered element, combining their props and behavior. |
| data-testid     | `string \| undefined`                                |         |                                                                                                     |
| ids             | `ElementIds \| undefined`                            |         | The ids of the elements in the switch. Useful for composition.                                      |
| readOnly        | `boolean \| undefined`                               |         | Whether the switch is read-only                                                                     |
| required        | `boolean \| undefined`                               |         | If `true`, the switch input is marked as required,                                                  |
| htmlFor         | `string \| undefined`                                |         |                                                                                                     |
| invalid         | `boolean \| undefined`                               |         | If `true`, the switch is marked as invalid.                                                         |
| checked         | `boolean \| undefined`                               |         | The controlled checked state of the switch                                                          |
| a11yMode        | `boolean \| undefined`                               |         |                                                                                                     |

### ChatPermissionsTrigger

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| title          | `string \| undefined`                                |         |             |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |
| type           | `"button" \| "submit" \| "reset" \| undefined`       |         |             |
| disabled       | `boolean \| undefined`                               |         |             |
| name           | `string \| undefined`                                |         |             |
| value          | `string \| number \| readonly string[] \| undefined` |         |             |
| data-testid    | `string \| undefined`                                |         |             |

## Explorer

