@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.
Files changed (85) hide show
  1. package/.storybook/main.js +2 -2
  2. package/.storybook/preview.js +3 -22
  3. package/.storybook/preview.scss +1 -255
  4. package/assets/icons/ellipsis.svg +7 -1
  5. package/assets/icons/eyedropper.svg +5 -1
  6. package/bases/PxBaseIconProp.vue +21 -0
  7. package/bases/PxBaseItemsSelect.vue +10 -1
  8. package/chromatic.config.json +5 -0
  9. package/components/PxArrowScroller.vue +5 -1
  10. package/components/PxBalancedText.vue +3 -0
  11. package/components/PxBaseColor.vue +187 -0
  12. package/components/PxCodeSample.vue +7 -0
  13. package/components/PxColorPalette.vue +13 -6
  14. package/components/PxColorPaletteButton.vue +0 -3
  15. package/components/PxColorPicker.vue +5 -0
  16. package/components/PxDropdown.vue +0 -3
  17. package/components/PxFloat.vue +16 -9
  18. package/components/PxIcon.vue +1 -1
  19. package/components/PxIconButton.vue +4 -2
  20. package/components/PxPivot.vue +7 -1
  21. package/components/PxQrCode.vue +1 -0
  22. package/components/PxToggleButton.vue +150 -57
  23. package/components/PxToggleButtonList.vue +1 -4
  24. package/package.json +78 -70
  25. package/stories/PxAnimate.stories.js +3 -3
  26. package/stories/PxArrow.stories.js +1 -1
  27. package/stories/PxArrowScroller.stories.js +3 -3
  28. package/stories/PxAspect.stories.js +3 -3
  29. package/stories/PxAutoClamp.stories.js +3 -3
  30. package/stories/PxBalancedText.stories.js +3 -3
  31. package/stories/PxButton.stories.js +3 -3
  32. package/stories/PxCalendar.stories.js +3 -3
  33. package/stories/PxCard.stories.js +3 -3
  34. package/stories/PxCardGrid.stories.js +4 -4
  35. package/stories/PxClock.stories.js +3 -3
  36. package/stories/PxCodeSample.stories.js +3 -3
  37. package/stories/PxColorPalette.stories.js +3 -3
  38. package/stories/PxColorPanel.stories.js +6 -20
  39. package/stories/PxColorPicker.stories.js +10 -13
  40. package/stories/PxContain.stories.js +3 -3
  41. package/stories/PxCopyText.stories.js +3 -3
  42. package/stories/PxDatePicker.stories.js +3 -3
  43. package/stories/PxDropdown.stories.js +4 -4
  44. package/stories/PxFit.stories.js +3 -3
  45. package/stories/PxFlex.stories.js +3 -3
  46. package/stories/PxFlip.stories.js +3 -3
  47. package/stories/PxFloat.stories.js +40 -3
  48. package/stories/PxGsapScrubber.stories.js +3 -3
  49. package/stories/PxIcon.stories.js +30 -39
  50. package/stories/PxIconButton.stories.js +3 -3
  51. package/stories/PxLabeledInput.stories.js +3 -3
  52. package/stories/PxMeasureContainer.stories.js +3 -3
  53. package/stories/PxMenu.stories.js +3 -3
  54. package/stories/PxPivot.stories.js +2 -2
  55. package/stories/PxPopupButton.stories.js +3 -3
  56. package/stories/PxProgressCircle.stories.js +3 -3
  57. package/stories/PxQrCode.stories.js +3 -3
  58. package/stories/PxRadioButton.stories.js +3 -3
  59. package/stories/PxResizer.stories.js +3 -3
  60. package/stories/PxScrubber.stories.js +3 -3
  61. package/stories/PxSideDrawer.stories.js +3 -3
  62. package/stories/PxSlides.stories.js +4 -4
  63. package/stories/PxSpinner.stories.js +3 -3
  64. package/stories/PxSticky.stories.js +3 -3
  65. package/stories/PxSvg.stories.js +3 -3
  66. package/stories/PxSvgRender.stories.js +3 -3
  67. package/stories/PxSyncHeight.stories.js +3 -3
  68. package/stories/PxTable.stories.js +4 -4
  69. package/stories/PxTextbox.stories.js +3 -3
  70. package/stories/PxToggle.stories.js +3 -3
  71. package/stories/PxToggleButton.stories.js +22 -3
  72. package/stories/PxToggleButtonList.stories.js +4 -4
  73. package/stories/PxTransition.stories.js +3 -3
  74. package/stories/PxTransitionExpand.stories.js +3 -3
  75. package/stories/PxTransitionItem.stories.js +3 -3
  76. package/stories/PxValidator.stories.js +3 -3
  77. package/stories/makestories.js +3 -3
  78. package/storybook/sb-styles.scss +174 -0
  79. package/{stories/helpers/extractArgTypes.js → storybook/sb-utils.js} +1 -1
  80. package/utils/SharedHeightManager.js +213 -0
  81. package/utils/propsFilter.js +3 -2
  82. package/utils/svgIcons.js +68 -12
  83. package/utils/textWidth.js +1 -1
  84. package/stories/helpers/scratch.vue +0 -30
  85. /package/{stories/helpers/sampleData.js → storybook/sb-sampledata.js} +0 -0
@@ -16,9 +16,9 @@ const config = {
16
16
  },
17
17
 
18
18
  docs: {
19
- autodocs: true,
20
- defaultName: 'Documentation',
19
+ defaultName: 'Documentation'
21
20
  },
21
+
22
22
  features: {
23
23
  interactionsDebugger: true,
24
24
  },
@@ -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
- a.id === b.id ? 0 : a.id.localeCompare(b.id, undefined, { numeric: true }),
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;
@@ -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"><g transform="translate(4 11)" fill="#000" fill-rule="evenodd"><circle cx="1.5" cy="1.5" r="1.5"/><circle cx="8" cy="1.5" r="1.5"/><circle cx="14.5" cy="1.5" r="1.5"/></g></svg>
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"><g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke="#000" stroke-width="2"><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"/></g></svg>
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') {
@@ -0,0 +1,5 @@
1
+ {
2
+ "onlyChanged": true,
3
+ "projectId": "Project:662fa9e7fdd6eadb4b9edb11",
4
+ "zip": true
5
+ }
@@ -207,7 +207,8 @@ export default {
207
207
  &__button {
208
208
  position: relative;
209
209
  align-self: center;
210
- padding: 1em 0.75em;
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
 
@@ -22,6 +22,9 @@
22
22
  {{ text }}
23
23
  </slot>
24
24
  </component>
25
+
26
+ <!-- after -->
27
+ <slot name="after"></slot>
25
28
  </component>
26
29
  </template>
27
30
 
@@ -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 '../bases/PxBaseColor.vue';
26
+ import PxBaseColor from './PxBaseColor.vue';
27
27
  import tinycolor from 'tinycolor2';
28
28
  import PxColorPaletteButton from './PxColorPaletteButton.vue';
29
- import { PxColorPicker, PxColorPickerPropsFilter } from './PxColorPicker.vue';
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: null },
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 PxColorPickerPropsFilter({
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
- // watch: {},
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) {