@thinkpixellab-public/px-vue 3.0.25 → 3.0.27

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.
@@ -109,9 +109,10 @@ You can define a template using space notation like this:
109
109
  :key="spaceIndex"
110
110
  >
111
111
  <div
112
- :class="bem('card')"
113
112
  v-for="(item, cardIndex) in space.cards"
114
113
  :key="cardIndex"
114
+ :class="bem('card')"
115
+ :ref="cardRefFromItem(item)"
115
116
  >
116
117
  <slot
117
118
  name="default"
@@ -382,6 +383,7 @@ export default {
382
383
 
383
384
  this.rowTemplates = rowTemplates;
384
385
  },
386
+
385
387
  resize() {
386
388
  let count = 1;
387
389
  let availableWidth = this.$el.offsetWidth;
@@ -401,6 +403,29 @@ export default {
401
403
  }
402
404
  this.columnCount = count;
403
405
  },
406
+
407
+ cardRefFromItem(item) {
408
+ if (!item) {
409
+ return null;
410
+ }
411
+
412
+ const key = this.getItemKey(item);
413
+
414
+ if (key && key.toString) {
415
+ const ref = `card-${key.toString()}`;
416
+ return ref;
417
+ }
418
+
419
+ return null;
420
+ },
421
+
422
+ cardElementFromItem(item) {
423
+ const ref = this.cardRefFromItem(item);
424
+ if (ref && this.$refs[ref] && this.$refs[ref].length) {
425
+ return this.$refs[ref][0];
426
+ }
427
+ return null;
428
+ },
404
429
  },
405
430
  };
406
431
  </script>
@@ -66,7 +66,7 @@
66
66
  import PxBaseVariants from './PxBaseVariants.vue';
67
67
  import PxPortal from './PxPortal.vue';
68
68
 
69
- import { computePosition, autoUpdate, flip, shift, offset } from '@floating-ui/dom';
69
+ import { computePosition, autoUpdate, flip, shift, offset, size } from '@floating-ui/dom';
70
70
  import { disableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock';
71
71
 
72
72
  const FOCUS_ELEMENTS = [
@@ -171,6 +171,10 @@ export default {
171
171
  // like flip but for the start/end direction
172
172
  shift: { default: true },
173
173
 
174
+ // uses the size middleware to keep the float on screen, resizing when necessary
175
+ sizeToView: { default: false },
176
+ sizeToViewPadding: { type: Number, default: 10 },
177
+
174
178
  // NOT IMPLEMENTED
175
179
  // hiddenClass: { type: String, default: null },
176
180
 
@@ -461,6 +465,18 @@ export default {
461
465
  middleware.push(flip(this.flip));
462
466
  }
463
467
 
468
+ let maxHeight = null;
469
+ if (this.sizeToView) {
470
+ let padding = this.sizeToViewPadding || 0;
471
+ middleware.push(
472
+ size({
473
+ apply({ availableHeight }) {
474
+ maxHeight = availableHeight - padding;
475
+ },
476
+ })
477
+ );
478
+ }
479
+
464
480
  if (this.placement && this.$refs.popup && reference) {
465
481
  computePosition(reference, this.$refs.popup, {
466
482
  placement: this.placement,
@@ -470,11 +486,13 @@ export default {
470
486
  if (this.useTranslate) {
471
487
  this.positionCss = {
472
488
  transform: `translate(${this.cssPx(x)},${this.cssPx(y)})`,
489
+ maxHeight: this.cssPx(maxHeight),
473
490
  };
474
491
  } else {
475
492
  this.positionCss = {
476
493
  left: this.cssPx(x),
477
494
  top: this.cssPx(y),
495
+ maxHeight: this.cssPx(maxHeight),
478
496
  };
479
497
  }
480
498
  });
@@ -503,6 +521,8 @@ export default {
503
521
  }
504
522
  }
505
523
 
524
+ console.log(`reference: ${reference}`);
525
+
506
526
  return reference;
507
527
  },
508
528
 
@@ -55,8 +55,6 @@ export default {
55
55
  },
56
56
 
57
57
  borderStyle() {
58
- //console.log(`this.slice: 👉 ${JSON.stringify(this.slice, null, 4)}`);
59
-
60
58
  let borderImageSlice = this.sliceArray
61
59
  .map((v, idx) => {
62
60
  return (v / (idx % 2 ? this.srcWidth : this.srcHeight)) * 100 + '%';
@@ -0,0 +1,130 @@
1
+ <!--
2
+ Shows a simple CSS based spinner. Future implementations can pull from here:
3
+ https://cssloaders.github.io/
4
+
5
+ Supported variants:
6
+
7
+ * classic - rotating semi-circle
8
+ * dots - three dots that fade in and out in turn
9
+
10
+ Size is derived from the current font size and color is derived from currentColor. These
11
+ properties (as well as a transform) can be set on the component itself without side effects.
12
+
13
+ Future enhancements could include additional properties for controlling things like timing,
14
+ additional colors, stroke thickness, etc.
15
+ -->
16
+
17
+ <template>
18
+ <span :class="bem(variantsMap)" v-if="visible">
19
+ <span :class="bem('spinner')"></span>
20
+ </span>
21
+ </template>
22
+
23
+ <script>
24
+ import PxBaseVariants from './PxBaseVariants.vue';
25
+ import PxBaseVisible from './PxBaseVisible.vue';
26
+
27
+ export default {
28
+ name: 'px-spinner',
29
+ mixins: [PxBaseVariants, PxBaseVisible],
30
+ props: { variant: { type: String, default: 'classic' } },
31
+ };
32
+ </script>
33
+
34
+ <style lang="scss">
35
+ @use '../styles/px.scss' as *;
36
+
37
+ .px-spinner {
38
+ display: inline-block;
39
+ position: relative;
40
+ pointer-events: none;
41
+
42
+ &__spinner {
43
+ display: block;
44
+ position: relative;
45
+ }
46
+
47
+ // classic
48
+
49
+ &--classic & {
50
+ &__spinner {
51
+ width: 1.33em;
52
+ height: 1.33em;
53
+ border: 0.15em solid currentColor;
54
+ border-bottom-color: transparent;
55
+ border-radius: 50%;
56
+ display: inline-block;
57
+ box-sizing: border-box;
58
+ animation: px-spinner-classic 1s linear infinite;
59
+ }
60
+ }
61
+
62
+ @keyframes px-spinner-classic {
63
+ 0% {
64
+ transform: rotate(0deg);
65
+ }
66
+ 100% {
67
+ transform: rotate(360deg);
68
+ }
69
+ }
70
+
71
+ // dots
72
+
73
+ &--dots {
74
+ width: 12.5em * 0.2;
75
+ height: 2.5em * 0.2;
76
+ }
77
+
78
+ &--dots & {
79
+ $dur: 1.8s;
80
+
81
+ &__spinner {
82
+ font-size: 0.2em;
83
+ }
84
+
85
+ &__spinner,
86
+ &__spinner:before,
87
+ &__spinner:after {
88
+ position: absolute;
89
+ top: -2.5em;
90
+ width: 2.5em;
91
+ height: 2.5em;
92
+ border-radius: 50%;
93
+ animation-fill-mode: both;
94
+ animation: px-spinner-dots $dur infinite $ease-in-out-quart;
95
+ }
96
+ &__spinner {
97
+ left: 5em;
98
+ color: currentColor;
99
+ position: relative;
100
+ text-indent: -9999em;
101
+ transform: translateZ(0);
102
+ animation-delay: ($dur * -0.088888888);
103
+ }
104
+ &__spinner:before,
105
+ &__spinner:after {
106
+ content: '';
107
+ position: absolute;
108
+ top: 0;
109
+ }
110
+ &__spinner:before {
111
+ left: -5em;
112
+ animation-delay: ($dur * -0.088888888 * 2);
113
+ }
114
+ &__spinner:after {
115
+ left: 5em;
116
+ }
117
+
118
+ @keyframes px-spinner-dots {
119
+ 0%,
120
+ 80%,
121
+ 100% {
122
+ box-shadow: 0 2.5em 0 -1.3em;
123
+ }
124
+ 40% {
125
+ box-shadow: 0 2.5em 0 0;
126
+ }
127
+ }
128
+ }
129
+ }
130
+ </style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thinkpixellab-public/px-vue",
3
- "version": "3.0.25",
3
+ "version": "3.0.27",
4
4
  "description": "General purpose Vue components and helpers that can be used across projects.",
5
5
  "author": "Pixel Lab",
6
6
  "license": "MIT",
@@ -1,8 +1,15 @@
1
1
  export default val => {
2
2
  if (!process.server) {
3
- var div = document.createElement('div');
3
+ val = val.replace(/<\/p>/g, '</p> ');
4
+ val = val.replace(/<\/li>/g, '</li> ');
5
+ val = val.replace(/<\/div>/g, '</div> ');
6
+
7
+ let div = document.createElement('div');
4
8
  div.innerHTML = val;
5
- var text = div.textContent || div.innerText || '';
9
+
10
+ let text = div.innerText || '';
11
+ text = text.replace(/(\n)+/g, ' ');
12
+
6
13
  return text;
7
14
  } else {
8
15
  return '';
package/utils/cardGrid.js CHANGED
@@ -94,7 +94,6 @@
94
94
  // return result;
95
95
  // });
96
96
 
97
- // console.log(`rows: 👉 ${JSON.stringify(rows, null, 4)}`);
98
97
  // };
99
98
 
100
99
  // export default cardGrid;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Uses canvas.measureText to compute the width of a string in px.
3
+ *
4
+ * @param str The text to be measured.
5
+ * @param fontOrElement The css font descriptor (e.g bold 15px arial) or an element from which to extract the font.
6
+ */
7
+ const textWidth = (str, fontOrElement, roundUp = true) => {
8
+ // get font metrics from an element
9
+ let font = fontOrElement;
10
+ if (typeof font !== 'string') {
11
+ const element = fontOrElement || document.body;
12
+ font = getFontFromElement(element);
13
+ }
14
+
15
+ // re-use canvas object for better performance
16
+ const canvas = textWidth.canvas || (textWidth.canvas = document.createElement('canvas'));
17
+ const context = canvas.getContext('2d');
18
+
19
+ context.font = font;
20
+ const metrics = context.measureText(str);
21
+ return roundUp ? Math.ceil(metrics.width) : metrics.width;
22
+ };
23
+
24
+ const getCssProp = (element, prop) => {
25
+ return window.getComputedStyle(element, null).getPropertyValue(prop);
26
+ };
27
+
28
+ const getFontFromElement = element => {
29
+ const fontWeight = getCssProp(element, 'font-weight') || 'normal';
30
+ const fontSize = getCssProp(element, 'font-size') || '16px';
31
+ const fontFamily = getCssProp(element, 'font-family') || 'sans-serif';
32
+
33
+ return `${fontWeight} ${fontSize} ${fontFamily}`;
34
+ };
35
+
36
+ export default textWidth;