@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.
- package/components/PxPopupButton.vue +51 -31
- package/package.json +18 -20
- package/components/PxVueTest.vue +0 -755
|
@@ -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
|
|
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 {
|
|
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
|
|
94
|
+
// the positioning strategy, possible values: fixed, absolute
|
|
95
95
|
strategy: { type: String, default: 'fixed' },
|
|
96
96
|
|
|
97
|
-
// the placement of the popup
|
|
98
|
-
//
|
|
99
|
-
//
|
|
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
|
-
|
|
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
|
|
167
|
-
//
|
|
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.
|
|
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
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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.
|
|
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.
|
|
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
|
-
"@
|
|
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.
|
|
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.
|
|
67
|
-
"@storybook/addon-docs": "^10.4.
|
|
68
|
-
"@storybook/addon-links": "^10.4.
|
|
69
|
-
"@storybook/vue3": "^10.4.
|
|
70
|
-
"@storybook/vue3-vite": "^10.4.
|
|
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.
|
|
72
|
+
"chromatic": "^17.7.2",
|
|
75
73
|
"jsdom": "^29.1.1",
|
|
76
|
-
"oxfmt": "^0.
|
|
77
|
-
"oxlint": "^1.
|
|
78
|
-
"sass": "^1.
|
|
79
|
-
"storybook": "^10.4.
|
|
80
|
-
"storybook-addon-pseudo-states": "^10.4.
|
|
81
|
-
"vite": "^8.0
|
|
82
|
-
"vitest": "^4.1.
|
|
83
|
-
"vue": "^3.5.
|
|
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",
|
package/components/PxVueTest.vue
DELETED
|
@@ -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>
|