@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.
@@ -120,7 +120,7 @@ export default {
120
120
  }
121
121
 
122
122
  // fallback is 1:1
123
- return 16 / 9;
123
+ return 1 / 1;
124
124
  },
125
125
  calcHeight() {
126
126
  if (!this.size && this.svgHeight) {
@@ -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 {
@@ -252,7 +252,9 @@ export default {
252
252
  grid-area: 1 / 1;
253
253
  }
254
254
 
255
- @include transition(opacity, $dur: 100ms);
255
+ & {
256
+ @include transition(opacity, $dur: 100ms);
257
+ }
256
258
  }
257
259
 
258
260
  &--fitting & {
@@ -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
- // px-vue feather icons helper
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
- const vueApp = nuxtApp.vueApp;
38
-
39
- // search for icons in the @/assets/feather folder
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
 
@@ -127,7 +127,7 @@ export default {
127
127
  .px-icon-button {
128
128
  // VARIANTS
129
129
 
130
- @include control-reset();
130
+ @include controls.control-reset();
131
131
 
132
132
  &--default {
133
133
  @include controls.button-icon(
@@ -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: darken(accent(), 10%);
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
- gap: var(--px-toggle-button-gap);
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: color(select);
261
+ background-color: clr(select);
260
262
  box-shadow: none;
261
263
  &:hover {
262
- background-color: color(select);
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: color(accent, 0.15);
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.5",
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
+ });
@@ -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
- const getFeatherIcons = names => {
8
- const icons = Object.values(import.meta.globEager('../assets/feather/*.svg')).reduce(
9
- (obj, value) => {
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
- // filter if names is provided
14
- if ((names && names.includes(name)) || !names) {
15
- obj[name] = url;
16
- }
17
- return obj;
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 {functintion} filterFunction
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
  */