@luigisbox/luma 0.7.1 → 0.8.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,37 @@
1
+ import { html, nothing, repeat } from '../../lit';
2
+ import type { ConvoAction, ConvoPreviewScope } from '../../types';
3
+ import { avatar, icon } from './icons';
4
+
5
+ const NONE: ConvoAction[] = [];
6
+
7
+ // The search page's box (`convo.assist`): the assistant's answer to the query
8
+ // above the results, as it streams in: its first lines (fading out), three of
9
+ // its products, its suggestions; "Continue with the assistant" opens the
10
+ // panel with this conversation, a suggestion its next turn.
11
+ export default (s: ConvoPreviewScope) => {
12
+ const text = s.blocks.find((b) => b.type === 'text');
13
+ const list = s.blocks.find((b) => Array.isArray(b.products));
14
+ const rs = list ? s.products(list).slice(0, 3) : [];
15
+ const chips = s.done ? (s.blocks.find((b) => b.type === 'suggestions')?.actions ?? NONE).filter((a: ConvoAction) => a.action_ref).slice(0, 3) : NONE;
16
+ return html`
17
+ <section class="lbx-cv__pv" aria-labelledby="lbx-cv-pv-title" aria-busy=${s.done ? 'false' : 'true'}>
18
+ <header class="lbx-cv__pv-head">
19
+ ${avatar}
20
+ <div class="lbx-cv__titles">
21
+ <h2 id="lbx-cv-pv-title">${s.t('title')}</h2>
22
+ <p>${s.t('disclaimer')}</p>
23
+ </div>
24
+ </header>
25
+ <div class="lbx-cv__pv-text lbx-cv__text">${text ? s.md(text.text) : html`<p class="lbx-cv__wait">${s.t('thinking')}</p>`}</div>
26
+ ${rs.length
27
+ ? html`<ul class="lbx-cv__list lbx-cv__pv-products" data-lbx-list>
28
+ ${repeat(rs, (r) => r.id, (r, i) => html`<li>${s.include('convo-result-default', { r, i, actions: NONE })}</li>`)}
29
+ </ul>`
30
+ : nothing}
31
+ <div class="lbx-cv__pv-foot">
32
+ ${chips.length ? html`<div class="lbx-cv__chips">${chips.map((a: ConvoAction) => html`<button type="button" class="lbx-cv__chip" @click=${(e: Event) => s.open(a, e.currentTarget as Element)}>${a.label}</button>`)}</div>` : nothing}
33
+ <button type="button" class="lbx-cv__continue" @click=${(e: Event) => s.open(undefined, e.currentTarget as Element)}>${icon('M5 12h14M13 6l6 6-6 6')}${s.t('continue')}</button>
34
+ </div>
35
+ </section>
36
+ `;
37
+ };
@@ -0,0 +1,13 @@
1
+ import { html, nothing } from '../../lit';
2
+ import type { ConvoResultScope } from '../../types';
3
+
4
+ export default ({ r, i, img, plain, price, actions, act }: ConvoResultScope) => html`
5
+ <a class="lbx-cv__tile" href=${r.c.url}>
6
+ ${r.c.image ? img(r, i, { sizes: '64px' }) : html`<span class="lbx-img"></span>`}
7
+ <span class="lbx-cv__info">
8
+ <span class="lbx-cv__title">${plain(r.c.title)}</span>
9
+ ${r.c.price ? html`<span class="lbx-cv__price">${price(r.c.price) || plain(r.c.price)}</span>` : nothing}
10
+ </span>
11
+ </a>
12
+ ${actions.map((a) => (a.action_ref ? html`<button type="button" class="lbx-cv__more" aria-label=${`${a.label}: ${plain(r.c.title)}`} @click=${() => act(a)}>${a.label}</button>` : nothing))}
13
+ `;
@@ -0,0 +1,44 @@
1
+ // Luma's sparkle in the site's search field (`convo.trigger`): a button that
2
+ // opens the panel with the phrase typed (main.ts's click listener, which
3
+ // knows it by identity: `created`). In lbx-place with the reconciler that
4
+ // places it (build/vite.mjs), loaded at boot on the pages with it: it waits
5
+ // for the anchor's framework to hydrate, is put back when the host re-renders
6
+ // the field, and stays out of Turbo's snapshots (data-turbo-temporary).
7
+
8
+ import { addRule } from '../../core/reconciler';
9
+ import { created } from '../../core/own';
10
+ import { schedule } from '../../core/scheduler';
11
+ import { layered, setCss } from '../../core/styles';
12
+ import type { ConvoConfigType, GlobalConfigType } from '../../types';
13
+
14
+ export const place = (tr: NonNullable<ConvoConfigType['trigger']>, g: GlobalConfigType) => {
15
+ const b = document.createElement('button');
16
+ b.type = 'button';
17
+ b.className = 'lbx-cv-trigger';
18
+ b.setAttribute('data-lbx', 'convo-trigger');
19
+ b.setAttribute('data-lbx-convo', '');
20
+ // Its name too (its only content is an aria-hidden icon), in the site's language where Luma has it.
21
+ b.title = tr.label ?? ({ cs: 'Zeptat se nákupního asistenta', de: 'Den Einkaufsassistenten fragen' } as Record<string, string>)[(g.locale ?? 'en').split('-')[0]] ?? 'Ask the shopping assistant';
22
+ created.add(b);
23
+ // A sparkle (elements, not markup: Trusted Types).
24
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
25
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
26
+ svg.setAttribute('viewBox', '0 0 24 24');
27
+ svg.setAttribute('aria-hidden', 'true');
28
+ path.setAttribute('d', 'M10 3l1.6 4.4L16 9l-4.4 1.6L10 15l-1.6-4.4L4 9l4.4-1.6zM18 13l.9 2.1L21 16l-2.1.9L18 19l-.9-2.1L15 16l2.1-.9z');
29
+ path.setAttribute('fill', 'currentColor');
30
+ svg.append(path);
31
+ b.append(svg);
32
+ // In @layer lbx: the integration's style-host.css (applied by the entry at boot, before it is
33
+ // placed) lays it over the field; in flow by default, never over the site's own controls. Its
34
+ // focus ring !important (a site's reset of outlines loses to it).
35
+ setCss(
36
+ 'convo:trigger',
37
+ layered(
38
+ '.lbx-cv-trigger{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;width:32px;height:32px;padding:0;border:1px solid;border-radius:50%;background:none;color:inherit;cursor:pointer}.lbx-cv-trigger svg{width:18px;height:18px}' +
39
+ '.lbx-cv-trigger:focus-visible{outline:2px solid!important;outline-offset:2px!important}@media (forced-colors:active){.lbx-cv-trigger:focus-visible{outline:3px solid Highlight!important}}',
40
+ ),
41
+ );
42
+ addRule({ id: 'convo-trigger', active: () => true, anchors: [tr.anchor], position: tr.position ?? 'append', create: () => b });
43
+ schedule();
44
+ };