@pequity/squirrel 5.5.0 → 6.0.1

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.
@@ -12,7 +12,7 @@ import { P_ICON_ALIASES } from "../p-icon.js";
12
12
  * Licensed under MIT.
13
13
  *
14
14
  * @license MIT
15
- * @version 2.1.0
15
+ * @version 2.2.0
16
16
  */
17
17
  const defaultIconDimensions = Object.freeze(
18
18
  {
@@ -162,7 +162,9 @@ const validateIconName = (icon, allowSimpleName) => {
162
162
  if (!icon) {
163
163
  return false;
164
164
  }
165
- return !!((icon.provider === "" || icon.provider.match(matchIconName)) && (allowSimpleName && icon.prefix === "" || icon.prefix.match(matchIconName)) && icon.name.match(matchIconName));
165
+ return !!// Check prefix: cannot be empty, unless allowSimpleName is enabled
166
+ // Check name: cannot be empty
167
+ ((allowSimpleName && icon.prefix === "" || !!icon.prefix) && !!icon.name);
166
168
  };
167
169
  function mergeIconTransformations(obj1, obj2) {
168
170
  const result = {};
@@ -277,10 +279,15 @@ function quicklyValidateIconSet(obj) {
277
279
  const icons = data.icons;
278
280
  for (const name in icons) {
279
281
  const icon = icons[name];
280
- if (!name.match(matchIconName) || typeof icon.body !== "string" || !checkOptionalProps(
281
- icon,
282
- defaultExtendedIconProps
283
- )) {
282
+ if (
283
+ // Name cannot be empty
284
+ !name || // Must have body
285
+ typeof icon.body !== "string" || // Check other props
286
+ !checkOptionalProps(
287
+ icon,
288
+ defaultExtendedIconProps
289
+ )
290
+ ) {
284
291
  return null;
285
292
  }
286
293
  }
@@ -288,10 +295,15 @@ function quicklyValidateIconSet(obj) {
288
295
  for (const name in aliases) {
289
296
  const icon = aliases[name];
290
297
  const parent = icon.parent;
291
- if (!name.match(matchIconName) || typeof parent !== "string" || !icons[parent] && !aliases[parent] || !checkOptionalProps(
292
- icon,
293
- defaultExtendedIconProps
294
- )) {
298
+ if (
299
+ // Name cannot be empty
300
+ !name || // Parent must be set and point to existing icon
301
+ typeof parent !== "string" || !icons[parent] && !aliases[parent] || // Check other props
302
+ !checkOptionalProps(
303
+ icon,
304
+ defaultExtendedIconProps
305
+ )
306
+ ) {
295
307
  return null;
296
308
  }
297
309
  }
@@ -369,7 +381,12 @@ function addIcon$1(name, data) {
369
381
  return false;
370
382
  }
371
383
  const storage2 = getStorage(icon.provider, icon.prefix);
372
- return addIconToStorage(storage2, icon.name, data);
384
+ if (data) {
385
+ return addIconToStorage(storage2, icon.name, data);
386
+ } else {
387
+ storage2.missing.add(icon.name);
388
+ return true;
389
+ }
373
390
  }
374
391
  function addCollection$1(data, provider) {
375
392
  if (typeof data !== "object") {
@@ -383,7 +400,7 @@ function addCollection$1(data, provider) {
383
400
  if (quicklyValidateIconSet(data)) {
384
401
  data.prefix = "";
385
402
  parseIconSet(data, (name, icon) => {
386
- if (icon && addIcon$1(name, icon)) {
403
+ if (addIcon$1(name, icon)) {
387
404
  added = true;
388
405
  }
389
406
  });
@@ -409,7 +426,7 @@ function getIcon$1(name) {
409
426
  return result ? {
410
427
  ...defaultIconProps,
411
428
  ...result
412
- } : null;
429
+ } : result;
413
430
  }
414
431
  function sortIcons(icons) {
415
432
  const result = {
@@ -1069,6 +1086,57 @@ function loadedNewIcons(storage2) {
1069
1086
  });
1070
1087
  }
1071
1088
  }
1089
+ function checkIconNamesForAPI(icons) {
1090
+ const valid = [];
1091
+ const invalid = [];
1092
+ icons.forEach((name) => {
1093
+ (name.match(matchIconName) ? valid : invalid).push(name);
1094
+ });
1095
+ return {
1096
+ valid,
1097
+ invalid
1098
+ };
1099
+ }
1100
+ function parseLoaderResponse(storage2, icons, data, isAPIResponse) {
1101
+ function checkMissing() {
1102
+ const pending = storage2.pendingIcons;
1103
+ icons.forEach((name) => {
1104
+ if (pending) {
1105
+ pending.delete(name);
1106
+ }
1107
+ if (!storage2.icons[name]) {
1108
+ storage2.missing.add(name);
1109
+ }
1110
+ });
1111
+ }
1112
+ if (data && typeof data === "object") {
1113
+ try {
1114
+ const parsed = addIconSet(storage2, data);
1115
+ if (!parsed.length) {
1116
+ checkMissing();
1117
+ return;
1118
+ }
1119
+ if (isAPIResponse) {
1120
+ storeInBrowserStorage(storage2, data);
1121
+ }
1122
+ } catch (err) {
1123
+ console.error(err);
1124
+ }
1125
+ }
1126
+ checkMissing();
1127
+ loadedNewIcons(storage2);
1128
+ }
1129
+ function parsePossiblyAsyncResponse(response, callback) {
1130
+ if (response instanceof Promise) {
1131
+ response.then((data) => {
1132
+ callback(data);
1133
+ }).catch(() => {
1134
+ callback(null);
1135
+ });
1136
+ } else {
1137
+ callback(response);
1138
+ }
1139
+ }
1072
1140
  function loadNewIcons(storage2, icons) {
1073
1141
  if (!storage2.iconsToLoad) {
1074
1142
  storage2.iconsToLoad = icons;
@@ -1082,38 +1150,50 @@ function loadNewIcons(storage2, icons) {
1082
1150
  const { provider, prefix } = storage2;
1083
1151
  const icons2 = storage2.iconsToLoad;
1084
1152
  delete storage2.iconsToLoad;
1085
- let api;
1086
- if (!icons2 || !(api = getAPIModule(provider))) {
1153
+ if (!icons2 || !icons2.length) {
1154
+ return;
1155
+ }
1156
+ const customIconLoader = storage2.loadIcon;
1157
+ if (storage2.loadIcons && (icons2.length > 1 || !customIconLoader)) {
1158
+ parsePossiblyAsyncResponse(
1159
+ storage2.loadIcons(icons2, prefix, provider),
1160
+ (data) => {
1161
+ parseLoaderResponse(storage2, icons2, data, false);
1162
+ }
1163
+ );
1087
1164
  return;
1088
1165
  }
1089
- const params = api.prepare(provider, prefix, icons2);
1166
+ if (customIconLoader) {
1167
+ icons2.forEach((name) => {
1168
+ const response = customIconLoader(name, prefix, provider);
1169
+ parsePossiblyAsyncResponse(response, (data) => {
1170
+ const iconSet = data ? {
1171
+ prefix,
1172
+ icons: {
1173
+ [name]: data
1174
+ }
1175
+ } : null;
1176
+ parseLoaderResponse(storage2, [name], iconSet, false);
1177
+ });
1178
+ });
1179
+ return;
1180
+ }
1181
+ const { valid, invalid } = checkIconNamesForAPI(icons2);
1182
+ if (invalid.length) {
1183
+ parseLoaderResponse(storage2, invalid, null, false);
1184
+ }
1185
+ if (!valid.length) {
1186
+ return;
1187
+ }
1188
+ const api = prefix.match(matchIconName) ? getAPIModule(provider) : null;
1189
+ if (!api) {
1190
+ parseLoaderResponse(storage2, valid, null, false);
1191
+ return;
1192
+ }
1193
+ const params = api.prepare(provider, prefix, valid);
1090
1194
  params.forEach((item) => {
1091
1195
  sendAPIQuery(provider, item, (data) => {
1092
- if (typeof data !== "object") {
1093
- item.icons.forEach((name) => {
1094
- storage2.missing.add(name);
1095
- });
1096
- } else {
1097
- try {
1098
- const parsed = addIconSet(
1099
- storage2,
1100
- data
1101
- );
1102
- if (!parsed.length) {
1103
- return;
1104
- }
1105
- const pending = storage2.pendingIcons;
1106
- if (pending) {
1107
- parsed.forEach((name) => {
1108
- pending.delete(name);
1109
- });
1110
- }
1111
- storeInBrowserStorage(storage2, data);
1112
- } catch (err) {
1113
- console.error(err);
1114
- }
1115
- }
1116
- loadedNewIcons(storage2);
1196
+ parseLoaderResponse(storage2, item.icons, data, true);
1117
1197
  });
1118
1198
  });
1119
1199
  });
@@ -1166,9 +1246,9 @@ const loadIcons$1 = (icons, callback) => {
1166
1246
  }
1167
1247
  });
1168
1248
  sources.forEach((storage2) => {
1169
- const { provider, prefix } = storage2;
1170
- if (newIcons[provider][prefix].length) {
1171
- loadNewIcons(storage2, newIcons[provider][prefix]);
1249
+ const list = newIcons[storage2.provider][storage2.prefix];
1250
+ if (list.length) {
1251
+ loadNewIcons(storage2, list);
1172
1252
  }
1173
1253
  });
1174
1254
  return callback ? storeCallback(callback, sortedIcons, sources) : emptyCallback;
@@ -1207,12 +1287,31 @@ function testIconObject(value) {
1207
1287
  }
1208
1288
  }
1209
1289
  function parseIconValue(value, onload) {
1210
- const name = typeof value === "string" ? stringToIcon(value, true, true) : null;
1211
- if (!name) {
1290
+ if (typeof value === "object") {
1212
1291
  const data2 = testIconObject(value);
1213
1292
  return {
1214
- value,
1215
- data: data2
1293
+ data: data2,
1294
+ value
1295
+ };
1296
+ }
1297
+ if (typeof value !== "string") {
1298
+ return {
1299
+ value
1300
+ };
1301
+ }
1302
+ if (value.includes("{")) {
1303
+ const data2 = testIconObject(value);
1304
+ if (data2) {
1305
+ return {
1306
+ data: data2,
1307
+ value
1308
+ };
1309
+ }
1310
+ }
1311
+ const name = stringToIcon(value, true, true);
1312
+ if (!name) {
1313
+ return {
1314
+ value
1216
1315
  };
1217
1316
  }
1218
1317
  const data = getIconData(name);
@@ -1238,6 +1337,7 @@ try {
1238
1337
  }
1239
1338
  function getRenderMode(body, mode) {
1240
1339
  switch (mode) {
1340
+ // Force mode
1241
1341
  case "svg":
1242
1342
  case "bg":
1243
1343
  case "mask":
@@ -1577,6 +1677,12 @@ const fetchAPIModule = {
1577
1677
  prepare,
1578
1678
  send
1579
1679
  };
1680
+ function setCustomIconsLoader$1(loader, prefix, provider) {
1681
+ getStorage(provider || "", prefix).loadIcons = loader;
1682
+ }
1683
+ function setCustomIconLoader$1(loader, prefix, provider) {
1684
+ getStorage(provider || "", prefix).loadIcon = loader;
1685
+ }
1580
1686
  function toggleBrowserCache(storage2, value) {
1581
1687
  switch (storage2) {
1582
1688
  case "local":
@@ -1602,7 +1708,7 @@ function updateStyle(parent, inline) {
1602
1708
  styleNode.setAttribute(nodeAttr, nodeAttr);
1603
1709
  parent.appendChild(styleNode);
1604
1710
  }
1605
- styleNode.textContent = ":host{display:inline-block;vertical-align:" + (inline ? "-0.125em" : "0") + "}span,svg{display:block}" + customStyle;
1711
+ styleNode.textContent = ":host{display:inline-block;vertical-align:" + (inline ? "-0.125em" : "0") + "}span,svg{display:block;margin:auto}" + customStyle;
1606
1712
  }
1607
1713
  function exportFunctions() {
1608
1714
  setAPIModule("", fetchAPIModule);
@@ -1679,6 +1785,8 @@ function exportFunctions() {
1679
1785
  loadIcons: loadIcons$1,
1680
1786
  loadIcon: loadIcon$1,
1681
1787
  addAPIProvider: addAPIProvider$1,
1788
+ setCustomIconLoader: setCustomIconLoader$1,
1789
+ setCustomIconsLoader: setCustomIconsLoader$1,
1682
1790
  appendCustomStyle,
1683
1791
  _api
1684
1792
  };
@@ -13,6 +13,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
13
13
  activeClass: {},
14
14
  exactActiveClass: {},
15
15
  ariaCurrentValue: {},
16
+ viewTransition: { type: Boolean },
16
17
  to: {},
17
18
  replace: { type: Boolean }
18
19
  },
package/dist/es/config.js CHANGED
@@ -1,4 +1,4 @@
1
- const config = {
1
+ const squirrelTailwindConfig = {
2
2
  content: ["./index.html", "./squirrel/**/*.{vue,js,ts,jsx,tsx,mdx}", "./src/**/*.{vue,js,ts,jsx,tsx,mdx}"],
3
3
  theme: {
4
4
  colors: {
@@ -101,5 +101,5 @@ const config = {
101
101
  }
102
102
  };
103
103
  export {
104
- config
104
+ squirrelTailwindConfig
105
105
  };
package/dist/es/index.js CHANGED
@@ -54,7 +54,7 @@ import { default as default19 } from "./p-table-td.js";
54
54
  import { _ as _14 } from "./chunks/p-tabs.js";
55
55
  import { default as default20 } from "./p-textarea.js";
56
56
  import { default as default21 } from "./p-toggle.js";
57
- import { config } from "./config.js";
57
+ import { squirrelTailwindConfig } from "./config.js";
58
58
  import { CURRENCY_INPUT_DEFAULTS } from "./currency.js";
59
59
  import { getNextActiveElement, isElement, isVisible } from "./dom.js";
60
60
  import { default as default22 } from "./inputClassesMixin.js";
@@ -1016,7 +1016,6 @@ export {
1016
1016
  SPACING_SUFFIX,
1017
1017
  TEXTAREA_BASE,
1018
1018
  colsInjectionKey,
1019
- config,
1020
1019
  createPagingRange,
1021
1020
  getColor,
1022
1021
  getColorDeep,
@@ -1032,6 +1031,7 @@ export {
1032
1031
  sanitizeUrl,
1033
1032
  setupListKeyboardNavigation,
1034
1033
  splitStringForHighlight,
1034
+ squirrelTailwindConfig,
1035
1035
  toNumberOrNull,
1036
1036
  toString,
1037
1037
  useInputClasses,
@@ -1,9 +1,20 @@
1
1
  import { setupListKeyboardNavigation } from "./listKeyboardNavigation.js";
2
+ import { Dropdown } from "floating-vue";
2
3
  import { defineComponent, resolveComponent, openBlock, createBlock, mergeProps, createSlots, renderList, withCtx, renderSlot, normalizeProps, guardReactiveProps } from "vue";
3
4
  import { _ as _export_sfc } from "./chunks/_plugin-vue_export-helper.js";
4
5
  const ESCAPE_KEY = "Escape";
6
+ const nextFrame = () => {
7
+ return new Promise(
8
+ (resolve) => requestAnimationFrame(() => {
9
+ requestAnimationFrame(resolve);
10
+ })
11
+ );
12
+ };
5
13
  const _sfc_main = defineComponent({
6
14
  name: "PDropdown",
15
+ components: {
16
+ Dropdown
17
+ },
7
18
  inheritAttrs: false,
8
19
  props: {
9
20
  /**
@@ -30,49 +41,24 @@ const _sfc_main = defineComponent({
30
41
  default: () => ({
31
42
  display: "inline-block"
32
43
  })
33
- },
34
- /**
35
- * Custom reference element that is used to position the popper.
36
- * Can be changed at runtime to create a dynamically positioned dropdown.
37
- */
38
- reference: {
39
- type: HTMLElement,
40
- default: null
41
44
  }
42
45
  },
43
46
  data() {
44
47
  return {
45
48
  defaultAttrs: {
46
49
  triggers: ["click"],
47
- "auto-hide": true,
50
+ autoHide: true,
48
51
  theme: "p-dropdown-theme",
49
- "popper-class": "dropdown",
52
+ popperClass: "dropdown",
50
53
  placement: "bottom-start",
51
54
  distance: 4,
52
55
  delay: 0,
53
56
  handleResize: true
54
57
  },
55
- navigationSvc: null
58
+ navigationSvc: null,
59
+ prevReference: null
56
60
  };
57
61
  },
58
- watch: {
59
- reference: {
60
- async handler(nV, oV) {
61
- if (nV && oV !== nV) {
62
- const popper = this.$refs.vPopper.$refs.popper;
63
- if (popper) {
64
- popper.$_detachPopperNode();
65
- if (popper.shown) {
66
- popper.hide({ skipDelay: true });
67
- }
68
- if (this.reference) {
69
- popper.$_referenceNode = this.reference;
70
- }
71
- }
72
- }
73
- }
74
- }
75
- },
76
62
  mounted() {
77
63
  Object.assign(this.$refs.vPopper.$refs.popper.$el.style, this.triggerStyle);
78
64
  },
@@ -99,12 +85,32 @@ const _sfc_main = defineComponent({
99
85
  var _a;
100
86
  (_a = this.navigationSvc) == null ? void 0 : _a.destroy();
101
87
  document.removeEventListener("keydown", this.popoverEscKeydown);
88
+ },
89
+ async updateReference(newReference) {
90
+ if (!newReference) {
91
+ throw Error("Reference element is required");
92
+ }
93
+ const popper = this.$refs.vPopper.$refs.popper;
94
+ if (popper) {
95
+ popper.$_detachPopperNode();
96
+ if (popper.isShown) {
97
+ popper.$emit("update:shown", false);
98
+ if (newReference === this.prevReference) {
99
+ return;
100
+ }
101
+ }
102
+ await nextFrame();
103
+ popper.$_referenceNode = newReference;
104
+ this.prevReference = newReference;
105
+ await nextFrame();
106
+ popper.$emit("update:shown", true);
107
+ }
102
108
  }
103
109
  }
104
110
  });
105
111
  function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
106
- const _component_VDropdown = resolveComponent("VDropdown");
107
- return openBlock(), createBlock(_component_VDropdown, mergeProps({ ref: "vPopper" }, { ..._ctx.defaultAttrs, ..._ctx.$attrs }, {
112
+ const _component_Dropdown = resolveComponent("Dropdown");
113
+ return openBlock(), createBlock(_component_Dropdown, mergeProps({ ref: "vPopper" }, { ..._ctx.defaultAttrs, ..._ctx.$attrs }, {
108
114
  onShow: _ctx.onShow,
109
115
  onHide: _ctx.destroy
110
116
  }), createSlots({ _: 2 }, [
@@ -1,8 +1,8 @@
1
1
  var _a;
2
- import { config as config$1 } from "./config.js";
2
+ import { squirrelTailwindConfig } from "./config.js";
3
3
  import { get } from "lodash-es";
4
4
  import resolveConfig from "tailwindcss/resolveConfig";
5
- const config = resolveConfig(config$1);
5
+ const config = resolveConfig(squirrelTailwindConfig);
6
6
  const theme = config.theme;
7
7
  const colors = theme == null ? void 0 : theme.colors;
8
8
  (_a = theme == null ? void 0 : theme.extend) == null ? void 0 : _a.colors;