diff --git a/TOC.md b/TOC.md index ac3245013..c0e2f481c 100644 --- a/TOC.md +++ b/TOC.md @@ -46,6 +46,8 @@ - [ProgressBar](./blocks/ProgressBar/) - abstract progress bar - [ProgressBarCommon](./blocks/ProgressBarCommon/) - displays uploading progress for the all files selected - [Range](./blocks/Range/) - customizable wrapper for the range input element + - [Select](./blocks/Select/) - customizable selector + - [ShadowWrapper](./blocks/ShadowWrapper/) - Shadow DOM wrapper to encapsulate your solution - [SimpleBtn](./blocks/SimpleBtn/) - button for the file uploading workflow start - [SourceBtn](./blocks/SourceBtn/) - button for the certain source activation - [SourceList](./blocks/SourceList/) - renders the list of file sources basing on configuration provided diff --git a/abstract/Block.js b/abstract/Block.js index 62068c57e..d21329068 100644 --- a/abstract/Block.js +++ b/abstract/Block.js @@ -114,3 +114,5 @@ export class Block extends BaseComponent { super.reg(name.startsWith(TAG_PREFIX) ? name : TAG_PREFIX + name); } } + +export { BaseComponent }; diff --git a/blocks/CameraSource/CameraSource.js b/blocks/CameraSource/CameraSource.js index fd94c93b8..53b6ded2b 100644 --- a/blocks/CameraSource/CameraSource.js +++ b/blocks/CameraSource/CameraSource.js @@ -18,7 +18,12 @@ export class CameraSource extends UploaderBlock { messageHidden: true, requestBtnHidden: canUsePermissionsApi(), l10nMessage: null, + cameraSelectOptions: null, + cameraSelectHidden: true, + onCameraSelectChange: (e) => { + console.log(e.target.value); + }, onCancel: () => { this.cancelFlow(); }, @@ -175,13 +180,29 @@ export class CameraSource extends UploaderBlock { }); } - initCallback() { + async initCallback() { super.initCallback(); this.registerActivity(this.activityType, this._onActivate, this._onDeactivate); this.sub('--cfg-camera-mirror', (val) => { this.$.videoTransformCss = val ? 'scaleX(-1)' : null; }); + + let deviceList = await navigator.mediaDevices.enumerateDevices(); + let cameraSelectOptions = deviceList + .filter((info) => { + return info.kind === 'videoinput'; + }) + .map((info) => { + return { + text: info.label, + value: info.deviceId, + }; + }); + if (cameraSelectOptions.length > 0) { + this.$.cameraSelectOptions = cameraSelectOptions; + this.$.cameraSelectHidden = false; + } } } @@ -206,6 +227,9 @@ CameraSource.template = /*html*/ ` set="onclick: onCancel" l10n="cancel"> + + - + diff --git a/blocks/CameraSource/ref.htm b/blocks/CameraSource/ref.htm index 35f0fd6e5..460d2d6cc 100644 --- a/blocks/CameraSource/ref.htm +++ b/blocks/CameraSource/ref.htm @@ -5,5 +5,5 @@ CameraSource - + \ No newline at end of file diff --git a/blocks/CameraSource/test.js b/blocks/CameraSource/test.js index fc5c978e2..a5a7ded92 100644 --- a/blocks/CameraSource/test.js +++ b/blocks/CameraSource/test.js @@ -1,12 +1,14 @@ import { CameraSource } from './CameraSource.js'; +import { Select } from '../Select/Select.js'; +import { Icon } from '../Icon/Icon.js'; import { registerBlocks } from '../../abstract/registerBlocks.js'; -registerBlocks({ CameraSource }); - -const cameraSrc = new CameraSource(); -cameraSrc.classList.add('lr-wgt-common'); - window.onload = () => { - document.querySelector('#viewport')?.appendChild(cameraSrc); + if (window.location.host) { + return; + } + registerBlocks({ CameraSource, Select, Icon }); + /** @type {CameraSource} */ + const cameraSrc = document.querySelector('lr-camera-source'); cameraSrc.$['*currentActivity'] = 'camera'; }; diff --git a/blocks/FileItem/index.html b/blocks/FileItem/index.html index c83fc9bfd..7da6e6522 100644 --- a/blocks/FileItem/index.html +++ b/blocks/FileItem/index.html @@ -39,7 +39,7 @@ - + diff --git a/blocks/Select/Select.js b/blocks/Select/Select.js new file mode 100644 index 000000000..007202774 --- /dev/null +++ b/blocks/Select/Select.js @@ -0,0 +1,53 @@ +import { Block, BaseComponent } from '../../abstract/Block.js'; + +export class Option extends BaseComponent { + initCallback() { + this.outerHTML = /*html*/ `${this.$.text}`; + } +} +Option.reg('lr-option'); + +export class Select extends Block { + init$ = { + ...this.init$, + currentText: '', + options: [], + }; + + initCallback() { + super.initCallback(); + + this.sub('options', (options) => { + this.$.currentText = options?.[0]?.text || ''; + }); + + /** @type {HTMLSelectElement} */ + let select = this.ref.select; + select.addEventListener( + 'change', + (e) => { + e.preventDefault(); + e.stopPropagation(); + this.value = this.ref.select.value; + this.$.currentText = + this.$.options.find((opt) => { + return opt.value == this.value; + })?.text || ''; + this.dispatchEvent(new Event('change')); + }, + false + ); + } +} + +Select.template = /*html*/ ` + + {{currentText}} + + + + +`; diff --git a/blocks/Select/index.html b/blocks/Select/index.html new file mode 100644 index 000000000..36ff6dca1 --- /dev/null +++ b/blocks/Select/index.html @@ -0,0 +1,47 @@ + + + + + + + blocks + + + + + + + + + 🟡 Uploadcare | blocks + + + Home + Blocks + Solutions + TOC + Discussions + + + + Select + + + + + + + + + + + + diff --git a/blocks/Select/ref.htm b/blocks/Select/ref.htm new file mode 100644 index 000000000..d2307c079 --- /dev/null +++ b/blocks/Select/ref.htm @@ -0,0 +1,9 @@ +Select + + + + + + + + \ No newline at end of file diff --git a/blocks/Select/select.css b/blocks/Select/select.css new file mode 100644 index 000000000..e511a2cb7 --- /dev/null +++ b/blocks/Select/select.css @@ -0,0 +1,21 @@ +lr-select { + display: inline-flex; +} + +lr-select > button { + position: relative; + display: inline-flex; + align-items: center; + padding-right: 0; + color: var(--clr-btn-txt-secondary); + background-color: var(--clr-btn-bgr-secondary); + box-shadow: var(--shadow-btn-secondary); +} + +lr-select > button > select { + position: absolute; + display: block; + width: 100%; + height: 100%; + opacity: 0; +} diff --git a/blocks/Select/test.js b/blocks/Select/test.js new file mode 100644 index 000000000..f76994139 --- /dev/null +++ b/blocks/Select/test.js @@ -0,0 +1,37 @@ +import { Select } from './Select.js'; +import { Icon } from '../Icon/Icon.js'; +import { registerBlocks } from '../../abstract/registerBlocks.js'; + +function init() { + registerBlocks({ Select, Icon }); + /** @type {Select} */ + let select = document.querySelector('lr-select'); + select.$.options = [ + { + text: 'Option 1', + value: 1, + }, + { + text: 'Option 2', + value: 2, + }, + { + text: 'Option 3', + value: 3, + }, + ]; + select.onchange = (e) => { + console.log(e); + console.log(select.value); + }; +} + +window.onload = () => { + if (window.location.host) { + return; + } + + window.requestAnimationFrame(() => { + init(); + }); +}; diff --git a/blocks/themes/lr-basic/icons.css b/blocks/themes/lr-basic/icons.css index 44a2414c7..2236ad3bb 100644 --- a/blocks/themes/lr-basic/icons.css +++ b/blocks/themes/lr-basic/icons.css @@ -15,6 +15,7 @@ --icon-remove: 'm6.35673 9.71429c-.76333 0-1.35856.66121-1.27865 1.42031l1.01504 9.6429c.06888.6543.62067 1.1511 1.27865 1.1511h9.25643c.658 0 1.2098-.4968 1.2787-1.1511l1.015-9.6429c.0799-.7591-.5153-1.42031-1.2786-1.42031zm.50041-4.5v.32142h-2.57143c-.71008 0-1.28571.57564-1.28571 1.28572s.57563 1.28571 1.28571 1.28571h15.42859c.7101 0 1.2857-.57563 1.2857-1.28571s-.5756-1.28572-1.2857-1.28572h-2.5714v-.32142c0-1.77521-1.4391-3.21429-3.2143-3.21429h-3.8572c-1.77517 0-3.21426 1.43908-3.21426 3.21429zm7.07146-.64286c.355 0 .6428.28782.6428.64286v.32142h-5.14283v-.32142c0-.35504.28782-.64286.64283-.64286z'; --icon-edit: 'M3.96371 14.4792c-.15098.151-.25578.3419-.3021.5504L2.52752 20.133c-.17826.8021.53735 1.5177 1.33951 1.3395l5.10341-1.1341c.20844-.0463.39934-.1511.55032-.3021l8.05064-8.0507-5.557-5.55702-8.05069 8.05062ZM13.4286 5.01437l5.557 5.55703 2.0212-2.02111c.6576-.65765.6576-1.72393 0-2.38159l-3.1755-3.17546c-.6577-.65765-1.7239-.65765-2.3816 0l-2.0211 2.02113Z'; --icon-detail: 'M5,3C3.89,3 3,3.89 3,5V19C3,20.11 3.89,21 5,21H19C20.11,21 21,20.11 21,19V5C21,3.89 20.11,3 19,3H5M5,5H19V19H5V5M7,7V9H17V7H7M7,11V13H17V11H7M7,15V17H14V15H7Z'; + --icon-select: 'M7,10L12,15L17,10H7Z'; --icon-check: 'm12 22c5.5228 0 10-4.4772 10-10 0-5.52285-4.4772-10-10-10-5.52285 0-10 4.47715-10 10 0 5.5228 4.47715 10 10 10zm4.7071-11.4929-5.9071 5.9071-3.50711-3.5071c-.39052-.3905-.39052-1.0237 0-1.4142.39053-.3906 1.02369-.3906 1.41422 0l2.09289 2.0929 4.4929-4.49294c.3905-.39052 1.0237-.39052 1.4142 0 .3905.39053.3905 1.02374 0 1.41424z'; --icon-edit-file: 'M3.96371 14.4792c-.15098.151-.25578.3419-.3021.5504L2.52752 20.133c-.17826.8021.53735 1.5177 1.33951 1.3395l5.10341-1.1341c.20844-.0463.39934-.1511.55032-.3021l8.05064-8.0507-5.557-5.55702-8.05069 8.05062ZM13.4286 5.01437l5.557 5.55703 2.0212-2.02111c.6576-.65765.6576-1.72393 0-2.38159l-3.1755-3.17546c-.6577-.65765-1.7239-.65765-2.3816 0l-2.0211 2.02113Z'; --icon-remove-file: 'm12 22c5.5228 0 10-4.4772 10-10 0-5.52285-4.4772-10-10-10-5.52285 0-10 4.47715-10 10 0 5.5228 4.47715 10 10 10zm3.7071-13.70711c.3905.39053.3905 1.02369 0 1.41422l-2.2929 2.29289 2.2929 2.2929c.3905.3905.3905 1.0237 0 1.4142s-1.0237.3905-1.4142 0l-2.2929-2.2929-2.29289 2.2929c-.39053.3905-1.02369.3905-1.41422 0-.39052-.3905-.39052-1.0237 0-1.4142l2.29291-2.2929-2.2929-2.29289c-.39053-.39053-.39053-1.02369 0-1.41422.39052-.39052 1.02369-.39052 1.41421 0l2.29289 2.29291 2.2929-2.29291c.3905-.39052 1.0237-.39052 1.4142 0z'; diff --git a/blocks/themes/lr-basic/index.css b/blocks/themes/lr-basic/index.css index d7b1bd19d..04450fe2b 100644 --- a/blocks/themes/lr-basic/index.css +++ b/blocks/themes/lr-basic/index.css @@ -39,3 +39,4 @@ @import url('../../ActivityCaption/activity-caption.css'); @import url('../../ActivityIcon/activity-icon.css'); @import url('../../CloudImageEditor/index.css'); +@import url('../../Select/select.css'); diff --git a/index.html b/index.html index 36d05accf..668b0c105 100644 --- a/index.html +++ b/index.html @@ -80,7 +80,7 @@ Supported browsers Internet Explorer is outdated and not supported anymore. 🚀 Feedback -Issues and PRs are welcome. You can provide your feedback or drop us a support request at hello@uploadcare.com. +Issues and PRs are welcome. You can provide your feedback or drop us a support request at hello@uploadcare.com. Browse documentation and live demos https://uploadcare.github.io/uc-blocks/ diff --git a/toc.html b/toc.html index 9bdd88f90..7a168e1a3 100644 --- a/toc.html +++ b/toc.html @@ -84,6 +84,8 @@ ProgressBar - abstract progress bar ProgressBarCommon - displays uploading progress for the all files selected Range - customizable wrapper for the range input element +Select - customizable selector +ShadowWrapper - Shadow DOM wrapper to encapsulate your solution SimpleBtn - button for the file uploading workflow start SourceBtn - button for the certain source activation SourceList - renders the list of file sources basing on configuration provided
Internet Explorer is outdated and not supported anymore.
Issues and PRs are welcome. You can provide your feedback or drop us a support request at hello@uploadcare.com.
https://uploadcare.github.io/uc-blocks/
diff --git a/toc.html b/toc.html index 9bdd88f90..7a168e1a3 100644 --- a/toc.html +++ b/toc.html @@ -84,6 +84,8 @@ ProgressBar - abstract progress bar ProgressBarCommon - displays uploading progress for the all files selected Range - customizable wrapper for the range input element +Select - customizable selector +ShadowWrapper - Shadow DOM wrapper to encapsulate your solution SimpleBtn - button for the file uploading workflow start SourceBtn - button for the certain source activation SourceList - renders the list of file sources basing on configuration provided