msc-ai-assistant
Version:
<msc-ai-assistant /> is a web component based on Chrome Built-in AI Prompt API. Web developers could use <msc-ai-assistant /> to help user consult anything they like to know.
675 lines (588 loc) • 23.9 kB
HTML
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Web Component: <msc-ai-assistant /> - a web component based on Chrome Built-in AI Prompt API</title>
<meta name="description" content="msc-ai-assistant is a web component based on Chrome Built-in AI Prompt API. Web developers could use msc-ai-assistant to help user consult anything they like to know. The following demo is a front-end skill consulting. User could press 「SUMMON ASSISTANT」 and go." />
<script type="module" src="mjs/wc-msc-ai-assistant.js"></script>
<link rel="stylesheet" href="https://blog.lalacube.com/mei/css/layers/input-set.css">
<link rel="stylesheet" href="https://blog.lalacube.com/mei/css/layers/radio-set.css">
<link rel="stylesheet" href="https://blog.lalacube.com/mei/css/layers/buttons.css">
<style>
/* reset */
body,div,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,legend,input,textarea,p,article,aside,figcaption,figure,nav,section,mark,audio,video,main{margin:0;padding:0}
article,aside,figcaption,figure,nav,section,main{display:block}
fieldset,img{border:0}
address,caption,cite,em,strong{font-style:normal;font-weight:400}
ol,ul{list-style:none}
caption{text-align:left}
h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:400}
abbr{border:0;font-variant:normal}
input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}
body{-webkit-text-size-adjust:none}
select,input,button,textarea{font:100% arial,helvetica,clean,sans-serif;}
del{font-style:normal;text-decoration:none}
pre{font-family:monospace;line-height:100%}
progress{-webkit-appearance:none;appearance:none;overflow:hidden;border:0 none;}
/* page */
:root {
--bd-bg: #fff;
--subject-text: #000;
}
@media (prefers-color-scheme: dark) {
:root {
--bd-bg: #121212;
--subject-text: #e8eaed;
}
}
/* defaults */
:root {
--ON: initial;
--OFF: ;
/* fuji */
--white: 255 255 255;
--marshmallow: 245 248 250;
--grey-hair: 240 243 245;
--dirty-seagull: 224 228 233;
--pebble: 199 205 210;
--bob: 176 185 193;
--gandalf: 151 158 168;
--shark: 130 138 147;
--dolphin: 110 119 128;
--battleship: 91 99 106;
--charcoal: 70 78 86;
--ramones: 44 54 63;
--batcave: 35 42 49;
--inkwell: 29 34 40;
--midnight: 16 21 24;
--black: 0 0 0;
--watermelon: 255 82 87;
--solo-cup: 235 15 41;
--malibu: 255 0 128;
--barney: 204 0 140;
--mimosa: 255 211 51;
--turmeric: 255 167 0;
--masala: 255 139 18;
--cheetos: 253 97 0;
--carrot-juice: 255 82 13;
--mulah: 26 197 103;
--bonsai: 0 135 81;
--spirulina: 0 160 160;
--sea-foam: 17 211 205;
--peeps: 125 203 255;
--sky: 18 169 255;
--dory: 15 105 255;
--scooter: 0 99 235;
--cobalt: 0 58 188;
--denim: 26 13 171;
--blurple: 93 94 255;
--hendrix: 248 244 255;
--thanos: 144 124 255;
--starfish: 119 89 255;
--hulk-pants: 126 31 255;
--grape-jelly: 96 1 210;
--mulberry: 80 21 176;
--malbec: 57 0 125;
/* property */
--theme-gradient-start: 255 231 98;
--theme-gradient-end: 252 218 25;
--anchor-green: 58 191 186;
--mark-buynow: 0 120 255;
--mark-bidding: 255 139 18;
--mark-metro-express: 255 77 82;
--heart-red: 253 79 87;
/* shadow */
--shadow-elevations-1: 0 1px 0 rgba(var(--dirty-seagull)), 0 0 1px rgba(var(--black)/0);
--shadow-elevations-2: 0 0 1px rgba(var(--black)/.1), 0 2px 4px rgba(var(--black)/.08);
--shadow-elevations-3: 0 0 1px rgba(var(--black)/.08), 0 4px 8px rgba(var(--black)/.1);
--shadow-elevations-4: 0 0 2px rgba(var(--black)/.05), 0 4px 16px rgba(var(--black)/.2);
--shadow-elevations-5: 0 0 16px rgba(var(--black)/.05), 0 32px 32px 20px rgba(var(--black)/.4);
/* safe-area */
--el:0;
--et:0;
--eb:0;
--basis-padding: 1em;
--spl: calc(var(--el) + var(--basis-padding));
--spb: calc(var(--eb) + var(--basis-padding));
/* icons */
--icon-home: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxNicgaGVpZ2h0PScxNicgdmlld0JveD0nMCAwIDMyIDMyJz48cGF0aCBmaWxsPScjZmZmJyBkPSdNMTYuMTUzIDMuMjI0TDAgMTYuOTYyaDQuMzE0djExLjgxNGg5Ljg3di04LjAwM2gzLjkzNHY4LjAwM2g5Ljg0VjE2Ljk2MkgzMicvPjwvc3ZnPg==) no-repeat 50% 50%/16px 16px;
--icon-cart: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyNCcgaGVpZ2h0PScyNCc+PHBhdGggZmlsbD0nI2ZmZicgZD0nTTkuNSAxMC41SDE2Yy41NTIgMCAxIC40NDQgMSAxIDAgLjU1Mi0uNDQ1IDEtMSAxSDkuNWMtLjU1MiAwLTEtLjQ0NC0xLTEgMC0uNTUyLjQ0NS0xIDEtMXpNMTAgMjFhMiAyIDAgMTAtMy45OTktLjAwMUEyIDIgMCAwMDEwIDIxem05LjUgMGEyIDIgMCAxMC0zLjk5OS0uMDAxQTIgMiAwIDAwMTkuNSAyMXpNNC40OTYgMkg0LjVjLjU1Mi4wMDUuOTk4LjQ0NSAxIC45OTZMNyAxNWgxMS41TDIwIDQuOTk2UzIwLjA4MiA0IDIxIDRjLjkxNSAwIDEgLjc2MiAxIDFsLTEuNSAxMS4wMDRjMCAuNTUtLjQ0OC45OTYtMSAuOTk2SDZhMSAxIDAgMDEtMS0uOTk2TDMuNjE2IDRIMS4wMUMuNDUgNCAwIDMuNTU2IDAgM2MwLS41NTIuNDUtMSAxLjAxLTFoMy40ODV6TTkuNSA1LjVIMTZjLjU1MiAwIDEgLjQ0NCAxIDEgMCAuNTUyLS40NDUgMS0xIDFIOS41Yy0uNTUyIDAtMS0uNDQ0LTEtMSAwLS41NTIuNDQ1LTEgMS0xeicvPjwvc3ZnPg==) no-repeat 0% 50%/contain;
--icon-order: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyNCcgaGVpZ2h0PScyNCc+PHBhdGggZmlsbD0nI2ZmZicgZD0nTTE4LjYxIDE5LjI1NmwtLjY0Mi0uNDYtMS4yMTgtLjg3Ny0xLjE0My45NjctMS4xNi45ODQtMS4yMzMtMS4wMDMtMS4yMTQtLjk5LTEuMjE0Ljk5LTEuMjMgMS4wMDQtMS4xNjUtLjk4NC0xLjE0My0uOTY3LTEuMjE4Ljg3NS0uNjQuNDZWMy44MzZoMTMuMjJ2MTUuNDJ6TTQuNDQ1IDJhLjk0Ni45NDYgMCAwMC0uOTQ0Ljk0djE4LjEzNmMwIC41NC40NTYuOTIuOTQ4LjkyLjE3IDAgLjM0OC0uMDQ2LjUxLS4xNDhsMi4xOTMtMS41NzZMOC45NyAyMS44MWEuOTc0Ljk3NCAwIDAwMS4xMjcuMDJMMTIgMjAuMjczbDEuOTA2IDEuNTU1YS45NzIuOTcyIDAgMDAxLjEyNy0uMDJsMS44MTQtMS41MzggMi4xOTYgMS41NzZjLjE2My4xMDIuMzQuMTQ4LjUxLjE0OC40OTIgMCAuOTQ3LS4zOC45NDctLjkyVjIuOTRhLjk0NS45NDUgMCAwMC0uOTQ0LS45NEg0LjQ0NHptMTEuMzMzIDEwLjExM2MuNTIyIDAgLjk0NS0uNDEuOTQ1LS45MThzLS40MjMtLjkyLS45NDUtLjkySDguMjIzYS45MzIuOTMyIDAgMDAtLjk0NC45MmMwIC41MDcuNDIuOTE4Ljk0My45MThoNy41NTR6TTExLjA1NSA4LjQ0Yy4yNjIgMCAuOTQ1LS4yMjQuOTQ1LS45MiAwLS41MDctLjQyMy0uOTE3LS45NDUtLjkxN0g4LjIyM2MtLjUyMiAwLS45NDQuNDEtLjk0NC45MThzLjQyLjkyLjk0My45MmgyLjgzMnptNC43MjIgNy4zNDdjLjUyMiAwIC45NDUtLjQxLjk0NS0uOTE4IDAtLjUxLS40MjMtLjkyLS45NDUtLjkySDguMjIzYS45My45MyAwIDAwLS45NDQuOTJjMCAuNTA2LjQyLjkxNy45NDMuOTE3aDcuNTU0eicvPjwvc3ZnPg==) no-repeat 0% 50%/contain;
--icon-close: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyNCcgaGVpZ2h0PScyNCc+PHBhdGggZmlsbD0nIzk3OWVhOCcgZD0nTTEyIDEwLjU4OEw2LjcwMiA1LjI5YTEgMSAwIDAwLTEuNDA4LjAwNC45OTMuOTkzIDAgMDAtLjAwMyAxLjQwOEwxMC41ODggMTJsLTUuMjk3IDUuMjk3YTEgMSAwIDAwLjAwMyAxLjQwOC45OTMuOTkzIDAgMDAxLjQwOC4wMDRMMTIgMTMuNDExbDUuMjk4IDUuMjk4YS45OTkuOTk5IDAgMDAxLjQxMS0xLjQxMkwxMy40MTIgMTJsNS4yOTctNS4yOThhMSAxIDAgMDAtLjAwMy0xLjQwOC45OTUuOTk1IDAgMDAtMS40MDgtLjAwNEwxMiAxMC41ODh6Jy8+PC9zdmc+) no-repeat 50% 50%/24px 24px;
--icon-arrow-left: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyNCcgaGVpZ2h0PScyNCc+PHBhdGggZD0nTTEwLjgwMiAxMmw0LjkwNi00LjgzNGEuOTczLjk3MyAwIDAwLS4wMDMtMS4zNzguOTk0Ljk5NCAwIDAwLTEuMzk3LS4wMDNMOCAxMi4wMDFsNi4zMSA2LjIxN2MuMzc4LjM3MyAxLjAxLjM4IDEuMzk3LS4wMDJhLjk2Mi45NjIgMCAwMC4wMDMtMS4zNzhsLTQuOTA4LTQuODM3eicgZmlsbD0nI2ZmZicgZmlsbC1ydWxlPSdldmVub2RkJy8+PC9zdmc+) no-repeat 50% 50%/24px 24px;
--icon-arrow-right: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyNCcgaGVpZ2h0PScyNCc+PHBhdGggZD0nTTEzLjE5NyAxMkw4LjI5MSA3LjE2NmEuOTczLjk3MyAwIDAxLjAwMy0xLjM3OC45OTQuOTk0IDAgMDExLjM5Ny0uMDAzbDYuMzA4IDYuMjE2LTYuMzEgNi4yMTdjLS4zNzguMzczLTEuMDEuMzgtMS4zOTctLjAwMmEuOTYyLjk2MiAwIDAxLS4wMDMtMS4zNzhsNC45MDgtNC44Mzd6JyBmaWxsPScjZmZmJyBmaWxsLXJ1bGU9J2V2ZW5vZGQnLz48L3N2Zz4=) no-repeat 50% 50%/24px 24px;
/* mask */
--mask-chevron-next: path('M13.197 12 8.29 7.167a.971.971 0 0 1 .003-1.378.995.995 0 0 1 1.397-.003L16 12.001l-6.31 6.217a1.004 1.004 0 0 1-1.397-.002.962.962 0 0 1-.003-1.378l4.908-4.837Z');
/* animation */
--transition-timing-function: cubic-bezier(.4,0,.2,1);
/* pages */
--view: '';
--max-width: 100%;
/*--section-padding: 0 1em;*/
--section-padding: 0 calc(1em + var(--el));
--border-radius: .5em;
--direction-factor: 1;
--margin-block-gap: 1.25em;
--main-bgc: #f1f1f5;
--module-bgc: rgba(var(--white));
--text-color: #232a31;
/* modules */
--nav-inline-size: 13em;
--intro-text: #5f6368;
}
@supports (bottom:env(safe-area-inset-top)) {
:root {
--el: env(safe-area-inset-left);
--et: env(safe-area-inset-top);
--eb: env(safe-area-inset-bottom);
}
@supports (bottom:max(.75em,1px)) {
:root {
--spl: max(var(--basis-padding), var(--el));
--spb: max(var(--basis-padding), var(--eb));
}
}
}
@media (prefers-color-scheme: dark) {
:root {
--intro-text: #9aa0a6;
}
}
/* page */
html{font-family:system-ui,sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;font-size:16px;background-color:var(--main-bgc);scroll-behavior:smooth;}
html[dir='rtl']{--direction-factor:-1;}
#bd{margin:0 auto;}
a,a:hover{text-decoration:none;}
a{color:rgba(var(--anchor-green));}
.center-module{max-inline-size:var(--max-width);margin:0 auto;box-sizing:border-box;padding:var(--section-padding);}
.center-module--main>*{margin-block-start:var(--margin-block-gap);}
.absolute-center{position:absolute;top:0;left:0;bottom:0;right:0;margin:auto;}
.text-overflow{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.text-overflow--ltr-start{direction:rtl;text-align:start;}
.text-overflow--rtl{direction:rtl;text-align:end;}
.line-fadeout{position:relative;}
.line-fadeout:after{position:absolute;content:'';text-align:right;bottom:0;right:0;width:70%;height:var(--fadeout-h, 1.2em);background:linear-gradient(to right, rgba(255,255,255,0), rgba(255,255,255,1));}
.line-clampin{display:-webkit-box;-webkit-line-clamp:var(--line-clamp,2);-webkit-box-orient:vertical;text-overflow:ellipsis;overflow:hidden;}
.stuff{text-indent:100%;white-space:nowrap;overflow:hidden;}
.aspect-ratio{position:relative;width:100%;--w:4;--h:3;}
.aspect-ratio:before{content:'';width:100%;padding-top:calc(var(--h) * 100% / var(--w));display:block;}
.aspect-ratio .content{position:absolute;top:0;left:0;right:0;bottom:0;}
.force-radius{overflow:hidden;transform:translate3d(0,0,0);border-radius:var(--r,8px);}
.contain{object-fit:contain;}
.cover{object-fit:cover;}
.overscrolling{-webkit-overflow-scrolling:touch;overflow:hidden;overflow-y:scroll;overscroll-behavior:contain;}
.vanquish{position:absolute;left:0;top:0;width:1px;height:1px;overflow:hidden;}
.flex-center{display:flex;justify-content:center;align-items:center;}
/* media query */
@media screen and (max-width: 767px) {
:root {
--view: 'mobile';
--section-padding: 0;
--border-radius: 0;
}
}
@media screen and (min-width: 768px) {
:root {
--view: 'tablet';
--max-width: 1023px;
}
}
@media screen and (min-width: 1024px) {
:root {
--view: 'desktop';
--max-width: 1279px;
}
}
@media screen and (min-width: 1280px) {
:root {
--view: 'desktop max';
--max-width: 1280px;
--section-padding: 0 1.5em;
}
}
/* setting-form */
.setting-form {
--background-color: #dce2f0;
--subject-inline-size: 150px;
--il-align-item: center;
--il-pair-gap: 6px;
--a11y-block-link-expand: 6px;
--a11y-block-link-border-radius: 32px;
inline-size: min(100%,800px);
box-sizing: border-box;
margin-block: 2.5em;
margin-inline: auto;
display: block;
.demo-wrap {
inline-size: 100%;
aspect-ratio: 2/1.5;
/*background-color: var(--background-color);*/
border-radius: .5em;
display: grid;
place-content: center;
}
.adjustments {
.adjustments__row {
display: flex;
align-items: flex-start;
gap: 1em;
&:has(select) {
align-items: center;
}
&:nth-child(n + 2 of .adjustments__row) {
margin-block-start: .75em;
}
.adjustments__row__subject {
inline-size: var(--subject-inline-size);
color: var(--subject-text);
flex-shrink: 0;
display: flex;
align-items: center;
gap: 6px;
&::before {
inline-size: 6px;
aspect-ratio: 1/1;
border-radius: 4px;
background-color: currentColor;
content: '';
}
}
.adjustments__row__content {
color: var(--intro-text);
min-inline-size: 0;
flex-grow: 1;
display: flex;
flex-wrap: wrap;
gap: 1em;
}
}
}
@media (prefers-color-scheme: dark) {
--background-color: rgba(var(--midnight));
.radio-set,.input-set {
--default-accent-color: rgba(75 168 248);
}
}
}
/* il-pair */
.il-pair {
--gap: var(--il-pair-gap, .75em);
--align-items: var(--il-align-item, flex-start);
display: flex;
align-items: var(--align-items);
gap: var(--gap);
> :first-child {
flex-shrink: 0;
}
> :last-child {
line-height: 20px;
}
&.a11y-block-link {
display: flex;
}
}
html,body{font-family:system-ui,sans-serif;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;font-size:16px;}
#hd,#ft{display:none;}
body{position:relative;inline-size:100vw;block-size:100vh;margin:0;background:var(--bd-bg);}
.wrap{inline-size:100%;max-inline-size:min(800px, calc(100% - 2em));box-sizing:border-box;}
.demo-container {
inline-size: 100%;
margin-inline: auto;
margin-block: 4em 2em;
}
.button__wrap {
--background-color: rgba(220 226 240);
inline-size: min(100%, 800px);
aspect-ratio: 2/.6;
margin-inline: auto;
margin-block: 4em 2em;
display: grid;
place-content: center;
border-radius: 1em;
background-color: var(--background-color);
@media (prefers-color-scheme: dark) {
--background-color: rgba(29 34 40);
}
.buttons[data-type='secondary1'] {
@media (prefers-color-scheme: dark) {
--default-text-color: rgba(75 168 248);
}
}
}
.setting-form {
input[type=range] {
inline-size: min(100%, 310px);
margin-block-start: 2px;
accent-color: #1b6efb;
}
.adjustments {
.adjustments__row--center {
align-items: center;
}
}
.input-set:has([type=number]) {
inline-size: 80px;
}
.adjustments__row__content:has([type=number]) {
display: flex;
align-items: center;
}
}
msc-ai-assistant {
--msc-ai-assistant-inline-size: 400px;
--msc-ai-assistant-block-size: 600px;
--msc-ai-assistant-inset-inline-start: calc(100% - 16px - var(--msc-ai-assistant-inline-size));
--msc-ai-assistant-inset-block-start: calc(100% - 16px - var(--msc-ai-assistant-block-size));
--msc-ai-assistant-box-shadow: 0 0 8px rgba(0 0 0/.2);
@media (prefers-color-scheme: dark) {
--msc-ai-assistant-background-color: rgba(30 31 32);
--msc-ai-assistant-head-text-color: rgba(255 255 255);
--msc-ai-assistant-line-color: rgba(91 99 106);
--msc-ai-assistant-content-text-color: rgba(255 255 255);
--msc-ai-assistant-content-highlight-text-color: rgba(227 229 228);
--msc-ai-assistant-content-highlight-background-color: rgba(51 53 55);
--msc-ai-assistant-content-group-background-color: rgba(40 42 44);
--msc-ai-assistant-close-hover-background-color: rgba(51 52 55);
--msc-ai-assistant-close-icon-color: rgba(130 138 147);
--msc-ai-assistant-input-text-color: rgba(255 255 255);
--msc-ai-assistant-input-placeholder-text-color: rgba(189 193 197);
--msc-ai-assistant-form-background-color: rgba(39 42 44);
--msc-ai-assistant-form-focus-background-color: rgba(50 53 55);
--msc-ai-assistant-submit-icon-color: rgba(226 229 228);
--msc-ai-assistant-submit-hover-background-color: rgba(255 255 255/.07);
--msc-ai-assistant-box-shadow: 0 0 8px rgba(255 255 255/.2);
}
}
msc-ai-assistant:not(:defined){visibility:hidden;}
</style>
</head>
<body class="flex-center">
<div class="wrap">
<div class="demo-container">
<div class="button__wrap">
<button
type="button"
class="buttons"
data-type="secondary1"
data-size="large"
>
SUMMON ASSISTANT
</button>
</div>
</div>
<form class="setting-form">
<ul class="adjustments">
<li class="adjustments__row">
<p class="adjustments__row__subject">Assistant Role:</p>
<div class="adjustments__row__content">
<div class="input-set input-set--hide-label">
<select name="role">
<option value="-1" disabled>Select role</option>
<hr />
<option value="front-end-expert">front-end expert</option>
<option value="top-sales">top sales</option>
<option value="translator">translator</option>
<option value="writer">writer</option>
<option value="gamer">gamer</option>
<option value="none">none</option>
</select>
<label class="input-set__label">
<span class="input-set__label__span">systemPrompt</span>
</label>
</div>
</div>
</li>
<li class="adjustments__row">
<p class="adjustments__row__subject">temperature:</p>
<div class="adjustments__row__content">
<input type="range" min="1" max="10" name="temperature" value="8" step="1" />
</div>
</li>
<li class="adjustments__row">
<p class="adjustments__row__subject">position:</p>
<div class="adjustments__row__content">
<div class="input-set input-set--hide-label">
<select name="position">
<option value="-1" disabled>Select position</option>
<hr />
<option value="start-start">left-top corner</option>
<option value="start-end">right-top corner</option>
<option value="end-end" selected>right-bottom corner</option>
<option value="end-start">left-bottom corner</option>
</select>
<label class="input-set__label">
<span class="input-set__label__span">position</span>
</label>
</div>
</div>
</li>
<li class="adjustments__row adjustments__row--center">
<p class="adjustments__row__subject">inline-size:</p>
<div class="adjustments__row__content">
<div class="input-set input-set--hide-label">
<input name="inline-size" type="number" value="400" min="100" placeholder="inline-size" />
<label class="input-set__label">
<span class="input-set__label__span">inline-size</span>
</label>
</div>
px
</div>
</li>
<li class="adjustments__row adjustments__row--center">
<p class="adjustments__row__subject">block-size:</p>
<div class="adjustments__row__content">
<div class="input-set input-set--hide-label">
<input name="block-size" type="number" value="600" min="100" placeholder="inline-size" />
<label class="input-set__label">
<span class="input-set__label__span">block-size</span>
</label>
</div>
px
</div>
</li>
<li class="adjustments__row adjustments__row--center">
<p class="adjustments__row__subject">PiP:</p>
<div class="adjustments__row__content">
<div class="il-pair a11y-block-link">
<div class="radio-set">
<input id="pip-0" type="radio" name="pip" value="yes" />
<label class="radio-set__label" for="pip-0"></label>
</div>
<label for="pip-0">
YES
</label>
</div>
<div class="il-pair a11y-block-link">
<div class="radio-set">
<input id="pip-1" type="radio" name="pip" value="no" checked />
<label class="radio-set__label" for="pip-1"></label>
</div>
<label for="pip-1">
NO
</label>
</div>
</div>
</li>
</ul>
</form>
<msc-ai-assistant class="my-ai-assistant">
<script type="application/json">
{
"config": {
"systemPrompt": "You are a front-end engineer and very good at CSS, HTML and JavaScript.",
"temperature": 0.8,
"topK": 3
},
"l10n": {
"subject": "AI Assistant (front-end)",
"placeholder": "Ask Gemini"
}
}
</script>
</msc-ai-assistant>
</div>
<script type="module">
import { _wcl } from './mjs/common-lib.js';
const mappings = {
'front-end-expert': {
prompts: 'You are a front-end engineer and very good at CSS, HTML and JavaScript.',
subject: 'AI Assistant (front-end)'
},
'top-sales': {
prompts: 'You are a top sales and very good at product consulting. You are also good at rewriting product information and make them more vivid.',
subject: 'AI Assistant (top sales)'
},
'translator': {
prompts: 'You are a translator and very good at translate English to Traditional Chinese or Traditional Chinese to English.',
subject: 'AI Assistant (translator)'
},
'writer': {
prompts: 'You are a writer and very good at rewriting article and make them more vivid.',
subject: 'AI Assistant (writer)'
},
'gamer':{
prompts: 'You are a gamer and very good at playing PC games and video games. You also know to all games\' background and stories.',
subject: 'AI Assistant (gamer)'
},
'none': {
prompts: '',
subject: 'AI Assistant'
}
};
customElements.whenDefined('msc-ai-assistant').then(() => {
const assistant = document.querySelector('msc-ai-assistant');
const form = document.querySelector('.setting-form');
const button = document.querySelector('.button__wrap button');
// detect Built-in AI ready or not
if (assistant.available === 'no') {
button.textContent = 'No Built-in AI support';
form.remove();
return;
}
const getAxis = (inlineSize, blockSize, axis) => {
let axisX, axisY;
switch (axis) {
case 'start-start': {
axisX = '16px';
axisY = '16px';
break;
}
case 'start-end': {
axisX = `calc(100% - 16px - ${inlineSize})`;
axisY = '16px';
break;
}
case 'end-end': {
axisX = `calc(100% - 16px - ${inlineSize})`;
axisY = `calc(100% - 16px - ${blockSize})`;
break;
}
case 'end-start': {
axisX = '16px';
axisY = `calc(100% - 16px - ${blockSize})`;
break;
}
}
return { axisX, axisY };
};
const handler = (evt) => {
const { type, target, detail } = evt;
switch (type) {
case 'click': {
assistant.show();
break;
}
case 'input': {
const formData = new FormData(form);
const fd = Object.fromEntries(formData.entries());
const inlineSize = `${fd['inline-size']}px`;
const blockSize = `${fd['block-size']}px`;
const { axisX, axisY } = getAxis(inlineSize, blockSize, fd['position']);
assistant.config = {
systemPrompt: mappings[fd.role]?.prompts || '',
temperature: +fd.temperature / 10
};
assistant.l10n = {
subject: mappings[fd.role]?.subject || 'AI Assistant',
};
_wcl.addStylesheetRules(
'.my-ai-assistant',
{
'--msc-ai-assistant-inline-size': inlineSize,
'--msc-ai-assistant-block-size': blockSize,
'--msc-ai-assistant-inset-inline-start': axisX,
'--msc-ai-assistant-inset-block-start': axisY
}
);
assistant.pip = fd['pip'] === 'yes' ? true : false;
break;
}
}
};
// events
form.addEventListener('input', handler);
button.addEventListener('click', handler);
});
</script>
</body>
</html>