Legal Consent

<sl-legal-consent> | SlLegalConsent
Since 2.5.0 experimental

Legal consent panel shown before a user starts using myhub AI.

<style>
  .legal-consent-banner {
    display: flex;
    flex-direction: column;
    gap: var(--hds-space-4x, 16px);
  }

  .legal-consent-banner__logo {
    width: 238px;
  }

  .legal-consent-banner__tagline {
    font-size: var(--hds-font-size-body-3xl, 24px);
    font-weight: var(--hds-font-application-weight-strong, 500);
  }

  .legal-consent-custom-width {
    --banner-width: 360px;
  }
</style>

<sl-legal-consent heading="Before you get started, Linda">
  <div slot="banner" class="legal-consent-banner">
    <img src="/dist/images/myhub.svg" alt="myhub" class="legal-consent-banner__logo" />
    <div class="legal-consent-banner__tagline">Connected and intelligent wealth tech is coming to HUB24</div>
  </div>
</sl-legal-consent>

<script>
  // Alert whenever any example's default "Agree & continue" button is clicked. A single
  // document-level listener catches the bubbling sl-agree event from every sl-legal-consent on the page.
  document.addEventListener('sl-agree', event => {
    if (event.target.tagName === 'SL-LEGAL-CONSENT') {
      alert('You agreed to the terms.');
    }
  });
</script>

Examples

Provide the brand panel via the banner slot — typically a logo and a short headline. The banner defaults to a 320px column and can be customised with the --banner-width CSS variable. It becomes a full-width band when the component is narrow.

<style>
  .legal-consent-banner {
    display: flex;
    flex-direction: column;
    gap: var(--hds-space-container-lg, 40px);
  }

  .legal-consent-banner__logo {
    width: 161px;
    height: 48.65px;
  }

  .legal-consent-banner__tagline {
    font-size: var(--hds-font-size-body-3xl, 24px);
    font-weight: var(--hds-font-application-weight-strong, 500);
  }

  .legal-consent-custom-width {
    --banner-width: 360px;
  }
</style>

<sl-legal-consent class="legal-consent-custom-width" heading="Before you get started">
  <div slot="banner" class="legal-consent-banner">
    <img src="/dist/images/myhub.svg" alt="myhub" class="legal-consent-banner__logo" />
    <div class="legal-consent-banner__tagline">Connected and intelligent wealth tech is coming to HUB24</div>
  </div>
</sl-legal-consent>

Heading

Set the disclosure title with the heading attribute, or use the heading slot when the title needs markup.

<sl-legal-consent heading="Please review before continuing">
  <div slot="banner" class="legal-consent-banner">
    <img src="/dist/images/myhub.svg" alt="myhub" class="legal-consent-banner__logo" />
    <div class="legal-consent-banner__tagline">Connected and intelligent wealth tech is coming to HUB24</div>
  </div>
</sl-legal-consent>

Custom Terms Content

Pass your own markup to the default slot to replace the built-in terms. Any HTML is supported — headings, lists, links, etc. Click See terms of use to reveal it.

Acme Platform Terms

These terms govern your use of the Acme platform. Please read them carefully before continuing.

  1. You agree to use the platform lawfully and in accordance with these terms.
  2. Content you submit remains your responsibility.
  3. See our privacy policy for how we handle your data.

Last updated: 1 September 2026

<sl-legal-consent>
  <div slot="banner" class="legal-consent-banner">
    <img src="/dist/images/myhub.svg" alt="myhub" class="legal-consent-banner__logo" />
    <div class="legal-consent-banner__tagline">Connected and intelligent wealth tech is coming to HUB24</div>
  </div>
  <div>
    <h4>Acme Platform Terms</h4>
    <p>These terms govern your use of the Acme platform. Please read them carefully before continuing.</p>
    <ol>
      <li>You agree to use the platform lawfully and in accordance with these terms.</li>
      <li>Content you submit remains your responsibility.</li>
      <li>
        See our <a href="https://example.com/privacy" target="_blank" rel="noopener">privacy policy</a> for how we
        handle your data.
      </li>
    </ol>
    <p><small>Last updated: 1 September 2026</small></p>
  </div>
</sl-legal-consent>

Max Height

Use the max-height attribute to cap the height (in pixels) of the expanded terms block. When set, the terms content is capped at this height and scrolls; when omitted, it grows to fit its content. Click See terms of use to reveal the scrollable terms.

<sl-legal-consent max-height="200">
  <div slot="banner" class="legal-consent-banner">
    <img src="/dist/images/myhub.svg" alt="myhub" class="legal-consent-banner__logo" />
    <div class="legal-consent-banner__tagline">Connected and intelligent wealth tech is coming to HUB24</div>
  </div>
</sl-legal-consent>

Use the consent-mode attribute to require the user to meet a condition before Agree & continue is enabled:

  • checkbox — the user must tick a consent checkbox;
  • scroll — the user must scroll to the bottom of the terms details.
<sl-legal-consent consent-mode="checkbox" max-height="200" open>
  <div slot="banner" class="legal-consent-banner">
    <img src="/dist/images/myhub.svg" alt="myhub" class="legal-consent-banner__logo" />
    <div class="legal-consent-banner__tagline">Connected and intelligent wealth tech is coming to HUB24</div>
  </div>
</sl-legal-consent>

With scroll, pair it with a max-height so the terms overflow and there is something to scroll before consent is granted.

<sl-legal-consent consent-mode="scroll" max-height="200" open>
  <div slot="banner" class="legal-consent-banner">
    <img src="/dist/images/myhub.svg" alt="myhub" class="legal-consent-banner__logo" />
    <div class="legal-consent-banner__tagline">Connected and intelligent wealth tech is coming to HUB24</div>
  </div>
</sl-legal-consent>

Decline Button

Set show-decline to render a built-in decline button to the left of the agree button. It stays clickable regardless of consent-mode and emits sl-decline; customise its text with decline-label. The agree button keeps its consent gating.

<sl-legal-consent id="decline-demo" heading="Before you get started" show-decline>
  <div slot="banner" class="legal-consent-banner">
    <img src="/dist/images/myhub.svg" alt="myhub" class="legal-consent-banner__logo" />
    <div class="legal-consent-banner__tagline">Connected and intelligent wealth tech is coming to HUB24</div>
  </div>
</sl-legal-consent>

<script>
  document.getElementById('decline-demo').addEventListener('sl-decline', () => alert('You declined.'));
</script>

Replace the footer buttons with the footer-left and footer-right slots while keeping the built-in footer layout. Custom buttons don’t inherit the built-in behaviors, so wire them up yourself:

  • Toggle the terms — the default toggle lives in footer-left, so a custom left button should call the public toggleDetails() method (or set the open property).
  • Match the consent state — a custom continue button doesn’t inherit the consent-mode gating. The component reflects consent to the consent-given attribute (target it with CSS) and emits sl-consent-change (event.detail.consentGiven) — listen for it to enable/disable your button.
Read the terms I understand
<sl-legal-consent id="custom-footer-demo" heading="Before you get started" consent-mode="scroll" max-height="200">
  <div slot="banner" class="legal-consent-banner">
    <img src="/dist/images/myhub.svg" alt="myhub" class="legal-consent-banner__logo" />
    <div class="legal-consent-banner__tagline">Connected and intelligent wealth tech is coming to HUB24</div>
  </div>

  <sl-button id="custom-footer-toggle" slot="footer-left" variant="text">Read the terms</sl-button>
  <sl-button id="custom-footer-continue" slot="footer-right" variant="primary" disabled>I understand</sl-button>
</sl-legal-consent>

<script>
  (() => {
    const consent = document.getElementById('custom-footer-demo');
    const toggleButton = document.getElementById('custom-footer-toggle');
    const continueButton = document.getElementById('custom-footer-continue');

    // A custom left button drives the terms panel via the public method.
    toggleButton.addEventListener('click', () => consent.toggleDetails());

    // The custom continue button is a plain button, so alert on its own click.
    continueButton.addEventListener('click', () => alert('You agreed to the terms.'));

    // Keep the custom continue button in sync with the consent requirement.
    const sync = () => (continueButton.disabled = !consent.consentGiven);
    consent.addEventListener('sl-consent-change', sync);
    sync();
  })();
</script>

[component-metadata:sl-legal-consent]

Slots

Name Description
(default) The full disclosure text, rendered inside the scrollable terms panel.
banner Brand panel content, typically a logo and a short headline, shown in the banner column. Set --banner-width to customise its width; it defaults to 320px.
heading The disclosure title. Use in place of the heading attribute when the title needs markup.
lead The plain-language summary shown above the terms panel.
consent The consent statement shown directly above the footer.
footer-left The buttons shown on the left side of the footer (defaults to the toggle).
footer-right The buttons shown on the right side of the footer (defaults to “Agree & continue”).

Learn more about using slots.

Properties

Name Description Reflects Type Default
open Whether the terms content is expanded. Set this attribute to control the initial expanded state, or toggle it to show and hide the terms; the “See / Hide terms of use” toggle keeps it in sync. boolean false
heading The disclosure title. Use the heading slot instead when the title needs markup. string 'Before you get started'
consentGiven
consent-given
Whether the consent requirement (checkbox / scroll) has been satisfied. Reflected to the consent-given attribute so it can be targeted with CSS (sl-legal-consent[consent-given]) and read/observed by a parent that renders its own continue button. boolean false
consentMode
consent-mode
The requirement the user must meet before “Agree & continue” is enabled: - null (default) — no requirement, the button is always clickable; - checkbox — the user must tick a consent checkbox; - scroll — the user must scroll to the bottom of the terms details. 'checkbox' | 'scroll' | null null
seeTermsLabel
see-terms-label
The toggle label shown while the terms content is collapsed. string 'See terms of use'
hideTermsLabel
hide-terms-label
The toggle label shown while the terms content is expanded. string 'Hide terms of use'
agreeLabel
agree-label
The label for the default “Agree & continue” button. string 'Agree & continue'
showDecline
show-decline
Whether to show a decline button to the left of the agree button. boolean false
declineLabel
decline-label
The label for the decline button (shown when show-decline is set). string 'Decline'
maxHeight
max-height
The maximum height (in pixels) of the expanded details block. When set, the details content is capped at this height and scrolls; when null (default), it grows to fit its content. number | null null
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-agree Emitted when the user clicks the default “Agree & continue” button. CustomEvent
sl-decline Emitted when the user clicks the built-in decline button (enabled with show-decline). CustomEvent
sl-consent-change Emitted when the consent requirement becomes met or unmet. event.detail.consentGiven reflects the new state. CustomEvent

Learn more about events.

Methods

Name Description Arguments
toggleDetails() Shows or hides the details paragraph. -

Learn more about methods.

Custom Properties

Name Description Default
--border-color The legal consent panel’s border color, including borders inside the panel.
--border-width The width of the legal consent panel’s borders.
--padding The padding to use for the legal consent panel’s sections.
--banner-width Width of the brand banner. Defaults to 320px.

Learn more about customizing CSS custom properties.

Parts

Name Description
base The component’s base wrapper.
banner The left banner panel.
body The right body panel.
content The content block (heading, lead, details and close paragraphs).
details The collapsible details paragraph region.
footer The footer wrapper containing the left and right sides.
footer-left The left side of the footer.
footer-right The right side of the footer.
consent-checkbox The consent checkbox shown when consent-mode="checkbox".

Learn more about customizing CSS parts.

Dependencies

This component automatically imports the following dependencies.

  • <sl-button>
  • <sl-checkbox>
  • <sl-icon>
  • <sl-spinner>