@uploadcare/file-uploader 1.13.1 → 1.13.3-alpha.0

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 (60) hide show
  1. package/abstract/UploaderBlock.d.ts +1 -0
  2. package/abstract/UploaderBlock.d.ts.map +1 -1
  3. package/abstract/UploaderPublicApi.d.ts +2 -1
  4. package/abstract/UploaderPublicApi.d.ts.map +1 -1
  5. package/abstract/UploaderPublicApi.js +12 -4
  6. package/abstract/l10nProcessor.d.ts.map +1 -1
  7. package/abstract/l10nProcessor.js +71 -58
  8. package/blocks/CameraSource/CameraSource.js +1 -1
  9. package/blocks/CameraSource/calcCameraModes.d.ts +5 -0
  10. package/blocks/CameraSource/calcCameraModes.d.ts.map +1 -0
  11. package/blocks/CameraSource/calcCameraModes.js +11 -0
  12. package/blocks/CameraSource/constants.d.ts +1 -0
  13. package/blocks/CameraSource/constants.d.ts.map +1 -1
  14. package/blocks/CameraSource/constants.js +2 -0
  15. package/blocks/CloudImageEditor/src/EditorButtonControl.js +1 -1
  16. package/blocks/CloudImageEditor/src/EditorFilterControl.js +1 -1
  17. package/blocks/CloudImageEditor/src/EditorToolbar.d.ts.map +1 -1
  18. package/blocks/CloudImageEditor/src/EditorToolbar.js +4 -0
  19. package/blocks/CloudImageEditor/src/css/common.css +4 -3
  20. package/blocks/CloudImageEditor/src/elements/button/BtnUi.js +5 -1
  21. package/blocks/Copyright/copyright.css +1 -0
  22. package/blocks/ExternalSource/ExternalSource.js +1 -1
  23. package/blocks/FileItem/FileItem.js +4 -4
  24. package/blocks/Icon/Icon.d.ts.map +1 -1
  25. package/blocks/Icon/Icon.js +2 -0
  26. package/blocks/SourceBtn/SourceBtn.d.ts +1 -1
  27. package/blocks/SourceBtn/SourceBtn.d.ts.map +1 -1
  28. package/blocks/SourceBtn/SourceBtn.js +13 -1
  29. package/blocks/SourceList/SourceList.d.ts.map +1 -1
  30. package/blocks/SourceList/SourceList.js +15 -1
  31. package/blocks/UploadList/UploadList.js +1 -1
  32. package/blocks/UrlSource/UrlSource.js +2 -2
  33. package/blocks/utils/UploadSource.d.ts +1 -0
  34. package/blocks/utils/UploadSource.d.ts.map +1 -1
  35. package/blocks/utils/UploadSource.js +1 -0
  36. package/blocks/utils/checkDevice.d.ts +9 -0
  37. package/blocks/utils/checkDevice.d.ts.map +1 -0
  38. package/blocks/utils/checkDevice.js +34 -0
  39. package/env.d.ts +1 -1
  40. package/env.js +1 -1
  41. package/index.ssr.d.ts +15 -1
  42. package/index.ssr.d.ts.map +1 -1
  43. package/index.ssr.js +32 -14
  44. package/locales/file-uploader/en.d.ts +1 -0
  45. package/locales/file-uploader/en.js +1 -0
  46. package/package.json +4 -9
  47. package/solutions/file-uploader/inline/FileUploaderInline.js +1 -1
  48. package/solutions/file-uploader/regular/FileUploaderRegular.js +1 -1
  49. package/web/file-uploader.iife.min.js +4 -4
  50. package/web/file-uploader.min.js +4 -4
  51. package/web/uc-basic.min.css +1 -1
  52. package/web/uc-cloud-image-editor.min.css +1 -1
  53. package/web/uc-cloud-image-editor.min.js +1 -1
  54. package/web/uc-file-uploader-inline.min.css +1 -1
  55. package/web/uc-file-uploader-inline.min.js +4 -4
  56. package/web/uc-file-uploader-minimal.min.css +1 -1
  57. package/web/uc-file-uploader-minimal.min.js +3 -3
  58. package/web/uc-file-uploader-regular.min.css +1 -1
  59. package/web/uc-file-uploader-regular.min.js +4 -4
  60. package/web/uc-img.min.js +1 -1
@@ -100,6 +100,7 @@ export namespace UploaderBlock {
100
100
  LOCAL: "local";
101
101
  DROP_AREA: "drop-area";
102
102
  CAMERA: "camera";
103
+ VIDEO_CAMERA: "video-camera";
103
104
  EXTERNAL: "external";
104
105
  API: "js-api";
105
106
  URL: "url";
@@ -1 +1 @@
1
- {"version":3,"file":"UploaderBlock.d.ts","sourceRoot":"","sources":["UploaderBlock.js"],"names":[],"mappings":"AAmBA;IACE,iBAAiB;IACjB,mCAAwB;IAExB,eAAe;IACf,mBAAmB;IAEnB;;;;;;;;;;;;;;MAA+B;IAE/B,eAAe;IACf,0BAOC;IA2BD;;;OAGG;IACH,qDAKC;IAED,mCAAmC;IACnC,6BAKC;IAED,4BAEC;IAED,iCAAiC;IACjC,wCAKC;IAYD,eAAe;IACf,qBA0BC;IAvBC,eAAe;IACf,6BAAiG;IAEjG,eAAe;IACf,uCAEC;IAmBH;;;OAGG;IACH,qBAkBC;IAED,eAAe;IACf,0BAYQ;IAER;;;;OAIG;IACH,gCAiCE;IAEF;;;OAGG;IACH,0CAyFE;IAEF,eAAe;IACf,mCAoBE;IAEF,eAAe;IACf,uBAuCC;IAED;;;OAGG;IACH,kCAHW,MAAM,qEAWhB;IAED;;;OAGG;IACH,oCAHa,QAAQ,OAAO,2BAA2B,EAAE,eAAe,CAAC,CA2BxE;IAED,kEAAkE;IAClE,iBADc,OAAO,sBAAsB,EAAE,eAAe,EAAE,CAK7D;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAra6B,oBAAoB;qCAWb,2BAA2B;kCAG9B,wBAAwB;kCADxB,wBAAwB;gCAD1B,sBAAsB"}
1
+ {"version":3,"file":"UploaderBlock.d.ts","sourceRoot":"","sources":["UploaderBlock.js"],"names":[],"mappings":"AAmBA;IACE,iBAAiB;IACjB,mCAAwB;IAExB,eAAe;IACf,mBAAmB;IAEnB;;;;;;;;;;;;;;MAA+B;IAE/B,eAAe;IACf,0BAOC;IA2BD;;;OAGG;IACH,qDAKC;IAED,mCAAmC;IACnC,6BAKC;IAED,4BAEC;IAED,iCAAiC;IACjC,wCAKC;IAYD,eAAe;IACf,qBA0BC;IAvBC,eAAe;IACf,6BAAiG;IAEjG,eAAe;IACf,uCAEC;IAmBH;;;OAGG;IACH,qBAkBC;IAED,eAAe;IACf,0BAYQ;IAER;;;;OAIG;IACH,gCAiCE;IAEF;;;OAGG;IACH,0CAyFE;IAEF,eAAe;IACf,mCAoBE;IAEF,eAAe;IACf,uBAuCC;IAED;;;OAGG;IACH,kCAHW,MAAM,qEAWhB;IAED;;;OAGG;IACH,oCAHa,QAAQ,OAAO,2BAA2B,EAAE,eAAe,CAAC,CA2BxE;IAED,kEAAkE;IAClE,iBADc,OAAO,sBAAsB,EAAE,eAAe,EAAE,CAK7D;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAra6B,oBAAoB;qCAWb,2BAA2B;kCAG9B,wBAAwB;kCADxB,wBAAwB;gCAD1B,sBAAsB"}
@@ -59,9 +59,10 @@ export class UploaderPublicApi {
59
59
  removeFileByInternalId: (internalId: string) => void;
60
60
  removeAllFiles(): void;
61
61
  uploadAll: () => void;
62
- /** @param {{ captureCamera?: boolean }} options */
62
+ /** @param {{ captureCamera?: boolean; modeCamera?: import('../blocks/CameraSource/constants.js').ModeCameraType }} options */
63
63
  openSystemDialog: (options?: {
64
64
  captureCamera?: boolean;
65
+ modeCamera?: import('../blocks/CameraSource/constants.js').ModeCameraType;
65
66
  }) => void;
66
67
  /**
67
68
  * @template {import('../types').OutputFileStatus} TStatus
@@ -1 +1 @@
1
- {"version":3,"file":"UploaderPublicApi.d.ts","sourceRoot":"","sources":["UploaderPublicApi.js"],"names":[],"mappings":"AAaA;IAOE,8DAA8D;IAC9D,iBADY,OAAO,oBAAoB,EAAE,aAAa,EAGrD;IATD;;;OAGG;IACH,aAAK;IAOL,eAAe;IACf,gCAEC;IAED,yCAEC;IAED;;iBAEC;IAED;;;;;;OAMG;IACH,sBAJW,MAAM;;;;sBAEJ,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAUrD;IAEF;;;;OAIG;IACH,wBAJW,MAAM;;;;sBAEJ,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAUrD;IAEF;;;;OAIG;IACH,4BAJW,MAAM;;;;sBAEJ,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAgBrD;IAEF;;;;OAIG;IACH,0BAJW,IAAI;;;;;sBAEF,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAcrD;IAEF,iCAAiC;IACjC,qCADY,MAAM,UAMhB;IAEF,uBAEC;IAED,sBAeE;IAEF,mDAAmD;IACnD,6BADY;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,UAkDrC;IAEF;;;;OAIG;IACH,8EAHW,MAAM,iDA8Cf;IAEF,oEAAoE;IACpE,oKAIE;IAEF,+BAA+B;IAC/B,gDAsCE;IAEF,qBAQE;IAEF;;;;;;;;;OASG;IACH,uTAFQ,IAAI,CAWV;IAEF,2DAA2D;IAC3D,0BADc,OAAO,oBAAoB,EAAE,YAAY,CAGrD;IAEF,8BAA8B;IAC9B,wBADY,OAAO,UAOjB;IAEF;;;OAGG;IACH,0BAOC;CACF"}
1
+ {"version":3,"file":"UploaderPublicApi.d.ts","sourceRoot":"","sources":["UploaderPublicApi.js"],"names":[],"mappings":"AAcA;IAOE,8DAA8D;IAC9D,iBADY,OAAO,oBAAoB,EAAE,aAAa,EAGrD;IATD;;;OAGG;IACH,aAAK;IAOL,eAAe;IACf,gCAEC;IAED,yCAEC;IAED;;iBAEC;IAED;;;;;;OAMG;IACH,sBAJW,MAAM;;;;sBAEJ,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAUrD;IAEF;;;;OAIG;IACH,wBAJW,MAAM;;;;sBAEJ,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAUrD;IAEF;;;;OAIG;IACH,4BAJW,MAAM;;;;sBAEJ,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAgBrD;IAEF;;;;OAIG;IACH,0BAJW,IAAI;;;;;sBAEF,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAcrD;IAEF,iCAAiC;IACjC,qCADY,MAAM,UAMhB;IAEF,uBAEC;IAED,sBAeE;IAEF,8HAA8H;IAC9H,6BADY;QAAE,aAAa,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,qCAAqC,EAAE,cAAc,CAAA;KAAE,UAyDhH;IAEF;;;;OAIG;IACH,8EAHW,MAAM,iDA8Cf;IAEF,oEAAoE;IACpE,oKAIE;IAEF,+BAA+B;IAC/B,gDAsCE;IAEF,qBAQE;IAEF;;;;;;;;;OASG;IACH,uTAFQ,IAAI,CAWV;IAEF,2DAA2D;IAC3D,0BADc,OAAO,oBAAoB,EAAE,YAAY,CAGrD;IAEF,8BAA8B;IAC9B,wBADY,OAAO,UAOjB;IAEF;;;OAGG;IACH,0BAOC;CACF"}
@@ -4,11 +4,12 @@ import { ActivityBlock } from './ActivityBlock.js';
4
4
  import { applyStyles, Data } from '@symbiotejs/symbiote';
5
5
  import { EventType } from '../blocks/UploadCtxProvider/EventEmitter.js';
6
6
  import { UploadSource } from '../blocks/utils/UploadSource.js';
7
- import { deserializeCsv, serializeCsv } from '../blocks/utils/comma-separated.js';
7
+ import { serializeCsv } from '../blocks/utils/comma-separated.js';
8
8
  import { IMAGE_ACCEPT_LIST, fileIsImage, mergeFileTypes } from '../utils/fileTypes.js';
9
9
  import { parseCdnUrl } from '../utils/parseCdnUrl.js';
10
10
  import { buildOutputCollectionState } from './buildOutputCollectionState.js';
11
11
  import { stringToArray } from '../utils/stringToArray.js';
12
+ import { calcCameraModes } from '../blocks/CameraSource/calcCameraModes.js';
12
13
  import { CameraSourceTypes } from '../blocks/CameraSource/constants.js';
13
14
 
14
15
  export class UploaderPublicApi {
@@ -137,7 +138,7 @@ export class UploaderPublicApi {
137
138
  );
138
139
  };
139
140
 
140
- /** @param {{ captureCamera?: boolean }} options */
141
+ /** @param {{ captureCamera?: boolean; modeCamera?: import('../blocks/CameraSource/constants.js').ModeCameraType }} options */
141
142
  openSystemDialog = (options = {}) => {
142
143
  const accept = serializeCsv(
143
144
  mergeFileTypes([this.cfg.accept ?? '', ...(this.cfg.imgOnly ? IMAGE_ACCEPT_LIST : [])]),
@@ -155,8 +156,15 @@ export class UploaderPublicApi {
155
156
  fileInput.multiple = this.cfg.multiple;
156
157
  if (options.captureCamera) {
157
158
  fileInput.capture = this.cfg.cameraCapture;
158
- const isVideoRecordingEnabled = deserializeCsv(this.cfg.cameraModes).includes(CameraSourceTypes.VIDEO);
159
- fileInput.accept = ['image/*', isVideoRecordingEnabled && 'video/*'].filter(Boolean).join(',');
159
+ const { isPhotoEnabled, isVideoRecordingEnabled } = calcCameraModes(this.cfg);
160
+
161
+ if (options.modeCamera === CameraSourceTypes.PHOTO && isPhotoEnabled) {
162
+ fileInput.accept = 'image/*';
163
+ }
164
+
165
+ if (options.modeCamera === CameraSourceTypes.VIDEO && isVideoRecordingEnabled) {
166
+ fileInput.accept = 'video/*';
167
+ }
160
168
  } else {
161
169
  fileInput.accept = accept;
162
170
  }
@@ -1 +1 @@
1
- {"version":3,"file":"l10nProcessor.d.ts","sourceRoot":"","sources":["l10nProcessor.js"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wEAHW,gBAAgB,kBAyE1B"}
1
+ {"version":3,"file":"l10nProcessor.d.ts","sourceRoot":"","sources":["l10nProcessor.js"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wEAHW,gBAAgB,kBAe1B"}
@@ -13,68 +13,81 @@ export function l10nProcessor(fr, fnCtx) {
13
13
  if (!key) {
14
14
  return;
15
15
  }
16
- let elProp = 'textContent';
17
- let useAttribute = false;
18
- if (key.includes(':')) {
19
- const arr = key.split(':');
20
- elProp = arr[0];
21
- key = arr[1];
22
- if (elProp.startsWith('@')) {
23
- elProp = elProp.slice(1);
24
- useAttribute = true;
25
- }
26
- }
16
+ const list = key.split(';');
27
17
 
28
- // Check if the key is present in the local context
29
- const localCtxKey = key;
30
- if (fnCtx.has(localCtxKey)) {
31
- fnCtx.sub(localCtxKey, (mappedKey) => {
32
- if (!mappedKey) {
33
- return;
34
- }
35
- // Store the subscription in a temporary map to be able to unsubscribe later
36
- if (!fnCtx.l10nProcessorSubs.has(localCtxKey)) {
37
- fnCtx.l10nProcessorSubs.set(localCtxKey, new Set());
38
- }
39
- const keySubs = fnCtx.l10nProcessorSubs.get(localCtxKey);
40
- keySubs?.forEach(
41
- /** @param {{ remove: () => void }} sub */
42
- (sub) => {
43
- sub.remove();
44
- keySubs.delete(sub);
45
- fnCtx.allSubs.delete(sub);
46
- },
47
- );
48
- // We don't need the leading * in the key because we use the key as a local context key relative to the global state
49
- const nodeStateKey = localeStateKey(mappedKey).replace('*', '');
50
- // If the key is not present in the node context, add it
51
- if (!fnCtx.nodeCtx.has(nodeStateKey)) {
52
- fnCtx.nodeCtx.add(nodeStateKey, mappedKey);
53
- }
54
- // Subscribe on the global l10n key change
55
- const sub = fnCtx.nodeCtx.sub(nodeStateKey, () => {
56
- el[/** @type {'textContent'} */ (elProp)] = fnCtx.l10n(mappedKey);
57
- });
58
- keySubs?.add(sub);
59
- // Store the subscription in the global context to make able Symbiote to unsubscribe it on destroy
60
- fnCtx.allSubs.add(sub);
61
- el.removeAttribute('l10n');
62
- });
18
+ for (const item of list) {
19
+ if (item) locale(el, item, fnCtx);
63
20
  }
21
+ });
22
+ }
64
23
 
65
- // Otherwise, assume the key is in the global context
66
- const stateKey = localeStateKey(key);
67
- if (!fnCtx.has(stateKey)) {
68
- fnCtx.add(stateKey, '');
24
+ /**
25
+ * @param {Element} el
26
+ * @param {string} key
27
+ * @param {any} fnCtx
28
+ */
29
+ const locale = (el, key, fnCtx) => {
30
+ let elProp = 'textContent';
31
+ let useAttribute = false;
32
+ if (key.includes(':')) {
33
+ const arr = key.split(':');
34
+ elProp = arr[0];
35
+ key = arr[1];
36
+ if (elProp.startsWith('@')) {
37
+ elProp = elProp.slice(1);
38
+ useAttribute = true;
69
39
  }
70
- fnCtx.sub(stateKey, () => {
71
- key = /** @type {string} */ (key);
72
- if (useAttribute) {
73
- el.setAttribute(elProp, fnCtx.l10n(key));
74
- } else {
75
- el[/** @type {'textContent'} */ (elProp)] = fnCtx.l10n(key);
40
+ }
41
+
42
+ // Check if the key is present in the local context
43
+ const localCtxKey = key;
44
+ if (fnCtx.has(localCtxKey)) {
45
+ fnCtx.sub(localCtxKey, (/** @type {string} */ mappedKey) => {
46
+ if (!mappedKey) {
47
+ return;
48
+ }
49
+ // Store the subscription in a temporary map to be able to unsubscribe later
50
+ if (!fnCtx.l10nProcessorSubs.has(localCtxKey)) {
51
+ fnCtx.l10nProcessorSubs.set(localCtxKey, new Set());
76
52
  }
53
+ const keySubs = fnCtx.l10nProcessorSubs.get(localCtxKey);
54
+ keySubs?.forEach(
55
+ /** @param {{ remove: () => void }} sub */
56
+ (sub) => {
57
+ sub.remove();
58
+ keySubs.delete(sub);
59
+ fnCtx.allSubs.delete(sub);
60
+ },
61
+ );
62
+ // We don't need the leading * in the key because we use the key as a local context key relative to the global state
63
+ const nodeStateKey = localeStateKey(mappedKey).replace('*', '');
64
+ // If the key is not present in the node context, add it
65
+ if (!fnCtx.nodeCtx.has(nodeStateKey)) {
66
+ fnCtx.nodeCtx.add(nodeStateKey, mappedKey);
67
+ }
68
+ // Subscribe on the global l10n key change
69
+ const sub = fnCtx.nodeCtx.sub(nodeStateKey, () => {
70
+ el[/** @type {'textContent'} */ (elProp)] = fnCtx.l10n(mappedKey);
71
+ });
72
+ keySubs?.add(sub);
73
+ // Store the subscription in the global context to make able Symbiote to unsubscribe it on destroy
74
+ fnCtx.allSubs.add(sub);
75
+ el.removeAttribute('l10n');
77
76
  });
78
- el.removeAttribute('l10n');
77
+ }
78
+
79
+ // Otherwise, assume the key is in the global context
80
+ const stateKey = localeStateKey(key);
81
+ if (!fnCtx.has(stateKey)) {
82
+ fnCtx.add(stateKey, '');
83
+ }
84
+ fnCtx.sub(stateKey, () => {
85
+ key = /** @type {string} */ (key);
86
+ if (useAttribute) {
87
+ el.setAttribute(elProp, fnCtx.l10n(key));
88
+ } else {
89
+ el[/** @type {'textContent'} */ (elProp)] = fnCtx.l10n(key);
90
+ }
79
91
  });
80
- }
92
+ el.removeAttribute('l10n');
93
+ };
@@ -844,7 +844,7 @@ CameraSource.template = /* HTML */ `
844
844
  type="button"
845
845
  class="uc-mini-btn uc-close-btn"
846
846
  set="onclick: *closeModal"
847
- l10n="@title:a11y-activity-header-button-close"
847
+ l10n="@title:a11y-activity-header-button-close;@aria-label:a11y-activity-header-button-close"
848
848
  >
849
849
  <uc-icon name="close"></uc-icon>
850
850
  </button>
@@ -0,0 +1,5 @@
1
+ export function calcCameraModes(cfg: import('../../types').ConfigType): {
2
+ isVideoRecordingEnabled: boolean;
3
+ isPhotoEnabled: boolean;
4
+ };
5
+ //# sourceMappingURL=calcCameraModes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calcCameraModes.d.ts","sourceRoot":"","sources":["calcCameraModes.js"],"names":[],"mappings":"AAKO,qCAAoC,OAAO,aAAa,EAAE,UAAU;;;EAK1E"}
@@ -0,0 +1,11 @@
1
+ //@ts-check
2
+
3
+ import { deserializeCsv } from '../utils/comma-separated.js';
4
+ import { CameraSourceTypes } from './constants.js';
5
+
6
+ export const calcCameraModes = (/** @type {import('../../types').ConfigType} } */ cfg) => {
7
+ return {
8
+ isVideoRecordingEnabled: deserializeCsv(cfg.cameraModes).includes(CameraSourceTypes.VIDEO),
9
+ isPhotoEnabled: deserializeCsv(cfg.cameraModes).includes(CameraSourceTypes.PHOTO),
10
+ };
11
+ };
@@ -12,4 +12,5 @@ export const CameraSourceEvents: Readonly<{
12
12
  RETAKE: "retake";
13
13
  ACCEPT: "accept";
14
14
  }>;
15
+ export type ModeCameraType = (typeof CameraSourceTypes)[keyof typeof CameraSourceTypes];
15
16
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["constants.js"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;GAWG"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["constants.js"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;GAWG;6BAEW,CAAC,wBAAwB,CAAC,CAAC,MAAM,wBAAwB,CAAC"}
@@ -15,3 +15,5 @@ export const CameraSourceEvents = Object.freeze({
15
15
  RETAKE: 'retake',
16
16
  ACCEPT: 'accept',
17
17
  });
18
+
19
+ /** @typedef {(typeof CameraSourceTypes)[keyof typeof CameraSourceTypes]} ModeCameraType */
@@ -38,7 +38,7 @@ export class EditorButtonControl extends Block {
38
38
  }
39
39
 
40
40
  EditorButtonControl.template = /* HTML */ `
41
- <button type="button" role="option" l10n="@title:title-prop">
41
+ <button role="option" type="button" set="@aria-label:title-prop;" l10n="@title:title-prop;">
42
42
  <uc-icon set="@name: icon;"></uc-icon>
43
43
  <div class="uc-title" ref="title-el">{{title}}</div>
44
44
  </button>
@@ -164,7 +164,7 @@ export class EditorFilterControl extends EditorButtonControl {
164
164
  }
165
165
 
166
166
  EditorFilterControl.template = /* HTML */ `
167
- <button type="button" role="option" l10n="@title:title-prop">
167
+ <button type="button" role="option" l10n="@title:title-prop;@aria-label:title-prop">
168
168
  <div class="uc-preview" ref="preview-el"></div>
169
169
  <uc-icon ref="icon-el" set="@name: icon; @size: iconSize;"></uc-icon>
170
170
  </button>
@@ -1 +1 @@
1
- {"version":3,"file":"EditorToolbar.d.ts","sourceRoot":"","sources":["EditorToolbar.js"],"names":[],"mappings":"AA2DA;IAII;;QAGE,qDAAqD;8BAA1C,OAAO,YAAY,EAAE,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAuDjD,4BAA4B;2BAAhB,UAAU;;;;;;;MAgBvB;IAED,eAAe;IAEf,6BAAsE;IAGxE,eAAe;IACf,uBAKC;IAED;;;OAGG;IACH,gCAKC;IAED;;;OAGG;IACH,6BAKC;IAED;;;OAGG;IACH,6BAKC;IAED;;;OAGG;IACH,4BAoCC;IAED;;;;OAIG;IACH,qBAyBC;IAED;;;OAGG;IACH,4BAKC;IAED,eAAe;IACf,0BAIC;IAED,eAAe;IACf,4BAWC;IALG,oBAGC;IAIL;;;OAGG;IACH,oBAEC;IAED;;MAwBM;CAiFP;;;;sBAlZqB,4BAA4B"}
1
+ {"version":3,"file":"EditorToolbar.d.ts","sourceRoot":"","sources":["EditorToolbar.js"],"names":[],"mappings":"AA2DA;IAII;;QAGE,qDAAqD;8BAA1C,OAAO,YAAY,EAAE,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAuDjD,4BAA4B;2BAAhB,UAAU;;;;;;;MAgBvB;IAED,eAAe;IAEf,6BAAsE;IAGxE,eAAe;IACf,uBAKC;IAED;;;OAGG;IACH,gCAKC;IAED;;;OAGG;IACH,6BAKC;IAED;;;OAGG;IACH,6BAKC;IAED;;;OAGG;IACH,4BAoCC;IAED;;;;OAIG;IACH,qBAyBC;IAED;;;OAGG;IACH,4BAKC;IAED,eAAe;IACf,0BAIC;IAED,eAAe;IACf,4BAWC;IALG,oBAGC;IAIL;;;OAGG;IACH,oBAEC;IAED;;MAwBM;CAqFP;;;;sBAtZqB,4BAA4B"}
@@ -402,6 +402,10 @@ export class EditorToolbar extends Block {
402
402
 
403
403
  this._updateInfoTooltip();
404
404
  }
405
+
406
+ destroyCallback() {
407
+ this.$['*showSlider'] = false;
408
+ }
405
409
  }
406
410
 
407
411
  EditorToolbar.template = /* HTML */ `
@@ -17,7 +17,9 @@
17
17
  --size-ui-min-width: 130px;
18
18
  --size-line-width: 1px;
19
19
  --size-modal-width: 650px;
20
- --size-icon: calc(var(--uc-button-size) / 2); /* TODO: remove icon size overrides */
20
+ --size-icon: calc(var(--uc-button-size) / 2);
21
+
22
+ /* TODO: remove icon size overrides */
21
23
 
22
24
  --border-radius-editor: var(--uc-radius);
23
25
  --border-radius-thumb: var(--uc-radius);
@@ -365,7 +367,6 @@ uc-editor-operation-control > button {
365
367
  height: var(--l-base-height);
366
368
  color: var(--color-effect);
367
369
  opacity: var(--opacity-effect);
368
- outline: none;
369
370
  cursor: pointer;
370
371
  transition: var(--l-width-transition);
371
372
  }
@@ -882,7 +883,6 @@ uc-btn-ui > button {
882
883
  background-color: var(--background-effect);
883
884
  border-radius: var(--uc-radius);
884
885
  opacity: var(--opacity-effect);
885
- outline: none;
886
886
  cursor: pointer;
887
887
  filter: brightness(var(--filter-effect));
888
888
  transition: var(--l-transition-effect);
@@ -1188,5 +1188,6 @@ uc-presence-toggle.uc-initial {
1188
1188
 
1189
1189
  [uc-cloud-image-editor] [role='button']:focus-visible,
1190
1190
  [uc-cloud-image-editor] button:focus-visible {
1191
+ outline: 1px auto Highlight;
1191
1192
  outline: 1px auto -webkit-focus-ring-color;
1192
1193
  }
@@ -88,7 +88,11 @@ export class BtnUi extends Block {
88
88
  BtnUi.bindAttributes({ text: 'text', icon: 'icon', reverse: 'reverse', theme: 'theme' });
89
89
 
90
90
  BtnUi.template = /* HTML */ `
91
- <button type="button" set="@role:aria-role; @aria-controls: aria-controls;" l10n="@title:title-prop">
91
+ <button
92
+ type="button"
93
+ set="@role:aria-role; @aria-controls: aria-controls; @aria-label:title-prop"
94
+ l10n="@title:title-prop;"
95
+ >
92
96
  <uc-icon set="className: iconCss; @name: icon; @hidden: !icon"></uc-icon>
93
97
  <div class="uc-text">{{text}}</div>
94
98
  </button>
@@ -22,6 +22,7 @@ uc-copyright .uc-credits {
22
22
  }
23
23
 
24
24
  uc-copyright .uc-credits:focus-visible {
25
+ outline: 1px auto Highlight;
25
26
  outline: 1px auto -webkit-focus-ring-color;
26
27
  }
27
28
 
@@ -274,7 +274,7 @@ ExternalSource.template = /* HTML */ `
274
274
  type="button"
275
275
  class="uc-mini-btn uc-close-btn"
276
276
  set="onclick: *historyBack"
277
- l10n="@title:a11y-activity-header-button-close"
277
+ l10n="@title:a11y-activity-header-button-close;@aria-label:a11y-activity-header-button-close"
278
278
  >
279
279
  <uc-icon name="close"></uc-icon>
280
280
  </button>
@@ -450,15 +450,15 @@ FileItem.template = /* HTML */ `
450
450
  <uc-icon set="@name: badgeIcon"></uc-icon>
451
451
  </div>
452
452
  </div>
453
- <div aria-live="polite" class="uc-file-name-wrapper" set="@aria-label:ariaLabelStatusFile;">
454
- <span class="uc-file-name" set="@title: itemName">{{itemName}}</span>
453
+ <div aria-atomic="true" aria-live="polite" class="uc-file-name-wrapper" set="@aria-label:ariaLabelStatusFile;">
454
+ <span class="uc-file-name">{{itemName}}</span>
455
455
  <span class="uc-file-error" set="@hidden: !errorText">{{errorText}}</span>
456
456
  <span class="uc-file-hint" set="@hidden: !hint">{{hint}}</span>
457
457
  </div>
458
458
  <div class="uc-file-actions">
459
459
  <button
460
460
  type="button"
461
- l10n="@title:file-item-edit-button"
461
+ l10n="@title:file-item-edit-button;@aria-label:file-item-edit-button"
462
462
  class="uc-edit-btn uc-mini-btn"
463
463
  set="onclick: onEdit; @hidden: !isEditable"
464
464
  >
@@ -466,7 +466,7 @@ FileItem.template = /* HTML */ `
466
466
  </button>
467
467
  <button
468
468
  type="button"
469
- l10n="@title:file-item-remove-button"
469
+ l10n="@title:file-item-remove-button;@aria-label:file-item-remove-button"
470
470
  class="uc-remove-btn uc-mini-btn"
471
471
  set="onclick: onRemove;"
472
472
  >
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["Icon.js"],"names":[],"mappings":"AAGA;IAII;;;MAIC;CAmBJ;;;;sBA7BqB,yBAAyB"}
1
+ {"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["Icon.js"],"names":[],"mappings":"AAGA;IAII;;;MAIC;CAqBJ;;;;sBA/BqB,yBAAyB"}
@@ -27,6 +27,8 @@ export class Icon extends Block {
27
27
  this.$.href = iconHref;
28
28
  });
29
29
  });
30
+
31
+ this.setAttribute('aria-hidden', 'true');
30
32
  }
31
33
  }
32
34
 
@@ -20,7 +20,7 @@ export class SourceBtn extends UploaderBlock {
20
20
  iconName: string;
21
21
  'src-type': string;
22
22
  '*commonProgress': number;
23
- '*uploadList': never[];
23
+ '*uploadList': never[]; /** @type {string | undefined} */
24
24
  '*uploadQueue': import("@uploadcare/upload-client").Queue;
25
25
  '*collectionErrors': any[];
26
26
  '*collectionState': import("../../index.js").OutputCollectionState<import("../../index.js").OutputCollectionStatus, "maybe-has-group"> | null;
@@ -1 +1 @@
1
- {"version":3,"file":"SourceBtn.d.ts","sourceRoot":"","sources":["SourceBtn.js"],"names":[],"mappings":"AAOA;;;;;;;;;GASG;AAEH;IAEE,iCAAiC;IACjC,MADW,MAAM,GAAG,SAAS,CACZ;IACjB;;;OAGG;IACH,yBAAsB;IAKpB;;;;;;;;;;;;;;;;MAIC;IAGH,kBAuCC;IAkBD,kCAAkC;IAClC,yBADY,OAAO,QAGlB;IAED,2BAA2B;IAC3B,cADY,MAAM,WAGjB;IAED,iBAYC;IAED,2BAA2B;IAC3B,gBADY,MAAM,QAcjB;CACF;;;;sBA9HY;IACZ,IAAQ,EAAE,MAAM,CAAC;IACjB,QAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAY,CAAC,EAAE,MAAM,OAAO,CAAC;IAC7B,cAAkB,CAAC,EAAE,OAAO,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;8BAd0B,iCAAiC"}
1
+ {"version":3,"file":"SourceBtn.d.ts","sourceRoot":"","sources":["SourceBtn.js"],"names":[],"mappings":"AAQA;;;;;;;;;GASG;AAEH;IAEE,iCAAiC;IACjC,MADW,MAAM,GAAG,SAAS,CACZ;IACjB;;;OAGG;IACH,yBAAsB;IAKpB;;;;gCAXF,iCAAiC;;;;;;;;;;;;MAe9B;IAGH,kBAkDC;IAkBD,kCAAkC;IAClC,yBADY,OAAO,QAGlB;IAED,2BAA2B;IAC3B,cADY,MAAM,WAGjB;IAED,iBAYC;IAED,2BAA2B;IAC3B,gBADY,MAAM,QAcjB;CACF;;;;sBAzIY;IACZ,IAAQ,EAAE,MAAM,CAAC;IACjB,QAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAY,CAAC,EAAE,MAAM,OAAO,CAAC;IAC7B,cAAkB,CAAC,EAAE,OAAO,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;8BAf0B,iCAAiC"}
@@ -2,6 +2,7 @@
2
2
  import { UploaderBlock } from '../../abstract/UploaderBlock.js';
3
3
  import { ActivityBlock } from '../../abstract/ActivityBlock.js';
4
4
  import { ExternalUploadSource, UploadSource } from '../utils/UploadSource.js';
5
+ import { CameraSourceTypes } from '../CameraSource/constants.js';
5
6
 
6
7
  const L10N_PREFIX = 'src-type-';
7
8
 
@@ -55,7 +56,18 @@ export class SourceBtn extends UploaderBlock {
55
56
  activate: () => {
56
57
  const supportsCapture = 'capture' in document.createElement('input');
57
58
  if (supportsCapture) {
58
- this.api.openSystemDialog({ captureCamera: true });
59
+ this.api.openSystemDialog({ captureCamera: true, modeCamera: CameraSourceTypes.PHOTO });
60
+ }
61
+ return !supportsCapture;
62
+ },
63
+ });
64
+ this.registerType({
65
+ type: UploadSource.VIDEO_CAMERA,
66
+ activity: ActivityBlock.activities.CAMERA,
67
+ activate: () => {
68
+ const supportsCapture = 'capture' in document.createElement('input');
69
+ if (supportsCapture) {
70
+ this.api.openSystemDialog({ captureCamera: true, modeCamera: CameraSourceTypes.VIDEO });
59
71
  }
60
72
  return !supportsCapture;
61
73
  },
@@ -1 +1 @@
1
- {"version":3,"file":"SourceList.d.ts","sourceRoot":"","sources":["SourceList.js"],"names":[],"mappings":"AAGA;CA2BC;sBA9BqB,yBAAyB"}
1
+ {"version":3,"file":"SourceList.d.ts","sourceRoot":"","sources":["SourceList.js"],"names":[],"mappings":"AAOA;CAqCC;sBA1CqB,yBAAyB"}
@@ -1,9 +1,15 @@
1
+ // @ts-check
2
+ import { ActivityBlock } from '../../abstract/ActivityBlock.js';
1
3
  import { Block } from '../../abstract/Block.js';
2
4
  import { stringToArray } from '../../utils/stringToArray.js';
5
+ import { calcCameraModes } from '../CameraSource/calcCameraModes.js';
6
+ import { isMobileDevice } from '../utils/checkDevice.js';
3
7
 
4
8
  export class SourceList extends Block {
5
9
  initCallback() {
6
10
  super.initCallback();
11
+ const isMobile = isMobileDevice();
12
+
7
13
  this.subConfigValue('sourceList', (/** @type {String} */ val) => {
8
14
  let list = stringToArray(val);
9
15
  let html = '';
@@ -18,7 +24,15 @@ export class SourceList extends Block {
18
24
  return;
19
25
  }
20
26
 
21
- html += /* HTML */ `<uc-source-btn type="${srcName}"></uc-source-btn>`;
27
+ html += /* HTML */ `<uc-source-btn role="listitem" type="${srcName}"></uc-source-btn>`;
28
+
29
+ if (
30
+ srcName === ActivityBlock.activities.CAMERA &&
31
+ isMobile &&
32
+ calcCameraModes(this.cfg).isVideoRecordingEnabled
33
+ ) {
34
+ html += /* HTML */ `<uc-source-btn role="listitem" type="video-camera"></uc-source-btn>`;
35
+ }
22
36
  });
23
37
 
24
38
  if (this.cfg.sourceListWrap) {
@@ -206,7 +206,7 @@ UploadList.template = /* HTML */ `
206
206
  type="button"
207
207
  class="uc-mini-btn uc-close-btn"
208
208
  set="onclick: *closeModal"
209
- l10n="@title:a11y-activity-header-button-close"
209
+ l10n="@title:a11y-activity-header-button-close;@aria-label:a11y-activity-header-button-close"
210
210
  >
211
211
  <uc-icon name="close"></uc-icon>
212
212
  </button>
@@ -38,7 +38,7 @@ export class UrlSource extends UploaderBlock {
38
38
 
39
39
  UrlSource.template = /* HTML */ `
40
40
  <uc-activity-header>
41
- <button type="button" class="uc-mini-btn" set="onclick: *historyBack" l10n="@title:back">
41
+ <button type="button" class="uc-mini-btn" set="onclick: *historyBack" l10n="@title:back;@aria-label:back">
42
42
  <uc-icon name="back"></uc-icon>
43
43
  </button>
44
44
  <div>
@@ -49,7 +49,7 @@ UrlSource.template = /* HTML */ `
49
49
  type="button"
50
50
  class="uc-mini-btn uc-close-btn"
51
51
  set="onclick: *closeModal"
52
- l10n="@title:a11y-activity-header-button-close"
52
+ l10n="@title:a11y-activity-header-button-close;@aria-label:a11y-activity-header-button-close"
53
53
  >
54
54
  <uc-icon name="close"></uc-icon>
55
55
  </button>
@@ -24,6 +24,7 @@ export const UploadSource: Readonly<{
24
24
  LOCAL: "local";
25
25
  DROP_AREA: "drop-area";
26
26
  CAMERA: "camera";
27
+ VIDEO_CAMERA: "video-camera";
27
28
  EXTERNAL: "external";
28
29
  API: "js-api";
29
30
  URL: "url";
@@ -1 +1 @@
1
- {"version":3,"file":"UploadSource.d.ts","sourceRoot":"","sources":["UploadSource.js"],"names":[],"mappings":"AACA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;;;;;GASG;0BAEW,CAAC,mBAAmB,CAAC,CAAC,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"UploadSource.d.ts","sourceRoot":"","sources":["UploadSource.js"],"names":[],"mappings":"AACA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;;;;;;GAUG;0BAEW,CAAC,mBAAmB,CAAC,CAAC,MAAM,mBAAmB,CAAC"}
@@ -16,6 +16,7 @@ export const UploadSource = Object.freeze({
16
16
  LOCAL: 'local',
17
17
  DROP_AREA: 'drop-area',
18
18
  CAMERA: 'camera',
19
+ VIDEO_CAMERA: 'video-camera',
19
20
  EXTERNAL: 'external',
20
21
  API: 'js-api',
21
22
  URL: 'url',
@@ -0,0 +1,9 @@
1
+ export const DeviceTypes: Readonly<{
2
+ iOS: "iOS";
3
+ Android: "Android";
4
+ WindowsPhone: "Windows Phone";
5
+ Desktop: "Desktop";
6
+ }>;
7
+ export function checkDevice(): "iOS" | "Android" | "Windows Phone" | "Desktop";
8
+ export function isMobileDevice(): boolean;
9
+ //# sourceMappingURL=checkDevice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkDevice.d.ts","sourceRoot":"","sources":["checkDevice.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEI,+EAoBN;AAEM,0CAIN"}
@@ -0,0 +1,34 @@
1
+ export const DeviceTypes = Object.freeze({
2
+ iOS: 'iOS',
3
+ Android: 'Android',
4
+ WindowsPhone: 'Windows Phone',
5
+ Desktop: 'Desktop',
6
+ });
7
+
8
+ export const checkDevice = () => {
9
+ const userAgent = navigator.userAgent || navigator.vendor || window.opera;
10
+
11
+ // Check for iOS
12
+ if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
13
+ return DeviceTypes.iOS;
14
+ }
15
+
16
+ // Check for Android
17
+ if (/android/i.test(userAgent)) {
18
+ return DeviceTypes.Android;
19
+ }
20
+
21
+ // Check for Windows Phone
22
+ if (/windows phone/i.test(userAgent)) {
23
+ return DeviceTypes.WindowsPhone;
24
+ }
25
+
26
+ // Default to desktop
27
+ return DeviceTypes.Desktop;
28
+ };
29
+
30
+ export const isMobileDevice = () => {
31
+ const deviceType = checkDevice();
32
+
33
+ return deviceType !== DeviceTypes.Desktop;
34
+ };
package/env.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  /** Do not edit this file manually. It's generated during build process. */
2
2
  export const PACKAGE_NAME: "blocks";
3
- export const PACKAGE_VERSION: "1.13.1";
3
+ export const PACKAGE_VERSION: "1.13.2";
4
4
  //# sourceMappingURL=env.d.ts.map
package/env.js CHANGED
@@ -1,3 +1,3 @@
1
1
  /** Do not edit this file manually. It's generated during build process. */
2
2
  export const PACKAGE_NAME = 'blocks';
3
- export const PACKAGE_VERSION = '1.13.1';
3
+ export const PACKAGE_VERSION = '1.13.2';