Skip to content

[BootstrapAdminUi] Add copy-to-clipboard component - #380

Open
Prometee wants to merge 4 commits into
Sylius:mainfrom
Prometee:copy-to-clipboard
Open

Prometee wants to merge 4 commits into
Sylius:mainfrom
Prometee:copy-to-clipboard

Conversation

@Prometee

@Prometee Prometee commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds two reusable anonymous Twig components to BootstrapAdminUi:

  • sylius_bootstrap_admin_ui:copy_to_clipboard: a standalone copy button, leaving consumers free to render the value separately.
  • sylius_bootstrap_admin_ui:copyable: displays a value or custom inline content next to the copy button.

Both copy the explicit value prop, never the rendered text. This supports resource IDs, product codes, email addresses, badges, and truncated or formatted labels without coupling clipboard behavior to presentation.

Implementation

Components and customization

  • copyable displays the escaped value by default and accepts custom markup through its content block. The copy button remains separate from that content, including links.
  • Additional attributes apply to the standalone button or to the copyable container; button: attributes customize the nested button.
  • Custom classes are merged with the defaults, while button_class can replace the default button classes.
  • Both components support direct rendering through Twig Hooks and consume the injected hookableMetadata without printing it as an HTML attribute.
  • Missing, null, and empty-string values disable copying; numeric and string zero remain copyable. An explicit disabled prop is also supported.

Clipboard behavior and accessibility

  • Uses a dedicated Stimulus controller and the modern Clipboard API, with independent state for each instance.
  • Ignores repeated clicks while a write is pending and exposes aria-busy without disabling the button or removing keyboard focus.
  • Shows success/error icons and announces translated feedback through an atomic, polite live region. Errors also display a visible message.
  • Resets feedback after two seconds, clears timers on disconnect, and ignores stale asynchronous results after disconnect/reconnect.
  • Handles unavailable clipboard support and rejected writes as failures.
  • Provides a translated native title and accessible aria-label, without requiring Bootstrap tooltip initialization for dynamically inserted content.
  • Adds English, French, German, Spanish, and Polish translations.

Documentation and integration

  • Documents standalone and composable usage, Twig Hooks, custom content, attributes, classes, translations, and secure-context requirements.
  • Explains how to register the controller in an existing Stimulus application with AssetMapper or Webpack Encore, without starting a second application.
  • Clarifies the styling dependencies and version constraints to consider when integrating with an existing Sylius administration.

Usage

Standalone button:

<span>{{ resource.code }}</span>
<twig:sylius_bootstrap_admin_ui:copy_to_clipboard
    :value="resource.code"
    data-test-copy-resource-code
/>

Default value display with a copy button:

<twig:sylius_bootstrap_admin_ui:copyable :value="resource.code" />

Custom content, with the copied value independent of its presentation:

<twig:sylius_bootstrap_admin_ui:copyable :value="customer.email">
    <a href="mailto:{{ customer.email }}">{{ customer.email }}</a>
</twig:sylius_bootstrap_admin_ui:copyable>

Direct Twig Hooks integration:

sylius_twig_hooks:
    hooks:
        'app.resource':
            copy:
                component: 'sylius_bootstrap_admin_ui:copyable'
                props:
                    value: '@=_context.resource.getCode()'

Testing

  • BootstrapAdminUi PHPUnit suite: 24 tests, 106 assertions passing locally. Coverage includes both components, real Twig Hooks rendering, escaping, custom content, attribute separation, labels, disabled states, and zero/empty values.
  • 13 JavaScript controller tests passing locally under Node.js 24, using Node's built-in test runner and DOM doubles, without adding a test dependency. They cover success/failure, unavailable clipboard support, retries, repeated clicks, timer replacement, disconnect/reconnect, stale results, and independent instances.
  • Adds execution of the JavaScript tests to CI on Node.js 24.
  • PHP coding standards, YAML syntax, and whitespace checks passed locally.
  • The full production asset build was verified locally using the committed lockfile. No dependency versions or lockfile changes are included in this PR.

The controller tests do not replace browser-level validation of clipboard permissions, focus behavior, or assistive technologies; those have not been tested in a real browser here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant