2021-05-27 21:00:43 +00:00
import { customElement , property , query } from 'lit/decorators.js' ;
2023-01-13 20:43:55 +00:00
import { html } from 'lit' ;
2021-09-29 12:40:26 +00:00
import { styleMap } from 'lit/directives/style-map.js' ;
2023-01-13 20:43:55 +00:00
import { watch } from '../../internal/watch' ;
2021-04-22 19:42:23 +00:00
import QrCreator from 'qr-creator' ;
2022-08-17 15:37:37 +00:00
import ShoelaceElement from '../../internal/shoelace-element' ;
2021-07-10 00:45:44 +00:00
import styles from './qr-code.styles' ;
2022-07-19 12:27:39 +00:00
import type { CSSResultGroup } from 'lit' ;
2021-04-22 19:42:23 +00:00
/ * *
2023-01-12 15:26:25 +00:00
* @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 : //shoelace.style/components/qr-code
2021-11-24 13:32:11 +00:00
* @status stable
2023-01-12 15:26:25 +00:00
* @since 2.0
2021-04-22 19:42:23 +00:00
*
2022-12-06 16:18:14 +00:00
* @csspart base - The component ' s base wrapper .
2021-04-22 19:42:23 +00:00
* /
@customElement ( 'sl-qr-code' )
2022-08-17 15:37:37 +00:00
export default class SlQrCode extends ShoelaceElement {
2022-07-19 12:27:39 +00:00
static styles : CSSResultGroup = styles ;
2021-04-22 19:42:23 +00:00
@query ( 'canvas' ) canvas : HTMLElement ;
/** The QR code's value. */
2021-07-01 00:04:46 +00:00
@property ( ) value = '' ;
2021-04-22 19:42:23 +00:00
2022-12-06 16:18:14 +00:00
/** The label for assistive devices to announce. If unspecified, the value will be used instead. */
2021-07-01 00:04:46 +00:00
@property ( ) label = '' ;
2021-04-22 19:42:23 +00:00
2022-12-06 16:18:14 +00:00
/** The size of the QR code, in pixels. */
2021-07-01 00:04:46 +00:00
@property ( { type : Number } ) size = 128 ;
2021-04-22 19:42:23 +00:00
/** The fill color. This can be any valid CSS color, but not a CSS custom property. */
2022-12-06 16:18:14 +00:00
@property ( ) fill = 'black' ;
2021-04-22 19:42:23 +00:00
2022-12-06 16:18:14 +00:00
/** The background color. This can be any valid CSS color or `transparent`. It cannot be a CSS custom property. */
@property ( ) background = 'white' ;
2021-04-22 19:42:23 +00:00
/** The edge radius of each module. Must be between 0 and 0.5. */
2021-07-01 00:04:46 +00:00
@property ( { type : Number } ) radius = 0 ;
2021-04-22 19:42:23 +00:00
2022-12-06 16:18:14 +00:00
/** The level of error correction to use. [Learn more](https://www.qrcode.com/en/about/error_correction.html) */
2021-04-22 19:42:23 +00:00
@property ( { attribute : 'error-correction' } ) errorCorrection : 'L' | 'M' | 'Q' | 'H' = 'H' ;
firstUpdated() {
this . generate ( ) ;
}
2023-01-09 21:07:59 +00:00
@watch ( [ 'background' , 'errorCorrection' , 'fill' , 'radius' , 'size' , 'value' ] )
2021-04-22 19:42:23 +00:00
generate() {
2021-06-15 13:26:35 +00:00
if ( ! this . hasUpdated ) {
return ;
}
2021-04-22 19:42:23 +00:00
QrCreator . render (
{
text : this.value ,
radius : this.radius ,
ecLevel : this.errorCorrection ,
fill : this.fill ,
2022-12-06 16:18:14 +00:00
background : null ,
2021-04-22 19:42:23 +00:00
// We draw the canvas larger and scale its container down to avoid blurring on high-density displays
size : this.size * 2
} ,
this . canvas
) ;
}
render() {
return html `
2022-12-06 16:18:14 +00:00
< canvas
2021-04-22 19:42:23 +00:00
part = "base"
2022-12-06 16:18:14 +00:00
class = "qr-code"
role = "img"
aria - label = $ { this . label . length > 0 ? this . label : this.value }
2021-04-22 19:42:23 +00:00
style = $ { styleMap ( {
width : ` ${ this . size } px ` ,
height : ` ${ this . size } px `
} ) }
2022-12-06 16:18:14 +00:00
> < / canvas >
2021-04-22 19:42:23 +00:00
` ;
}
}
declare global {
interface HTMLElementTagNameMap {
'sl-qr-code' : SlQrCode ;
}
}