@thinkpixellab-public/px-vue 3.0.42 → 4.0.0

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.
Files changed (115) hide show
  1. package/README.md +22 -64
  2. package/{components → bases}/PxBase.vue +4 -0
  3. package/bases/PxBaseDate.vue +49 -0
  4. package/bases/PxBaseIcon.vue +32 -0
  5. package/bases/PxBaseItems.vue +105 -0
  6. package/bases/PxBaseItemsSelect.vue +415 -0
  7. package/{components → bases}/PxBaseMobileAware.vue +4 -2
  8. package/{components → bases}/PxBaseResize.vue +11 -4
  9. package/bases/PxBaseScroll.vue +46 -0
  10. package/bases/PxBaseToggle.vue +67 -0
  11. package/bases/PxBaseUniqueId.vue +18 -0
  12. package/{components → bases}/PxBaseVariants.vue +10 -0
  13. package/{components → bases}/PxBaseVariantsOverride.vue +4 -2
  14. package/{components → bases}/PxBaseVisible.vue +2 -0
  15. package/components/PxArrowScroller.vue +9 -7
  16. package/components/PxAspect.vue +28 -10
  17. package/components/PxAutoClamp.vue +3 -1
  18. package/components/PxBalancedText.vue +22 -9
  19. package/components/PxButton.vue +42 -0
  20. package/components/PxCalendar.vue +3 -2
  21. package/components/PxCard.vue +2 -3
  22. package/components/PxCardGrid.vue +3 -1
  23. package/components/PxClock.vue +5 -2
  24. package/components/PxContain.vue +3 -1
  25. package/components/PxCopyText.vue +6 -2
  26. package/components/PxDatePicker.vue +6 -4
  27. package/components/PxDropdown.vue +77 -61
  28. package/components/PxExpander.vue +36 -20
  29. package/components/PxFit.vue +4 -1
  30. package/components/PxFlex.vue +27 -17
  31. package/components/PxFloat.vue +151 -77
  32. package/components/PxIcon.vue +88 -15
  33. package/components/PxIconButton.vue +43 -29
  34. package/components/PxIdUniquer.vue +5 -1
  35. package/components/PxModal.vue +1 -0
  36. package/components/PxNineGrid.vue +4 -0
  37. package/components/PxPivot.vue +20 -8
  38. package/components/PxPopup.vue +8 -6
  39. package/components/PxProgressCircle.vue +3 -3
  40. package/components/PxQrCode.vue +6 -2
  41. package/components/PxRadioButton.vue +30 -10
  42. package/components/PxResizer.vue +207 -0
  43. package/components/PxSideDrawer.vue +16 -10
  44. package/components/PxSlideTransition.vue +3 -1
  45. package/components/PxSlides.vue +4 -3
  46. package/components/PxSpinner.vue +4 -2
  47. package/components/PxSvg.vue +97 -45
  48. package/components/PxSwiperSlide.vue +3 -7
  49. package/components/PxSyncHeight.vue +3 -0
  50. package/components/PxTable.vue +8 -2
  51. package/components/PxToggle.vue +9 -7
  52. package/components/PxToggleButton.vue +94 -60
  53. package/components/PxToggleButtonList.vue +61 -38
  54. package/components/PxTransitionExpand.vue +8 -1
  55. package/components/PxValidator.vue +5 -2
  56. package/package.json +37 -29
  57. package/plugins/common-client.js +19 -8
  58. package/plugins/common.js +35 -53
  59. package/plugins/filters/kebab.js +1 -1
  60. package/plugins/filters/unkebab.js +11 -0
  61. package/stories/PxAspect.stories.js +62 -0
  62. package/stories/PxBalancedText.stories.js +57 -0
  63. package/stories/PxButton.stories.js +44 -0
  64. package/stories/PxDropdown.stories.js +49 -0
  65. package/stories/PxExpander.stories.js +31 -0
  66. package/stories/PxFloat.stories.js +69 -0
  67. package/stories/PxIcon.mdx +62 -0
  68. package/stories/PxIcon.stories.js +70 -0
  69. package/stories/PxPivot.stories.js +38 -0
  70. package/stories/PxRadioButton.stories.js +33 -0
  71. package/stories/PxSvg.stories.js +37 -0
  72. package/stories/PxToggleButton.stories.js +86 -0
  73. package/stories/PxToggleButtonList.stories.js +97 -0
  74. package/stories/assets/alpha.svg +6 -0
  75. package/stories/helpers/extractArgTypes.js +31 -0
  76. package/stories/helpers/sampleData.js +28 -0
  77. package/stories/helpers/scratch.vue +30 -0
  78. package/styles/px.scss +1 -1
  79. package/test/PxBaseItems.test.js +92 -0
  80. package/test/PxBaseItemsSelect.test.js +430 -0
  81. package/utils/getFeatherIcons.js +25 -0
  82. package/utils/hasSlot.js +9 -0
  83. package/utils/uniqueId.js +30 -0
  84. package/vite.config.js +34 -0
  85. package/assets/icons/calendar.svg +0 -6
  86. package/assets/icons/check.svg +0 -1
  87. package/assets/icons/close-sm.svg +0 -1
  88. package/assets/icons/close.svg +0 -1
  89. package/assets/icons/copy.svg +0 -1
  90. package/assets/icons/dropdown.svg +0 -1
  91. package/assets/icons/invalid.svg +0 -1
  92. package/assets/icons/menu.svg +0 -1
  93. package/assets/icons/nav-next.svg +0 -1
  94. package/assets/icons/nav-prev.svg +0 -1
  95. package/assets/icons/sort-asc.svg +0 -1
  96. package/assets/icons/sort-desc.svg +0 -1
  97. package/assets/test/README.md +0 -1
  98. package/assets/test/trash.svg +0 -8
  99. package/components/PxBaseDate.vue +0 -27
  100. package/components/PxBaseItems.vue +0 -72
  101. package/components/PxBaseItemsSelect.vue +0 -230
  102. package/components/PxBaseToggle.vue +0 -56
  103. package/components/PxFeatherIcon.vue +0 -29
  104. package/components/PxFeatherIconButton.vue +0 -19
  105. package/components/PxPortal.vue +0 -138
  106. package/components/PxPortalTarget.vue +0 -27
  107. package/components/PxStylesPreview.vue +0 -159
  108. package/components/PxSwiper.vue +0 -271
  109. package/components/PxTabs.vue +0 -1
  110. package/components/PxTextbox.vue +0 -90
  111. package/components/README.md +0 -0
  112. package/plugins/common-lib.js +0 -4
  113. package/plugins/common-vue3.js +0 -60
  114. package/plugins/mixins/eventBus.js +0 -30
  115. package/styles/helpers.scss +0 -14
@@ -0,0 +1,415 @@
1
+ <!--
2
+ #VUE3 Done (has breaking changes)
3
+ -->
4
+
5
+ <script>
6
+ import PxBaseItems from './PxBaseItems.vue';
7
+ import utils from '../utils/utils.js';
8
+
9
+ // helper to define what an "empty" key or set of keys looks like
10
+ const isKeySetEmpty = keyOrKeys => {
11
+ return (
12
+ keyOrKeys == null ||
13
+ keyOrKeys == undefined ||
14
+ (Array.isArray(keyOrKeys) && keyOrKeys.length == 0)
15
+ );
16
+ };
17
+
18
+ // helper to ensure that a potential key or set of keys is an array
19
+ const ensureSet = valueOrArray => {
20
+ if (isKeySetEmpty(valueOrArray)) {
21
+ return [];
22
+ }
23
+
24
+ return Array.isArray(valueOrArray) ? valueOrArray : [valueOrArray];
25
+ };
26
+
27
+ export default {
28
+ mixins: [PxBaseItems],
29
+
30
+ props: {
31
+ /**
32
+ * Set the selection as either a single item key or an array of item keys.
33
+ */
34
+ selected: { default: null },
35
+
36
+ /**
37
+ * If true, the first item in a collection will be automatically selected on load or when
38
+ * items is updated and no other item is selected
39
+ */
40
+ autoSelectFirst: { type: Boolean, default: false },
41
+ },
42
+
43
+ data() {
44
+ return {
45
+ selectedKeys: [],
46
+ baseUpdateMode: 'single',
47
+ };
48
+ },
49
+
50
+ computed: {
51
+ /**
52
+ * Indicates whether the update event arg is a single key or an array of keys. Note that
53
+ * selection is always stored internally (selectedKeys) as an array of keys.
54
+ *
55
+ * Derived classes should override this to indicate the current update mode and can expose
56
+ * an additional prop to control it. We're returning the value of a data value so that it
57
+ * can be set when testing but there's no internal process that would ever change this
58
+ * value.
59
+ *
60
+ * In `single` mode the event is the first selected item or null when empty. The intended
61
+ * use is components that don't support multiselection.
62
+ *
63
+ * In `multi` mode the event is always an array with all selected items.
64
+ *
65
+ * @values single, multi
66
+ */
67
+ updateMode() {
68
+ return this.baseUpdateMode;
69
+ },
70
+
71
+ /**
72
+ * Returns an array that contains the keys for all fo the items in items.
73
+ */
74
+ itemKeys() {
75
+ return this.items.map(item => this.getItemKey(item));
76
+ },
77
+
78
+ /**
79
+ * Returns the first selected key
80
+ */
81
+ selectedKey() {
82
+ return this.selectedKeys?.length ? this.selectKeys[0] : null;
83
+ },
84
+
85
+ /**
86
+ * Returns the currently selected items.
87
+ */
88
+ selectedItems() {
89
+ return (this.selectedKeys || []).map(key => {
90
+ return this.getItem(key);
91
+ });
92
+ },
93
+
94
+ /**
95
+ * Returns the first selected item or null if selection is empty.
96
+ */
97
+ selectedItem() {
98
+ return this.selectedItems.length ? this.selectedItems[0] : null;
99
+ },
100
+
101
+ /**
102
+ * Returns the indices of the currently selected items.
103
+ */
104
+ selectedIndices() {
105
+ return (this.selectedKeys || []).map(key => {
106
+ return this.getItemKeyIndex(key);
107
+ });
108
+ },
109
+
110
+ /**
111
+ * Returns the index of the first selected item or null if selection is empty.
112
+ */
113
+ selectedIndex() {
114
+ return this.selectedIndices.length ? this.selectedIndices[0] : null;
115
+ },
116
+ },
117
+
118
+ watch: {
119
+ selected: {
120
+ immediate: true,
121
+ handler(nv, ov) {
122
+ // check for matching values
123
+ if (nv && ov && nv.length == ov.length) {
124
+ let match = true;
125
+ for (let i = 0; i < nv.length; i++) {
126
+ match = match && nv[i] == ov[i];
127
+ }
128
+ if (match) {
129
+ return;
130
+ }
131
+ }
132
+ this.setSelection(nv);
133
+ },
134
+ },
135
+ selectedKeys: {
136
+ immediate: true,
137
+ handler() {
138
+ this.emitUpdateEvent();
139
+ },
140
+ },
141
+
142
+ // selected(nv) {
143
+ // this.selectedKeys = this.ensureCorrectValue(nv);
144
+ // },
145
+
146
+ // items() {
147
+ // this.tryAutoSelect();
148
+ // },
149
+ },
150
+
151
+ mounted() {
152
+ if (this.autoSelectFirst && isKeySetEmpty(this.selected) && this.items?.length) {
153
+ this.selectAt(0);
154
+ }
155
+ // this.$nextTick(() => {
156
+ // this.tryAutoSelect();
157
+ // });
158
+ },
159
+
160
+ methods: {
161
+ /**
162
+ * Emit the change / update:selected event
163
+ */
164
+ emitUpdateEvent() {
165
+ let updateArg;
166
+
167
+ if (this.updateMode == 'single') {
168
+ updateArg = this.selectedKeys.length ? this.selectedKeys[0] : null;
169
+ } else {
170
+ updateArg = this.selectedKeys;
171
+ }
172
+
173
+ this.$emit('change', updateArg);
174
+ this.$emit('update:selected', updateArg);
175
+ },
176
+
177
+ /**
178
+ * Replace the current set of selected keys with the keys provided here. Keys that don't
179
+ * have a corresponding item in the items collection in items will be ignored.
180
+ */
181
+ setSelection(keyOrKeys) {
182
+ const validKeys = ensureSet(keyOrKeys).filter(key => this.isValidItemKey(key));
183
+ this.selectedKeys = validKeys;
184
+ },
185
+
186
+ // ----------------------------------------------------------------------
187
+ // Key-based methods
188
+
189
+ /**
190
+ * Check if the provided key is selected.
191
+ */
192
+ isSelected(key) {
193
+ return !!(this.selectedKeys?.length && this.selectedKeys.includes(key));
194
+ },
195
+
196
+ /**
197
+ * Add the provided key or keys to the current selection.
198
+ */
199
+ selectKeys(addKeyOrKeys, replaceSelection = 'auto') {
200
+ const replace = this.getShouldReplace(replaceSelection);
201
+
202
+ if (isKeySetEmpty(addKeyOrKeys)) {
203
+ if (replace) {
204
+ this.selectedKeys = [];
205
+ }
206
+ return;
207
+ }
208
+
209
+ const addKeys = ensureSet(addKeyOrKeys).filter(key => this.isValidItemKey(key));
210
+
211
+ if (replace) {
212
+ this.selectedKeys = addKeys;
213
+ return;
214
+ } else {
215
+ this.selectedKeys = [
216
+ ...this.selectedKeys,
217
+ ...addKeys.filter(key => !this.selectedKeys.includes(key)),
218
+ ];
219
+ }
220
+ },
221
+
222
+ /**
223
+ * Select the provided key and replace the selection if updateMode is 'single' or add to the
224
+ * selection if updateMode is 'multi'
225
+ */
226
+ selectKey(key, replaceSelection = 'auto') {
227
+ this.selectKeys(key, this.getShouldReplace(replaceSelection));
228
+ },
229
+
230
+ /**
231
+ * Select the provided key (and replace the current selection)
232
+ */
233
+ selectKeyOnly(key) {
234
+ this.selectKeys(key, true);
235
+ },
236
+
237
+ /**
238
+ * Select the provided key or keys (and replace the current selection)
239
+ */
240
+ selectKeysOnly(addKeyOrKeys) {
241
+ this.selectKeys(addKeyOrKeys, true);
242
+ },
243
+
244
+ /**
245
+ * Remove the provided key or keys from the current selection.
246
+ */
247
+ unselectKeys(removeKeyOrKeys) {
248
+ const removeKeys = ensureSet(removeKeyOrKeys);
249
+ if (removeKeys.length) {
250
+ this.selectedKeys = this.selectedKeys.filter(key => !removeKeys.includes(key));
251
+ }
252
+ },
253
+
254
+ /**
255
+ * Remove the provided key from the current selection (convenience for better syntax when
256
+ * working with 'single' mode).
257
+ */
258
+ unselectKey(key) {
259
+ this.unselectKeys(key);
260
+ },
261
+
262
+ /**
263
+ * Toggle selection of the given key.
264
+ */
265
+ toggleKey(key) {
266
+ if (this.isSelected(key)) {
267
+ this.unselectKeys(key);
268
+ } else {
269
+ this.selectKeys(key);
270
+ }
271
+ },
272
+
273
+ // ----------------------------------------------------------------------
274
+ // Item-based methods
275
+
276
+ /**
277
+ * Check if the provided key is selected.
278
+ */
279
+ isItemSelected(item) {
280
+ return this.isSelected(this.getItemKey(item));
281
+ },
282
+
283
+ /**
284
+ * Add the provided item or items to the current selection. (Note: this is a convenience
285
+ * method and selection will continue to be stored as keys.)
286
+ */
287
+ selectItems(items, replaceSelection = 'auto') {
288
+ const keys = ensureSet(items).map(item => this.getItemKey(item));
289
+ this.selectKeys(keys, this.getShouldReplace(replaceSelection));
290
+ },
291
+
292
+ /**
293
+ * Select the provided item and replace the selection if updateMode is 'single' or add to
294
+ * the selection if updateMode is 'multi'. (Note: this is a convenience method and selection
295
+ * will continue to be stored as keys.)
296
+ */
297
+ selectItem(item, replaceSelection = 'auto') {
298
+ this.selectItems(item, this.getShouldReplace(replaceSelection));
299
+ },
300
+
301
+ /**
302
+ * Select the provided item (and replace the current selection). (Note: this is a convenience
303
+ * method and selection will continue to be stored as keys.)
304
+ */
305
+ selectItemOnly(item) {
306
+ this.selectItem(item, true);
307
+ },
308
+
309
+ /**
310
+ * Select the provided item or items (and replace the current selection). (Note: this is a
311
+ * convenience method and selection will continue to be stored as keys.)
312
+ */
313
+ selectItemsOnly(items) {
314
+ this.selectItems(items, true);
315
+ },
316
+
317
+ /**
318
+ * Remove the provided item or items from the current selection.
319
+ */
320
+ unselectItems(itemOrItems) {
321
+ const keys = ensureSet(itemOrItems).map(item => this.getItemKey(item));
322
+ this.unselectKeys(keys);
323
+ },
324
+
325
+ /**
326
+ * Remove the provided key from the current selection (convenience for better syntax when
327
+ * working with 'single' mode).
328
+ */
329
+ unselectItem(item) {
330
+ this.unselectItems(item);
331
+ },
332
+
333
+ /**
334
+ * Toggle selection of the given item.
335
+ */
336
+ toggleItem(item) {
337
+ const key = this.getItemKey(item);
338
+ if (key) {
339
+ this.toggleKey(key);
340
+ }
341
+ },
342
+
343
+ // ----------------------------------------------------------------------
344
+ // Index-based methods
345
+
346
+ selectAt(index, replaceSelection = 'auto') {
347
+ const keyAtIndex = this.itemKeys[index];
348
+
349
+ const replace =
350
+ replaceSelection == 'auto' ? this.updateMode == 'single' : replaceSelection;
351
+
352
+ this.selectKeys(keyAtIndex, replace);
353
+ },
354
+
355
+ selectAtSafe(index, wrap = false, replaceSelection = 'auto') {
356
+ const replace =
357
+ replaceSelection == 'auto' ? this.updateMode == 'single' : replaceSelection;
358
+
359
+ index = utils.arraySafeIndex(this.items, index, 0, wrap);
360
+ this.selectAt(index, replace);
361
+ },
362
+
363
+ selectOffset(offsetFromSelectedIndex, wrap = true) {
364
+ if (this.selectedIndex === null) {
365
+ this.selectAt(0);
366
+ } else {
367
+ const index = utils.arraySafeIndex(
368
+ this.items,
369
+ this.selectedIndex,
370
+ offsetFromSelectedIndex,
371
+ wrap
372
+ );
373
+ this.selectAt(index, true);
374
+ }
375
+ },
376
+
377
+ selectNext(wrap = true) {
378
+ this.selectOffset(1, wrap);
379
+ },
380
+
381
+ selectPrevious(wrap = true) {
382
+ this.selectOffset(-1, wrap);
383
+ },
384
+
385
+ unselectAt(index) {},
386
+
387
+ // ----------------------------------------------------------------------
388
+ // Other Selection
389
+
390
+ selectAll() {
391
+ if (Array.isArray(this.items) && this.items.length) {
392
+ if (this.updateMode == 'multi') {
393
+ this.selectedKeys = this.itemKeys;
394
+ } else {
395
+ this.selectedKeys = ensureSet(this.getItemKey(this.items[0]));
396
+ }
397
+ }
398
+ },
399
+
400
+ selectNone() {
401
+ this.selectedKeys = [];
402
+ },
403
+
404
+ // ----------------------------------------------------------------------
405
+ // Internal / helper
406
+
407
+ getShouldReplace(value) {
408
+ if (value == 'auto') {
409
+ return this.updateMode == 'single';
410
+ }
411
+ return value;
412
+ },
413
+ },
414
+ };
415
+ </script>
@@ -1,4 +1,6 @@
1
1
  <!--
2
+ #VUE3 Todo
3
+
2
4
  Use for global mobile awareness in javascript. This doesn't actually handle mobile detection
3
5
  but provides a consistent interface for communicating between a single component that does
4
6
  the detection and other components that subscribe to an eventbus and update a property called
@@ -9,7 +11,7 @@
9
11
  ### MyLayout.vue (or other global component)
10
12
 
11
13
  // add PxBaseMobileAware as a mixin
12
- import PxBaseMobileAware from '@thinkpixellab-public/px-vue/components/PxBaseMobileAware.vue';
14
+ import PxBaseMobileAware from '@thinkpixellab-public/px-vue/bases/PxBaseMobileAware.vue';
13
15
  mixins: [PxBaseMobileAware],
14
16
 
15
17
  // add a resize handler and call setGlobalIsMobile
@@ -32,7 +34,7 @@
32
34
  ### MyComponent.vue
33
35
 
34
36
  // use PxBaseMobileAware as a mixin
35
- import PxBaseMobileAware from '@thinkpixellab-public/px-vue/components/PxBaseMobileAware.vue';
37
+ import PxBaseMobileAware from '@thinkpixellab-public/px-vue/bases/PxBaseMobileAware.vue';
36
38
  mixins: [PxBaseMobileAware]
37
39
 
38
40
  // use the isMobile property as needed in a template
@@ -1,6 +1,13 @@
1
+ <!--
2
+ #VUE3 Todo
3
+ -->
4
+
1
5
  <script>
2
- import { debounce } from 'debounce';
6
+ import { debounce } from 'throttle-debounce';
3
7
 
8
+ /**
9
+ * Mixin that provides size watch capabilities using the ResizeObserver api.
10
+ */
4
11
  export default {
5
12
  data() {
6
13
  return {
@@ -23,10 +30,10 @@ export default {
23
30
  mounted() {
24
31
  const resizeDebouncedFn =
25
32
  this.resizeDebounceValue && this.resize
26
- ? debounce(e => {
33
+ ? debounce(this.resizeDebounceValue, e => {
27
34
  this.resize(e);
28
35
  this.resizing = false;
29
- }, this.resizeDebounceValue)
36
+ })
30
37
  : null;
31
38
 
32
39
  const resizeFn = () => {
@@ -52,7 +59,7 @@ export default {
52
59
  this.resizeObserver = new ResizeObserver(resizeFn);
53
60
  this.resizeObserver.observe(this.observeElementValue);
54
61
  },
55
- beforeDestroy() {
62
+ beforeUnmount() {
56
63
  this.resizeObserver.disconnect();
57
64
  delete this.resizeObserver;
58
65
  },
@@ -0,0 +1,46 @@
1
+ <!--
2
+ #VUE3 Todo
3
+ -->
4
+
5
+ <script>
6
+
7
+ export default {
8
+ // components: { Component },
9
+ // mixins: [ Mixin ],
10
+ // props: { a: { type: Boolean, default: false } },
11
+ data() {
12
+ return { scrollPosition: { x: 0, y: 0 } };
13
+ },
14
+ computed: {
15
+ scrollingElement() {
16
+ // derived classes can return something here to watch somethign other than document
17
+ return window !== undefined ? window : null;
18
+ },
19
+ },
20
+ // watch: {},
21
+ mounted() {
22
+ if (this.scrollingElement && this.scroll) {
23
+ let scroller = this.scrollingElement;
24
+ let ticking = false;
25
+
26
+ scroller.addEventListener('scroll', event => {
27
+ this.scrollPosition.x = scroller.scrollX;
28
+ this.scrollPosition.y = scroller.scrollY;
29
+
30
+ if (!ticking) {
31
+ window.requestAnimationFrame(() => {
32
+ this.scroll();
33
+ ticking = false;
34
+ });
35
+
36
+ ticking = true;
37
+ }
38
+ });
39
+ }
40
+ },
41
+ methods: {
42
+ // base class should override
43
+ // onScroll() {},
44
+ },
45
+ };
46
+ </script>
@@ -0,0 +1,67 @@
1
+ <!--
2
+ #VUE3 Todo
3
+
4
+ Base class for classes that manage a checked state. In order to simplify the data
5
+ synchronization with the input, we enable v-model binding by also providing a data property
6
+ (checkedValue) that mirrors the checked prop. The intention is that this property will only be
7
+ used internally as v-model.
8
+
9
+ -->
10
+
11
+ <script>
12
+ export default {
13
+ props: {
14
+ /**
15
+ * The value of the checked property.
16
+ */
17
+ checked: { type: Boolean, default: false },
18
+
19
+ /**
20
+ * Class that should be set on the component when checked.
21
+ */
22
+ checkedClass: { type: String, default: null },
23
+
24
+ /**
25
+ * Disables interaction.
26
+ */
27
+ disabled: { type: Boolean, default: false },
28
+ },
29
+ data() {
30
+ return {
31
+ checkedValue: this.checked,
32
+ };
33
+ },
34
+
35
+ watch: {
36
+ checked(nv) {
37
+ // update checkedValue when checked changes
38
+ this.checkedValue = nv;
39
+ },
40
+
41
+ checkedValue(nv) {
42
+ // emit update when checkedValue changes (enables .sync on parent)
43
+ this.$emit('update:checked', nv);
44
+
45
+ if (nv) {
46
+ this.$emit('checked');
47
+ }
48
+ if (!nv) {
49
+ this.$emit('unchecked');
50
+ }
51
+ },
52
+ },
53
+ computed: {
54
+ calcCheckedClass() {
55
+ return this.checkedValue && this.checkedClass ? this.checkedClass : null;
56
+ },
57
+ },
58
+ methods: {
59
+ toggleChecked() {
60
+ if (this.disabled) {
61
+ return;
62
+ }
63
+ this.checkedValue = !this.checkedValue;
64
+ },
65
+ },
66
+ };
67
+ </script>
@@ -0,0 +1,18 @@
1
+ <!--
2
+ #VUE3 Todo
3
+ -->
4
+
5
+ <script>
6
+ // TODO: this is currently not compatible with SSR
7
+
8
+ export default {
9
+ methods: {
10
+ uniqueId(prefix) {
11
+ if (!this.__uniqueId) {
12
+ this.__uniqueId = Math.random().toString(36).substring(2);
13
+ }
14
+ return (prefix ? `${prefix}-` : '') + this.__uniqueId;
15
+ },
16
+ },
17
+ };
18
+ </script>
@@ -1,4 +1,6 @@
1
1
  <!--
2
+ #VUE3 Done
3
+
2
4
 
3
5
  Provides a standardized way of specifying variants of a component. Variants are typically css-based
4
6
  modifications to a component and might be defined by the component or declared in the app. Typical
@@ -19,6 +21,11 @@ usage might look like:
19
21
  import variants from '../utils/variants.js';
20
22
  export default {
21
23
  props: {
24
+ /**
25
+ * The variant property is intepreted in different ways by different components, but
26
+ * typically used to trigger a different style or layout otherwise effect the way the
27
+ * component is rendered or used.
28
+ */
22
29
  variant: { type: String, default: 'default' },
23
30
  },
24
31
  computed: {
@@ -42,6 +49,7 @@ export default {
42
49
  isVariant(variantName) {
43
50
  return this.variants?.includes(variantName);
44
51
  },
52
+
45
53
  // find the first matching variant key in a map and return the correspond value
46
54
  variantsToValue(valueMap, fallback) {
47
55
  for (let key in valueMap) {
@@ -51,9 +59,11 @@ export default {
51
59
  }
52
60
  return fallback;
53
61
  },
62
+
54
63
  stringToVariants: str => {
55
64
  return variants.stringToVariants(str);
56
65
  },
66
+
57
67
  stringToVariantsMap: str => {
58
68
  return variants.stringToVariantsMap(str);
59
69
  },
@@ -1,10 +1,12 @@
1
1
  <!--
2
+ #VUE3 Done
3
+
2
4
  Extends PxBaseVariants with the ability to specify default and base variants
3
5
  (see descriptions of props below).
4
6
  -->
5
7
 
6
8
  <script>
7
- import PxBaseVariants from './PxBaseVariants.vue';
9
+ import PxBaseVariants from '../bases/PxBaseVariants.vue';
8
10
  export default {
9
11
  mixins: [PxBaseVariants],
10
12
  props: {
@@ -18,7 +20,7 @@ export default {
18
20
  variantValue() {
19
21
  return (
20
22
  (this.variantBase ? `${this.variantBase} ` : '') +
21
- (this.variant ?? this.variantDefault)
23
+ (this.variantDefault ? this.variantDefault : this.variant)
22
24
  );
23
25
  },
24
26
  },
@@ -1,4 +1,6 @@
1
1
  <!--
2
+ #VUE3 Done
3
+
2
4
  Base class that provides a single visible property / data value this is sync capable. Also
3
5
  provides show/hide/toggle methods. Override the visible prop to change the default state.
4
6
  -->