@thinkpixellab-public/px-vue 4.1.5 → 4.1.7
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/bases/PxBaseSvg.vue +1 -1
- package/components/PxColorPaletteButton.vue +2 -1
- package/components/PxFit.vue +3 -1
- package/components/PxIcon.vue +13 -25
- package/components/PxIconButton.vue +1 -1
- package/components/PxResizer.vue +2 -1
- package/components/PxToggleButton.vue +6 -4
- package/package.json +2 -1
- package/test/utils.test.js +46 -0
- package/utils/getFeatherIcons.js +11 -18
- package/utils/getIcons.js +28 -0
- package/utils/utils.js +33 -2
package/bases/PxBaseSvg.vue
CHANGED
|
@@ -36,6 +36,7 @@ export default {
|
|
|
36
36
|
</script>
|
|
37
37
|
|
|
38
38
|
<style lang="scss">
|
|
39
|
+
@use 'sass:string';
|
|
39
40
|
@use '../styles/px.scss' as *;
|
|
40
41
|
|
|
41
42
|
@function color-wheel-gradient($count, $blend: true, $sat: 100%, $light: 50%) {
|
|
@@ -53,7 +54,7 @@ export default {
|
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
@return unquote($grad);
|
|
57
|
+
@return string.unquote($grad);
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
.px-color-palette-button {
|
package/components/PxFit.vue
CHANGED
package/components/PxIcon.vue
CHANGED
|
@@ -30,41 +30,29 @@ PxVue contains the full set of [feather icons](https://feathericons.com/) and a
|
|
|
30
30
|
those available by name within the application. See the plugin reference below.
|
|
31
31
|
|
|
32
32
|
```js
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
// icons.js (add to plugins folder)
|
|
35
|
+
|
|
36
|
+
import { defineNuxtPlugin } from '#app';
|
|
37
|
+
import getIcons from '@thinkpixellab-public/px-vue/utils/getIcons.js';
|
|
34
38
|
import getFeatherIcons from '@thinkpixellab-public/px-vue/utils/getFeatherIcons.js';
|
|
35
39
|
|
|
36
40
|
export default defineNuxtPlugin(nuxtApp => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const icons = Object.values(
|
|
41
|
-
import.meta.globEager('@thinkpixellab-public/px-vue/assets/feather/*.svg')
|
|
42
|
-
).reduce((obj, value) => {
|
|
43
|
-
const url = value.default;
|
|
44
|
-
const name = url.match(/([^\/]+)(?=\.\w+$)/)[0];
|
|
45
|
-
obj[name] = url;
|
|
46
|
-
return obj;
|
|
47
|
-
}, {});
|
|
48
|
-
|
|
49
|
-
vueApp.provide('PxIcon.icons', {
|
|
50
|
-
// local icons
|
|
51
|
-
...icons,
|
|
52
|
-
|
|
53
|
-
// feather icons from px-vue
|
|
41
|
+
nuxtApp.vueApp?.provide('PxIcon.icons', {
|
|
42
|
+
|
|
43
|
+
// use getFeatherIcons to get a filtered map of px-vue feather icons
|
|
54
44
|
...getFeatherIcons([
|
|
55
|
-
'chevron-left',
|
|
56
|
-
'chevron-right',
|
|
57
|
-
'chevron-up',
|
|
58
|
-
'chevron-down',
|
|
59
45
|
'arrow-left',
|
|
60
46
|
'arrow-right',
|
|
61
|
-
'arrow-up',
|
|
62
|
-
'arrow-down',
|
|
63
|
-
'settings',
|
|
64
47
|
'folder',
|
|
65
48
|
]),
|
|
49
|
+
|
|
50
|
+
// use getIcons to get a map of custom icons
|
|
51
|
+
...getIcons(import.meta.glob('~/assets/icons/*.svg', { eager: true })),
|
|
66
52
|
});
|
|
67
53
|
});
|
|
54
|
+
|
|
55
|
+
|
|
68
56
|
```
|
|
69
57
|
*/
|
|
70
58
|
|
package/components/PxResizer.vue
CHANGED
|
@@ -141,6 +141,7 @@ export default {
|
|
|
141
141
|
|
|
142
142
|
<style lang="scss">
|
|
143
143
|
@use '../styles/px.scss' as *;
|
|
144
|
+
@use 'sass:color';
|
|
144
145
|
|
|
145
146
|
.px-resizer {
|
|
146
147
|
position: relative;
|
|
@@ -173,7 +174,7 @@ export default {
|
|
|
173
174
|
&__resize-y {
|
|
174
175
|
color: accent();
|
|
175
176
|
&:hover {
|
|
176
|
-
color:
|
|
177
|
+
color: color.adjust(accent(), $lightness: -10%);
|
|
177
178
|
}
|
|
178
179
|
&:active {
|
|
179
180
|
opacity: 0.5;
|
|
@@ -206,7 +206,9 @@ export default {
|
|
|
206
206
|
@include button();
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
|
|
209
|
+
& {
|
|
210
|
+
gap: var(--px-toggle-button-gap);
|
|
211
|
+
}
|
|
210
212
|
|
|
211
213
|
&__icon,
|
|
212
214
|
&__label {
|
|
@@ -256,17 +258,17 @@ export default {
|
|
|
256
258
|
|
|
257
259
|
// default checked state
|
|
258
260
|
&--checked.px-button--default:not(:disabled) {
|
|
259
|
-
background-color:
|
|
261
|
+
background-color: clr(select);
|
|
260
262
|
box-shadow: none;
|
|
261
263
|
&:hover {
|
|
262
|
-
background-color:
|
|
264
|
+
background-color: clr(select);
|
|
263
265
|
box-shadow: none;
|
|
264
266
|
}
|
|
265
267
|
}
|
|
266
268
|
|
|
267
269
|
// outline checked state
|
|
268
270
|
&--checked.px-button--outline:not(:disabled) {
|
|
269
|
-
background-color:
|
|
271
|
+
background-color: clr(accent, 0.15);
|
|
270
272
|
}
|
|
271
273
|
|
|
272
274
|
&--icon & {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thinkpixellab-public/px-vue",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.7",
|
|
4
4
|
"description": "General purpose Vue components and helpers that can be used across projects.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Pixel Lab"
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@babel/core": "^7.26.7",
|
|
43
43
|
"@chromatic-com/storybook": "^3.2.4",
|
|
44
|
+
"@nuxt/kit": "^3.15.4",
|
|
44
45
|
"@rushstack/eslint-patch": "^1.10.5",
|
|
45
46
|
"@storybook/addon-essentials": "^8.5.3",
|
|
46
47
|
"@storybook/addon-interactions": "^8.5.3",
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { objectToArray } from '../utils/utils.js';
|
|
2
|
+
|
|
3
|
+
test('objectToArray (defaults with value type value)', () => {
|
|
4
|
+
expect(objectToArray({ one: 1, two: 2, three: 3 })).toEqual([
|
|
5
|
+
{ key: 'one', value: 1 },
|
|
6
|
+
{ key: 'two', value: 2 },
|
|
7
|
+
{ key: 'three', value: 3 },
|
|
8
|
+
]);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('objectToArray (override naming params)', () => {
|
|
12
|
+
expect(objectToArray({ one: 1, two: 2, three: 3 }, 'id', 'number')).toEqual([
|
|
13
|
+
{ id: 'one', number: 1 },
|
|
14
|
+
{ id: 'two', number: 2 },
|
|
15
|
+
{ id: 'three', number: 3 },
|
|
16
|
+
]);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('objectToArray (defaults with object type value)', () => {
|
|
20
|
+
expect(objectToArray({ one: { number: 1 }, two: { number: 2 }, three: { number: 3 } })).toEqual(
|
|
21
|
+
[
|
|
22
|
+
{ key: 'one', value: { number: 1 } },
|
|
23
|
+
{ key: 'two', value: { number: 2 } },
|
|
24
|
+
{ key: 'three', value: { number: 3 } },
|
|
25
|
+
],
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('objectToArray (expand objects)', () => {
|
|
30
|
+
expect(
|
|
31
|
+
objectToArray(
|
|
32
|
+
{
|
|
33
|
+
one: { number: 1, ordinal: 'first' },
|
|
34
|
+
two: { number: 2, ordinal: 'second' },
|
|
35
|
+
three: { number: 3, ordinal: 'third' },
|
|
36
|
+
},
|
|
37
|
+
undefined,
|
|
38
|
+
undefined,
|
|
39
|
+
true,
|
|
40
|
+
),
|
|
41
|
+
).toEqual([
|
|
42
|
+
{ key: 'one', number: 1, ordinal: 'first' },
|
|
43
|
+
{ key: 'two', number: 2, ordinal: 'second' },
|
|
44
|
+
{ key: 'three', number: 3, ordinal: 'third' },
|
|
45
|
+
]);
|
|
46
|
+
});
|
package/utils/getFeatherIcons.js
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
|
+
import getIcons from './getIcons.js';
|
|
2
|
+
import { filterObjectByKeys } from './utils.js';
|
|
1
3
|
/**
|
|
2
4
|
* Returns an object enumerating feather icons that can be used with a PxIcons provide function to
|
|
3
5
|
* make feather icons available. If the names array non-null is provided, only icons with those
|
|
4
6
|
* names will be included.
|
|
5
7
|
*/
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const url = value.default;
|
|
11
|
-
const name = url.match(/([^\/]+)(?=\.\w+$)/)[0];
|
|
9
|
+
export default function getFeatherIcons(names) {
|
|
10
|
+
const importIcons = import.meta.glob('../assets/feather/*.svg', { eager: true });
|
|
11
|
+
const icons = getIcons(importIcons);
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
{}
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
return icons;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export default getFeatherIcons;
|
|
13
|
+
if (names && names.length) {
|
|
14
|
+
return filterObjectByKeys(icons, names);
|
|
15
|
+
} else {
|
|
16
|
+
return icons;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Processes a raw icon map (e.g. from import.meta.glob) and returns a formatted map.
|
|
3
|
+
*
|
|
4
|
+
* @param {object} iconsImport - The raw object returned by import.meta.glob.
|
|
5
|
+
* @returns {object} iconMap - An object mapping icon names to their corresponding modules.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // In your file (for example, in nuxt.config.js or another module processed by Vite):
|
|
9
|
+
* // Use a literal glob pattern to ensure Vite can statically analyze the files.
|
|
10
|
+
*
|
|
11
|
+
* import { getIcons } from './iconsUtil.js';
|
|
12
|
+
* const importIcons = import.meta.glob('~/assets/icons/*.svg', { eager: true });
|
|
13
|
+
* const icons = getIcons(importIcons);
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export default function getIcons(iconsImport) {
|
|
18
|
+
const iconMap = Object.fromEntries(
|
|
19
|
+
Object.entries(iconsImport).map(([path, module]) => {
|
|
20
|
+
const parts = path.split('/');
|
|
21
|
+
const fileName = parts[parts.length - 1];
|
|
22
|
+
const iconName = fileName.replace('.svg', '');
|
|
23
|
+
return [iconName, module.default || module];
|
|
24
|
+
}),
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
return iconMap;
|
|
28
|
+
}
|
package/utils/utils.js
CHANGED
|
@@ -204,11 +204,20 @@ export function arrayMoveItem(arr, fromIndex, toIndex) {
|
|
|
204
204
|
arr.splice(toIndex, 0, arr.splice(fromIndex, 1)[0]);
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
+
export function objectToArray(object, keyName = 'key', valueName = 'value', expandObjects = false) {
|
|
208
|
+
return Object.keys(object).map(key => {
|
|
209
|
+
if (expandObjects && typeof object[key] === 'object') {
|
|
210
|
+
return { [keyName]: key, ...object[key] };
|
|
211
|
+
}
|
|
212
|
+
return { [keyName]: key, [valueName]: object[key] };
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
207
216
|
/**
|
|
208
|
-
* Returns a version with only values that past the test defined in filterFunction.
|
|
217
|
+
* Returns a version of an object with only values that past the test defined in filterFunction.
|
|
209
218
|
*
|
|
210
219
|
* @param {object} obj
|
|
211
|
-
* @param {
|
|
220
|
+
* @param {function} filterFunction
|
|
212
221
|
* @return {object}
|
|
213
222
|
*/
|
|
214
223
|
export function filterObject(obj, filterFunction) {
|
|
@@ -220,6 +229,28 @@ export function filterObject(obj, filterFunction) {
|
|
|
220
229
|
}, {});
|
|
221
230
|
}
|
|
222
231
|
|
|
232
|
+
/**
|
|
233
|
+
* Filters an object to only include keys that are present in the allowedKeys array.
|
|
234
|
+
*
|
|
235
|
+
* @param {Object} obj - The object to filter.
|
|
236
|
+
* @param {string[]} allowedKeys - An array of keys that should be retained in the result.
|
|
237
|
+
* @returns {Object} A new object containing only the key/value pairs for keys in allowedKeys.
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* const data = { a: 1, b: 2, c: 3 };
|
|
241
|
+
* const result = filterObjectByKeys(data, ['a', 'c']);
|
|
242
|
+
* // result is { a: 1, c: 3 }
|
|
243
|
+
*/
|
|
244
|
+
|
|
245
|
+
export function filterObjectByKeys(obj, allowedKeys) {
|
|
246
|
+
return Object.keys(obj)
|
|
247
|
+
.filter(key => allowedKeys.includes(key))
|
|
248
|
+
.reduce((result, key) => {
|
|
249
|
+
result[key] = obj[key];
|
|
250
|
+
return result;
|
|
251
|
+
}, {});
|
|
252
|
+
}
|
|
253
|
+
|
|
223
254
|
/**
|
|
224
255
|
* Returns an object representing the current query string parameters.
|
|
225
256
|
*/
|