@bagelink/vue 0.0.1119 → 0.0.1121

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.
@@ -1,16 +1,16 @@
1
- declare global {
2
- interface Window {
3
- heic2any: any;
4
- }
5
- }
6
- type __VLS_Props = {
1
+ interface ImageProps {
7
2
  src?: string;
8
3
  pathKey?: string;
9
4
  alt?: string;
10
5
  width?: string | number;
11
6
  height?: string | number;
12
7
  caption?: string;
13
- };
14
- declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
8
+ }
9
+ declare global {
10
+ interface Window {
11
+ heic2any: any;
12
+ }
13
+ }
14
+ declare const _default: import('vue').DefineComponent<ImageProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<ImageProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
15
15
  export default _default;
16
16
  //# sourceMappingURL=Image.vue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Image.vue.d.ts","sourceRoot":"","sources":["../../src/components/Image.vue"],"names":[],"mappings":"AA6GA,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,MAAM;QACf,QAAQ,EAAE,GAAG,CAAA;KACb;CACD;AAED,KAAK,WAAW,GAAG;IAClB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB,CAAC;;AAwJF,wBAMG"}
1
+ {"version":3,"file":"Image.vue.d.ts","sourceRoot":"","sources":["../../src/components/Image.vue"],"names":[],"mappings":"AA+JA,UAAU,UAAU;IACnB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,MAAM;QACf,QAAQ,EAAE,GAAG,CAAA;KACb;CACD;;AAkMD,wBAMG"}
@@ -1 +1 @@
1
- {"version":3,"file":"EditorToolbar.vue.d.ts","sourceRoot":"","sources":["../../../../../../src/components/form/inputs/RichText/components/EditorToolbar.vue"],"names":[],"mappings":"AAAA,OAsDO,KAAK,EAAE,aAAa,EAAsC,MAAM,kBAAkB,CAAA;AAKzF,KAAK,WAAW,GAAG;IAClB,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC3B,CAAC;;;;;;AAmJF,wBAQG"}
1
+ {"version":3,"file":"EditorToolbar.vue.d.ts","sourceRoot":"","sources":["../../../../../../src/components/form/inputs/RichText/components/EditorToolbar.vue"],"names":[],"mappings":"AAAA,OAuDO,KAAK,EAAE,aAAa,EAAsC,MAAM,kBAAkB,CAAA;AAKzF,KAAK,WAAW,GAAG;IAClB,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC3B,CAAC;;;;;;AAqJF,wBAQG"}
package/dist/index.cjs CHANGED
@@ -21127,6 +21127,7 @@ const _sfc_main$z = /* @__PURE__ */ vue.defineComponent({
21127
21127
  flat: "",
21128
21128
  "aria-label": action.name,
21129
21129
  class: vue.normalizeClass([[action.class, { active: _ctx.selectedStyles.has(action.name) }], ""]),
21130
+ tabindex: "-1",
21130
21131
  onClick: ($event) => runAction(action.name)
21131
21132
  }, null, 8, ["icon", "aria-label", "class", "onClick"])), [
21132
21133
  [_directive_tooltip, action.label]
@@ -21140,7 +21141,7 @@ const _sfc_main$z = /* @__PURE__ */ vue.defineComponent({
21140
21141
  };
21141
21142
  }
21142
21143
  });
21143
- const EditorToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["__scopeId", "data-v-33dff8fa"]]);
21144
+ const EditorToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["__scopeId", "data-v-bcd681b9"]]);
21144
21145
  function createCommandExecutor(state2, commands) {
21145
21146
  return {
21146
21147
  execute(command, value) {
@@ -31400,65 +31401,82 @@ const _sfc_main$p = /* @__PURE__ */ vue.defineComponent({
31400
31401
  props: {
31401
31402
  src: {},
31402
31403
  pathKey: {},
31403
- alt: { default: "" },
31404
+ alt: {},
31404
31405
  width: {},
31405
31406
  height: {},
31406
31407
  caption: {}
31407
31408
  },
31408
31409
  setup(__props) {
31410
+ const props2 = __props;
31409
31411
  let imageSrc = vue.ref(null);
31410
- const fileBaseUrl = vue.computed(() => "https://files.bagel.design".replace(/\/$/, ""));
31411
- function pathToUrl() {
31412
+ let loadingError = vue.ref(false);
31413
+ const fileBaseUrl = vue.computed(() => "https://files.bagel.design");
31414
+ function getImageUrl() {
31412
31415
  var _a2;
31413
- if ((_a2 = __props.pathKey) == null ? void 0 : _a2.startsWith("static/")) return `${void 0}/${__props.pathKey}`;
31414
- return `${fileBaseUrl.value}/${__props.pathKey}`;
31416
+ if (!props2.src && !props2.pathKey) return null;
31417
+ if (props2.src) return props2.src;
31418
+ if ((_a2 = props2.pathKey) == null ? void 0 : _a2.startsWith("static/")) {
31419
+ return `${void 0}/${props2.pathKey}`;
31420
+ }
31421
+ return `${fileBaseUrl.value}/${props2.pathKey}`;
31422
+ }
31423
+ async function getCachedImage(url) {
31424
+ if (!("caches" in window)) return null;
31425
+ try {
31426
+ const imgCache = await window.caches.open("img-cache");
31427
+ const cachedResponse = await imgCache.match(url);
31428
+ if (cachedResponse) {
31429
+ return URL.createObjectURL(await cachedResponse.blob());
31430
+ }
31431
+ } catch (error) {
31432
+ console.warn("Cache access error:", error);
31433
+ }
31434
+ return null;
31435
+ }
31436
+ async function cacheImage(url, blob) {
31437
+ if (!("caches" in window)) return;
31438
+ try {
31439
+ const imgCache = await window.caches.open("img-cache");
31440
+ await imgCache.put(url, new Response(blob));
31441
+ } catch (error) {
31442
+ console.warn("Cache write error:", error);
31443
+ }
31444
+ }
31445
+ async function convertHeicImage(url) {
31446
+ await appendScript("https://cdnjs.cloudflare.com/ajax/libs/heic2any/0.0.1/index.min.js");
31447
+ const response = await fetch(normalizeURL(url));
31448
+ const blob = await response.blob();
31449
+ const convertedBlob = await window.heic2any({ blob });
31450
+ await cacheImage(url, convertedBlob);
31451
+ return URL.createObjectURL(convertedBlob);
31415
31452
  }
31416
31453
  async function loadImage() {
31417
31454
  var _a2;
31418
- const url = __props.src || pathToUrl();
31419
- console.log(url);
31455
+ loadingError.value = false;
31456
+ const url = getImageUrl();
31420
31457
  if (!url) {
31421
31458
  imageSrc.value = null;
31422
31459
  return;
31423
31460
  }
31424
- const ext = (_a2 = url.split(".").pop()) == null ? void 0 : _a2.toLowerCase().split("?").shift();
31425
- if (ext === "heic") {
31426
- if (!("caches" in window)) {
31427
- console.warn("Caching is not available. Proceeding without cache.");
31428
- } else {
31429
- try {
31430
- const imgCache = await window.caches.open("img-cache");
31431
- const cachedResponse = await imgCache.match(url);
31432
- if (cachedResponse) {
31433
- imageSrc.value = URL.createObjectURL(await cachedResponse.blob());
31434
- return;
31435
- }
31436
- } catch (error) {
31437
- console.warn("Error accessing cache:", error);
31438
- }
31439
- }
31440
- try {
31441
- await appendScript("https://cdnjs.cloudflare.com/ajax/libs/heic2any/0.0.1/index.min.js");
31442
- const response = await fetch(normalizeURL(url));
31443
- const blob = await response.blob();
31444
- const convertedBlob = await window.heic2any({ blob });
31445
- imageSrc.value = URL.createObjectURL(convertedBlob);
31446
- if ("caches" in window) {
31447
- try {
31448
- const imgCache = await window.caches.open("img-cache");
31449
- imgCache.put(url, new Response(convertedBlob));
31450
- } catch (cacheError) {
31451
- console.warn("Failed to cache the image:", cacheError);
31452
- }
31461
+ try {
31462
+ const ext = (_a2 = url.split(".").pop()) == null ? void 0 : _a2.toLowerCase().split("?")[0];
31463
+ if (ext === "heic") {
31464
+ const cachedSrc = await getCachedImage(url);
31465
+ if (cachedSrc) {
31466
+ imageSrc.value = cachedSrc;
31467
+ return;
31453
31468
  }
31454
- } catch (error) {
31455
- console.error("Error converting HEIC file:", error);
31469
+ imageSrc.value = await convertHeicImage(url);
31470
+ } else {
31471
+ imageSrc.value = url;
31456
31472
  }
31457
- } else {
31458
- imageSrc.value = url;
31473
+ } catch (error) {
31474
+ console.error("Image loading error:", error);
31475
+ loadingError.value = true;
31476
+ imageSrc.value = null;
31459
31477
  }
31460
31478
  }
31461
- vue.watch(() => [__props.src, __props.pathKey], loadImage, { immediate: true });
31479
+ vue.watch(() => [props2.src, props2.pathKey], loadImage, { immediate: true });
31462
31480
  return (_ctx, _cache) => {
31463
31481
  return _ctx.caption ? (vue.openBlock(), vue.createElementBlock("figcaption", _hoisted_1$h, [
31464
31482
  vue.unref(imageSrc) ? (vue.openBlock(), vue.createElementBlock("img", vue.mergeProps({
@@ -31481,8 +31499,17 @@ const _sfc_main$p = /* @__PURE__ */ vue.defineComponent({
31481
31499
  alt: _ctx.alt,
31482
31500
  width: vue.unref(normalizeDimension)(_ctx.width),
31483
31501
  height: vue.unref(normalizeDimension)(_ctx.height)
31484
- }), null, 16, _hoisted_3$7)) : (vue.openBlock(), vue.createBlock(vue.unref(Skeleton), {
31502
+ }), null, 16, _hoisted_3$7)) : vue.unref(loadingError) ? (vue.openBlock(), vue.createElementBlock("div", {
31485
31503
  key: 2,
31504
+ class: "flex-center error-image",
31505
+ style: vue.normalizeStyle({
31506
+ width: vue.unref(normalizeDimension)(_ctx.width),
31507
+ height: vue.unref(normalizeDimension)(_ctx.height)
31508
+ })
31509
+ }, [
31510
+ vue.createVNode(vue.unref(_sfc_main$d), { name: "broken_image" })
31511
+ ], 4)) : (vue.openBlock(), vue.createBlock(vue.unref(Skeleton), {
31512
+ key: 3,
31486
31513
  class: "img-web-kit",
31487
31514
  width: vue.unref(normalizeDimension)(_ctx.width),
31488
31515
  height: vue.unref(normalizeDimension)(_ctx.height)
@@ -31490,7 +31517,7 @@ const _sfc_main$p = /* @__PURE__ */ vue.defineComponent({
31490
31517
  };
31491
31518
  }
31492
31519
  });
31493
- const Image$1 = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["__scopeId", "data-v-1b7f9bb3"]]);
31520
+ const Image$1 = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["__scopeId", "data-v-6f277b5b"]]);
31494
31521
  const _hoisted_1$g = { class: "m-0 pb-025 txt14 line-height-1 w60 menu-text" };
31495
31522
  const _sfc_main$o = /* @__PURE__ */ vue.defineComponent({
31496
31523
  __name: "BottomMenu",
@@ -32644,6 +32671,7 @@ function debounceFilter(ms, options = {}) {
32644
32671
  lastRejector();
32645
32672
  lastRejector = noop;
32646
32673
  };
32674
+ let lastInvoker;
32647
32675
  const filter3 = (invoke) => {
32648
32676
  const duration = vue.toValue(ms);
32649
32677
  const maxDuration = vue.toValue(options.maxWait);
@@ -32658,12 +32686,13 @@ function debounceFilter(ms, options = {}) {
32658
32686
  }
32659
32687
  return new Promise((resolve, reject3) => {
32660
32688
  lastRejector = options.rejectOnCancel ? reject3 : resolve;
32689
+ lastInvoker = invoke;
32661
32690
  if (maxDuration && !maxTimer) {
32662
32691
  maxTimer = setTimeout(() => {
32663
32692
  if (timer)
32664
32693
  _clearTimeout(timer);
32665
32694
  maxTimer = null;
32666
- resolve(invoke());
32695
+ resolve(lastInvoker());
32667
32696
  }, maxDuration);
32668
32697
  }
32669
32698
  timer = setTimeout(() => {
package/dist/index.mjs CHANGED
@@ -21125,6 +21125,7 @@ const _sfc_main$z = /* @__PURE__ */ defineComponent({
21125
21125
  flat: "",
21126
21126
  "aria-label": action.name,
21127
21127
  class: normalizeClass([[action.class, { active: _ctx.selectedStyles.has(action.name) }], ""]),
21128
+ tabindex: "-1",
21128
21129
  onClick: ($event) => runAction(action.name)
21129
21130
  }, null, 8, ["icon", "aria-label", "class", "onClick"])), [
21130
21131
  [_directive_tooltip, action.label]
@@ -21138,7 +21139,7 @@ const _sfc_main$z = /* @__PURE__ */ defineComponent({
21138
21139
  };
21139
21140
  }
21140
21141
  });
21141
- const EditorToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["__scopeId", "data-v-33dff8fa"]]);
21142
+ const EditorToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["__scopeId", "data-v-bcd681b9"]]);
21142
21143
  function createCommandExecutor(state2, commands) {
21143
21144
  return {
21144
21145
  execute(command, value) {
@@ -31398,65 +31399,82 @@ const _sfc_main$p = /* @__PURE__ */ defineComponent({
31398
31399
  props: {
31399
31400
  src: {},
31400
31401
  pathKey: {},
31401
- alt: { default: "" },
31402
+ alt: {},
31402
31403
  width: {},
31403
31404
  height: {},
31404
31405
  caption: {}
31405
31406
  },
31406
31407
  setup(__props) {
31408
+ const props2 = __props;
31407
31409
  let imageSrc = ref(null);
31408
- const fileBaseUrl = computed(() => "https://files.bagel.design".replace(/\/$/, ""));
31409
- function pathToUrl() {
31410
+ let loadingError = ref(false);
31411
+ const fileBaseUrl = computed(() => "https://files.bagel.design");
31412
+ function getImageUrl() {
31410
31413
  var _a2;
31411
- if ((_a2 = __props.pathKey) == null ? void 0 : _a2.startsWith("static/")) return `${void 0}/${__props.pathKey}`;
31412
- return `${fileBaseUrl.value}/${__props.pathKey}`;
31414
+ if (!props2.src && !props2.pathKey) return null;
31415
+ if (props2.src) return props2.src;
31416
+ if ((_a2 = props2.pathKey) == null ? void 0 : _a2.startsWith("static/")) {
31417
+ return `${void 0}/${props2.pathKey}`;
31418
+ }
31419
+ return `${fileBaseUrl.value}/${props2.pathKey}`;
31420
+ }
31421
+ async function getCachedImage(url) {
31422
+ if (!("caches" in window)) return null;
31423
+ try {
31424
+ const imgCache = await window.caches.open("img-cache");
31425
+ const cachedResponse = await imgCache.match(url);
31426
+ if (cachedResponse) {
31427
+ return URL.createObjectURL(await cachedResponse.blob());
31428
+ }
31429
+ } catch (error) {
31430
+ console.warn("Cache access error:", error);
31431
+ }
31432
+ return null;
31433
+ }
31434
+ async function cacheImage(url, blob) {
31435
+ if (!("caches" in window)) return;
31436
+ try {
31437
+ const imgCache = await window.caches.open("img-cache");
31438
+ await imgCache.put(url, new Response(blob));
31439
+ } catch (error) {
31440
+ console.warn("Cache write error:", error);
31441
+ }
31442
+ }
31443
+ async function convertHeicImage(url) {
31444
+ await appendScript("https://cdnjs.cloudflare.com/ajax/libs/heic2any/0.0.1/index.min.js");
31445
+ const response = await fetch(normalizeURL(url));
31446
+ const blob = await response.blob();
31447
+ const convertedBlob = await window.heic2any({ blob });
31448
+ await cacheImage(url, convertedBlob);
31449
+ return URL.createObjectURL(convertedBlob);
31413
31450
  }
31414
31451
  async function loadImage() {
31415
31452
  var _a2;
31416
- const url = __props.src || pathToUrl();
31417
- console.log(url);
31453
+ loadingError.value = false;
31454
+ const url = getImageUrl();
31418
31455
  if (!url) {
31419
31456
  imageSrc.value = null;
31420
31457
  return;
31421
31458
  }
31422
- const ext = (_a2 = url.split(".").pop()) == null ? void 0 : _a2.toLowerCase().split("?").shift();
31423
- if (ext === "heic") {
31424
- if (!("caches" in window)) {
31425
- console.warn("Caching is not available. Proceeding without cache.");
31426
- } else {
31427
- try {
31428
- const imgCache = await window.caches.open("img-cache");
31429
- const cachedResponse = await imgCache.match(url);
31430
- if (cachedResponse) {
31431
- imageSrc.value = URL.createObjectURL(await cachedResponse.blob());
31432
- return;
31433
- }
31434
- } catch (error) {
31435
- console.warn("Error accessing cache:", error);
31436
- }
31437
- }
31438
- try {
31439
- await appendScript("https://cdnjs.cloudflare.com/ajax/libs/heic2any/0.0.1/index.min.js");
31440
- const response = await fetch(normalizeURL(url));
31441
- const blob = await response.blob();
31442
- const convertedBlob = await window.heic2any({ blob });
31443
- imageSrc.value = URL.createObjectURL(convertedBlob);
31444
- if ("caches" in window) {
31445
- try {
31446
- const imgCache = await window.caches.open("img-cache");
31447
- imgCache.put(url, new Response(convertedBlob));
31448
- } catch (cacheError) {
31449
- console.warn("Failed to cache the image:", cacheError);
31450
- }
31459
+ try {
31460
+ const ext = (_a2 = url.split(".").pop()) == null ? void 0 : _a2.toLowerCase().split("?")[0];
31461
+ if (ext === "heic") {
31462
+ const cachedSrc = await getCachedImage(url);
31463
+ if (cachedSrc) {
31464
+ imageSrc.value = cachedSrc;
31465
+ return;
31451
31466
  }
31452
- } catch (error) {
31453
- console.error("Error converting HEIC file:", error);
31467
+ imageSrc.value = await convertHeicImage(url);
31468
+ } else {
31469
+ imageSrc.value = url;
31454
31470
  }
31455
- } else {
31456
- imageSrc.value = url;
31471
+ } catch (error) {
31472
+ console.error("Image loading error:", error);
31473
+ loadingError.value = true;
31474
+ imageSrc.value = null;
31457
31475
  }
31458
31476
  }
31459
- watch(() => [__props.src, __props.pathKey], loadImage, { immediate: true });
31477
+ watch(() => [props2.src, props2.pathKey], loadImage, { immediate: true });
31460
31478
  return (_ctx, _cache) => {
31461
31479
  return _ctx.caption ? (openBlock(), createElementBlock("figcaption", _hoisted_1$h, [
31462
31480
  unref(imageSrc) ? (openBlock(), createElementBlock("img", mergeProps({
@@ -31479,8 +31497,17 @@ const _sfc_main$p = /* @__PURE__ */ defineComponent({
31479
31497
  alt: _ctx.alt,
31480
31498
  width: unref(normalizeDimension)(_ctx.width),
31481
31499
  height: unref(normalizeDimension)(_ctx.height)
31482
- }), null, 16, _hoisted_3$7)) : (openBlock(), createBlock(unref(Skeleton), {
31500
+ }), null, 16, _hoisted_3$7)) : unref(loadingError) ? (openBlock(), createElementBlock("div", {
31483
31501
  key: 2,
31502
+ class: "flex-center error-image",
31503
+ style: normalizeStyle({
31504
+ width: unref(normalizeDimension)(_ctx.width),
31505
+ height: unref(normalizeDimension)(_ctx.height)
31506
+ })
31507
+ }, [
31508
+ createVNode(unref(_sfc_main$d), { name: "broken_image" })
31509
+ ], 4)) : (openBlock(), createBlock(unref(Skeleton), {
31510
+ key: 3,
31484
31511
  class: "img-web-kit",
31485
31512
  width: unref(normalizeDimension)(_ctx.width),
31486
31513
  height: unref(normalizeDimension)(_ctx.height)
@@ -31488,7 +31515,7 @@ const _sfc_main$p = /* @__PURE__ */ defineComponent({
31488
31515
  };
31489
31516
  }
31490
31517
  });
31491
- const Image$1 = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["__scopeId", "data-v-1b7f9bb3"]]);
31518
+ const Image$1 = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["__scopeId", "data-v-6f277b5b"]]);
31492
31519
  const _hoisted_1$g = { class: "m-0 pb-025 txt14 line-height-1 w60 menu-text" };
31493
31520
  const _sfc_main$o = /* @__PURE__ */ defineComponent({
31494
31521
  __name: "BottomMenu",
@@ -32642,6 +32669,7 @@ function debounceFilter(ms, options = {}) {
32642
32669
  lastRejector();
32643
32670
  lastRejector = noop;
32644
32671
  };
32672
+ let lastInvoker;
32645
32673
  const filter3 = (invoke) => {
32646
32674
  const duration = toValue(ms);
32647
32675
  const maxDuration = toValue(options.maxWait);
@@ -32656,12 +32684,13 @@ function debounceFilter(ms, options = {}) {
32656
32684
  }
32657
32685
  return new Promise((resolve, reject3) => {
32658
32686
  lastRejector = options.rejectOnCancel ? reject3 : resolve;
32687
+ lastInvoker = invoke;
32659
32688
  if (maxDuration && !maxTimer) {
32660
32689
  maxTimer = setTimeout(() => {
32661
32690
  if (timer)
32662
32691
  _clearTimeout(timer);
32663
32692
  maxTimer = null;
32664
- resolve(invoke());
32693
+ resolve(lastInvoker());
32665
32694
  }, maxDuration);
32666
32695
  }
32667
32696
  timer = setTimeout(() => {
package/dist/style.css CHANGED
@@ -1435,7 +1435,7 @@ input[type="range"][data-v-25d991e5]:active::-webkit-slider-thumb {
1435
1435
  background: var(--bgl-primary-light);
1436
1436
  }
1437
1437
 
1438
- .toolbar[data-v-33dff8fa] .active {
1438
+ .toolbar[data-v-bcd681b9] .active {
1439
1439
  background: var(--bgl-primary);
1440
1440
  color: white;
1441
1441
  }
@@ -2123,12 +2123,15 @@ line-height: 1.65;
2123
2123
  color: var(--bgl-green);
2124
2124
  }
2125
2125
 
2126
- .img-web-kit[data-v-1b7f9bb3] {
2126
+ .img-web-kit[data-v-6f277b5b] {
2127
2127
  max-width: 100%;
2128
2128
  vertical-align: middle;
2129
2129
  border: 0;
2130
2130
  width: 100%;
2131
2131
  }
2132
+ .error-image[data-v-6f277b5b] {
2133
+ background-color: var(--skeleton-bg);
2134
+ }
2132
2135
 
2133
2136
  .bgl_bottombar .bgl_btn-flex{
2134
2137
  flex-direction: column;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "0.0.1119",
4
+ "version": "0.0.1121",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Neveh Allon",
@@ -1,83 +1,112 @@
1
1
  <script setup lang="ts">
2
- import { Skeleton, normalizeDimension, appendScript, normalizeURL } from '@bagelink/vue'
3
- import { watch } from 'vue'
2
+ import { Skeleton, normalizeDimension, appendScript, normalizeURL, Icon } from '@bagelink/vue'
3
+ import { watch, computed } from 'vue'
4
4
 
5
- declare global {
6
- interface Window {
7
- heic2any: any
8
- }
9
- }
10
-
11
- const { height, width, alt = '', src, pathKey } = defineProps<{
5
+ interface ImageProps {
12
6
  src?: string
13
7
  pathKey?: string
14
8
  alt?: string
15
9
  width?: string | number
16
10
  height?: string | number
17
11
  caption?: string
18
- }>()
12
+ }
13
+
14
+ declare global {
15
+ interface Window {
16
+ heic2any: any
17
+ }
18
+ }
19
+
20
+ const props = defineProps<ImageProps>()
19
21
 
20
22
  let imageSrc = $ref<string | null>(null)
23
+ let loadingError = $ref(false)
21
24
 
22
- const fileBaseUrl = $computed(() => ('https://files.bagel.design').replace(/\/$/, ''))
23
- function pathToUrl() {
24
- if (pathKey?.startsWith('static/')) return `${import.meta.env.VITE_BAGEL_BASE_URL}/${pathKey}`
25
+ const fileBaseUrl = computed(() => 'https://files.bagel.design')
25
26
 
26
- return `${fileBaseUrl}/${pathKey}`
27
+ function getImageUrl(): string | null {
28
+ if (!props.src && !props.pathKey) return null
29
+ if (props.src) return props.src
30
+ if (props.pathKey?.startsWith('static/')) {
31
+ return `${import.meta.env.VITE_BAGEL_BASE_URL}/${props.pathKey}`
32
+ }
33
+ return `${fileBaseUrl.value}/${props.pathKey}`
34
+ }
35
+
36
+ async function getCachedImage(url: string): Promise<string | null> {
37
+ if (!('caches' in window)) return null
38
+ try {
39
+ const imgCache = await window.caches.open('img-cache')
40
+ const cachedResponse = await imgCache.match(url)
41
+ if (cachedResponse) {
42
+ return URL.createObjectURL(await cachedResponse.blob())
43
+ }
44
+ } catch (error) {
45
+ console.warn('Cache access error:', error)
46
+ }
47
+ return null
48
+ }
49
+
50
+ async function cacheImage(url: string, blob: Blob) {
51
+ if (!('caches' in window)) return
52
+ try {
53
+ const imgCache = await window.caches.open('img-cache')
54
+ await imgCache.put(url, new Response(blob))
55
+ } catch (error) {
56
+ console.warn('Cache write error:', error)
57
+ }
58
+ }
59
+
60
+ async function convertHeicImage(url: string): Promise<string> {
61
+ await appendScript('https://cdnjs.cloudflare.com/ajax/libs/heic2any/0.0.1/index.min.js')
62
+ const response = await fetch(normalizeURL(url))
63
+ const blob = await response.blob()
64
+ const convertedBlob = await window.heic2any({ blob }) as Blob
65
+ await cacheImage(url, convertedBlob)
66
+ return URL.createObjectURL(convertedBlob)
27
67
  }
28
68
 
29
69
  async function loadImage() {
30
- const url = src || pathToUrl()
31
- console.log(url)
70
+ loadingError = false
71
+ const url = getImageUrl()
32
72
  if (!url) {
33
73
  imageSrc = null
34
74
  return
35
75
  }
36
- const ext = url.split('.').pop()?.toLowerCase().split('?').shift()
37
76
 
38
- if (ext === 'heic') {
39
- if (!('caches' in window)) {
40
- console.warn('Caching is not available. Proceeding without cache.')
41
- } else {
42
- try {
43
- const imgCache = await window.caches.open('img-cache')
44
- const cachedResponse = await imgCache.match(url)
45
- if (cachedResponse) {
46
- imageSrc = URL.createObjectURL(await cachedResponse.blob())
47
- return
48
- }
49
- } catch (error) {
50
- console.warn('Error accessing cache:', error)
51
- }
52
- }
53
- try {
54
- await appendScript('https://cdnjs.cloudflare.com/ajax/libs/heic2any/0.0.1/index.min.js')
55
- const response = await fetch(normalizeURL(url))
56
- const blob = await response.blob()
57
- const convertedBlob = await window.heic2any({ blob }) as Blob
58
- imageSrc = URL.createObjectURL(convertedBlob)
59
- // Only attempt to cache if the cache API is available
60
- if ('caches' in window) {
61
- try {
62
- const imgCache = await window.caches.open('img-cache')
63
- imgCache.put(url, new Response(convertedBlob))
64
- } catch (cacheError) {
65
- console.warn('Failed to cache the image:', cacheError)
66
- }
77
+ try {
78
+ const ext = url.split('.').pop()?.toLowerCase().split('?')[0]
79
+
80
+ if (ext === 'heic') {
81
+ const cachedSrc = await getCachedImage(url)
82
+ if (cachedSrc) {
83
+ imageSrc = cachedSrc
84
+ return
67
85
  }
68
- } catch (error) {
69
- console.error('Error converting HEIC file:', error)
86
+ imageSrc = await convertHeicImage(url)
87
+ } else {
88
+ imageSrc = url
70
89
  }
71
- } else {
72
- imageSrc = url
90
+ } catch (error) {
91
+ console.error('Image loading error:', error)
92
+ loadingError = true
93
+ imageSrc = null
73
94
  }
74
95
  }
75
- watch(() => [src, pathKey], loadImage, { immediate: true })
96
+
97
+ watch(() => [props.src, props.pathKey], loadImage, { immediate: true })
76
98
  </script>
77
99
 
78
100
  <template>
79
101
  <figcaption v-if="caption">
80
- <img v-if="imageSrc" :src="imageSrc" v-bind="$attrs" :alt="alt" :width="normalizeDimension(width)" :height="normalizeDimension(height)">
102
+ <img
103
+ v-if="imageSrc"
104
+ :src="imageSrc"
105
+ v-bind="$attrs"
106
+ :alt="alt"
107
+ :width="normalizeDimension(width)"
108
+ :height="normalizeDimension(height)"
109
+ >
81
110
  <Skeleton
82
111
  v-else
83
112
  class="img-web-kit"
@@ -85,7 +114,25 @@ watch(() => [src, pathKey], loadImage, { immediate: true })
85
114
  :height="normalizeDimension(height)"
86
115
  />
87
116
  </figcaption>
88
- <img v-else-if="imageSrc" :src="imageSrc" v-bind="$attrs" :alt="alt" :width="normalizeDimension(width)" :height="normalizeDimension(height)">
117
+
118
+ <img
119
+ v-else-if="imageSrc"
120
+ :src="imageSrc"
121
+ v-bind="$attrs"
122
+ :alt="alt"
123
+ :width="normalizeDimension(width)"
124
+ :height="normalizeDimension(height)"
125
+ >
126
+ <div
127
+ v-else-if="loadingError"
128
+ class="flex-center error-image"
129
+ :style="{
130
+ width: normalizeDimension(width),
131
+ height: normalizeDimension(height),
132
+ }"
133
+ >
134
+ <Icon name="broken_image" />
135
+ </div>
89
136
  <Skeleton
90
137
  v-else
91
138
  class="img-web-kit"
@@ -101,4 +148,7 @@ watch(() => [src, pathKey], loadImage, { immediate: true })
101
148
  border: 0;
102
149
  width: 100%;
103
150
  }
151
+ .error-image {
152
+ background-color: var(--skeleton-bg);
153
+ }
104
154
  </style>
@@ -35,6 +35,7 @@ function runAction(name: ToolbarConfigOption, value?: string) {
35
35
  v-else-if="action.name !== 'separator'" v-tooltip="action.label" :icon="action.icon" thin flat
36
36
  :aria-label="action.name" :class="[action.class, { active: selectedStyles.has(action.name) }]"
37
37
  class=""
38
+ tabindex="-1"
38
39
  @click="runAction(action.name)"
39
40
  />
40
41
  <span v-else-if="action.name === 'separator'" :key="`separator-${index}`" class="opacity-2 mb-025">|</span>