Files
webawesome/src/components/qr-code/qr-code.ts
Konnor Rogers 14914abf65 Initial SSR implementation (#157)
* continued ssr work

* continued ssr work

* prettier

* all components now rendering

* everything finally works

* fix type issues

* working on breadcrumb

* working on breadcrumb

* radio group

* convert all tests to ssr

* prettier

* test suite finally passing

* add layout stuff

* add changelog

* fix TS issue

* fix tests

* fixing deploy stuff

* get QR code displaying

* fix tests

* fix tests

* prettier

* condense hydration stuff

* prettier

* comment out range test

* fixing issues

* use base fixtures

* fixing examples

* dont vendor

* fix import of hydration support

* adding notes

* add notesg

* add ssr loader

* fix build

* prettier

* add notes

* add notes

* prettier

* fixing bundled stuff

* remove cdn

* remove cdn

* prettier

* fiixng tests

* prettier

* split jobs??

* prettier

* fix build stuff

* add reset mouse and await aTimeout

* prettier

* fix improper tests

* prettier

* bail on first

* fix linting

* only test form with client

* redundancy on ssr-loader??

* maybe this will work

* prettier

* try callout now

* fix form.test.ts

* fix form.test.ts

* prettier

* fix forms

* fix forms

* try again

* prettier

* add some awaits

* prettier

* comment out broken SSR tests

* prettier

* comment out broken SSR tests

* prettier

* dont skip in CI

* upgrade playwright to beta

* prettier

* try some trickery

* try some trickery

* await updateComplete

* try to fix form.test.ts

* import hydrateable elements 1 time

* prettier

* fix input defaultValue issues

* fix form controls to behave like their native counterpartS

* add changelog entry

* prettier

* fix unexpected behavior with range / button
2024-09-11 10:25:42 -04:00

111 lines
3.3 KiB
TypeScript

import { customElement, property, query, state } from 'lit/decorators.js';
import { html } from 'lit';
import { watch } from '../../internal/watch.js';
import componentStyles from '../../styles/component.styles.js';
import styles from './qr-code.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup, PropertyValues } from 'lit';
import type _QrCreator from 'qr-creator';
let QrCreator: _QrCreator.default;
/**
* @summary Generates a [QR code](https://www.qrcode.com/) and renders it using the [Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API).
* @documentation https://backers.webawesome.com/docs/components/qr-code
* @status stable
* @since 2.0
*
* @csspart base - The component's base wrapper.
*/
@customElement('wa-qr-code')
export default class WaQrCode extends WebAwesomeElement {
static styles: CSSResultGroup = [componentStyles, styles];
@query('canvas') canvas: HTMLElement;
/** The QR code's value. */
@property() value = '';
/** The label for assistive devices to announce. If unspecified, the value will be used instead. */
@property() label = '';
/** The size of the QR code, in pixels. */
@property({ type: Number }) size = 128;
/** The fill color. This can be any valid CSS color, but not a CSS custom property. */
@property() fill = 'black';
/** The background color. This can be any valid CSS color or `transparent`. It cannot be a CSS custom property. */
@property() background = 'white';
/** The edge radius of each module. Must be between 0 and 0.5. */
@property({ type: Number }) radius = 0;
/** The level of error correction to use. [Learn more](https://www.qrcode.com/en/about/error_correction.html) */
@property({ attribute: 'error-correction' }) errorCorrection: 'L' | 'M' | 'Q' | 'H' = 'H';
/**
* Whether or not the qr-code generated.
*/
// @ts-expect-error Don't know why it marks it as unused.
@state() private generated = false;
firstUpdated(changedProperties: PropertyValues<this>) {
super.firstUpdated(changedProperties);
if (this.hasUpdated) {
this.generate();
}
}
@watch(['background', 'errorCorrection', 'fill', 'radius', 'size', 'value'])
generate() {
this.style.setProperty('--size', `${this.size}px`);
if (!this.hasUpdated) {
return;
}
// We lazy load because the QR generator will cause the server to crash, but we want to reduce layout shift.
if (!QrCreator) {
import('qr-creator').then(mod => {
QrCreator = mod.default;
this.generate();
});
return;
}
(QrCreator as unknown as typeof _QrCreator.default).render(
{
text: this.value,
radius: this.radius,
ecLevel: this.errorCorrection,
fill: this.fill,
background: this.background,
// We draw the canvas larger and scale its container down to avoid blurring on high-density displays
size: this.size * 2
},
this.canvas
);
this.generated = true;
}
render() {
return html`
<canvas
part="base"
class="qr-code"
role="img"
aria-label=${this.label?.length > 0 ? this.label : this.value}
></canvas>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'wa-qr-code': WaQrCode;
}
}