Components

Input Shortcode

A specialized text input with shortcode insertion and optional emoji picker for rich content composition.

Installation

npm install @marmoui/ui
yarn add @marmoui/ui
pnpm add @marmoui/ui
bun add @marmoui/ui

Usage

import { InputShortcode } from '@marmoui/ui';

Examples

Basic Shortcode Input

Default

Input with a single shortcode group

<InputShortcode
value={value}
onChange={setValue}
shortcodes={[
  { id: 'contact', section: 'contact', text: 'Contact', menu: [
    { text: 'First Name', value: '{{first_name}}' },
    { text: 'Last Name', value: '{{last_name}}' },
    { text: 'Email', value: '{{email}}' },
  ]},
]}
/>

Multiple Shortcode Groups

Multi-Group

Input with Contact, Order, Account, Affiliate, and Links shortcode groups

<InputShortcode
value={value}
onChange={setValue}
shortcodes={[
  { id: 'contact', section: 'contact', text: 'Contact', menu: [...] },
  { id: 'order', section: 'order', text: 'Order', menu: [...] },
  { id: 'account', section: 'account', text: 'Account', menu: [...] },
  { id: 'affiliate', section: 'affiliate', text: 'Affiliate', menu: [...] },
  { id: 'links', section: 'links', text: 'Links', menu: [...] },
]}
placeholder="Compose with merge fields..."
/>

Emoji Only

Emoji Picker

Input with only the emoji picker enabled, no shortcodes

<InputShortcode
value={value}
onChange={setValue}
enableEmoji
placeholder="Type and add emoji..."
/>

Shortcodes with Emoji

Combined

Input with both shortcode insertion and emoji picker

<InputShortcode
value={value}
onChange={setValue}
shortcodes={shortcodes}
enableEmoji
placeholder="Hey {{first_name}}, your order is ready! 🎉"
/>

With Placeholder

Placeholder

Input with a descriptive placeholder

<InputShortcode
value={value}
onChange={setValue}
shortcodes={shortcodes}
placeholder="Enter email subject line..."
/>

Async Loading from Backend

Async Shortcodes

Shortcodes loaded on demand when the popover opens. Shows a spinner while fetching.

const loadShortcodes = async () => {
const response = await fetch('/api/shortcodes');
return await response.json();
};

<InputShortcode
value={value}
onChange={setValue}
onLoadShortcodes={loadShortcodes}
placeholder="Click the shortcode button to load from API..."
/>

Disabled

Disabled

Disabled state with pre-filled value

<InputShortcode
value="Hello {{first_name}}"
onChange={setValue}
shortcodes={shortcodes}
disabled
/>

Best Practices

✓

Organize shortcodes by category

Group shortcodes logically (Contact, Order, Account) for easy discovery.

✓

Show shortcode previews

Display a readable label for each shortcode, not just the raw merge field syntax.

✗

Don't overload with options

Limit shortcode categories to keep the dropdown manageable.

✗

Don't use without fallback guidance

Inform users what happens when a shortcode can't resolve (e.g., empty contact field).

Props

Props

Accessibility

  • Shortcode dropdown is navigable via keyboard.
  • Inserted shortcodes are part of the input's text value for screen readers.
  • Emoji picker (when enabled) supports keyboard navigation.