Ai Prompt

<sl-ai-prompt> | SlAiPrompt
Since 1.1.14 experimental

This component allows users to enter prompts to retrieve relevant information quickly or perform certain actions. It leverages artificial intelligence to understand the context and intent behind the search, providing accurate and personalised results.

<sl-ai-prompt class="ai-prompt"></sl-ai-prompt>

<script type="module">
  import { html } from 'https://cdn.jsdelivr.net/npm/lit@3/+esm';
  import { renderHighlightedText } from '../../dist/utilities/renderHighlightedText.js';

  const prompt = document.querySelector('.ai-prompt');
  prompt.matchingResults = [
    {id: 1, label: "Check my client's CGT eligibility and calculate CGT based on the following materials"},
    {id: 2, label: "Review my client's superannuation contribution caps for this financial year"},
    {id: 3, label: "Summarize my client's investment portfolio performance for the last quarter"},
    {id: 4, label: "Prepare for client review", isRecent: true},
    {id: 5, label: "Validate electronic record compliance for last 3 client meetings"},
    {id: 6, label: "Determine tax residency and cross border compliance for clients next week"},
    {id: 7, label: "Draft a retirement income strategy summary for my client's upcoming meeting", isRecent: true},
    {id: 8, label: "Calculate my client's minimum pension drawdown for this financial year"},
    {id: 9, label: "Compare insurance premiums across my client's current policies"},
    {id: 10, label: "Identify estate planning gaps in my client's existing arrangements", isRecent: true},
    {id: 11, label: "Generate a fee disclosure statement for my client's annual review"},
    {id: 12, label: "Assess my client's eligibility for the downsizer contribution scheme"},
  ];

  prompt.commandCategories = [
    {
      id: 13,
      label: 'Clients',
      commandItems: [{id: 1, label: 'Alianna Marshall'}, {id: 2, label: 'Nick & Ali'}, {id: 3, label: 'Maryalian Poe'}, {id: 4, label: 'HUB24 Super Group'}],
      iconName: 'user-group',
      renderCommandItemsFunc: (item, {searchString, onClick}) => {
        return html`
         <sl-option @click=${onClick}>
            <sl-icon slot="prefix"
              name="user-group"
              style="border-radius: var(--hds-border-radius-sm, 3px);
                    background: var(--hds-color-secondary-100, #DFEFF6); padding: var(--hds-space-1x, 4px);"
              >
            </sl-icon>
            ${renderHighlightedText(item.label, searchString)}
          </sl-option>
        `
      },
      filterCommandItemsFunc: (items, {searchString}) => {
        return items.filter((item) => item.label.toLowerCase().includes(searchString.toLowerCase()));
      },
    },
    {
      id: 14,
      label: 'Accounts',
      commandItems: [
        { id: 1, label: 'Alianna Marshall Corporate Trustee', accountNumber: '24166304', productName: 'Super-Accumulation (AB)' },
        { id: 2, label: 'Nick & Ali Family Trust', accountNumber: '31890527', productName: 'Retirement Income Stream (AB)' },
        { id: 3, label: 'Maryalian Poe Corporate Trustee', accountNumber: '44712093', productName: 'Transition to Retirement (AB)' },
        { id: 4, label: 'HUB24 Super Group Trustee', accountNumber: '55278146', productName: 'Managed Pension (AB)' }
      ],
      renderCommandItemsFunc: (item, {searchString, onClick}) => {
          return html`
          <sl-option
            style="font-size: var(--hds-font-size-body-base, 14px); font-weight: var(--hds-font-application-weight-default, 400); font-variant-numeric: lining-nums tabular-nums;"
            @click=${onClick}
          >
            <div style="display: flex; flex-direction: column; gap: var(--hds-space-half-x);">
              ${renderHighlightedText(item.label, searchString)}
              <div style="display: flex; align-items: center;">
                ${renderHighlightedText(item.accountNumber, searchString)}
                <sl-divider vertical style="height: 16px; --spacing: var(--hds-space-2x);"></sl-divider>
                ${renderHighlightedText(item.productName, searchString)}
              </div>
            </div>
          </sl-option>
        `
      },
      filterCommandItemsFunc: (items, {searchString}) => {
        return items.filter((item) => item.label.toLowerCase().includes(searchString.toLowerCase()) || item.accountNumber.toLowerCase().includes(searchString.toLowerCase()) || item.productName.toLowerCase().includes(searchString.toLowerCase()));
      },
    }
  ]

  let timeout;
  prompt.addEventListener('sl-prompt-submit', () => {
    console.log('submit');
    prompt.state = 'loading';

    timeout = setTimeout(() => {
      prompt.state = 'disabled';
      console.log('disabled')
      timeout = setTimeout(() => {
        prompt.state = 'default';
        console.log('default')
      }, 3000);
    }, 3000);
  });

  prompt.addEventListener('sl-prompt-stop', () => {
    clearTimeout(timeout);
    prompt.state = 'default';
    console.log('default')
  });
</script>

Feature summary

Feature Description
Contenteditable editor Rich text editor with dynamic height, placeholder text, caret preservation, and inline tokens.
Matching results Autocomplete-style suggestions shown while typing.
Recent results Recent matching results can be prioritised with isRecent.
Command tokens Users can insert non-editable command tokens into the editor.
Command categories Command items can be grouped by category, such as Clients or Accounts.
Command category icons iconName displays a sl-icon in selected command token buttons for that category.
Custom command rendering renderCommandItemsFunc customises how dropdown items are rendered.
Custom command filtering filterCommandItemsFunc customises how command items are searched.
Keyboard navigation Supports arrow navigation, Enter selection/submission, Escape close, Tab chip focus, Home/End.
State management Supports default, active, loading, and disabled states.
Submit and stop events Emits sl-prompt-submit and sl-prompt-stop.

Basic usage

<sl-ai-prompt class="basic-ai-prompt"></sl-ai-prompt>

<script>
  const prompt = document.querySelector('.basic-ai-prompt');

  prompt.matchingResults = [
    { id: 1, label: "Check client's tax eligibility", isRecent: true },
    { id: 2, label: 'Review superannuation contributions' },
    { id: 3, label: 'Calculate investment returns' }
  ];

  prompt.commandCategories = [
    {
      id: 'clients',
      label: 'Clients',
      iconName: 'user-group',
      commandItems: [
        { id: 'alianna', label: 'Alianna Marshall' },
        { id: 'nick-ali', label: 'Nick & Ali' }
      ]
    },
    {
      id: 'accounts',
      label: 'Accounts',
      commandItems: [
        { id: 'account-1', label: 'Alianna Marshall Corporate Trustee' }
      ]
    }
  ];

  prompt.addEventListener('sl-prompt-submit', (event) => {
    console.log('Submitted:', event.detail.value);
  });

  prompt.addEventListener('sl-prompt-stop', () => {
    console.log('Stopped');
  });
</script>

States

State Description
default Initial empty state. Submit action is disabled.
active Editor contains content. Submit action is enabled.
loading Prompt is being processed. Action button becomes a stop button.
disabled Component is disabled and cannot be interacted with.

Default

<sl-ai-prompt class="default-ai-prompt"></sl-ai-prompt>

<script>
  const prompt = document.querySelector('.default-ai-prompt');

  prompt.commandCategories = [
    {
      id: 'actions',
      label: 'Actions',
      commandItems: [
        { id: 'help', label: 'Help' },
        { id: 'settings', label: 'Settings' }
      ]
    }
  ];
</script>

Active

<sl-ai-prompt class="active-ai-prompt" state="active"></sl-ai-prompt>

Disabled

<sl-ai-prompt class="disabled-ai-prompt" state="disabled"></sl-ai-prompt>

Loading

<sl-ai-prompt state="loading" class="loading-ai-prompt"></sl-ai-prompt>

<script>
  const prompt = document.querySelector('.loading-ai-prompt');

  prompt.addEventListener('sl-prompt-submit', () => {
    console.log('submit');
  });

  prompt.addEventListener('sl-prompt-stop', () => {
    console.log('stop');
  });
</script>

Matching results

Use matchingResults to show autocomplete-style suggestions while the user types.

prompt.matchingResults = [
  {
    id: 1,
    label: 'Check client tax eligibility'
  },
  {
    id: 2,
    label: 'Review superannuation contributions',
    prompt: 'Review my client’s superannuation contribution caps for this financial year'
  },
  {
    id: 3,
    label: 'Prepare for client review',
    isRecent: true
  }
];

matchingResults item properties

Property Type Required Description
id string Yes Unique result identifier.
label string Yes Text displayed in the dropdown.
prompt string No Text inserted into the editor when selected. Falls back to label.
isRecent boolean No Places the result before non-recent results and displays a clock icon.

Matching results example

<sl-ai-prompt class="matching-results-ai-prompt"></sl-ai-prompt>

<script>
  const prompt = document.querySelector('.matching-results-ai-prompt');

  prompt.matchingResults = [
    { id: 1, label: "Check client's tax eligibility", isRecent: true },
    { id: 2, label: 'Review superannuation contributions' },
    { id: 3, label: 'Calculate investment returns' }
  ];
</script>

Command tokens

Command tokens are structured, non-editable items inserted into the editor.

Users can open command selection by typing a command trigger such as @, followed by a search term.

Only one command can be selected from each category.

Command categories

Use commandCategories to group command items.

prompt.commandCategories = [
  {
    id: 'clients',
    label: 'Clients',
    iconName: 'user-group',
    commandItems: [
      {
        id: 'alianna',
        label: 'Alianna Marshall'
      },
      {
        id: 'nick-ali',
        label: 'Nick & Ali'
      }
    ]
  },
  {
    id: 'accounts',
    label: 'Accounts',
    commandItems: [
      {
        id: 'account-1',
        label: 'Alianna Marshall Corporate Trustee'
      }
    ]
  }
];

commandCategories properties

Property Type Required Description
id string Yes Unique category identifier.
label string Yes Category label displayed in the category chip list.
commandItems AIPromptCommandItem[] Yes Items that can be selected for this category.
iconName string No HDS icon name displayed in the inserted command token button. See more
renderCommandItemsFunc Function No Custom renderer for command dropdown items.
filterCommandItemsFunc Function No Custom filter function for command dropdown search.

commandItems properties

Property Type Required Description
id string Yes Unique command item identifier within the category.
label string Yes Text displayed in the dropdown and command token.

Command token icons

Set iconName on a command category to show an icon in the inserted command token button.

prompt.commandCategories = [
  {
    id: 'actions',
    label: 'Actions',
    iconName: 'user-group',
    commandItems: [
      { id: 'client', label: 'Client' },
      { id: 'account', label: 'Account' },
      { id: 'review', label: 'Review' }
    ]
  }
];

When the user selects any command items in Actions category, the inserted command token button displays the user-group icon next to the label.

Command tokens example

<sl-ai-prompt class="command-tokens-ai-prompt"></sl-ai-prompt>

<script>
  const prompt = document.querySelector('.command-tokens-ai-prompt');

  prompt.commandCategories = [
    {
      id: 'clients',
      label: 'Clients',
      iconName: 'user-group',
      commandItems: [
        { id: 101, label: 'John Smith' },
        { id: 102, label: 'Jane Doe' },
        { id: 103, label: 'ABC Corporation' }
      ]
    },
    {
      id: 'accounts',
      label: 'Accounts',
      commandItems: [
        { id: 201, label: 'Savings Account - $50,000' },
        { id: 202, label: 'Investment Portfolio - $150,000' },
        { id: 203, label: 'Superannuation - $250,000'}
      ]
    }
  ];

  prompt.addEventListener('sl-prompt-submit', (event) => {
    console.log('Submitted value:', event.detail.value);
  });
</script>

Custom command rendering

Use renderCommandItemsFunc to control how command items appear in the dropdown.

The function receives:

Argument Description
item Current command item.
context.searchString Current search text typed after the command trigger.
context.onClick The callback to attach to the option item.

When using renderCommandItemsFunc, the renderer receives an onClick callback. Attach it to the selectable sl-option to select the item.

<sl-ai-prompt class="custom-renderer-ai-prompt"></sl-ai-prompt>

<script type="module">
  import { html } from 'https://cdn.jsdelivr.net/npm/lit@3/+esm';
  import { renderHighlightedText } from '../../dist/utilities/renderHighlightedText.js';

  const prompt = document.querySelector('.custom-renderer-ai-prompt');

  prompt.commandCategories = [
    {
      id: 'clients',
      label: 'Clients',
      iconName: 'people-group',
      commandItems: [
        { id: 1, label: 'Alianna Marshall', type: 'Individual'  },
        { id: 2, label: 'ABC Corporation', type: 'Business' },
        { id: 3, label: 'Smith Family Trust', type: 'Trust' }
      ],
      renderCommandItemsFunc: (item, { searchString, onClick }) => {
        return html`
          <sl-option
            @click=${onClick}
          >
            <sl-icon slot="prefix" name="${item.iconName}"></sl-icon>
            <div>
              ${renderHighlightedText(item.label, searchString)}
              <div style="font-size: 12px; color: var(--hds-color-neutral-500);">
                ${item.type}
              </div>
            </div>
          </sl-option>
        `;
      }
    }
  ];
</script>

Custom command filtering

Use filterCommandItemsFunc to filter command items by fields other than label.

The function receives:

Argument Description
items Command items in the active category.
context.searchString Current search text typed after the command trigger.
<sl-ai-prompt class="custom-filter-ai-prompt"></sl-ai-prompt>

<script>
  const prompt = document.querySelector('.custom-filter-ai-prompt');

  prompt.commandCategories = [
    {
      id: 'accounts',
      label: 'Accounts',
      commandItems: [
        {
          id: 1,
          label: 'Alianna Marshall Corporate Trustee',
          accountNumber: '24166304',
          productName: 'Super-Accumulation'
        },
        {
          id: 2,
          label: 'Nick & Ali Family Trust',
          accountNumber: '31890527',
          productName: 'Retirement Income Stream'
        }
      ],
      filterCommandItemsFunc: (items, { searchString }) => {
        const query = searchString.toLowerCase();

        return items.filter((item) =>
          item.label.toLowerCase().includes(query) ||
          item.accountNumber.toLowerCase().includes(query) ||
          item.productName.toLowerCase().includes(query)
        );
      }
    }
  ];
</script>

Contenteditable editor customisation

Use CSS custom properties and parts to customise the editor.

sl-ai-prompt {
  --hds-ai-prompt-contenteditable-max-height: 150px;
  --hds-ai-prompt-contenteditable-placeholder: 'Type @ for commands or ask a question...';
}

sl-ai-prompt::part(editor) {
  font-family: 'Monaco', 'Courier New', monospace;
  font-size: 14px;
}

sl-ai-prompt::part(command-token) {
  border-left: 3px solid var(--hds-color-primary-500);
  border-radius: 3px;
  font-weight: 500;
}

Keyboard navigation

Key Behaviour
@ Opens command selection when used as a command trigger.
ArrowUp / ArrowDown Navigates dropdown options.
ArrowLeft / ArrowRight Navigates between command category chips.
Home / End Moves caret to the start or end of editor content.
PageUp / PageDown Moves caret to the start or end of editor content.
Enter Submits when dropdown is closed; selects highlighted option when dropdown is open.
Shift + Enter Inserts a new line without submitting.
Escape Closes the active dropdown.
Tab Moves focus through category chips and focusable controls.
Backspace / Delete Removes text or command tokens.

Keyboard workflow

1. Type "@" to open command selection.
2. Type a search term, for example "ali".
3. Use ArrowDown or ArrowUp to navigate options.
4. Press Enter to insert the selected command token.
5. Continue typing the prompt.
6. Press Enter to submit.

[component-metadata:sl-ai-prompt]

Slots

Name Description
action-button A slot for the prompt’s action button.

Learn more about using slots.

Properties

Name Description Reflects Type Default
state The current state of the prompt. - default: The default state when the prompt editor is empty and not focused. In this state, the action button is disabled. When the editor receives input, the state changes to active. - active: The state when the prompt editor has content. In this state, the action button is enabled, allowing the user to submit the prompt. When the editor is cleared, the state changes back to default. - loading: The state when a prompt submission is in progress. In this state, the action button shows a stop button and allows the user to stop the submission. - disabled: The state when the prompt is disabled. In this state, the action button is disabled and shows a disabled appearance. 'loading' | 'active' | 'disabled' | 'default' 'default'
placement The preferred placement of the dropdown panel. Note that the actual placement may vary as needed to keep the panel inside of the viewport. 'top' | 'bottom' 'bottom'
distance The distance in pixels from which to offset the panel away from its anchor. number 0
skidding The distance in pixels from which to offset the panel along its anchor. number 0
hoist Enable this option to prevent the panel from being clipped when the component is placed inside a container with overflow: auto|scroll. Hoisting uses a fixed positioning strategy that works in many, but not all, scenarios. boolean false
showResultPopupAfter
show-result-popup-after
The number of letters to wait before showing the result popup after typing. number 2
matchingResults The list of matching results for the current input. MatchingResult[] []
commandCategories The command categories available in the AI prompt. Each category has the following structure: - id — A unique string or number. - label — The category’s display label. - commandItems — The commands in the category. - renderCommandItemsFunc — Optional custom item renderer. Must use sl-option for the dropdown to work correctly. - filterCommandItemsFunc — Optional custom item filter. AIPromptCommandCategory[] []
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Events

Name React Event Description Event Detail
sl-ai-prompt-dropdown-navigation Emitted when the user navigates through the dropdown items using arrow keys or selects an item with Enter. CustomEvent
sl-blur Emitted when the prompt editor loses focus. -
sl-focus Emitted when the prompt editor gains focus. -
sl-input Emitted when the prompt editor receives input. -
sl-prompt-submit Emitted when the prompt is submitted. -
sl-prompt-stop Emitted when the prompt is stopped (only applicable when state="loading"). -

Learn more about events.

Custom Properties

Name Description Default
--hds-ai-prompt-contenteditable-max-height The maximum height of the contenteditable prompt editor. By default, this is set to 300px.\
--hds-ai-prompt-contenteditable-placeholder The placeholder text for the contenteditable prompt editor. By default, this is set to ‘Ask me anything…’.

Learn more about customizing CSS custom properties.

Parts

Name Description
base The component’s base wrapper.
prompt-container The container that wraps the prompt editor and action button.
editor The contenteditable prompt editor.
actions-container The container that wraps the action button and agent model select.
command-token The non-editable command token inserted into the prompt editor.

Learn more about customizing CSS parts.

Dependencies

This component automatically imports the following dependencies.

  • <sl-button>
  • <sl-button-group>
  • <sl-chip>
  • <sl-chip-group>
  • <sl-empty-state>
  • <sl-icon>
  • <sl-icon-button>
  • <sl-option>
  • <sl-popup>
  • <sl-spinner>
  • <sl-tooltip>