@thinkpixellab-public/px-vue 4.0.16 → 4.0.18
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/.storybook/main.js +2 -2
- package/.storybook/preview.js +3 -22
- package/.storybook/preview.scss +1 -255
- package/assets/icons/ellipsis.svg +7 -1
- package/assets/icons/eyedropper.svg +5 -1
- package/bases/PxBaseIconProp.vue +21 -0
- package/bases/PxBaseItemsSelect.vue +10 -1
- package/chromatic.config.json +5 -0
- package/components/PxArrowScroller.vue +5 -1
- package/components/PxBalancedText.vue +3 -0
- package/components/PxBaseColor.vue +187 -0
- package/components/PxCodeSample.vue +7 -0
- package/components/PxColorPalette.vue +13 -6
- package/components/PxColorPaletteButton.vue +0 -3
- package/components/PxColorPicker.vue +5 -0
- package/components/PxDropdown.vue +0 -3
- package/components/PxFloat.vue +16 -9
- package/components/PxIcon.vue +1 -1
- package/components/PxIconButton.vue +4 -2
- package/components/PxPivot.vue +7 -1
- package/components/PxQrCode.vue +1 -0
- package/components/PxToggleButton.vue +150 -57
- package/components/PxToggleButtonList.vue +1 -4
- package/package.json +78 -70
- package/stories/PxAnimate.stories.js +3 -3
- package/stories/PxArrow.stories.js +1 -1
- package/stories/PxArrowScroller.stories.js +3 -3
- package/stories/PxAspect.stories.js +3 -3
- package/stories/PxAutoClamp.stories.js +3 -3
- package/stories/PxBalancedText.stories.js +3 -3
- package/stories/PxButton.stories.js +3 -3
- package/stories/PxCalendar.stories.js +3 -3
- package/stories/PxCard.stories.js +3 -3
- package/stories/PxCardGrid.stories.js +4 -4
- package/stories/PxClock.stories.js +3 -3
- package/stories/PxCodeSample.stories.js +3 -3
- package/stories/PxColorPalette.stories.js +3 -3
- package/stories/PxColorPanel.stories.js +6 -20
- package/stories/PxColorPicker.stories.js +10 -13
- package/stories/PxContain.stories.js +3 -3
- package/stories/PxCopyText.stories.js +3 -3
- package/stories/PxDatePicker.stories.js +3 -3
- package/stories/PxDropdown.stories.js +4 -4
- package/stories/PxFit.stories.js +3 -3
- package/stories/PxFlex.stories.js +3 -3
- package/stories/PxFlip.stories.js +3 -3
- package/stories/PxFloat.stories.js +40 -3
- package/stories/PxGsapScrubber.stories.js +3 -3
- package/stories/PxIcon.stories.js +30 -39
- package/stories/PxIconButton.stories.js +3 -3
- package/stories/PxLabeledInput.stories.js +3 -3
- package/stories/PxMeasureContainer.stories.js +3 -3
- package/stories/PxMenu.stories.js +3 -3
- package/stories/PxPivot.stories.js +2 -2
- package/stories/PxPopupButton.stories.js +3 -3
- package/stories/PxProgressCircle.stories.js +3 -3
- package/stories/PxQrCode.stories.js +3 -3
- package/stories/PxRadioButton.stories.js +3 -3
- package/stories/PxResizer.stories.js +3 -3
- package/stories/PxScrubber.stories.js +3 -3
- package/stories/PxSideDrawer.stories.js +3 -3
- package/stories/PxSlides.stories.js +4 -4
- package/stories/PxSpinner.stories.js +3 -3
- package/stories/PxSticky.stories.js +3 -3
- package/stories/PxSvg.stories.js +3 -3
- package/stories/PxSvgRender.stories.js +3 -3
- package/stories/PxSyncHeight.stories.js +3 -3
- package/stories/PxTable.stories.js +4 -4
- package/stories/PxTextbox.stories.js +3 -3
- package/stories/PxToggle.stories.js +3 -3
- package/stories/PxToggleButton.stories.js +22 -3
- package/stories/PxToggleButtonList.stories.js +4 -4
- package/stories/PxTransition.stories.js +3 -3
- package/stories/PxTransitionExpand.stories.js +3 -3
- package/stories/PxTransitionItem.stories.js +3 -3
- package/stories/PxValidator.stories.js +3 -3
- package/stories/makestories.js +3 -3
- package/storybook/sb-styles.scss +174 -0
- package/{stories/helpers/extractArgTypes.js → storybook/sb-utils.js} +1 -1
- package/utils/SharedHeightManager.js +213 -0
- package/utils/propsFilter.js +3 -2
- package/utils/svgIcons.js +68 -12
- package/utils/textWidth.js +1 -1
- package/stories/helpers/scratch.vue +0 -30
- /package/{stories/helpers/sampleData.js → storybook/sb-sampledata.js} +0 -0
package/.storybook/main.js
CHANGED
package/.storybook/preview.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { setup } from '@storybook/vue3';
|
|
2
|
-
import { themes } from '@storybook/theming';
|
|
3
2
|
import common from '../plugins/common.js';
|
|
4
|
-
|
|
5
3
|
import './preview.scss';
|
|
6
4
|
|
|
7
5
|
// px-vue common plugins
|
|
@@ -11,7 +9,6 @@ setup(app => {
|
|
|
11
9
|
|
|
12
10
|
const preview = {
|
|
13
11
|
parameters: {
|
|
14
|
-
//actions: { argTypesRegex: '^on[A-Z].*' },
|
|
15
12
|
controls: {
|
|
16
13
|
matchers: {
|
|
17
14
|
color: /(background|color)$/i,
|
|
@@ -20,26 +17,10 @@ const preview = {
|
|
|
20
17
|
},
|
|
21
18
|
},
|
|
22
19
|
order: ['Intro', 'Components'],
|
|
23
|
-
storySort: (a, b) =>
|
|
24
|
-
|
|
25
|
-
// theme
|
|
26
|
-
// darkMode: {
|
|
27
|
-
// // Override the default dark theme
|
|
28
|
-
// dark: { ...themes.dark, appBg: '#2A2C2E' },
|
|
29
|
-
// // Override the default light theme
|
|
30
|
-
// light: { ...themes.normal },
|
|
31
|
-
|
|
32
|
-
// darkClass: 'theme-dark',
|
|
33
|
-
// lightClass: 'theme-light',
|
|
34
|
-
// stylePreview: true,
|
|
35
|
-
// classTarget: 'body',
|
|
36
|
-
// },
|
|
37
|
-
|
|
38
|
-
docs: {
|
|
39
|
-
// requires import { themes } from '@storybook/theming';
|
|
40
|
-
// theme: themes.dark,
|
|
41
|
-
},
|
|
20
|
+
storySort: (a, b) => a.id === b.id ? 0 : a.id.localeCompare(b.id, undefined, { numeric: true }),
|
|
21
|
+
docs: { },
|
|
42
22
|
},
|
|
23
|
+
tags: ['autodocs']
|
|
43
24
|
};
|
|
44
25
|
|
|
45
26
|
export default preview;
|
package/.storybook/preview.scss
CHANGED
|
@@ -1,257 +1,3 @@
|
|
|
1
1
|
@use '../styles/px.scss' as *;
|
|
2
2
|
@use '@thinkpixellab-public/px-styles/src/modules/controls' as *;
|
|
3
|
-
|
|
4
|
-
@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600&family=Public+Sans:wght@300;400;500;600&family=Work+Sans:wght@400;600&display=swap');
|
|
5
|
-
|
|
6
|
-
@if get('is-fluent', false) {
|
|
7
|
-
@font-face {
|
|
8
|
-
font-family: segoe-vf;
|
|
9
|
-
font-weight: 100;
|
|
10
|
-
src:
|
|
11
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display-light.e452665.woff2)
|
|
12
|
-
format('woff2'),
|
|
13
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display-light.68c90c4.woff)
|
|
14
|
-
format('woff'),
|
|
15
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display-light.9d3d90d.ttf)
|
|
16
|
-
format('truetype');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
@font-face {
|
|
20
|
-
font-family: segoe-vf;
|
|
21
|
-
font-weight: 300;
|
|
22
|
-
src:
|
|
23
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display-semilight.1338e9a.woff2)
|
|
24
|
-
format('woff2'),
|
|
25
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display-semilight.9c37400.woff)
|
|
26
|
-
format('woff'),
|
|
27
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display-semilight.f65cf1c.ttf)
|
|
28
|
-
format('truetype');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@font-face {
|
|
32
|
-
font-family: segoe-vf;
|
|
33
|
-
font-weight: 400;
|
|
34
|
-
src:
|
|
35
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display.e85854a.woff2)
|
|
36
|
-
format('woff2'),
|
|
37
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display.f8bb08f.woff)
|
|
38
|
-
format('woff'),
|
|
39
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display.dc5de3f.ttf)
|
|
40
|
-
format('truetype');
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
@font-face {
|
|
44
|
-
font-family: segoe-vf;
|
|
45
|
-
font-weight: 600;
|
|
46
|
-
src:
|
|
47
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display-semibold.1977a17.woff2)
|
|
48
|
-
format('woff2'),
|
|
49
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display-semibold.3326bd2.woff)
|
|
50
|
-
format('woff'),
|
|
51
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display-semibold.0f5cc00.ttf)
|
|
52
|
-
format('truetype');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
@font-face {
|
|
56
|
-
font-family: segoe-vf;
|
|
57
|
-
font-weight: 700;
|
|
58
|
-
src:
|
|
59
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display-bold.2756fcb.woff2)
|
|
60
|
-
format('woff2'),
|
|
61
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display-bold.65cd9e3.woff)
|
|
62
|
-
format('woff'),
|
|
63
|
-
url(https://edgestatic.azureedge.net/shared/edgeweb/fonts/segoeui-vf-display-bold.4f8bd09.ttf)
|
|
64
|
-
format('truetype');
|
|
65
|
-
}
|
|
66
|
-
@include fluent-themes();
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// .sbdocs-h2,
|
|
70
|
-
// .sbdocs-h3,
|
|
71
|
-
// .sbdocs-h4,
|
|
72
|
-
// .sbdocs-h5,
|
|
73
|
-
// .sbdocs h1:where(:not(.sb-unstyled h1)),
|
|
74
|
-
// .sbdocs h2:where(:not(.sb-unstyled h2)),
|
|
75
|
-
// .sbdocs h3:where(:not(.sb-unstyled h3)),
|
|
76
|
-
// .sbdocs h4:where(:not(.sb-unstyled h4)),
|
|
77
|
-
// .sbdocs h5:where(:not(.sb-unstyled h5)),
|
|
78
|
-
// .sbdocs-title,
|
|
79
|
-
// .sbdocs-content p,
|
|
80
|
-
// .docblock-argstable,
|
|
81
|
-
// .docblock-argstable tr,
|
|
82
|
-
// .docblock-argstable th,
|
|
83
|
-
// .docblock-argstable td,
|
|
84
|
-
// .docblock-argstable td button {
|
|
85
|
-
// font-family: $font !important;
|
|
86
|
-
// }
|
|
87
|
-
|
|
88
|
-
// Update this to test font inheritance
|
|
89
|
-
.sbdocs {
|
|
90
|
-
font-family: sans-serif;
|
|
91
|
-
perspective: 6000px;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
body {
|
|
95
|
-
font-family: sans-serif;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
.story-flex {
|
|
99
|
-
display: flex;
|
|
100
|
-
gap: 1em;
|
|
101
|
-
justify-content: center;
|
|
102
|
-
align-items: center;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.story-flex-top {
|
|
106
|
-
display: flex;
|
|
107
|
-
gap: 1em;
|
|
108
|
-
justify-content: center;
|
|
109
|
-
align-items: flex-start;
|
|
110
|
-
}
|
|
111
|
-
.story-flex-vert {
|
|
112
|
-
display: flex;
|
|
113
|
-
gap: 1em;
|
|
114
|
-
justify-content: center;
|
|
115
|
-
align-items: center;
|
|
116
|
-
text-align: center;
|
|
117
|
-
flex-direction: column;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
.story-flex-bounds {
|
|
121
|
-
@extend .story-flex;
|
|
122
|
-
> * {
|
|
123
|
-
@extend .story-bounds;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
.story-bounds {
|
|
128
|
-
display: inline-block;
|
|
129
|
-
height: auto;
|
|
130
|
-
width: auto;
|
|
131
|
-
padding: 0;
|
|
132
|
-
margin: 0;
|
|
133
|
-
display: block;
|
|
134
|
-
border: 1px dashed rgba(black, 0.33);
|
|
135
|
-
perspective: 20em;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.story-square {
|
|
139
|
-
background-color: tomato;
|
|
140
|
-
width: 6em;
|
|
141
|
-
height: 6em;
|
|
142
|
-
border-radius: 0.5em;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
.story-circle {
|
|
146
|
-
background-color: tomato;
|
|
147
|
-
width: 6em;
|
|
148
|
-
height: 6em;
|
|
149
|
-
border-radius: 100%;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.story-orange {
|
|
153
|
-
background-color: tomato;
|
|
154
|
-
padding: 0.5em;
|
|
155
|
-
color: white;
|
|
156
|
-
border-radius: 0.5em;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
.story-fill {
|
|
160
|
-
background-color: tomato;
|
|
161
|
-
width: 100%;
|
|
162
|
-
height: 100%;
|
|
163
|
-
border-radius: 8px;
|
|
164
|
-
color: white;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
.story-center {
|
|
168
|
-
display: flex;
|
|
169
|
-
align-items: center;
|
|
170
|
-
justify-content: center;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
.story-aspect-16-9 {
|
|
174
|
-
background-color: tomato;
|
|
175
|
-
width: 100%;
|
|
176
|
-
border-radius: 8px;
|
|
177
|
-
aspect-ratio: 16/9;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.story-gradient {
|
|
181
|
-
background-image: repeating-linear-gradient(
|
|
182
|
-
-45deg,
|
|
183
|
-
rgba(black, 0.1) 0 20px,
|
|
184
|
-
rgba(black, 0) 20px 40px
|
|
185
|
-
),
|
|
186
|
-
linear-gradient(135deg, tomato, purple);
|
|
187
|
-
width: 100%;
|
|
188
|
-
height: 100%;
|
|
189
|
-
border-radius: 8px;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
.story-state-blue {
|
|
193
|
-
background-color: dodgerblue;
|
|
194
|
-
color: white;
|
|
195
|
-
width: 3em;
|
|
196
|
-
height: 3em;
|
|
197
|
-
border-radius: 8px;
|
|
198
|
-
padding: 1em;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
.story-state-orange {
|
|
202
|
-
background-color: tomato;
|
|
203
|
-
color: white;
|
|
204
|
-
width: 7em;
|
|
205
|
-
height: 7em;
|
|
206
|
-
border-radius: 8px;
|
|
207
|
-
padding: 1em;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
.story-size-xs {
|
|
211
|
-
width: 2em;
|
|
212
|
-
height: 2em;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
.story-size-sm {
|
|
216
|
-
width: 4em;
|
|
217
|
-
height: 4em;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
.story-size-base {
|
|
221
|
-
width: 6em;
|
|
222
|
-
height: 6em;
|
|
223
|
-
}
|
|
224
|
-
.story-size-md {
|
|
225
|
-
width: 8em;
|
|
226
|
-
height: 8em;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.story-popup {
|
|
230
|
-
font-family: sans-serif;
|
|
231
|
-
padding: 1em;
|
|
232
|
-
@include popup();
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
.story-tooltip {
|
|
236
|
-
@include popup(
|
|
237
|
-
(
|
|
238
|
-
font-family: sans-serif,
|
|
239
|
-
padding: 0.5em,
|
|
240
|
-
font-size: 14px,
|
|
241
|
-
background-color: mix(dodgerblue, white, 15%),
|
|
242
|
-
)
|
|
243
|
-
);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// icons
|
|
247
|
-
|
|
248
|
-
.story-inline-border {
|
|
249
|
-
display: inline-block;
|
|
250
|
-
border: 1px dotted tomato;
|
|
251
|
-
margin-inline: 0.25em;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
.theme-dark {
|
|
255
|
-
background-color: #151617;
|
|
256
|
-
color: white;
|
|
257
|
-
}
|
|
3
|
+
@use '../storybook/sb-styles.scss' as *;
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
<svg viewBox="0 0 24 24"
|
|
1
|
+
<svg viewBox="0 0 24 24">
|
|
2
|
+
<g transform="translate(4 11)" fill="currentColor" fill-rule="evenodd">
|
|
3
|
+
<circle cx="1.5" cy="1.5" r="1.5"/>
|
|
4
|
+
<circle cx="8" cy="1.5" r="1.5"/>
|
|
5
|
+
<circle cx="14.5" cy="1.5" r="1.5"/>
|
|
6
|
+
</g>
|
|
7
|
+
</svg>
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
<svg viewBox="0 0 24 24"
|
|
1
|
+
<svg viewBox="0 0 24 24">
|
|
2
|
+
<g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width="2">
|
|
3
|
+
<path d="M16.716 2.498a3.067 3.067 0 0 1 2.962-.793c1.059.283 2.654 1.878 2.937 2.937a3.067 3.067 0 0 1-.793 2.962l-4.152 4.152-.538-.537-9.72 9.72L1.6 22.72l1.78-5.811 9.721-9.721-.537-.538 4.152-4.152ZM11.315 5.402l7.526 7.526"/>
|
|
4
|
+
</g>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { PxIconSrcOrAttrs } from '../components/PxIcon.vue';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
props: {
|
|
6
|
+
/**
|
|
7
|
+
* The icon. If a string is provided, it will be interpreted as the src of the icon. If an
|
|
8
|
+
* object is provided, it will be passed directly to the icon component as props (with a
|
|
9
|
+
* filter applied to ensure no unused attributes get set on the element). See PxIcon for the
|
|
10
|
+
* full list of supported attributes.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
icon: { type: [String, Object], default: null },
|
|
14
|
+
},
|
|
15
|
+
computed: {
|
|
16
|
+
iconAttrs() {
|
|
17
|
+
return PxIconSrcOrAttrs(this.icon);
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
</script>
|
|
@@ -43,6 +43,7 @@ export default {
|
|
|
43
43
|
return {
|
|
44
44
|
selectedKeys: [],
|
|
45
45
|
baseUpdateMode: 'single',
|
|
46
|
+
isMounted: false,
|
|
46
47
|
};
|
|
47
48
|
},
|
|
48
49
|
|
|
@@ -122,7 +123,6 @@ export default {
|
|
|
122
123
|
if (nv != null) {
|
|
123
124
|
const name =
|
|
124
125
|
'bem' in this ? this.bem() : this.$options?.name || 'UnknownComponent';
|
|
125
|
-
console.log(`nv: ${nv}`);
|
|
126
126
|
console.error(
|
|
127
127
|
`[MIGRATION] PxBaseItemsSelect (${name}): v-model has syntax has changed. Please replace <${name} v-model="mySelection" /> with <${name} v-model:selected="mySelection" />.`,
|
|
128
128
|
);
|
|
@@ -158,11 +158,16 @@ export default {
|
|
|
158
158
|
},
|
|
159
159
|
|
|
160
160
|
mounted() {
|
|
161
|
+
this.isMounted = true;
|
|
161
162
|
this.$nextTick(() => {
|
|
162
163
|
this.tryAutoSelect();
|
|
163
164
|
});
|
|
164
165
|
},
|
|
165
166
|
|
|
167
|
+
unmounted() {
|
|
168
|
+
this.isMounted = false;
|
|
169
|
+
},
|
|
170
|
+
|
|
166
171
|
methods: {
|
|
167
172
|
tryAutoSelect() {
|
|
168
173
|
if (this.autoSelectFirst && isKeySetEmpty(this.selected) && this.items?.length) {
|
|
@@ -174,6 +179,10 @@ export default {
|
|
|
174
179
|
* Emit the change / update:selected event
|
|
175
180
|
*/
|
|
176
181
|
emitUpdateEvent() {
|
|
182
|
+
if (!this.isMounted) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
177
186
|
let updateArg;
|
|
178
187
|
|
|
179
188
|
if (this.updateMode == 'single') {
|
|
@@ -207,7 +207,8 @@ export default {
|
|
|
207
207
|
&__button {
|
|
208
208
|
position: relative;
|
|
209
209
|
align-self: center;
|
|
210
|
-
padding:
|
|
210
|
+
padding: 0;
|
|
211
|
+
height: 1.25em;
|
|
211
212
|
|
|
212
213
|
&--start {
|
|
213
214
|
grid-area: arrow-start;
|
|
@@ -242,6 +243,9 @@ export default {
|
|
|
242
243
|
padding-left: 0;
|
|
243
244
|
padding-right: 0;
|
|
244
245
|
}
|
|
246
|
+
|
|
247
|
+
min-height: 0.8em;
|
|
248
|
+
height: 100%;
|
|
245
249
|
}
|
|
246
250
|
}
|
|
247
251
|
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import tinycolor from 'tinycolor2';
|
|
3
|
+
import {
|
|
4
|
+
hsvaEnsureObject,
|
|
5
|
+
hsvaIsEqual,
|
|
6
|
+
hsvaToHsla,
|
|
7
|
+
hslaToStr,
|
|
8
|
+
hsvaContrastColor,
|
|
9
|
+
} from '../utils/color.js';
|
|
10
|
+
|
|
11
|
+
const TINY_FORMATS = ['rgb', 'prgb', 'hex6', 'hex3', 'hex8', 'name', 'hsl', 'hsv'];
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
name: 'px-color-picker',
|
|
15
|
+
|
|
16
|
+
props: {
|
|
17
|
+
/**
|
|
18
|
+
* The color value.
|
|
19
|
+
*/
|
|
20
|
+
color: { default: '#FF0000' },
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The format of the color value (used for emitting events, v-model, and the default format
|
|
24
|
+
* for getColor). Allowed values are the same as those available from the tinycolor library
|
|
25
|
+
* (rgb, prgb, hex6, hex3, hex8, name, hsl, hsv) as well as 'auto' (which will attempt to
|
|
26
|
+
* use the same format as the last value set with the color prop) and 'tiny' (which will
|
|
27
|
+
* return a tinycolor object) and 'hsva' which will return hsva values as an object. The
|
|
28
|
+
* format has the advantage of not requiring a tinycolor object to be created when the color
|
|
29
|
+
* changes.
|
|
30
|
+
*
|
|
31
|
+
* @values rgb, prgb, hex6, hex3, hex8, name, hsl, hsv, auto, tiny
|
|
32
|
+
*/
|
|
33
|
+
format: { type: String, default: 'hsva' },
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Whether alpha colors are enabled.
|
|
37
|
+
*/
|
|
38
|
+
alphaEnabled: { type: Boolean, default: false },
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
data() {
|
|
42
|
+
return { autoFormat: this.format, h: 0, s: 0, v: 0, a: 1 };
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
computed: {
|
|
46
|
+
hsva() {
|
|
47
|
+
return { h: this.h, s: this.s, v: this.v, a: this.alphaEnabled ? this.a : 1 };
|
|
48
|
+
},
|
|
49
|
+
hsla() {
|
|
50
|
+
return hsvaToHsla(this.hsva);
|
|
51
|
+
},
|
|
52
|
+
hslStr() {
|
|
53
|
+
return hslaToStr(this.hsla, false);
|
|
54
|
+
},
|
|
55
|
+
hslaStr() {
|
|
56
|
+
return hslaToStr(this.hsla, true);
|
|
57
|
+
},
|
|
58
|
+
hslaTransparentStr() {
|
|
59
|
+
return hslaToStr({ ...this.hsla, a: 0 }, true);
|
|
60
|
+
},
|
|
61
|
+
hueStr() {
|
|
62
|
+
return `hsl(${this.h}, 100%, 50%)`;
|
|
63
|
+
},
|
|
64
|
+
contrastStr() {
|
|
65
|
+
return hsvaContrastColor(this.hsva);
|
|
66
|
+
},
|
|
67
|
+
eyedropperSupported() {
|
|
68
|
+
return window?.EyeDropper;
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
watch: {
|
|
73
|
+
color(nv) {
|
|
74
|
+
// update colorValue when color changes
|
|
75
|
+
this.setColor(nv);
|
|
76
|
+
},
|
|
77
|
+
hsla() {
|
|
78
|
+
// emit change when this changes as a proxy for changes to hsva as individual props
|
|
79
|
+
this.emitChange();
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
mounted() {
|
|
84
|
+
if (this.color) {
|
|
85
|
+
this.setColor(this.color);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// TODO: default is hsva, but that isn't in the TINY_FORMATS list
|
|
89
|
+
// if (this.format) {
|
|
90
|
+
// if (!TINY_FORMATS.includes(this.format)) {
|
|
91
|
+
// console.warn(
|
|
92
|
+
// `[PxBaseColor] Invalid format: "${this.format}". See comments in PxBaseColor.vue`,
|
|
93
|
+
// );
|
|
94
|
+
// }
|
|
95
|
+
// }
|
|
96
|
+
},
|
|
97
|
+
methods: {
|
|
98
|
+
setColor(strOrHsva) {
|
|
99
|
+
if (typeof strOrHsva === 'string') {
|
|
100
|
+
this.setColorStr(strOrHsva);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (typeof strOrHsva === 'object') {
|
|
104
|
+
this.setColorHsva(strOrHsva);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
setColorStr(str) {
|
|
109
|
+
// this is for efficiency but also to prevent color creep as we convert between formats
|
|
110
|
+
if (this.lastEmit == str) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const tiny = tinycolor(str);
|
|
115
|
+
this.autoFormat = tiny.getFormat();
|
|
116
|
+
|
|
117
|
+
const hsva = tiny.toHsv();
|
|
118
|
+
this.setColorHsva(hsva);
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
setColorHsva(hsva) {
|
|
122
|
+
if (this.isCurrentHsva(hsva)) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this.h = hsva.h;
|
|
127
|
+
this.s = hsva.s;
|
|
128
|
+
this.v = hsva.v;
|
|
129
|
+
this.a = hsva.a;
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
emitChange() {
|
|
133
|
+
const clr = this.getColor(this.format);
|
|
134
|
+
|
|
135
|
+
this.lastEmit = clr;
|
|
136
|
+
|
|
137
|
+
this.$emit('update:color', clr);
|
|
138
|
+
this.$emit('change', clr);
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
getColor(format = null) {
|
|
142
|
+
format = format || this.format;
|
|
143
|
+
|
|
144
|
+
if (format == 'auto') {
|
|
145
|
+
format = this.autoFormat;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
let clr = { h: this.h, s: this.s, v: this.v, a: this.a };
|
|
149
|
+
|
|
150
|
+
if (format == 'hsva') {
|
|
151
|
+
return clr;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (format && [...TINY_FORMATS, 'tiny'].includes(format)) {
|
|
155
|
+
const tiny = tinycolor(clr);
|
|
156
|
+
|
|
157
|
+
if (format == 'tiny') {
|
|
158
|
+
clr = tiny;
|
|
159
|
+
} else {
|
|
160
|
+
clr = tiny.toString(format);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return clr;
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
colorStrToHsva(str) {
|
|
168
|
+
const tiny = tinycolor(str);
|
|
169
|
+
return tiny.toHsv();
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
isCurrentHsva(hOrObj, s, v, a) {
|
|
173
|
+
const hsvaCompare = hsvaEnsureObject(hOrObj, s, v, a);
|
|
174
|
+
return hsvaIsEqual(this.hsva, hsvaCompare);
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
setColorFromEyedropper() {
|
|
178
|
+
if (this.eyedropperSupported) {
|
|
179
|
+
const eyeDropper = new EyeDropper();
|
|
180
|
+
eyeDropper.open().then(result => {
|
|
181
|
+
this.setColorStr(result.sRGBHex);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
</script>
|
|
@@ -15,6 +15,13 @@
|
|
|
15
15
|
</template>
|
|
16
16
|
|
|
17
17
|
<script>
|
|
18
|
+
// Note: for Nuxt projects, the following nuxt.config.js setting may be necessary:
|
|
19
|
+
// vite: {
|
|
20
|
+
// optimizeDeps: {
|
|
21
|
+
// include: ['highlight.js'],
|
|
22
|
+
// }
|
|
23
|
+
// }
|
|
24
|
+
|
|
18
25
|
import hljs from 'highlight.js/lib/core';
|
|
19
26
|
import javascript from 'highlight.js/lib/languages/javascript';
|
|
20
27
|
import xml from 'highlight.js/lib/languages/xml';
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
</template>
|
|
24
24
|
|
|
25
25
|
<script>
|
|
26
|
-
import PxBaseColor from '
|
|
26
|
+
import PxBaseColor from './PxBaseColor.vue';
|
|
27
27
|
import tinycolor from 'tinycolor2';
|
|
28
28
|
import PxColorPaletteButton from './PxColorPaletteButton.vue';
|
|
29
|
-
import
|
|
29
|
+
import PxColorPicker from './PxColorPicker.vue';
|
|
30
30
|
|
|
31
31
|
export default {
|
|
32
32
|
name: 'px-color-palette',
|
|
@@ -36,7 +36,8 @@ export default {
|
|
|
36
36
|
/**
|
|
37
37
|
* Array of colors to display in the palette
|
|
38
38
|
*/
|
|
39
|
-
palette: { type: Array, default:
|
|
39
|
+
palette: { type: Array, default: () => [] },
|
|
40
|
+
paletteInitColor: { type: String, default: null },
|
|
40
41
|
|
|
41
42
|
// none | picker | eyedropper | eyedropper-only
|
|
42
43
|
pickerMode: { type: String, default: 'none' },
|
|
@@ -76,26 +77,32 @@ export default {
|
|
|
76
77
|
'eyedropper-only': 'eyedropper',
|
|
77
78
|
}[this.pickerMode];
|
|
78
79
|
|
|
79
|
-
return
|
|
80
|
+
return {
|
|
80
81
|
iconFallback,
|
|
81
82
|
eyedropperMode,
|
|
82
83
|
alphaEnabled: this.alphaEnabled,
|
|
83
84
|
...this.pickerAttrs,
|
|
84
|
-
}
|
|
85
|
+
};
|
|
85
86
|
},
|
|
86
87
|
showPicker() {
|
|
87
88
|
return this.pickerMode != 'none';
|
|
88
89
|
},
|
|
89
90
|
},
|
|
90
|
-
|
|
91
|
+
watch: {
|
|
92
|
+
paletteInitColor(val) {
|
|
93
|
+
this.setColorHsva(this.colorStrToHsva(val));
|
|
94
|
+
},
|
|
95
|
+
},
|
|
91
96
|
mounted() {},
|
|
92
97
|
methods: {
|
|
93
98
|
onPaletteClick(color) {
|
|
94
99
|
this.pickerActive = false;
|
|
95
100
|
this.setColorHsva(color.hsva);
|
|
101
|
+
this.$emit('paletteClick');
|
|
96
102
|
},
|
|
97
103
|
onPickerClick() {
|
|
98
104
|
this.pickerActive = true;
|
|
105
|
+
this.$emit('pickerClick');
|
|
99
106
|
},
|
|
100
107
|
onPickerChange(e) {
|
|
101
108
|
if (this.pickerActive) {
|