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

MWPW-157776 Prompt Card Block #805

Open
wants to merge 9 commits into
base: stage
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions acrobat/blocks/prompt-card/prompt-card.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#prompt {
display: none
}

.prompt-toast {
font-family: "Adobe Clean", adobe-clean, "Trebuchet MS", sans-serif;
align-items: flex-start;
background: #05834e;
border-radius: 10px;
color: #fff;
display: none;
gap: 10px;
left: 50%;
padding: 20px 16px;
position: fixed;
top: 110px;
transform: translate(-50%, -50%);
z-index: 1;
z-index: 11
}

.prompt-toast--show {
display: inline-flex
}

.prompt-toast:before {

Check failure on line 26 in acrobat/blocks/prompt-card/prompt-card.css

View workflow job for this annotation

GitHub Actions / runner / stylelint (18.x)

[stylelint] reported by reviewdog 🐶 Expected double colon pseudo-element notation Raw Output: message:"Expected double colon pseudo-element notation" location:{path:"/home/runner/work/dc/dc/acrobat/blocks/prompt-card/prompt-card.css" range:{start:{line:26 column:14}}} severity:ERROR source:{name:"stylelint" url:"https://stylelint.io/"} code:{value:"selector-pseudo-element-colon-notation"}
background: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTEwIDE4Ljc1Yy00LjgyNSAwLTguNzUtMy45MjUtOC43NS04Ljc1UzUuMTc1IDEuMjUgMTAgMS4yNXM4Ljc1IDMuOTI1IDguNzUgOC43NS0zLjkyNSA4Ljc1LTguNzUgOC43NVptMC0xNkE3LjI1OCA3LjI1OCAwIDAgMCAyLjc1IDEwYzAgMy45OTggMy4yNTIgNy4yNSA3LjI1IDcuMjVzNy4yNS0zLjI1MiA3LjI1LTcuMjVTMTMuOTk4IDIuNzUgMTAgMi43NVoiLz48cGF0aCBkPSJNOS4xODMgMTMuOTQzYS43NTEuNzUxIDAgMCAxLS41NTgtLjI0OGwtMi42NDMtMi45NGEuNzUuNzUgMCAwIDEgMS4xMTUtMS4wMDNsMi4wMjYgMi4yNTQgMy43LTUuMDQ2YS43NS43NSAwIDEgMSAxLjIwOS44ODdsLTQuMjQ1IDUuNzlhLjc0NS43NDUgMCAwIDEtLjU2Ny4zMDVsLS4wMzcuMDAxWiIvPjwvZz48L3N2Zz4=");
background-repeat: no-repeat;
background-size: contain;
content: "";
height: 20px;
margin-top: 3px;
min-width: 20px;
width: 20px
}

.prompt-close {
background: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgY2xpcC1wYXRoPSJ1cmwoI2EpIj48cGF0aCBkPSJtNy4zNDIgNiAzLjM5Ni0zLjM5NmEuOTUuOTUgMCAwIDAtMS4zNDMtMS4zNDJMNiA0LjY1OCAyLjYwNCAxLjI2MmEuOTUuOTUgMCAxIDAtMS4zNDMgMS4zNDJMNC42NTcgNiAxLjI2MSA5LjM5NmEuOTUuOTUgMCAxIDAgMS4zNDMgMS4zNDJMNiA3LjM0MmwzLjM5NSAzLjM5NmEuOTQ2Ljk0NiAwIDAgMCAxLjM0My4wMDEuOTUuOTUgMCAwIDAgMC0xLjM0M0w3LjM0MiA2WiIgZmlsbD0iI2ZmZiIvPjwvZz48ZGVmcz48Y2xpcFBhdGggaWQ9ImEiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0wIDBoMTJ2MTJIMHoiLz48L2NsaXBQYXRoPjwvZGVmcz48L3N2Zz4=");
background-repeat: no-repeat;
background-size: contain;
content: "";
height: 12px;
margin-left: 10px;
margin-top: 7px;
min-width: 12px;
width: 12px
}

.prompt-blade {
align-items: center;
align-items: flex-start;
align-self: stretch;
background-color: #fff;
border: 1px solid #e8e8e8;
border-radius: 10px;
cursor: pointer;
display: flow;
flex: 1 0 0;
flex-direction: column;
justify-content: space-between;
padding: 20px 20px 24px;
transition-delay: 3s;
transition-property: border;
max-width: 276px;
}

.prompt-blade:hover {
box-shadow: 3px 6px 6px 0 rgba(0, 0, 0, .16)

Check failure on line 68 in acrobat/blocks/prompt-card/prompt-card.css

View workflow job for this annotation

GitHub Actions / runner / stylelint (18.x)

[stylelint] reported by reviewdog 🐶 Expected ".16" to be "16%" Raw Output: message:"Expected \".16\" to be \"16%\"" location:{path:"/home/runner/work/dc/dc/acrobat/blocks/prompt-card/prompt-card.css" range:{start:{line:68 column:43}}} severity:ERROR source:{name:"stylelint" url:"https://stylelint.io/"} code:{value:"alpha-value-notation"}

Check failure on line 68 in acrobat/blocks/prompt-card/prompt-card.css

View workflow job for this annotation

GitHub Actions / runner / stylelint (18.x)

[stylelint] reported by reviewdog 🐶 Expected modern color-function notation Raw Output: message:"Expected modern color-function notation" location:{path:"/home/runner/work/dc/dc/acrobat/blocks/prompt-card/prompt-card.css" range:{start:{line:68 column:29}}} severity:ERROR source:{name:"stylelint" url:"https://stylelint.io/"} code:{value:"color-function-notation"}
}

.prompt-blade:active {
border: 1px solid #095aba;
transition-delay: 0s
}

.prompt-icon {
margin-inline-end: 5px;
position: relative;
top: 5px
}

.prompt-prefix {
color: #6d6d6d;
font-size: 12px;
padding: 0 0 16px;
text-transform: uppercase
}

.prompt-prefix,
.prompt-title {
font-family: "Adobe Clean", adobe-clean, "Trebuchet MS", sans-serif;
font-style: normal;
font-weight: 700;
line-height: 125%
}

.prompt-title {
align-self: stretch;
color: #2c2c2c;
font-size: 18px
}

.prompt-copy {
-webkit-line-clamp: 5;
-webkit-box-orient: vertical;
background: #f8f8f8;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
color: #696969;
display: -webkit-box;

Check failure on line 110 in acrobat/blocks/prompt-card/prompt-card.css

View workflow job for this annotation

GitHub Actions / runner / stylelint (18.x)

[stylelint] reported by reviewdog 🐶 Unexpected vendor-prefix "-webkit-box" Raw Output: message:"Unexpected vendor-prefix \"-webkit-box\"" location:{path:"/home/runner/work/dc/dc/acrobat/blocks/prompt-card/prompt-card.css" range:{start:{line:110 column:12}}} severity:ERROR source:{name:"stylelint" url:"https://stylelint.io/"} code:{value:"value-no-vendor-prefix"}
flex: 1 0 0;
font-family: "Adobe Clean", adobe-clean, "Trebuchet MS", sans-serif;
font-size: 20px;
font-style: normal;
font-weight: 400;
height: 155px;
line-height: 150%;
margin-top: 16px;
overflow: hidden;
padding: 8px 16px 0
}

.prompt-copy-btn-wrapper {
align-items: center;
align-self: stretch;
background: #f8f8f8;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
display: flex;
gap: 8px;
justify-content: flex-end;
padding-bottom: 16px;
padding-top: 5px
}

.prompt-copy-btn {
color: #686868;
cursor: pointer;
font-family: "Adobe Clean", adobe-clean, "Trebuchet MS", sans-serif;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 150%;
padding: 2px 8px
}

.prompt-copy-btn:after {

Check failure on line 147 in acrobat/blocks/prompt-card/prompt-card.css

View workflow job for this annotation

GitHub Actions / runner / stylelint (18.x)

[stylelint] reported by reviewdog 🐶 Expected double colon pseudo-element notation Raw Output: message:"Expected double colon pseudo-element notation" location:{path:"/home/runner/work/dc/dc/acrobat/blocks/prompt-card/prompt-card.css" range:{start:{line:147 column:17}}} severity:ERROR source:{name:"stylelint" url:"https://stylelint.io/"} code:{value:"selector-pseudo-element-colon-notation"}
background: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTkiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iIzI0MjQyNCI+PHBhdGggZD0iTTE2Ljc1IDExLjVoLS41YS4yNS4yNSAwIDAgMC0uMjUuMjV2LjVjMCAuMTM4LjExMi4yNS4yNS4yNWguNWEuMjUuMjUgMCAwIDAgLjI1LS4yNXYtLjVhLjI1LjI1IDAgMCAwLS4yNS0uMjVaTTE2Ljc1IDkuNWgtLjVhLjI1LjI1IDAgMCAwLS4yNS4yNXYuNWMwIC4xMzguMTEyLjI1LjI1LjI1aC41YS4yNS4yNSAwIDAgMCAuMjUtLjI1di0uNWEuMjUuMjUgMCAwIDAtLjI1LS4yNVpNMTYuNzUgNy41aC0uNWEuMjUuMjUgMCAwIDAtLjI1LjI1di41YzAgLjEzOC4xMTIuMjUuMjUuMjVoLjVhLjI1LjI1IDAgMCAwIC4yNS0uMjV2LS41YS4yNS4yNSAwIDAgMC0uMjUtLjI1Wk0xNi43NSA1LjVoLS41YS4yNS4yNSAwIDAgMC0uMjUuMjV2LjVjMCAuMTM4LjExMi4yNS4yNS4yNWguNWEuMjUuMjUgMCAwIDAgLjI1LS4yNXYtLjVhLjI1LjI1IDAgMCAwLS4yNS0uMjVaTTE2Ljc1IDMuNWgtLjVhLjI1LjI1IDAgMCAwLS4yNS4yNXYuNWMwIC4xMzguMTEyLjI1LjI1LjI1aC41YS4yNS4yNSAwIDAgMCAuMjUtLjI1di0uNWEuMjUuMjUgMCAwIDAtLjI1LS4yNVpNMTYuNzUgMS41aC0uNWEuMjUuMjUgMCAwIDAtLjI1LjI1di41YzAgLjEzOC4xMTIuMjUuMjUuMjVoLjVhLjI1LjI1IDAgMCAwIC4yNS0uMjV2LS41YS4yNS4yNSAwIDAgMC0uMjUtLjI1Wk0xNC43NSAxLjVoLS41YS4yNS4yNSAwIDAgMC0uMjUuMjV2LjVjMCAuMTM4LjExMi4yNS4yNS4yNWguNWEuMjUuMjUgMCAwIDAgLjI1LS4yNXYtLjVhLjI1LjI1IDAgMCAwLS4yNS0uMjVaTTEyLjc1IDEuNWgtLjVhLjI1LjI1IDAgMCAwLS4yNS4yNXYuNWMwIC4xMzguMTEyLjI1LjI1LjI1aC41YS4yNS4yNSAwIDAgMCAuMjUtLjI1di0uNWEuMjUuMjUgMCAwIDAtLjI1LS4yNVpNMTAuNzUgMS41aC0uNWEuMjUuMjUgMCAwIDAtLjI1LjI1di41YzAgLjEzOC4xMTIuMjUuMjUuMjVoLjVhLjI1LjI1IDAgMCAwIC4yNS0uMjV2LS41YS4yNS4yNSAwIDAgMC0uMjUtLjI1Wk04Ljc1IDEuNWgtLjVhLjI1LjI1IDAgMCAwLS4yNS4yNXYuNWMwIC4xMzguMTEyLjI1LjI1LjI1aC41QS4yNS4yNSAwIDAgMCA5IDIuMjV2LS41YS4yNS4yNSAwIDAgMC0uMjUtLjI1Wk02Ljc1IDEuNWgtLjVhLjI1LjI1IDAgMCAwLS4yNS4yNXYuNWMwIC4xMzguMTEyLjI1LjI1LjI1aC41QS4yNS4yNSAwIDAgMCA3IDIuMjV2LS41YS4yNS4yNSAwIDAgMC0uMjUtLjI1Wk02Ljc1IDMuNWgtLjVhLjI1LjI1IDAgMCAwLS4yNS4yNXYuNWMwIC4xMzguMTEyLjI1LjI1LjI1aC41QS4yNS4yNSAwIDAgMCA3IDQuMjV2LS41YS4yNS4yNSAwIDAgMC0uMjUtLjI1Wk02Ljc1IDUuNWgtLjVhLjI1LjI1IDAgMCAwLS4yNS4yNXYuNWMwIC4xMzguMTEyLjI1LjI1LjI1aC41QS4yNS4yNSAwIDAgMCA3IDYuMjV2LS41YS4yNS4yNSAwIDAgMC0uMjUtLjI1Wk02Ljc1IDcuNWgtLjVhLjI1LjI1IDAgMCAwLS4yNS4yNXYuNWMwIC4xMzguMTEyLjI1LjI1LjI1aC41QS4yNS4yNSAwIDAgMCA3IDguMjV2LS41YS4yNS4yNSAwIDAgMC0uMjUtLjI1Wk02Ljc1IDkuNWgtLjVhLjI1LjI1IDAgMCAwLS4yNS4yNXYuNWMwIC4xMzguMTEyLjI1LjI1LjI1aC41YS4yNS4yNSAwIDAgMCAuMjUtLjI1di0uNWEuMjUuMjUgMCAwIDAtLjI1LS4yNVpNNi43NSAxMS41aC0uNWEuMjUuMjUgMCAwIDAtLjI1LjI1di41YzAgLjEzOC4xMTIuMjUuMjUuMjVoLjVhLjI1LjI1IDAgMCAwIC4yNS0uMjV2LS41YS4yNS4yNSAwIDAgMC0uMjUtLjI1Wk04Ljc1IDExLjVoLS41YS4yNS4yNSAwIDAgMC0uMjUuMjV2LjVjMCAuMTM4LjExMi4yNS4yNS4yNWguNWEuMjUuMjUgMCAwIDAgLjI1LS4yNXYtLjVhLjI1LjI1IDAgMCAwLS4yNS0uMjVaTTEwLjc1IDExLjVoLS41YS4yNS4yNSAwIDAgMC0uMjUuMjV2LjVjMCAuMTM4LjExMi4yNS4yNS4yNWguNWEuMjUuMjUgMCAwIDAgLjI1LS4yNXYtLjVhLjI1LjI1IDAgMCAwLS4yNS0uMjVaTTEyLjc1IDExLjVoLS41YS4yNS4yNSAwIDAgMC0uMjUuMjV2LjVjMCAuMTM4LjExMi4yNS4yNS4yNWguNWEuMjUuMjUgMCAwIDAgLjI1LS4yNXYtLjVhLjI1LjI1IDAgMCAwLS4yNS0uMjVaTTE0Ljc1IDExLjVoLS41YS4yNS4yNSAwIDAgMC0uMjUuMjV2LjVjMCAuMTM4LjExMi4yNS4yNS4yNWguNWEuMjUuMjUgMCAwIDAgLjI1LS4yNXYtLjVhLjI1LjI1IDAgMCAwLS4yNS0uMjVaIi8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik01IDYuNUgxLjVBLjUuNSAwIDAgMCAxIDd2MTBhLjUuNSAwIDAgMCAuNS41aDEwYS41LjUgMCAwIDAgLjUtLjV2LTMuNUg1LjVBLjUuNSAwIDAgMSA1IDEzVjYuNVoiLz48L2c+PC9zdmc+");
background-repeat: no-repeat;
background-size: contain;
content: "";
display: inline-block;
height: 18px;
min-width: 18px;
position: relative;
top: 5px;
width: 18px;
margin-inline-start: 8px
}
119 changes: 119 additions & 0 deletions acrobat/blocks/prompt-card/prompt-card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { setLibs } from '../../scripts/utils.js';

const miloLibs = setLibs('/libs');
const { createTag } = await import(`${miloLibs}/utils/utils.js`);

const classToastShow = 'prompt-toast--show';
const getPlaceHolder = (x) => (window.mph?.[x] || x);

function copyPrompt(cfg) {
navigator.clipboard.writeText(cfg.prompt);

let toast = document.querySelector('.prompt-toast');
if (!toast) {
toast = createTag('div', { class: 'prompt-toast' }, cfg.toast);
const toastClose = createTag('i', { class: 'prompt-close' });
toast.appendChild(toastClose);
document.body.appendChild(toast);

toastClose.addEventListener('click', () => {
toast.classList.remove(classToastShow);
});
}
toast.childNodes[0].textContent = cfg.toast;
toast.classList.add(classToastShow);

setTimeout(() => toast.classList.remove(classToastShow), 5000);
}

async function createBlock(element, cfg) {
cfg.icon = cfg.icon || '/acrobat/img/icons/aichat.svg';
cfg.button = cfg.button || getPlaceHolder('Copy');
cfg.toast = cfg.toast || getPlaceHolder('Copied to clipboard');
const blade = createTag('div', {
class: 'prompt-blade',
title: cfg.prompt,
'data-toast': cfg.toast,
'daa-im': true,
'daa-lh': 'Featured prompts | Executive summary',
});
const prefix = createTag('div', { class: 'prompt-prefix' });
const icon = createTag('img', {
class: 'prompt-icon',
alt: 'AI Assistant Icon',
src: cfg.icon,
width: 18,
height: 18,
});
const title = createTag('div', { class: 'prompt-title' }, cfg.title);
const copy = createTag('div', { class: 'prompt-copy' }, cfg.prompt);
const prompt = createTag('input', { id: 'prompt', value: cfg.prompt });
const wrapper = createTag('div', { class: 'prompt-copy-btn-wrapper' });
const copyBtn = createTag('span', { class: 'prompt-copy-btn', role: 'button', tabindex: 0, 'aria-label': 'Copy button' }, cfg.button);
wrapper.append(copyBtn);
prefix.appendChild(icon);
prefix.appendChild(createTag('span', null, cfg.prefix));
blade.append(prefix, title, copy, prompt, wrapper);
element.replaceChildren(blade);

blade.addEventListener('click', () => {
copyPrompt(cfg);
});

copyBtn.addEventListener('keypress', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
copyPrompt(cfg);
}
});
}

async function processGroup(element, startIndex, templateCfg) {
const blockArray = [];
const keys = [...element.children[startIndex].children].map((x) => x.textContent.toLowerCase());
[...element.children].slice(startIndex + 1).forEach((x) => {
const values = [...x.children].map((y) => y.textContent);
const block = keys.reduce((obj, key, index) => ({ ...obj, [key]: values[index] }), {});
blockArray.push(block);
});
for (const cfg of blockArray) {
const blockEl = createTag('div', { class: 'prompt-card' });
await createBlock(blockEl, { ...templateCfg, ...cfg });
element.parentNode.insertBefore(blockEl, element.nextSibling);
}
element.remove();
}

function readKeyValueSet(element) {
const cfg = {};
for (const x of [...element.children]) {
if (x.children.length < 2) break;
cfg[x.children[0].textContent.toLowerCase()] = x.children[1].textContent;
}
return cfg;
}

export default async function init(element) {
if (element.classList.contains('template') && element.classList.contains('group')) {
const cfg = readKeyValueSet(element);
await processGroup(element, Object.keys(cfg).length + 1, cfg);
return;
}

if (element.classList.contains('group')) {
await processGroup(element, 0, window.promptCardTemplate);
return;
}

let cfg = readKeyValueSet(element);

if (element.classList.contains('template')) {
window.promptCardTemplate = cfg;
element.remove();
return;
}

cfg = { ...window.promptCardTemplate, ...cfg };

await createBlock(element, cfg);
}
21 changes: 21 additions & 0 deletions acrobat/img/icons/aichat.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions test/blocks/prompt-card/mocks/body-block-icon.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<main>
<div class="prompt-card">
<div>
<div>Icon</div>
<div>https://main--dc--adobecom.hlx.live/dc-shared/assets/images/frictionless/verb-footer-images/word-to-pdf.svg</div>
</div>
<div>
<div>Prefix</div>
<div>Ask</div>
</div>
<div>
<div>Title</div>
<div>Sum it up</div>
</div>
<div>
<div>Prompt</div>
<div>Summarize this document in 3 sentences.</div>
</div>
<div>
<div>Button</div>
<div>Copy</div>
</div>
<div>
<div>Toast</div>
<div>Copied to clipboard</div>
</div>
</div>
</main>
24 changes: 24 additions & 0 deletions test/blocks/prompt-card/mocks/body-block.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<main>
<div class="prompt-card">
<div>
<div>Prefix</div>
<div>Ask</div>
</div>
<div>
<div>Title</div>
<div>Sum it up</div>
</div>
<div>
<div>Prompt</div>
<div>Summarize this document in 3 sentences.</div>
</div>
<div>
<div>Button</div>
<div>Copy</div>
</div>
<div>
<div>Toast</div>
<div>Copied to clipboard</div>
</div>
</div>
</main>
Loading
Loading