You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.6 KiB
92 lines
2.6 KiB
import type { Morfo } from '../types';
|
|
import { v } from '../types';
|
|
|
|
/**
|
|
* QrCode — themeable QR code rendered from the own zero-dependency encoder
|
|
* (`$libs/qr`). Eidos-native display primitive (like Avatar / Image): a
|
|
* `value` → module matrix → SVG. No soma — there is no interactive state, just
|
|
* a derived render. The optional DownloadTrigger is the only action.
|
|
*
|
|
* `scope: ['eidos']`. The Frame is the root `<svg role="img">`; the Pattern is
|
|
* the module `<path>` (decorative — the Frame's `aria-label` carries the
|
|
* meaning); the Overlay is a centred logo slot; the DownloadTrigger exports the
|
|
* code as PNG / SVG.
|
|
*
|
|
* 0-event surface (like Badge): the only act is downloading, expressed by the
|
|
* consumer's handler on the DownloadTrigger.
|
|
*/
|
|
export const qrCodeMorfo = {
|
|
name: 'QrCode',
|
|
kebab: 'qr-code',
|
|
scope: ['eidos'],
|
|
apg: 'https://www.w3.org/WAI/ARIA/apg/#img',
|
|
texts: {
|
|
download: '#?components.qr-code.download|Download QR code'
|
|
},
|
|
parts: [
|
|
{
|
|
// Frame — the root `<svg>`. `role="img"` + `aria-label` make the QR a
|
|
// single labelled graphic; the module pattern inside is decorative.
|
|
name: 'Provider',
|
|
kebab: 'provider',
|
|
archetype: 'provider',
|
|
kind: 'public',
|
|
defaultElement: 'svg',
|
|
role: 'img',
|
|
optional: false,
|
|
data: [
|
|
{ attr: 'data-cell-shape', values: ['square', 'rounded', 'dots'] }
|
|
],
|
|
aria: [
|
|
{
|
|
attr: 'aria-label',
|
|
value: v.propRef('alt'),
|
|
severity: 'recommended'
|
|
}
|
|
]
|
|
},
|
|
{
|
|
// The module matrix as one `<path>`. Decorative — aria-hidden.
|
|
name: 'Pattern',
|
|
kebab: 'pattern',
|
|
archetype: 'indicator',
|
|
kind: 'public',
|
|
defaultElement: 'path',
|
|
optional: false,
|
|
data: [],
|
|
aria: [{ attr: 'aria-hidden', value: v.literal('true') }]
|
|
},
|
|
{
|
|
// Centred logo / media slot. Decorative — the cells behind it are
|
|
// cleared (quiet zone) and ECC is auto-boosted so it stays scannable.
|
|
name: 'Overlay',
|
|
kebab: 'overlay',
|
|
archetype: 'indicator',
|
|
kind: 'public',
|
|
defaultElement: 'div',
|
|
optional: true,
|
|
data: [],
|
|
aria: [{ attr: 'aria-hidden', value: v.literal('true') }]
|
|
},
|
|
{
|
|
// Export affordance — `<button>` that downloads the code (PNG / SVG).
|
|
name: 'DownloadTrigger',
|
|
kebab: 'download-trigger',
|
|
archetype: 'trigger',
|
|
kind: 'public',
|
|
defaultElement: 'button',
|
|
role: 'button',
|
|
optional: true,
|
|
data: [],
|
|
aria: [
|
|
{ attr: 'type', value: v.literal('button') },
|
|
{
|
|
attr: 'aria-label',
|
|
value: v.translationRef('#?components.qr-code.download|Download QR code'),
|
|
severity: 'recommended'
|
|
}
|
|
]
|
|
}
|
|
]
|
|
} as const satisfies Morfo;
|