@thinkpixellab-public/px-vue 5.3.0 → 5.3.6

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.
@@ -1,7 +1,7 @@
1
1
  <!--
2
2
 
3
3
  Simple popup attached to a reference element. Most common scenarios would be tooltips or menus.
4
- Uses popper.js for placement and PxModal for the popup itself. Has built in support for click
4
+ Uses Floating UI for placement and PxFloat for the popup itself. Has built in support for click
5
5
  and hover triggers.
6
6
 
7
7
  Usage as a menu:
@@ -77,7 +77,7 @@
77
77
 
78
78
  <script>
79
79
  import PxFloat from './PxFloat.vue';
80
- import { createPopper } from '@popperjs/core';
80
+ import { computePosition, autoUpdate, offset, flip, shift } from '@floating-ui/dom';
81
81
  export default {
82
82
  name: 'px-popup',
83
83
  components: { PxFloat },
@@ -91,12 +91,12 @@ export default {
91
91
  // whether the popup is visible (syncable)
92
92
  popupVisible: { type: Boolean, default: false },
93
93
 
94
- // the placement strategy to use with popper.js, possible values: fixed, absolute
94
+ // the positioning strategy, possible values: fixed, absolute
95
95
  strategy: { type: String, default: 'fixed' },
96
96
 
97
- // the placement of the popup (proxy for popper.js placement), possible values are: auto,
98
- // auto-start, auto-end, top, top-start, top-end, bottom, bottom-start, bottom-end, right,
99
- // right-start, right-end, left, left-start, left-end
97
+ // the placement of the popup relative to the reference element, possible values are: top,
98
+ // top-start, top-end, bottom, bottom-start, bottom-end, right, right-start, right-end, left,
99
+ // left-start, left-end
100
100
  placement: { type: String, default: 'bottom' },
101
101
 
102
102
  // the number of pixels to shift the popup in the direction perpendicular to it's alignment,
@@ -147,37 +147,23 @@ export default {
147
147
  this.popupMinWidth = null;
148
148
  }
149
149
 
150
- let popperOptions = {
151
- placement: this.placement,
152
- strategy: this.strategy,
153
- modifiers: [
154
- {
155
- name: 'offset',
156
- options: {
157
- offset: [this.skidding, this.distance],
158
- },
159
- },
160
- ],
161
- };
162
-
163
- this.clearPopper();
150
+ this.stopPositioning();
164
151
 
165
152
  if (this.calcUseModal) {
166
- // if we're using a modal we need to delay the creation of the popper so that
167
- // we have the popup element in the right place in the DOM
153
+ // if we're using a modal we need to delay positioning so that the popup element
154
+ // is in the right place in the DOM (PxFloat teleports it)
168
155
  await this.$nextTick();
169
156
  await this.$nextTick();
170
- this.popper = createPopper(this.$el, this.$refs.popup, popperOptions);
171
- } else {
172
- // but if we don't have a modal, we want to create it immediately to avoid
173
- // layout flashes
174
- this.popper = createPopper(this.$el, this.$refs.popup, popperOptions);
175
157
  }
158
+
159
+ this.startPositioning();
160
+ } else {
161
+ this.stopPositioning();
176
162
  }
177
163
  },
178
164
  },
179
165
  beforeUnmount() {
180
- this.clearPopper();
166
+ this.stopPositioning();
181
167
  },
182
168
  computed: {
183
169
  calcUseModal() {
@@ -219,9 +205,43 @@ export default {
219
205
  this.syncPopupVisible = false;
220
206
  }
221
207
  },
222
- clearPopper() {
223
- if (this.popper) {
224
- this.popper.destroy();
208
+ startPositioning() {
209
+ let reference = this.$el;
210
+ let popup = this.$refs.popup;
211
+ if (!reference || !popup) {
212
+ return;
213
+ }
214
+
215
+ // establish the strategy up front so measurements aren't affected by normal flow
216
+ popup.style.position = this.strategy;
217
+ popup.style.left = '0';
218
+ popup.style.top = '0';
219
+
220
+ // autoUpdate positions immediately and keeps it in sync on scroll/resize
221
+ this.cleanup = autoUpdate(reference, popup, () =>
222
+ this.updatePosition(reference, popup),
223
+ );
224
+ },
225
+
226
+ updatePosition(reference, popup) {
227
+ computePosition(reference, popup, {
228
+ placement: this.placement,
229
+ strategy: this.strategy,
230
+ middleware: [
231
+ // popper's offset was [skidding, distance] => [crossAxis, mainAxis]
232
+ offset({ mainAxis: this.distance, crossAxis: this.skidding }),
233
+ flip(),
234
+ shift(),
235
+ ],
236
+ }).then(({ x, y }) => {
237
+ Object.assign(popup.style, { left: `${x}px`, top: `${y}px` });
238
+ });
239
+ },
240
+
241
+ stopPositioning() {
242
+ if (this.cleanup) {
243
+ this.cleanup();
244
+ this.cleanup = null;
225
245
  }
226
246
  },
227
247
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thinkpixellab-public/px-vue",
3
- "version": "5.3.0",
3
+ "version": "5.3.6",
4
4
  "description": "General purpose Vue components and helpers that can be used across projects.",
5
5
  "author": {
6
6
  "name": "Pixel Lab"
@@ -10,7 +10,7 @@
10
10
  "engines": {
11
11
  "node": ">=24 <25"
12
12
  },
13
- "packageManager": "pnpm@11.5.2",
13
+ "packageManager": "pnpm@11.9.0",
14
14
  "publishConfig": {
15
15
  "access": "public"
16
16
  },
@@ -43,16 +43,14 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@floating-ui/dom": "^1.7.6",
46
- "@popperjs/core": "^2.11.8",
47
- "@thinkpixellab-public/px-styles": "^4.2.1",
48
- "@thinkpixellab-public/px-vue-tester": "^2.0.0",
46
+ "@thinkpixellab-public/px-styles": "^4.2.2",
49
47
  "body-scroll-lock": "^3.1.5",
50
48
  "chrono-node": "^2.9.1",
51
49
  "dateformat": "^5.0.3",
52
50
  "figma-squircle": "^1.1.0",
53
51
  "gsap": "^3.15.0",
54
52
  "highlight.js": "^11.11.1",
55
- "lenis": "^1.3.23",
53
+ "lenis": "^1.3.25",
56
54
  "mitt": "^3.0.1",
57
55
  "qr-code-styling": "^1.9.2",
58
56
  "sortablejs": "^1.15.7",
@@ -63,24 +61,24 @@
63
61
  },
64
62
  "devDependencies": {
65
63
  "@chromatic-com/storybook": "^5.2.1",
66
- "@nuxt/kit": "^4.4.7",
67
- "@storybook/addon-docs": "^10.4.2",
68
- "@storybook/addon-links": "^10.4.2",
69
- "@storybook/vue3": "^10.4.2",
70
- "@storybook/vue3-vite": "^10.4.2",
64
+ "@nuxt/kit": "^4.4.8",
65
+ "@storybook/addon-docs": "^10.4.6",
66
+ "@storybook/addon-links": "^10.4.6",
67
+ "@storybook/vue3": "^10.4.6",
68
+ "@storybook/vue3-vite": "^10.4.6",
71
69
  "@vitejs/plugin-vue": "^6.0.7",
72
70
  "@vue/test-utils": "^2.4.11",
73
71
  "@vueless/storybook-dark-mode": "^10.0.8",
74
- "chromatic": "^17.3.0",
72
+ "chromatic": "^17.7.2",
75
73
  "jsdom": "^29.1.1",
76
- "oxfmt": "^0.53.0",
77
- "oxlint": "^1.68.0",
78
- "sass": "^1.100.0",
79
- "storybook": "^10.4.2",
80
- "storybook-addon-pseudo-states": "^10.4.2",
81
- "vite": "^8.0.16",
82
- "vitest": "^4.1.8",
83
- "vue": "^3.5.35"
74
+ "oxfmt": "^0.56.0",
75
+ "oxlint": "^1.71.0",
76
+ "sass": "^1.101.0",
77
+ "storybook": "^10.4.6",
78
+ "storybook-addon-pseudo-states": "^10.4.6",
79
+ "vite": "^8.1.0",
80
+ "vitest": "^4.1.9",
81
+ "vue": "^3.5.39"
84
82
  },
85
83
  "peerDependencies": {
86
84
  "@nuxt/kit": "^3.0.0 || ^4.0.0",
@@ -1,755 +0,0 @@
1
- <!--
2
-
3
- -->
4
- <template>
5
- <div class="px-vue-test">
6
- <px-tester>
7
- <px-test test-id="px-nine-grid" name="px-nine-grid" :size="{ h: 300 }">
8
- <px-nine-grid
9
- slice="50"
10
- src="https://harnerdesigns.com/wp-content/uploads/2018/08/border.svg"
11
- :src-width="300"
12
- :src-height="300"
13
- :style="{ width: cssPcnt(1), height: cssPcnt(1) }"
14
- />
15
- </px-test>
16
-
17
- <px-test test-id="px-card-grd" name="px-card-grid" :size="{ h: 300 }">
18
- <px-card-grid />
19
- </px-test>
20
-
21
- <px-test test-id="px-fit" name="px-fit" :size="{ h: 300 }">
22
- <px-fit :fits="['lg', 'md', 'sm']" :debug="false">
23
- <template #default="{ fit }">
24
- <div :class="`fit fit--${fit}`">
25
- <span v-if="fit == 'lg'">LARGE</span>
26
- <span v-if="fit == 'md'">MEDIUM</span>
27
- <span v-if="fit == 'sm'">SMALL</span>
28
- One Two Three Four Five Size Seven Eight Nine Ten
29
- </div>
30
- </template>
31
- </px-fit>
32
- </px-test>
33
-
34
- <px-test test-id="px-table" name="px-table" :size="{ h: 300 }">
35
- <!--
36
- id: 'orange',
37
- name: 'Orange',
38
- color: 'orange',
39
- deliciousNess: 8,
40
- lastPurchase: new Date('2022-02-01T00:00:00.000Z'),
41
-
42
- -->
43
-
44
- <px-table
45
- :items="fruits"
46
- items-key-property="id"
47
- :columns="[
48
- {
49
- property: 'name',
50
- align: 'start',
51
- },
52
- {
53
- template: 'color',
54
- headerTemplate: 'color-header',
55
- label: 'COLOR',
56
- sortable: false,
57
- },
58
- {
59
- property: 'deliciousNess',
60
- },
61
- {
62
- property: 'description',
63
- overflow: 'ellipsis',
64
- align: 'start',
65
- },
66
- {
67
- property: 'lastPurchase',
68
- },
69
- ]"
70
- >
71
- <!-- color column slot -->
72
- <template #color="{ item }">
73
- <div
74
- :style="{
75
- width: '1em',
76
- height: '1em',
77
- borderRadius: '50%',
78
- backgroundColor: item.color,
79
- }"
80
- />
81
- </template>
82
-
83
- <!-- color-header column header slot -->
84
- <template #color-header>
85
- <div
86
- :style="{
87
- width: '1em',
88
- height: '1em',
89
- borderRadius: '50%',
90
- background: 'silver',
91
- }"
92
- />
93
- </template>
94
- </px-table>
95
- </px-test>
96
- <px-test test-id="px-validator" name="px-validator">
97
- <px-flex vertical :style="{ maxWidth: '400px', margin: '0 auto' }" gap="1">
98
- <span>Has errors: {{ !allValid }}</span>
99
-
100
- <px-validator
101
- :value="validateThree"
102
- @valid-changed="onValidChanged"
103
- :rules="{
104
- apple: val => {
105
- if (val !== 'apple') {
106
- return 'Must be apple';
107
- }
108
- },
109
- }"
110
- >
111
- <px-dropdown
112
- v-model:selected="validateThree"
113
- tag="button"
114
- trigger="click"
115
- :items="fruits"
116
- items-value-property="id"
117
- items-label-property="name"
118
- items-key-property="id"
119
- placeholder="Select a fruit..."
120
- ></px-dropdown>
121
- </px-validator>
122
-
123
- PHONE
124
- <br />
125
- <px-validator
126
- :value="validateOne"
127
- rules="required phone"
128
- @valid-changed="onValidChanged"
129
- >
130
- <template #default="v">
131
- <px-textbox
132
- v-model:text="validateOne"
133
- :class="[v.class, v.requiredClass, v.violationClasses]"
134
- />
135
- </template>
136
- </px-validator>
137
-
138
- <px-validator
139
- :value="validateTwo"
140
- rules="required"
141
- @valid-changed="onValidChanged"
142
- >
143
- <template #default="v">
144
- <px-textbox
145
- v-model:text="validateTwo"
146
- :class="[v.class, v.requiredClass, v.violationClasses]"
147
- />
148
- </template>
149
- </px-validator>
150
- </px-flex>
151
- </px-test>
152
-
153
- <px-test test-id="px-progress-circle" name="px-progress-circle">
154
- <px-progress-circle
155
- :progress="0.5"
156
- :stroke-width="4"
157
- style="width: 60px; color: black"
158
- />
159
- </px-test>
160
-
161
- <px-test test-id="px-aspect" name="px-aspect">
162
- <px-aspect :debug="true">
163
- <div :style="{ backgroundColor: 'gold' }">
164
- Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.
165
- Nullam id dolor id nibh ultricies vehicula ut id elit. Sed posuere
166
- consectetur est at lobortis. Duis mollis, est non commodo luctus, nisi erat
167
- porttitor ligula, eget lacinia odio sem nec elit. Vivamus sagittis lacus vel
168
- augue laoreet rutrum faucibus dolor auctor. Nullam id dolor id nibh
169
- ultricies vehicula ut id elit. Sed posuere consectetur est at lobortis. Duis
170
- mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia
171
- odio sem nec elit.
172
- </div>
173
-
174
- <img
175
- :style="{ opacity: 0.5 }"
176
- src="https://images.unsplash.com/photo-1650923500748-eee80ee6e7d1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1920&q=80"
177
- />
178
- </px-aspect>
179
- </px-test>
180
-
181
- <px-test test-id="px-swiper-cards" name="Card Swiper">
182
- <div>
183
- <px-swiper>
184
- <px-swiper-slide>
185
- <px-card>This is some content</px-card>
186
- </px-swiper-slide>
187
- <px-swiper-slide>
188
- <px-card>This is some content</px-card>
189
- </px-swiper-slide>
190
- <px-swiper-slide>
191
- <px-card>This is some content</px-card>
192
- </px-swiper-slide>
193
- </px-swiper>
194
- </div>
195
-
196
- <!-- <px-swiper :loop="true">
197
- <px-swiper-slide>
198
- <div class="swiper-max-width">
199
- <img
200
- class="swiper-img"
201
- src="https://picsum.photos/1600/900?grayscale"
202
- />
203
- </div>
204
- </px-swiper-slide>
205
- <px-swiper-slide>
206
- <img class="swiper-img" src="https://picsum.photos/1601/900?grayscale" />
207
- </px-swiper-slide>
208
- <px-swiper-slide>
209
- <img class="swiper-img" src="https://picsum.photos/1602/900?grayscale" />
210
- </px-swiper-slide>
211
- </px-swiper> -->
212
- </px-test>
213
-
214
- <px-test test-id="px-date-picker" name="px-date-picker">
215
- <px-flex vertical align="center" gap="1">
216
- <span>Selected Date: {{ currentDateNull }}</span>
217
- <px-date-picker mode="textbox" v-model:date="currentDateNull" />
218
- <px-date-picker mode="textbox" clock v-model:date="currentDateNull" />
219
- <px-date-picker v-model:date="currentDateNull" />
220
- <px-date-picker time v-model:date="currentDateNull" />
221
- </px-flex>
222
- </px-test>
223
-
224
- <px-test test-id="px-clock" name="px-clock">
225
- <px-clock v-model:date="currentDate" />
226
- Selected Date: {{ currentDate }}
227
- </px-test>
228
-
229
- <px-test test-id="px-calendar" name="px-calendar">
230
- <px-calendar v-model:date="currentDate" />
231
- Selected Date: {{ currentDate }}
232
- </px-test>
233
-
234
- <px-test test-id="single-vs-multiple" name="Single vs Multiple Selection">
235
- <px-flex align="center" gap="1">
236
- <!-- dynamic select -->
237
-
238
- <px-toggle-button-list
239
- :multi-select="supportsMultiSelect"
240
- :items="fruits"
241
- items-key-property="id"
242
- items-value-property="id"
243
- items-label-property="name"
244
- v-model:selected="currentFruitOrFruits"
245
- ></px-toggle-button-list>
246
-
247
- <px-toggle v-model:checked="supportsMultiSelect">Multi-select</px-toggle>
248
- <span>{{ currentFruitOrFruits }}</span>
249
- </px-flex>
250
- </px-test>
251
-
252
- <px-test test-id="px-textbox" name="px-textbox">
253
- <px-flex :vertical="true" :gap="1">
254
- <div>currentText: {{ currentText }}</div>
255
-
256
- <px-textbox v-model:text="currentText" placeholder="Say what you want..." />
257
-
258
- <px-textbox
259
- multiline
260
- v-model:text="currentText"
261
- rows="5"
262
- placeholder="Say it longer..."
263
- />
264
-
265
- <px-textbox type="password" />
266
- <px-textbox :text="'hello@thinkpixellab.com'" type="email" />
267
- </px-flex>
268
- </px-test>
269
-
270
- <px-test test-id="px-dropdown" name="px-dropdown">
271
- <px-flex gap="1" align="center" justify="center">
272
- <px-dropdown
273
- v-model:selected="currentFruit"
274
- tag="button"
275
- trigger="click"
276
- :items="fruits"
277
- items-value-property="id"
278
- items-label-property="name"
279
- items-key-property="id"
280
- placeholder="Select a fruit..."
281
- >
282
- Button Label
283
-
284
- <template #popup>
285
- <div class="popup-menu">
286
- <button>Menu Option 1</button>
287
- <button>Menu Option 2</button>
288
- </div>
289
- </template>
290
- </px-dropdown>
291
- <span>{{ currentFruit }}</span>
292
- </px-flex>
293
- </px-test>
294
-
295
- <px-test test-id="px-popup" name="px-popup">
296
- <px-flex vertical gap="1" align="center">
297
- <px-popup tag="button" trigger="click">
298
- Click This Button
299
-
300
- <template #popup>
301
- <px-flex vertical class="popup-menu">
302
- <button>Option 1</button>
303
- <button>Option 2</button>
304
- <button>Option 3</button>
305
- <button>Option 4</button>
306
- </px-flex>
307
- </template>
308
- </px-popup>
309
-
310
- <px-popup tag="button" trigger="hover">
311
- Hover Over This
312
-
313
- <template #popup>
314
- <px-flex vertical class="popup-menu">
315
- <button>Option 1</button>
316
- <button>Option 2</button>
317
- <button>Option 3</button>
318
- <button>Option 4</button>
319
- </px-flex>
320
- </template>
321
- </px-popup>
322
-
323
- <px-popup tag="button" trigger="contextmenu">
324
- Context Menu
325
-
326
- <template #popup>
327
- <px-flex vertical class="popup-menu">
328
- <button>Option 1</button>
329
- <button>Option 2</button>
330
- <button>Option 3</button>
331
- <button>Option 4</button>
332
- </px-flex>
333
- </template>
334
- </px-popup>
335
- </px-flex>
336
- </px-test>
337
-
338
- <px-test test-id="px-swiper" name="px-swiper" :size="{ w: 1440 }">
339
- <px-swiper :loop="true">
340
- <px-swiper-slide>
341
- <div class="swiper-max-width">
342
- <img
343
- class="swiper-img"
344
- src="https://picsum.photos/1600/900?grayscale"
345
- />
346
- </div>
347
- </px-swiper-slide>
348
- <px-swiper-slide>
349
- <img class="swiper-img" src="https://picsum.photos/1601/900?grayscale" />
350
- </px-swiper-slide>
351
- <px-swiper-slide>
352
- <img class="swiper-img" src="https://picsum.photos/1602/900?grayscale" />
353
- </px-swiper-slide>
354
- </px-swiper>
355
- </px-test>
356
-
357
- <px-test test-id="px-icon-button" name="px-icon-button">
358
- <px-flex gap="3" justify="center">
359
- <px-icon-button :src="iconTrash" />
360
-
361
- <px-icon-button :src="iconTrash" variant="basic" />
362
- <px-icon-button :src="iconTrash" variant="basic accent-hover" />
363
- <px-icon-button :src="iconTrash" variant="default accent-hover" />
364
- <px-icon v-if="false" :src="iconTrash" />
365
- <px-svg v-if="false" :src="iconTrash" />
366
- </px-flex>
367
- </px-test>
368
-
369
- <px-test test-id="toggle-button-list" name="px-toggle-button-list">
370
- <px-toggle-button-list
371
- :items="fruits"
372
- items-value-property="id"
373
- items-label-property="name"
374
- items-key-property="id"
375
- />
376
-
377
- <br />
378
-
379
- <px-toggle-button-list
380
- :items="fruits"
381
- items-value-property="id"
382
- items-label-property="name"
383
- items-key-property="id"
384
- :multi-select="true"
385
- @change="toggleButtonChange"
386
- />
387
-
388
- <br />
389
-
390
- <px-toggle-button-list
391
- :items="fruits"
392
- items-value-property="id"
393
- items-label-property="name"
394
- items-key-property="id"
395
- variant="radio"
396
- />
397
-
398
- <br />
399
-
400
- <px-toggle-button-list
401
- :items="fruits"
402
- items-value-property="id"
403
- items-label-property="name"
404
- items-key-property="id"
405
- variant="vertical radio"
406
- />
407
-
408
- <br />
409
-
410
- <px-toggle-button-list
411
- :items="fruits"
412
- items-value-property="id"
413
- items-label-property="name"
414
- items-key-property="id"
415
- variant="default connected"
416
- />
417
-
418
- <br />
419
-
420
- <px-toggle-button-list
421
- :items="fruits"
422
- items-value-property="id"
423
- items-label-property="name"
424
- items-key-property="id"
425
- >
426
- <template v-slot:item="{ item, checked }">
427
- <span
428
- :style="{
429
- width: '0.5em',
430
- height: '0.5em',
431
- backgroundColor: item.color,
432
- display: 'inline-block',
433
- transform: checked ? 'scale(1.5)' : null,
434
- }"
435
- ></span>
436
- {{ item.name }}
437
- </template>
438
- </px-toggle-button-list>
439
-
440
- <br />
441
-
442
- <px-toggle-button-list
443
- :items="fruits"
444
- items-value-property="id"
445
- items-label-property="name"
446
- items-key-property="id"
447
- variant="outline"
448
- />
449
-
450
- <br />
451
-
452
- <px-toggle-button-list
453
- :items="fruits"
454
- items-value-property="id"
455
- items-label-property="name"
456
- items-key-property="id"
457
- variant="connected outline"
458
- />
459
-
460
- <br />
461
-
462
- <div style="max-width: 400px">
463
- <px-toggle-button-list
464
- :items="fruits"
465
- items-value-property="id"
466
- items-label-property="name"
467
- items-key-property="id"
468
- variant="default wrap"
469
- />
470
- </div>
471
-
472
- <br />
473
-
474
- <px-toggle-button-list
475
- :items="fruits"
476
- items-value-property="id"
477
- items-label-property="name"
478
- items-key-property="id"
479
- variant="tags wrap"
480
- :multi-select="true"
481
- />
482
- </px-test>
483
-
484
- <px-test test-id="px-flex" name="px-flex">
485
- <px-flex gap="2" class="flex-test" justify="center">
486
- <px-flex :vertical="true" class="flex-test" gap="1">
487
- <div class="flex-item"></div>
488
- <div class="flex-item flex-item--small"></div>
489
- <div class="flex-item"></div>
490
- </px-flex>
491
-
492
- <px-flex :vertical="true" :reverse="true" class="flex-test" gap="1">
493
- <div class="flex-item"></div>
494
- <div class="flex-item flex-item--small"></div>
495
- <div class="flex-item"></div>
496
- </px-flex>
497
-
498
- <px-flex align-y="center" :vertical="false" class="flex-test" gap="20px">
499
- <div class="flex-item"></div>
500
- <div class="flex-item flex-item--small"></div>
501
- <div class="flex-item"></div>
502
- </px-flex>
503
-
504
- <px-flex class="flex-test" :reverse="true" gap="0.5">
505
- <div class="flex-item"></div>
506
- <div class="flex-item flex-item--small"></div>
507
- <div class="flex-item"></div>
508
- </px-flex>
509
- </px-flex>
510
- </px-test>
511
-
512
- <px-test test-id="px-toggle" name="px-toggle">
513
- <px-toggle>Test</px-toggle>
514
- </px-test>
515
-
516
- <px-test test-id="px-toggle-button" name="px-toggle">
517
- <div>
518
- <px-toggle-button>Test</px-toggle-button>
519
- </div>
520
- </px-test>
521
- </px-tester>
522
- </div>
523
- </template>
524
-
525
- <script>
526
- import { PxTester, PxTest } from '@thinkpixellab-public/px-vue-tester';
527
- import PxToggle from './PxToggle.vue';
528
- import PxToggleButton from './PxToggleButton.vue';
529
- import PxFlex from './PxFlex.vue';
530
- import PxToggleButtonList from './PxToggleButtonList.vue';
531
- import PxIconButton from './PxIconButton.vue';
532
- import PxIcon from './PxIcon.vue';
533
- import PxSvg from './PxSvg.vue';
534
- import PxSwiper from './PxSwiper.vue';
535
- import PxSwiperSlide from './PxSwiperSlide.vue';
536
- import PxDropdown from './PxDropdown.vue';
537
- import PxPopupButton from './PxPopupButton.vue';
538
- import PxTextbox from './PxTextbox.vue';
539
- import PxCalendar from './PxCalendar.vue';
540
- import PxClock from './PxClock.vue';
541
- import PxDatePicker from './PxDatePicker.vue';
542
- import PxCard from './PxCard.vue';
543
- import PxAspect from './PxAspect.vue';
544
- import PxProgressCircle from './PxProgressCircle.vue';
545
- import PxValidator from './PxValidator.vue';
546
- import PxTable from './PxTable.vue';
547
- import PxFit from './PxFit.vue';
548
- import PxCardGrid from './PxCardGrid.vue';
549
- import PxNineGrid from './PxNineGrid.vue';
550
-
551
- import iconTrash from '../assets/test/trash.svg?url';
552
-
553
- export default {
554
- name: 'px-vue-test',
555
- components: {
556
- PxTester,
557
- PxTest,
558
- PxToggle,
559
- PxToggleButton,
560
- PxFlex,
561
- PxToggleButtonList,
562
- PxIconButton,
563
- PxIcon,
564
- PxSvg,
565
- PxSwiper,
566
- PxSwiperSlide,
567
- PxPopupButton,
568
- PxDropdown,
569
- PxTextbox,
570
- PxCalendar,
571
- PxClock,
572
- PxDatePicker,
573
- PxCard,
574
- PxAspect,
575
- PxProgressCircle,
576
- PxValidator,
577
- PxTable,
578
- PxFit,
579
- PxCardGrid,
580
- PxNineGrid,
581
- },
582
-
583
- data() {
584
- return {
585
- validateOne: null,
586
- validateTwo: null,
587
- validateThree: null,
588
- validation: {},
589
-
590
- iconTrash,
591
-
592
- currentDate: new Date(),
593
- currentDateNull: null,
594
- supportsMultiSelect: false,
595
- currentFruitOrFruits: null,
596
- currentFruits: ['orange', 'apple'],
597
- currentFruit: 'orange',
598
- fruits: [
599
- {
600
- id: 'apple',
601
- name: 'Apple',
602
- color: 'red',
603
- deliciousNess: 7,
604
- description:
605
- 'Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Etiam porta sem malesuada magna mollis euismod. Nulla vitae elit libero, a pharetra augue.',
606
- lastPurchase: new Date('2022-03-01T00:00:00.000Z'),
607
- },
608
- {
609
- id: 'orange',
610
- name: 'Orange',
611
- color: 'orange',
612
- deliciousNess: 8,
613
- description:
614
- 'Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.',
615
- lastPurchase: new Date('2022-02-01T00:00:00.000Z'),
616
- },
617
- {
618
- id: 'lime',
619
- name: 'Lime',
620
- color: 'yellowgreen',
621
- deliciousNess: 3,
622
- description:
623
- 'Donec sed odio dui. Nullam id dolor id nibh ultricies vehicula ut id elit.',
624
- lastPurchase: new Date('2022-01-01T00:00:00.000Z'),
625
- },
626
- {
627
- id: 'banana',
628
- name: 'Banana',
629
- color: 'gold',
630
- deliciousNess: 7,
631
- description: 'Donec id elit non mi porta gravida at eget metus.',
632
- lastPurchase: new Date('2021-12-01T00:00:00.000Z'),
633
- },
634
- {
635
- id: 'grape',
636
- name: 'Grape',
637
- color: 'purple',
638
- deliciousNess: 5,
639
- description:
640
- 'Etiam porta sem malesuada magna mollis euismod. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.',
641
- lastPurchase: new Date('2021-11-01T00:00:00.000Z'),
642
- },
643
- {
644
- id: 'strawberry',
645
- name: 'Strawberry',
646
- color: 'pink',
647
- deliciousNess: 9,
648
- description: 'Donec ullamcorper nulla non metus auctor fringilla.',
649
- lastPurchase: new Date('2021-10-01T00:00:00.000Z'),
650
- },
651
- ],
652
- currentText: 'Howdy',
653
- };
654
- },
655
- computed: {
656
- allValid() {
657
- return Object.values(this.validation).reduce((acc, val) => {
658
- return acc && val;
659
- }, true);
660
- },
661
- },
662
- methods: {
663
- toggleButtonChange() {},
664
- onValidChanged(isValid, id) {
665
- this.validation.id = isValid;
666
- },
667
- },
668
- };
669
- </script>
670
-
671
- <style lang="scss">
672
- @use '../styles/px.scss' as *;
673
-
674
- .px-vue-test {
675
- .fit {
676
- white-space: nowrap;
677
- color: black;
678
- }
679
-
680
- .fit--sm {
681
- font-size: 12px;
682
- color: red;
683
- }
684
-
685
- .fit--md {
686
- font-size: 18px;
687
- color: purple;
688
- }
689
-
690
- .fit--lg {
691
- font-size: 24px;
692
- color: blue;
693
- }
694
-
695
- .swiper-max-width {
696
- max-width: 800px;
697
- margin: 0 auto;
698
- img {
699
- width: 100%;
700
- height: 100%;
701
- object-fit: contain;
702
- }
703
- }
704
- .swiper-img {
705
- width: 100%;
706
- font-size: 0;
707
- display: block;
708
- width: 100%;
709
- height: 100%;
710
- object-fit: contain;
711
- }
712
- .flex-item {
713
- background-color: accent();
714
- width: 80px;
715
- height: 80px;
716
- border-radius: 10px;
717
- &--small {
718
- width: 50px;
719
- height: 50px;
720
- }
721
-
722
- &:nth-child(2) {
723
- background-color: accent(2);
724
- }
725
- &:nth-child(3) {
726
- background-color: accent(4);
727
- }
728
- }
729
- .flex-test {
730
- border: 2px dashed gray();
731
- padding: 2px;
732
- border-radius: 12px;
733
- }
734
-
735
- // custom toggle button variant
736
- .px-toggle-button-list--tags {
737
- .px-toggle-button-list__button {
738
- @include button(
739
- (
740
- font-size: fs(xs),
741
- background-color: #f6c268,
742
- border-radius: 2px,
743
- min-height: 2em,
744
- min-width: 0,
745
- padding: 0 0.5em,
746
- checked: (
747
- background-color: accent(-2),
748
- color: white,
749
- ),
750
- )
751
- );
752
- }
753
- }
754
- }
755
- </style>