Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cta)!: href #1608

Merged
merged 13 commits into from
Jun 21, 2024
4 changes: 4 additions & 0 deletions .changeset/mighty-vans-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
"@rhds/elements": major
---
`<rh-cta>`: Removed previously-deprecated `color-palette` attribute
5 changes: 5 additions & 0 deletions .changeset/mighty-vans-skate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rhds/elements": major
---
`<rh-cta>`: Deprecated `rhCta.cta` public property. This will be removed in the
next major version.
17 changes: 17 additions & 0 deletions .changeset/shaky-yaks-win.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@rhds/elements": minor
---
`<rh-cta>`: added `href` attribute. When set, do not slot an anchor or button,
instead, slot in the link text.

These two are equivalent:

```html
<rh-cta>
<a href="/elements">Elements</a>
</rh-cta>
```

```html
<rh-cta href="/elements">Elements</rh-cta>
```
8 changes: 8 additions & 0 deletions .changeset/wet-readers-shine.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@rhds/elements": minor
---
`<rh-cta>`: added `icon-set` attribute to better control icon loading

```html
<rh-cta icon="success" icon-set="custom">...</rh-cta>
```
164 changes: 109 additions & 55 deletions elements/rh-cta/demo/analytics.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,54 +3,114 @@
support for analytics internally, <code>&lt;rh-cta></code> users must implement their own
analytics code, taking this demo as an example.</p>

<pre class="language-javascript"><code class="language-javascript">
function deepClosest(event, selector) {
for (const node of event.composedPath().reverse()) {
if (node.matches?.(selector)) {
return node;
}
}
return event.target.closest(selector);
}

document.addEventListener('click', function(event) {
const cta = deepClosest(event, 'rh-cta');
if (cta) {
const { href, text, title } = cta.cta;
const color = cta.colorPalette;
const type = cta.variant;
console.log('CTA ANALYTICS EVENT', { href, text, title, color, type });
}
});
</code></pre>

<section>
<section data-analytics-category="simple">
<h2>Simple Case: Light DOM Analytics</h2>
<rh-cta><a href="#default">Default</a></rh-cta>
<rh-cta variant="primary"><a href="#primary">Primary</a></rh-cta>
<rh-cta variant="secondary"><a href="#secondary">Secondary</a></rh-cta>
<rh-cta variant="brick"><a href="#brick">Brick</a></rh-cta>
<rh-cta data-analytics-linktype="cta"
data-analytics-text="Default">
<a href="#default">Default</a>
</rh-cta>
<rh-cta variant="primary"
data-analytics-linktype="cta"
data-analytics-text="Primary">
<a href="#primary">Primary</a>
</rh-cta>
<rh-cta variant="secondary"
data-analytics-linktype="cta"
data-analytics-text="Secondary">
<a href="#secondary">Secondary</a>
</rh-cta>
<rh-cta variant="brick"
data-analytics-linktype="cta"
data-analytics-text="Brick">
<a href="#brick">Brick</a>
</rh-cta>

<section data-analytics-category="href-attr">
<h3>Using <code>href</code> attribute</h3>
<rh-cta href="#default"
data-analytics-linktype="cta"
data-analytics-text="Default">Default</rh-cta>
<rh-cta href="#primary"
variant="primary"
data-analytics-linktype="cta"
data-analytics-text="Primary">Primary</rh-cta>
<rh-cta href="#secondary"
variant="secondary"
data-analytics-linktype="cta"
data-analytics-text="Secondary">Secondary</rh-cta>
<rh-cta href="#brick"
variant="brick"
data-analytics-linktype="cta"
data-analytics-text="Brick">Brick</rh-cta>
</section>
</section>

<section>
<section data-analytics-category="shadow">
<h2>Advanced Case: Deep Shadow Analytics</h2>
<shadow-root>
<template shadowroot="open" shadowrootmode="open">
<rh-cta><a href="#default">Default</a></rh-cta>
<rh-cta variant="primary"><a href="#primary">Primary</a></rh-cta>
<rh-cta variant="secondary"><a href="#secondary">Secondary</a></rh-cta>
<rh-cta variant="brick"><a href="#brick">Brick</a></rh-cta>
<template shadowrootmode="open">
<rh-cta data-analytics-linktype="cta"
data-analytics-text="Default">
<a href="#default">Default</a>
</rh-cta>
<rh-cta variant="primary"
data-analytics-linktype="cta"
data-analytics-text="Primary">
<a href="#primary">Primary</a>
</rh-cta>
<rh-cta variant="secondary"
data-analytics-linktype="cta"
data-analytics-text="Secondary">
<a href="#secondary">Secondary</a>
</rh-cta>
<rh-cta variant="brick"
data-analytics-linktype="cta"
data-analytics-text="Brick">
<a href="#brick">Brick</a>
</rh-cta>
</template>
</shadow-root>
<h3>Using <code>href</code> attribute</h3>
<shadow-root data-analytics-category="href-attr">
<template shadowrootmode="open">
<rh-cta href="#default"
data-analytics-linktype="cta"
data-analytics-text="Default">Default</rh-cta>
<rh-cta href="#primary"
data-analytics-linktype="cta"
data-analytics-text="Primary"
variant="primary">Primary</rh-cta>
<rh-cta href="#secondary"
data-analytics-linktype="cta"
data-analytics-text="Secondary"
variant="secondary">Secondary</rh-cta>
<rh-cta href="#brick"
variant="brick"
data-analytics-linktype="cta"
data-analytics-text="Brick">Brick</rh-cta>
</template>
</shadow-root>
</section>

<section>
<section data-analytics-category="slotted">
<h2>Complex Case: Slotted Link, Deep CTA Analytics</h2>
<slotted-link>
<a slot="default" href="#default">Default</a>
<a slot="primary" href="#primary">Primary</a>
<a slot="secondary" href="#secondary">Secondary</a>
<a slot="brick" href="#brick">Brick</a>
<a slot="default"
data-analytics-linktype="cta"
data-analytics-text="Default"
href="#default">Default</a>
<a slot="primary"
data-analytics-linktype="cta"
data-analytics-text="Primary"
href="#primary">Primary</a>
<a slot="secondary"
data-analytics-linktype="cta"
data-analytics-text="Secondary"
href="#secondary">Secondary</a>
<a slot="brick"
data-analytics-linktype="cta"
data-analytics-text="Brick"
href="#brick">Brick</a>
</slotted-link>
</section>

Expand Down Expand Up @@ -87,25 +147,19 @@ <h2>Last CTA Analytics Event</h2>
}
});

function deepClosest(event, selector) {
for (const node of event.composedPath().reverse()) {
if (node.matches?.(selector)) {
return node;
}
}
return event.target.closest(selector);
}

document.addEventListener('click', function(event) {
const cta = deepClosest(event, 'rh-cta');
if (cta) {
const { href, text, title } = cta.cta;
const color = cta.colorPalette;
const type = cta.variant ?? 'default';
const data = { href, text, title, color, type };
// for the purposes of the demo, let's enable console logging here
// eslint-disable-next-line no-console
console.log('CTA ANALYTICS EVENT', data);
const data = event.composedPath().reduceRight((acc, node) => {
if (node instanceof HTMLElement) {
for (const [datakey, value] of Object.entries(node.dataset)) {
if (datakey.startsWith('analytics')) {
const key = datakey.replace(/^analytics(.)/, (_, m) => m.toLowerCase());
acc[key] = `${acc[key] ?? ''}|${value}`.replace(/^\|/,'');
}
}
}
return acc;
}, {});
if (Object.keys(data).length) {
document.querySelector('json-viewer').object = data;
}
});
Expand Down
31 changes: 31 additions & 0 deletions elements/rh-cta/demo/href-attribute.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<section>
<rh-cta href="#default">Default</rh-cta>
<rh-cta href="#default-video" icon="play-circle">Default Video</rh-cta>
<rh-cta href="#primary" variant="primary">Primary</rh-cta>
<rh-cta href="#primary-video" variant="primary" icon="play-circle">Video</rh-cta>
<rh-cta href="#secondary" variant="secondary">Secondary</rh-cta>
<div id="brick">
<rh-cta href="#brick" variant="brick">Brick</rh-cta>
<rh-cta href="#brick-icon" variant="brick" icon="user">Brick Icon</rh-cta>
</div>
</section>

<style>
section {
display: flex;
gap: var(--rh-space-lg, 16px);
flex-flow: row wrap;
max-width: 750px;
margin: var(--rh-space-2xl, 32px) auto;
}

#brick {
display: flex;
width: 100%;
gap: var(--rh-space-lg, 16px);
}
</style>

<script type="module">
import '@rhds/elements/rh-cta/rh-cta.js';
</script>
20 changes: 14 additions & 6 deletions elements/rh-cta/rh-cta.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
max-width: max-content;
}

::slotted(*) {
a,
::slotted(:is(a, button, input)) {
vertical-align: middle !important;
white-space: break-spaces !important;
word-break: break-word !important;
Expand All @@ -20,6 +21,7 @@
z-index: 2 !important;
}

a:after,
::slotted(a):after {
display: block;
content: "";
Expand Down Expand Up @@ -109,7 +111,9 @@ svg {
*****************************************************************************/

:host(:is(:focus, :focus-within)),
:host(:is(:focus, :focus-within)) ::slotted(*),
:host(:is(:focus, :focus-within)) ::slotted(:is(a, button, input)),
a:focus,
a:focus-within,
::slotted(:focus) {
outline: none !important;
}
Expand Down Expand Up @@ -193,20 +197,24 @@ svg {
padding-block: var(--rh-space-lg, 16px);
}

:host([variant]) #container ::slotted(*) {
:host([variant]) #container a,
:host([variant]) #container ::slotted(:is(a, button, input)) {
display: inline-flex !important;
text-align: center !important;
}

:host([variant$="ary"]) #container ::slotted(*) {
:host([variant$="ary"]) #container a,
:host([variant$="ary"]) #container ::slotted(:is(a, button, input)) {
font-size: var(--rh-cta-font-size-priority, var(--rh-font-size-body-text-md, 1rem));
}

:host([variant]) #container.icon ::slotted(*) {
:host([variant]) #container.icon a,
:host([variant]) #container.icon ::slotted(:is(a, button, input)) {
display: inline !important;
}

:host([variant]) #container.svg ::slotted(*) {
:host([variant]) #container.svg a,
:host([variant]) #container.svg ::slotted(:is(a, button, input)) {
padding-inline-end: calc(var(--_arrow-plus-padding) + var(--rh-space-xl, 24px)) !important;
}

Expand Down
Loading
Loading