@thinkpixellab-public/px-vue 4.1.28 → 4.1.30

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.
@@ -139,7 +139,9 @@ export default {
139
139
  min-height: 0,
140
140
  )
141
141
  );
142
- outline: 1px dashed currentColor;
142
+ @include focus() {
143
+ outline: 1px dashed currentColor;
144
+ }
143
145
  }
144
146
 
145
147
  &--toggles.px-icon-button--unchecked {
@@ -10,7 +10,7 @@
10
10
  <div
11
11
  class="px-qr-code"
12
12
  ref="qrCode"
13
- :style="{ width: size + 'px', height: size + 'px' }"
13
+ :style="{ width: size + 'px', height: size + 'px', opacity: isRendered ? 1 : 0 }"
14
14
  role="img"
15
15
  :aria-label="label || content"
16
16
  ></div>
@@ -20,8 +20,6 @@
20
20
  <script>
21
21
  import QRCodeStyling from 'qr-code-styling';
22
22
 
23
- // test
24
-
25
23
  export default {
26
24
  name: 'px-qr-code',
27
25
  props: {
@@ -32,11 +30,54 @@ export default {
32
30
  qrCodeConfig: { type: Object, default: null },
33
31
  },
34
32
  data() {
35
- return { size: 0 };
33
+ return { size: 0, isRendered: false, percentageMargin: 0 };
34
+ },
35
+ methods: {
36
+ setScale(retryCount = 0) {
37
+ if (!this.percentageMargin) {
38
+ this.isRendered = true;
39
+ return;
40
+ }
41
+
42
+ const MAX_RETRIES = 10;
43
+
44
+ const svg = this.$refs.qrCode?.querySelector('svg');
45
+ const rectEls = svg?.querySelectorAll(':scope > rect');
46
+ const imageEls = svg?.querySelectorAll(':scope > image');
47
+
48
+ const marginPx = (this.percentageMargin / 100) * svg.clientWidth;
49
+ const scale = (svg.clientWidth - marginPx * 2) / svg.clientWidth;
50
+
51
+ // the second rect is the qrcode
52
+ const qrRect = rectEls?.[1];
53
+ const qrImage = imageEls?.[0];
54
+
55
+ if (!qrRect || !qrImage) {
56
+ if (retryCount < MAX_RETRIES) {
57
+ setTimeout(() => {
58
+ this.setScale(retryCount + 1);
59
+ }, 25);
60
+ } else {
61
+ // Optionally, log a warning or handle the error
62
+ // console.warn('QR rect or image not found after maximum retries.');
63
+ }
64
+ return;
65
+ }
66
+
67
+ this.isRendered = true;
68
+
69
+ qrRect.style.transform = `scale(${scale})`;
70
+ qrImage.style.transform = `scale(${scale})`;
71
+ },
36
72
  },
37
73
  mounted() {
38
74
  this.size = Math.min(this.$el.clientWidth, this.$el.clientHeight);
39
75
 
76
+ const { margin, ...rest } = this.qrCodeConfig || {};
77
+
78
+ // margin is a percentage of the svg width
79
+ this.percentageMargin = margin ? Math.min(Math.max(0, margin), 100) : 0;
80
+
40
81
  const options = {
41
82
  width: this.size,
42
83
  height: this.size,
@@ -48,10 +89,14 @@ export default {
48
89
  crossOrigin: 'anonymous',
49
90
  },
50
91
  data: this.content,
51
- ...this.qrCodeConfig,
92
+ ...rest,
52
93
  type: 'svg',
53
94
  };
54
95
 
96
+ if (!this.percentageMargin) {
97
+ this.isRendered = true;
98
+ }
99
+
55
100
  this.qrCode = new QRCodeStyling(options);
56
101
 
57
102
  this.onSizeChange = () => {
@@ -78,6 +123,10 @@ export default {
78
123
  options.height = qrSize;
79
124
 
80
125
  this.qrCode.update(options);
126
+
127
+ this.$nextTick(() => {
128
+ this.setScale();
129
+ });
81
130
  };
82
131
 
83
132
  this.resizeObserver = new ResizeObserver(this.onSizeChange);
@@ -87,6 +136,15 @@ export default {
87
136
  this.qrCode.append(this.$refs.qrCode);
88
137
 
89
138
  this.onSizeChange();
139
+
140
+ if (this.percentageMargin) {
141
+ this.qrCode.getRawData('svg').then(() => {
142
+ // QR code has been rendered
143
+ this.$nextTick(() => {
144
+ this.setScale();
145
+ });
146
+ });
147
+ }
90
148
  });
91
149
  },
92
150
  beforeUnmount() {
@@ -100,6 +158,11 @@ export default {
100
158
  svg {
101
159
  width: 100%;
102
160
  height: 100%;
161
+
162
+ rect,
163
+ image {
164
+ transform-origin: center;
165
+ }
103
166
  }
104
167
  }
105
168
  </style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thinkpixellab-public/px-vue",
3
- "version": "4.1.28",
3
+ "version": "4.1.30",
4
4
  "description": "General purpose Vue components and helpers that can be used across projects.",
5
5
  "author": {
6
6
  "name": "Pixel Lab"