From 2ed578102e24667d4cc9c5e3ab8cf06911fd2524 Mon Sep 17 00:00:00 2001 From: nd0ut Date: Fri, 14 Jun 2024 19:55:52 +0300 Subject: [PATCH 1/7] feat: remove deprecated `setUploadMetadata` method --- abstract/CTX.js | 1 - abstract/UploaderBlock.js | 33 +-------------------------------- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/abstract/CTX.js b/abstract/CTX.js index fd349d240..520a8abc7 100644 --- a/abstract/CTX.js +++ b/abstract/CTX.js @@ -24,7 +24,6 @@ export const uploaderBlockCtx = (fnCtx) => ({ '*commonProgress': 0, '*uploadList': [], '*focusedEntry': null, - '*uploadMetadata': null, '*uploadQueue': new Queue(1), '*uploadCollection': null, /** @type {ReturnType[]} */ diff --git a/abstract/UploaderBlock.js b/abstract/UploaderBlock.js index fadb23975..a43f2290d 100644 --- a/abstract/UploaderBlock.js +++ b/abstract/UploaderBlock.js @@ -13,7 +13,6 @@ import { customUserAgent } from '../blocks/utils/userAgent.js'; import { createCdnUrl, createCdnUrlModifiers } from '../utils/cdn-utils.js'; import { IMAGE_ACCEPT_LIST, fileIsImage, mergeFileTypes } from '../utils/fileTypes.js'; import { stringToArray } from '../utils/stringToArray.js'; -import { warnOnce } from '../utils/warnOnce.js'; import { uploaderBlockCtx } from './CTX.js'; import { TypedCollection } from './TypedCollection.js'; import { buildOutputCollectionState } from './buildOutputCollectionState.js'; @@ -28,32 +27,6 @@ export class UploaderBlock extends ActivityBlock { init$ = uploaderBlockCtx(this); - /** @private */ - __initialUploadMetadata = null; - - /** - * This is Public JS API method. Could be called before block initialization, so we need to delay state interactions - * until block init. - * - * TODO: If we add more public methods, it is better to use the single queue instead of tons of private fields per - * each method. See https://github.com/uploadcare/blocks/pull/162/ - * - * @deprecated Use `metadata` instance property on `lr-config` block instead. - * @param {import('@uploadcare/upload-client').Metadata} metadata - * @public - */ - setUploadMetadata(metadata) { - warnOnce( - 'setUploadMetadata is deprecated. Use `metadata` instance property on `lr-config` block instead. See migration guide: https://uploadcare.com/docs/file-uploader/migration-to-0.25.0/', - ); - if (!this.connectedOnce) { - // @ts-ignore TODO: fix this - this.__initialUploadMetadata = metadata; - } else { - this.$['*uploadMetadata'] = metadata; - } - } - get hasCtxOwner() { return this.hasBlockInCtx((block) => { if (block instanceof UploaderBlock) { @@ -112,10 +85,6 @@ export class UploaderBlock extends ActivityBlock { this.$['*uploadQueue'].concurrency = Number(value) || 1; }); - if (this.__initialUploadMetadata) { - this.$['*uploadMetadata'] = this.__initialUploadMetadata; - } - if (!this.$['*secureUploadsManager']) { this.$['*secureUploadsManager'] = new SecureUploadsManager(this); } @@ -584,7 +553,7 @@ export class UploaderBlock extends ActivityBlock { * @protected */ async getMetadataFor(entryId) { - const configValue = this.cfg.metadata ?? /** @type {import('../types').Metadata} */ (this.$['*uploadMetadata']); + const configValue = this.cfg.metadata || undefined; if (typeof configValue === 'function') { const outputFileEntry = this.getOutputItem(entryId); const metadata = await configValue(outputFileEntry); From 51f094f312bf1b27d6108a1747cd9ec596cfdfb3 Mon Sep 17 00:00:00 2001 From: nd0ut Date: Fri, 14 Jun 2024 19:56:24 +0300 Subject: [PATCH 2/7] feat: remove depreacted `addFiles` method --- abstract/UploaderBlock.js | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/abstract/UploaderBlock.js b/abstract/UploaderBlock.js index a43f2290d..0125de8f4 100644 --- a/abstract/UploaderBlock.js +++ b/abstract/UploaderBlock.js @@ -162,28 +162,6 @@ export class UploaderBlock extends ActivityBlock { return this.getOutputItem(internalId); } - /** - * @deprecated Will be removed in the near future. Please use `addFileFromObject`, `addFileFromUrl` or - * `addFileFromUuid` instead. - * @param {File[]} files - * @returns {import('../types').OutputFileEntry<'idle'>[]} - */ - addFiles(files) { - console.warn( - '`addFiles` method is deprecated. Please use `addFileFromObject`, `addFileFromUrl` or `addFileFromUuid` instead.', - ); - return files.map((/** @type {File} */ file) => { - const internalId = this.uploadCollection.add({ - file, - isImage: fileIsImage(file), - mimeType: file.type, - fileName: file.name, - fileSize: file.size, - }); - return this.getOutputItem(internalId); - }); - } - /** @param {string} internalId */ removeFileByInternalId(internalId) { if (!this.uploadCollection.read(internalId)) { From ee90e66c076e21e1ee92b2f4c60f8eb955a7d5bc Mon Sep 17 00:00:00 2001 From: Anton Nesterov Date: Fri, 21 Jun 2024 14:13:29 +0200 Subject: [PATCH 3/7] feat: updated theming mechanics with oklch colors and reworked css properties (#662) * let's begin * ui-size -> uc-size and other changes in common.css * common.css done * ActivityHeader done * TEMPORARY add Inter to font-family * FileItem done * almost * modal * ProgressBar * CloudImageEditorActivity * ProgressBarCommon * UploadList * SourceBtn * DropArea intermediate * DropArea * Copyright * CameraSource * Color * ConfirmationDialog * EditableCanvas * ExternalSource * Icon * Range * Select * SimpleBtn intermediate * Tabs * UploadList error colors * UrlSource * Video * cleanup * increase dialog corner radius * remove --ui-size * minimal intermediate * fix add-more icon * fix copyright in inline * added --uc-preview-size, minimal intermediate * fix transparency issues in minimal * minimal done * minor changes * Copyright: fix more transparency issues * separate variables for simplebtn * simplify SimpleBtn * prepare button to switch to lr-basic * intermediate commit * slider recolored * intermediate commit * keep colors together * dark theme * controls coloring done * color the crop guides * minor * fix operation control active state * filter-control icon coloring * rm some hardcode * color errors * rm old variables from theme * dark mode with media query * demo background with theme media query * cleanup CloudImageEditor's common.css * editor icons update * edit icon is a pencil now * StartFrom: hide DropArea on phones * make primary colors derive from one value * use system-ui as a default font-family * make chroma and hue uniform across grays * stop forcing `lr` prefix * make theme forceable with classes * rm rules from stylelintrc.cjs * add rgb fallback * remove dakrmode css custom property * prevent link styles external override * fix typo * remove unused css config properties * remove editor host selectors * remove unnecessary styles from inline * do not apply ltr direction style * remove unnecessary styles * fix cloud image editor solution styles * fix(cloud-image-editor): supress wheel passive handler warning * fix editor icons size styles * fix editor initial flashing * fix editor demo page * remove unused components * update icons sprite * rgb fallback * Styling selectors via attrs * Rename custom property * Hide close button for inline mode * Fix not-image icon color * Refactor CloudImageEditorSolution solution * Add cursor pointer to the copyright link * Fix theme colors specificity * Fix cloud image editor solution styles * Add some comments * Simplify uc-dark/light selectors * Move all the theme variables to the :root scope * independent vars for simple-btn, rgb fallback fix * darker color for dark demos * Fix modal content width * Move theme variables back to lr-wgt-common scope * desaturated all grays * brighten simple-btn * fix destructive-dark * fix potential color notation problems * detach simplebtn font values * another syntax mistake fixed * rm comments in fallback * dark demo background again * Better social sources theming * rm uc-light from raw-regular demo * social sources button title `Done` * remove unneeded icons * svg sprite rebuild * replaced image in readme * rm theme readme * rm fullscreen icons * fix error line height * Restore edit-file icon * Rebuild sprites * Add `--uc-line-height` css property * Update thumb generation observer options to fix inline mode * Specifiy file item height, add some optimizations to rendering, specify transition properties * Fix drop-area icon transition --------- Co-authored-by: nd0ut --- .stylelintrc.cjs | 5 - README.md | 2 +- abstract/ActivityBlock.js | 1 - abstract/Block.js | 15 +- abstract/SolutionBlock.js | 3 +- blocks/ActivityHeader/activity-header.css | 26 +- blocks/CameraSource/camera-source.css | 55 +-- .../src/CloudImageEditorBlock.js | 2 +- blocks/CloudImageEditor/src/CropFrame.js | 6 +- blocks/CloudImageEditor/src/EditorScroller.js | 28 +- blocks/CloudImageEditor/src/EditorToolbar.js | 8 +- blocks/CloudImageEditor/src/css/common.css | 400 ++++++++++-------- blocks/CloudImageEditor/src/css/icons.css | 7 +- .../presence-toggle/PresenceToggle.js | 9 +- .../CloudImageEditor/src/icons/closeMax.svg | 4 +- blocks/CloudImageEditor/src/icons/done.svg | 4 +- .../CloudImageEditor/src/icons/edit-file.svg | 3 + .../CloudImageEditor/src/icons/original.svg | 2 +- blocks/CloudImageEditor/src/svg-sprite.js | 2 +- blocks/CloudImageEditorActivity/index.css | 6 +- blocks/Color/Color.js | 17 - blocks/Color/color.css | 32 -- .../ConfirmationDialog/ConfirmationDialog.js | 77 ---- blocks/ConfirmationDialog/confirmation.css | 21 - blocks/Copyright/copyright.css | 22 +- blocks/DropArea/DropArea.js | 1 + blocks/DropArea/drop-area.css | 168 ++++---- blocks/EditableCanvas/CanMan.js | 209 --------- blocks/EditableCanvas/EditableCanvas.js | 104 ----- .../EditableCanvas/EditableCanvasToolbar.js | 143 ------- blocks/EditableCanvas/buttons.js | 109 ----- blocks/EditableCanvas/editable-canvas.css | 80 ---- blocks/EditableCanvas/test/test.htm | 34 -- blocks/EditableCanvas/test/test.jpg | Bin 40740 -> 0 bytes blocks/ExternalSource/ExternalSource.js | 24 +- blocks/ExternalSource/buildStyles.js | 67 ++- blocks/ExternalSource/external-source.css | 23 +- blocks/FileItem/FileItem.js | 6 +- blocks/FileItem/file-item.css | 83 ++-- blocks/FilePreview/FilePreview.js | 55 --- blocks/FilePreview/file-preview.css | 27 -- blocks/Icon/icon.css | 8 +- blocks/LiveHtml/LiveHtml.js | 273 ------------ blocks/LiveHtml/live-html.css | 68 --- blocks/Modal/Modal.js | 1 + blocks/Modal/modal.css | 46 +- blocks/ProgressBar/progress-bar.css | 2 +- .../ProgressBarCommon/progress-bar-common.css | 4 +- blocks/Range/range.css | 2 +- blocks/Select/select.css | 5 +- blocks/SimpleBtn/SimpleBtn.js | 1 + blocks/SimpleBtn/simple-btn.css | 83 ++-- blocks/SourceBtn/source-btn.css | 30 +- blocks/StartFrom/start-from.css | 24 +- blocks/Tabs/Tabs.js | 78 ---- blocks/Tabs/tabs.css | 33 -- blocks/UploadList/upload-list.css | 56 +-- blocks/UrlSource/url-source.css | 14 +- blocks/Video/Video.js | 299 ------------- blocks/Video/test-track.vtt | 10 - blocks/Video/video.css | 106 ----- blocks/Video/video.json | 29 -- blocks/svg-backgrounds/svg-backgrounds.js | 2 +- blocks/themes/lr-basic/README.md | 77 ---- blocks/themes/lr-basic/common.css | 161 +++---- blocks/themes/lr-basic/config.css | 45 +- blocks/themes/lr-basic/icons/check.svg | 3 - blocks/themes/lr-basic/icons/detail.svg | 3 - blocks/themes/lr-basic/icons/dots.svg | 3 - .../themes/lr-basic/icons/edit-brightness.svg | 3 - blocks/themes/lr-basic/icons/edit-color.svg | 3 - .../themes/lr-basic/icons/edit-contrast.svg | 3 - blocks/themes/lr-basic/icons/edit-crop.svg | 3 - blocks/themes/lr-basic/icons/edit-draw.svg | 3 - blocks/themes/lr-basic/icons/edit-file.svg | 3 - blocks/themes/lr-basic/icons/edit-flip-h.svg | 3 - blocks/themes/lr-basic/icons/edit-flip-v.svg | 3 - blocks/themes/lr-basic/icons/edit-guides.svg | 3 - blocks/themes/lr-basic/icons/edit-resize.svg | 3 - blocks/themes/lr-basic/icons/edit-rotate.svg | 3 - .../themes/lr-basic/icons/edit-saturation.svg | 3 - blocks/themes/lr-basic/icons/edit-text.svg | 3 - blocks/themes/lr-basic/icons/edit.svg | 3 - .../themes/lr-basic/icons/fullscreen-exit.svg | 3 - blocks/themes/lr-basic/icons/fullscreen.svg | 3 - blocks/themes/lr-basic/icons/remove.svg | 3 - blocks/themes/lr-basic/icons/trash-file.svg | 3 - blocks/themes/lr-basic/index.css | 6 - blocks/themes/lr-basic/svg-sprite.js | 2 +- blocks/themes/lr-basic/theme.css | 391 +++++++++-------- demo/cloud-image-editor.html | 17 +- demo/form.html | 15 +- demo/inline-mode.html | 54 --- demo/raw-build.html | 16 - demo/raw-inline.html | 8 +- demo/raw-minimal.html | 7 + demo/raw-regular.html | 7 + index.js | 6 +- .../cloud-image-editor/CloudImageEditor.js | 19 +- solutions/cloud-image-editor/index.css | 1 + .../inline/FileUploaderInline.js | 2 + solutions/file-uploader/inline/index.css | 38 +- .../minimal/FileUploaderMinimal.js | 2 + solutions/file-uploader/minimal/index.css | 131 +++--- .../regular/FileUploaderRegular.js | 4 +- types/jsx.d.ts | 3 - 106 files changed, 1078 insertions(+), 3061 deletions(-) create mode 100644 blocks/CloudImageEditor/src/icons/edit-file.svg delete mode 100644 blocks/Color/Color.js delete mode 100644 blocks/Color/color.css delete mode 100644 blocks/ConfirmationDialog/ConfirmationDialog.js delete mode 100644 blocks/ConfirmationDialog/confirmation.css delete mode 100644 blocks/EditableCanvas/CanMan.js delete mode 100644 blocks/EditableCanvas/EditableCanvas.js delete mode 100644 blocks/EditableCanvas/EditableCanvasToolbar.js delete mode 100644 blocks/EditableCanvas/buttons.js delete mode 100644 blocks/EditableCanvas/editable-canvas.css delete mode 100644 blocks/EditableCanvas/test/test.htm delete mode 100644 blocks/EditableCanvas/test/test.jpg delete mode 100644 blocks/FilePreview/FilePreview.js delete mode 100644 blocks/FilePreview/file-preview.css delete mode 100644 blocks/LiveHtml/LiveHtml.js delete mode 100644 blocks/LiveHtml/live-html.css delete mode 100644 blocks/Tabs/Tabs.js delete mode 100644 blocks/Tabs/tabs.css delete mode 100644 blocks/Video/Video.js delete mode 100644 blocks/Video/test-track.vtt delete mode 100644 blocks/Video/video.css delete mode 100644 blocks/Video/video.json delete mode 100644 blocks/themes/lr-basic/README.md delete mode 100644 blocks/themes/lr-basic/icons/check.svg delete mode 100644 blocks/themes/lr-basic/icons/detail.svg delete mode 100644 blocks/themes/lr-basic/icons/dots.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-brightness.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-color.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-contrast.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-crop.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-draw.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-file.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-flip-h.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-flip-v.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-guides.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-resize.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-rotate.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-saturation.svg delete mode 100644 blocks/themes/lr-basic/icons/edit-text.svg delete mode 100644 blocks/themes/lr-basic/icons/edit.svg delete mode 100644 blocks/themes/lr-basic/icons/fullscreen-exit.svg delete mode 100644 blocks/themes/lr-basic/icons/fullscreen.svg delete mode 100644 blocks/themes/lr-basic/icons/remove.svg delete mode 100644 blocks/themes/lr-basic/icons/trash-file.svg delete mode 100644 demo/inline-mode.html delete mode 100644 demo/raw-build.html diff --git a/.stylelintrc.cjs b/.stylelintrc.cjs index 99ff09b8f..497259778 100644 --- a/.stylelintrc.cjs +++ b/.stylelintrc.cjs @@ -40,11 +40,6 @@ module.exports = { files: ['blocks/**/*.css', 'solutions/**/*.css'], ignoreFiles: ['**/test/**/*.css'], plugins: ['./stylelint-force-app-name-prefix.cjs'], - rules: { - 'plugin/stylelint-force-app-name-prefix': { - appName: 'lr', - }, - }, }, ], }; diff --git a/README.md b/README.md index 81d4d5a66..ec138ac17 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ and [even more](<(https://uploadcare.com/features/?ref=github-readme)>). See Uploadcare Blocks [in action](https://codesandbox.io/p/devbox/github/uploadcare/blocks-examples/tree/main/examples/js-uploader)! -Uploadcare Blocks examples +Uploadcare Blocks examples ## Core features diff --git a/abstract/ActivityBlock.js b/abstract/ActivityBlock.js index 99e0c453d..3155f04f1 100644 --- a/abstract/ActivityBlock.js +++ b/abstract/ActivityBlock.js @@ -198,7 +198,6 @@ ActivityBlock.activities = Object.freeze({ DRAW: 'draw', UPLOAD_LIST: 'upload-list', URL: 'url', - CONFIRMATION: 'confirmation', CLOUD_IMG_EDIT: 'cloud-image-edit', EXTERNAL: 'external', DETAILS: 'details', diff --git a/abstract/Block.js b/abstract/Block.js index 1546c8a5c..47fefeac2 100644 --- a/abstract/Block.js +++ b/abstract/Block.js @@ -19,7 +19,9 @@ const TAG_PREFIX = 'lr-'; export class Block extends BaseComponent { /** @type {string | null} */ static StateConsumerScope = null; - static className = ''; + + /** @type {string[]} */ + static styleAttrs = []; requireCtxName = false; allowCustomTemplate = true; /** @type {import('./ActivityBlock.js').ActivityType} */ @@ -128,10 +130,10 @@ export class Block extends BaseComponent { } connectedCallback() { - const className = /** @type {typeof Block} */ (this.constructor).className; - if (className) { - this.classList.toggle(`${TAG_PREFIX}${className}`, true); - } + const styleAttrs = /** @type {typeof Block} */ (this.constructor).styleAttrs; + styleAttrs.forEach((attr) => { + this.setAttribute(attr, ''); + }); if (this.hasAttribute('retpl')) { // @ts-ignore TODO: fix this @@ -179,7 +181,8 @@ export class Block extends BaseComponent { } this.sub(localeStateKey('locale-id'), (localeId) => { - this.style.direction = getLocaleDirection(localeId); + const direction = getLocaleDirection(localeId); + this.style.direction = direction === 'ltr' ? '' : direction; }); } diff --git a/abstract/SolutionBlock.js b/abstract/SolutionBlock.js index d0d5ed423..1f466032c 100644 --- a/abstract/SolutionBlock.js +++ b/abstract/SolutionBlock.js @@ -1,8 +1,9 @@ -import { uploaderBlockCtx } from './CTX.js'; import svgIconsSprite from '../blocks/themes/lr-basic/svg-sprite.js'; import { Block } from './Block.js'; +import { uploaderBlockCtx } from './CTX.js'; export class SolutionBlock extends Block { + static styleAttrs = ['lr-wgt-common']; requireCtxName = true; init$ = uploaderBlockCtx(this); _template = null; diff --git a/blocks/ActivityHeader/activity-header.css b/blocks/ActivityHeader/activity-header.css index 50a236602..94f19bf92 100644 --- a/blocks/ActivityHeader/activity-header.css +++ b/blocks/ActivityHeader/activity-header.css @@ -1,34 +1,14 @@ lr-activity-header { display: flex; - gap: var(--gap-mid); justify-content: space-between; - padding: var(--gap-mid); - color: var(--clr-txt); + gap: var(--uc-padding); + padding: var(--uc-padding); + color: var(--uc-foreground); font-weight: 500; font-size: 1em; - line-height: var(--ui-size); -} - -lr-activity-header lr-icon { - height: var(--ui-size); } lr-activity-header > * { display: flex; align-items: center; } - -lr-activity-header button { - display: inline-flex; - align-items: center; - justify-content: center; - color: var(--clr-txt-mid); -} - -lr-activity-header button:hover { - background-color: var(--clr-background); -} - -lr-activity-header button:active { - background-color: var(--clr-background-dark); -} diff --git a/blocks/CameraSource/camera-source.css b/blocks/CameraSource/camera-source.css index 15353cd75..c2ad41e75 100644 --- a/blocks/CameraSource/camera-source.css +++ b/blocks/CameraSource/camera-source.css @@ -6,12 +6,12 @@ lr-camera-source { height: 100%; max-height: 100%; overflow: hidden; - background-color: var(--clr-background-light); - border-radius: var(--border-radius-element); + background-color: var(--uc-background); + border-radius: var(--uc-radius); } -lr-modal lr-camera-source { - width: min(calc(var(--modal-max-w) - var(--gap-mid) * 2), calc(100vw - var(--gap-mid) * 2)); +[lr-modal] lr-camera-source { + width: min(calc(var(--uc-dialog-max-width) - var(--uc-padding) * 2), calc(100vw - var(--uc-padding) * 2)); height: 100vh; max-height: var(--modal-max-content-height); } @@ -22,7 +22,7 @@ lr-camera-source.initialized { @media only screen and (max-width: 430px) { lr-camera-source { - width: calc(100vw - var(--gap-mid) * 2); + width: calc(100vw - var(--uc-padding) * 2); height: var(--modal-content-height-fill, 100%); } } @@ -33,8 +33,8 @@ lr-camera-source video { max-height: 100%; object-fit: contain; object-position: center center; - background-color: var(--clr-background-dark); - border-radius: var(--border-radius-element); + background-color: var(--uc-muted); + border-radius: var(--uc-radius); } lr-camera-source .toolbar { @@ -43,8 +43,8 @@ lr-camera-source .toolbar { display: flex; justify-content: space-between; width: 100%; - padding: var(--gap-mid); - background-color: var(--clr-background-light); + padding: var(--uc-padding); + background-color: var(--uc-background); } lr-camera-source .content { @@ -52,38 +52,39 @@ lr-camera-source .content { flex: 1; justify-content: center; width: 100%; - padding: var(--gap-mid); + padding: var(--uc-padding); padding-top: 0; overflow: hidden; } lr-camera-source .message-box { - --padding: calc(var(--gap-max) * 2); - display: flex; flex-direction: column; - grid-gap: var(--gap-max); + grid-gap: 40px; align-items: center; justify-content: center; - padding: var(--padding) var(--padding) 0 var(--padding); - color: var(--clr-txt); + padding: 40px 40px 0; + color: var(--uc-foreground); } lr-camera-source .message-box button { - color: var(--clr-btn-txt-primary); - background-color: var(--clr-btn-bgr-primary); + color: var(--uc-primary-foreground); + background-color: var(--uc-primary); } lr-camera-source .shot-btn { position: absolute; - bottom: var(--gap-max); - width: calc(var(--ui-size) * 1.8); - height: calc(var(--ui-size) * 1.8); - color: var(--clr-background-light); - background-color: var(--clr-txt); + bottom: 20px; + width: 58px; + height: 58px; + color: var(--uc-background); + background-color: var(--uc-foreground); border-radius: 50%; opacity: 0.85; - transition: var(--transition-duration) ease; + transition: + bottom var(--uc-transition), + opacity var(--uc-transition), + transform var(--uc-transition); } lr-camera-source .shot-btn:hover { @@ -92,15 +93,15 @@ lr-camera-source .shot-btn:hover { } lr-camera-source .shot-btn:active { - background-color: var(--clr-txt-mid); + transform: scale(1); opacity: 1; } lr-camera-source .shot-btn[disabled] { - bottom: calc(var(--gap-max) * -1 - var(--gap-mid) - var(--ui-size) * 2); + bottom: -80px; } lr-camera-source .shot-btn lr-icon svg { - width: calc(var(--ui-size) / 1.5); - height: calc(var(--ui-size) / 1.5); + width: 20px; + height: 20px; } diff --git a/blocks/CloudImageEditor/src/CloudImageEditorBlock.js b/blocks/CloudImageEditor/src/CloudImageEditorBlock.js index e99f38acc..d00c60c2f 100644 --- a/blocks/CloudImageEditor/src/CloudImageEditorBlock.js +++ b/blocks/CloudImageEditor/src/CloudImageEditorBlock.js @@ -19,7 +19,7 @@ import { TabId } from './toolbar-constants.js'; export class CloudImageEditorBlock extends Block { ctxOwner = true; - static className = 'cloud-image-editor'; + static styleAttrs = ['lr-cloud-image-editor']; constructor() { super(); diff --git a/blocks/CloudImageEditor/src/CropFrame.js b/blocks/CloudImageEditor/src/CropFrame.js index 26e483216..8b1f79842 100644 --- a/blocks/CloudImageEditor/src/CropFrame.js +++ b/blocks/CloudImageEditor/src/CropFrame.js @@ -256,7 +256,7 @@ export class CropFrame extends Block { width: '100%', height: '100%', fill: 'none', - stroke: '#000000', + stroke: 'currentColor', 'stroke-width': GUIDE_STROKE_WIDTH, 'stroke-opacity': 0.5, }); @@ -268,7 +268,7 @@ export class CropFrame extends Block { y1: `0%`, x2: `${GUIDE_THIRD * i}%`, y2: `100%`, - stroke: '#000000', + stroke: 'currentColor', 'stroke-width': GUIDE_STROKE_WIDTH, 'stroke-opacity': 0.3, }); @@ -281,7 +281,7 @@ export class CropFrame extends Block { y1: `${GUIDE_THIRD * i}%`, x2: `100%`, y2: `${GUIDE_THIRD * i}%`, - stroke: '#000000', + stroke: 'currentColor', 'stroke-width': GUIDE_STROKE_WIDTH, 'stroke-opacity': 0.3, }); diff --git a/blocks/CloudImageEditor/src/EditorScroller.js b/blocks/CloudImageEditor/src/EditorScroller.js index 8338f417e..ccdb9f6c2 100644 --- a/blocks/CloudImageEditor/src/EditorScroller.js +++ b/blocks/CloudImageEditor/src/EditorScroller.js @@ -6,14 +6,26 @@ export class EditorScroller extends Block { initCallback() { super.initCallback(); - this.addEventListener('wheel', (e) => { - e.preventDefault(); - let { deltaY, deltaX } = e; - if (Math.abs(deltaX) > X_THRESHOLD) { - this.scrollLeft += deltaX; - } else { - this.scrollLeft += deltaY; - } + this.addEventListener( + 'wheel', + (e) => { + e.preventDefault(); + + let { deltaY, deltaX } = e; + if (Math.abs(deltaX) > X_THRESHOLD) { + this.scrollLeft += deltaX; + } else { + this.scrollLeft += deltaY; + } + }, + { + passive: false, + }, + ); + + // This fixes some strange bug on MacOS - wheel event doesn't fire for physical mouse wheel if no scroll event attached also + this.addEventListener('scroll', () => {}, { + passive: true, }); } } diff --git a/blocks/CloudImageEditor/src/EditorToolbar.js b/blocks/CloudImageEditor/src/EditorToolbar.js index f757661f1..10b3ffb22 100644 --- a/blocks/CloudImageEditor/src/EditorToolbar.js +++ b/blocks/CloudImageEditor/src/EditorToolbar.js @@ -21,7 +21,7 @@ function renderTabToggle(id) { return /* HTML */ `
${ALL_TABS.map(renderTabContent).join('')}
- +
${ALL_TABS.map(renderTabToggle).join('')}
- +
@@ -408,7 +408,7 @@ EditorToolbar.template = /* HTML */ `
- +
diff --git a/blocks/CloudImageEditor/src/css/common.css b/blocks/CloudImageEditor/src/css/common.css index 09b4060d9..84ed9c58a 100644 --- a/blocks/CloudImageEditor/src/css/common.css +++ b/blocks/CloudImageEditor/src/css/common.css @@ -1,67 +1,39 @@ /* TODO: we shuoud use basic theme there */ -:host(.lr-cloud-image-editor), -.lr-cloud-image-editor { - /* Theme settings >>> */ - --rgb-primary-accent: 6, 2, 196; - --rgb-text-base: 0, 0, 0; - --rgb-text-accent-contrast: 255, 255, 255; - --rgb-fill-contrast: 255, 255, 255; - --rgb-fill-shaded: 245, 245, 245; - --rgb-shadow: 0, 0, 0; - --rgb-error: 209, 81, 81; - --opacity-shade-mid: 0.2; - - /* <<< Theme settings */ - - --color-primary-accent: rgb(var(--rgb-primary-accent)); - --color-text-base: rgb(var(--rgb-text-base)); - --color-text-accent-contrast: rgb(var(--rgb-text-accent-contrast)); - --color-text-soft: rgb(var(--rgb-fill-contrast)); - --color-text-error: rgb(var(--rgb-error)); - --color-fill-contrast: rgb(var(--rgb-fill-contrast)); - --color-modal-backdrop: rgba(var(--rgb-fill-shaded), 0.95); - --color-image-background: rgba(var(--rgb-fill-shaded)); - --color-outline: rgba(var(--rgb-text-base), var(--opacity-shade-mid)); - --color-underline: rgba(var(--rgb-text-base), 0.08); - --color-shade: rgba(var(--rgb-text-base), 0.02); +[lr-cloud-image-editor] { + --color-primary-accent: var(--uc-primary); + --color-text-base: var(--uc-foreground); + --color-text-accent-contrast: var(--uc-background); + --color-fill-contrast: var(--uc-background); + --color-modal-backdrop: oklch(0 0 0 / 0.1); + --color-image-background: var(--uc-muted); --color-focus-ring: var(--color-primary-accent); - --color-input-placeholder: rgba(var(--rgb-text-base), 0.32); - --color-error: rgb(var(--rgb-error)); + --color-crop-guides: var(--uc-foreground); - --font-size-ui: 16px; - --font-size-title: 18px; - --font-weight-title: 500; - --font-size-soft: 14px; + --font-size-ui: var(--uc-font-size); - --size-touch-area: 40px; - --size-panel-heading: 66px; + --size-touch-area: var(--uc-button-size); + --size-panel-heading: calc(var(--uc-button-size) + var(--uc-padding) * 2); --size-ui-min-width: 130px; --size-line-width: 1px; --size-modal-width: 650px; + --size-icon: calc(var(--uc-button-size) / 2); /* TODO: remove icon size overrides */ - --border-radius-connect: 2px; - --border-radius-editor: 3px; - --border-radius-thumb: 4px; - --border-radius-ui: 5px; - --border-radius-base: 6px; + --border-radius-editor: var(--uc-radius); + --border-radius-thumb: var(--uc-radius); + --border-radius-ui: var(--uc-radius); + --border-radius-base: var(--uc-radius); --cldtr-gap-min: 5px; --cldtr-gap-mid-1: 10px; --cldtr-gap-mid-2: 15px; --cldtr-gap-max: 20px; - --opacity-min: var(--opacity-shade-mid); - --opacity-mid: 0.1; - --opacity-max: 0.05; - --transition-duration-2: var(--transition-duration-all, 0.2s); --transition-duration-3: var(--transition-duration-all, 0.3s); --transition-duration-4: var(--transition-duration-all, 0.4s); --transition-duration-5: var(--transition-duration-all, 0.5s); - --shadow-base: 0px 5px 15px rgba(var(--rgb-shadow), 0.1), 0px 1px 4px rgba(var(--rgb-shadow), 0.15); - --modal-header-opacity: 1; --modal-header-height: var(--size-panel-heading); --modal-toolbar-height: var(--size-panel-heading); @@ -74,61 +46,54 @@ max-height: 100%; } -:host(.lr-cloud-image-editor) :is([can-handle-paste]:hover, [can-handle-paste]:focus), -.lr-cloud-image-editor :is([can-handle-paste]:hover, [can-handle-paste]:focus) { +[lr-cloud-image-editor] :is([can-handle-paste]:hover, [can-handle-paste]:focus) { --can-handle-paste: 'true'; } -:host(.lr-cloud-image-editor) - :is([tabindex][focus-visible], [tabindex]:hover, [with-effects][focus-visible], [with-effects]:hover), -.lr-cloud-image-editor +[lr-cloud-image-editor] :is([tabindex][focus-visible], [tabindex]:hover, [with-effects][focus-visible], [with-effects]:hover) { --filter-effect: var(--hover-filter) !important; --opacity-effect: var(--hover-opacity) !important; --color-effect: var(--hover-color-rgb) !important; + --background-effect: var(--hover-background) !important; } -:host(.lr-cloud-image-editor) :is([tabindex]:active, [with-effects]:active), -.lr-cloud-image-editor :is([tabindex]:active, [with-effects]:active) { +[lr-cloud-image-editor] :is([tabindex]:active, [with-effects]:active) { --filter-effect: var(--down-filter) !important; --opacity-effect: var(--down-opacity) !important; --color-effect: var(--down-color-rgb) !important; + --background-effect: var(--down-background) !important; } -:host(.lr-cloud-image-editor) :is([tabindex][active], [with-effects][active]), -.lr-cloud-image-editor :is([tabindex][active], [with-effects][active]) { +[lr-cloud-image-editor] :is([tabindex][active], [with-effects][active]) { --filter-effect: var(--active-filter) !important; --opacity-effect: var(--active-opacity) !important; --color-effect: var(--active-color-rgb) !important; + --background-effect: var(--active-background) !important; } -:host(.lr-cloud-image-editor) [hidden-scrollbar]::-webkit-scrollbar, -.lr-cloud-image-editor [hidden-scrollbar]::-webkit-scrollbar { +[lr-cloud-image-editor] [hidden-scrollbar]::-webkit-scrollbar { display: none; } -:host(.lr-cloud-image-editor) [hidden-scrollbar], -.lr-cloud-image-editor [hidden-scrollbar] { +[lr-cloud-image-editor] [hidden-scrollbar] { -ms-overflow-style: none; scrollbar-width: none; } -:host(.lr-cloud-image-editor.editor_ON), -.lr-cloud-image-editor.editor_ON { +[lr-cloud-image-editor].editor_ON { --modal-header-opacity: 0; --modal-header-height: 0px; --modal-toolbar-height: calc(var(--size-panel-heading) * 2); } -:host(.lr-cloud-image-editor.editor_OFF), -.lr-cloud-image-editor.editor_OFF { +[lr-cloud-image-editor].editor_OFF { --modal-header-opacity: 1; --modal-header-height: var(--size-panel-heading); --modal-toolbar-height: var(--size-panel-heading); } -:host(.lr-cloud-image-editor) > .wrapper, -.lr-cloud-image-editor > .wrapper { +[lr-cloud-image-editor] > .wrapper { --l-min-img-height: var(--modal-toolbar-height); --l-max-img-height: 100%; --l-edit-button-width: 120px; @@ -143,23 +108,20 @@ } @media only screen and (max-width: 800px) { - :host(.lr-cloud-image-editor) > .wrapper, - .lr-cloud-image-editor > .wrapper { + [lr-cloud-image-editor] > .wrapper { --l-edit-button-width: 70px; --l-toolbar-horizontal-padding: var(--cldtr-gap-min); } } -:host(.lr-cloud-image-editor) > .wrapper > .viewport, -.lr-cloud-image-editor > .wrapper > .viewport { +[lr-cloud-image-editor] > .wrapper > .viewport { display: flex; align-items: center; justify-content: center; overflow: hidden; } -:host(.lr-cloud-image-editor) > .wrapper > .viewport > .image_container > .image, -.lr-cloud-image-editor > .wrapper > .viewport > .image_container > .image { +[lr-cloud-image-editor] > .wrapper > .viewport > .image_container > .image { --viewer-image-opacity: 1; position: absolute; @@ -178,15 +140,13 @@ pointer-events: auto; } -:host(.lr-cloud-image-editor) > .wrapper > .viewport > .image_container > .image.image_visible_viewer, -.lr-cloud-image-editor > .wrapper > .viewport > .image_container > .image.image_visible_viewer { +[lr-cloud-image-editor] > .wrapper > .viewport > .image_container > .image.image_visible_viewer { transition: opacity var(--transition-duration-3) ease-in-out, transform var(--transition-duration-4); } -:host(.lr-cloud-image-editor) > .wrapper > .viewport > .image_container > .image.image_hidden_to_cropper, -.lr-cloud-image-editor > .wrapper > .viewport > .image_container > .image.image_hidden_to_cropper { +[lr-cloud-image-editor] > .wrapper > .viewport > .image_container > .image.image_hidden_to_cropper { --viewer-image-opacity: 0; background-image: var(--transparent-pixel); @@ -197,8 +157,7 @@ pointer-events: none; } -:host(.lr-cloud-image-editor) > .wrapper > .viewport > .image_container > .image.image_hidden_effects, -.lr-cloud-image-editor > .wrapper > .viewport > .image_container > .image.image_hidden_effects { +[lr-cloud-image-editor] > .wrapper > .viewport > .image_container > .image.image_hidden_effects { --viewer-image-opacity: 0; transform: scale(1); @@ -208,8 +167,7 @@ pointer-events: none; } -:host(.lr-cloud-image-editor) > .wrapper > .viewport > .image_container, -.lr-cloud-image-editor > .wrapper > .viewport > .image_container { +[lr-cloud-image-editor] > .wrapper > .viewport > .image_container { position: relative; display: block; width: 100%; @@ -218,14 +176,12 @@ transition: var(--transition-duration-3); } -:host(.lr-cloud-image-editor) > .wrapper > .toolbar, -.lr-cloud-image-editor > .wrapper > .toolbar { +[lr-cloud-image-editor] > .wrapper > .toolbar { position: relative; transition: 0.3s; } -:host(.lr-cloud-image-editor) > .wrapper > .toolbar > .toolbar_content, -.lr-cloud-image-editor > .wrapper > .toolbar > .toolbar_content { +[lr-cloud-image-editor] > .wrapper > .toolbar > .toolbar_content { position: absolute; bottom: 0px; left: 0px; @@ -236,8 +192,7 @@ background-color: var(--color-fill-contrast); } -:host(.lr-cloud-image-editor) > .wrapper > .toolbar > .toolbar_content.toolbar_content__viewer, -.lr-cloud-image-editor > .wrapper > .toolbar > .toolbar_content.toolbar_content__viewer { +[lr-cloud-image-editor] > .wrapper > .toolbar > .toolbar_content.toolbar_content__viewer { display: flex; align-items: center; justify-content: space-between; @@ -246,19 +201,16 @@ padding-left: var(--l-toolbar-horizontal-padding); } -:host(.lr-cloud-image-editor) > .wrapper > .toolbar > .toolbar_content.toolbar_content__editor, -.lr-cloud-image-editor > .wrapper > .toolbar > .toolbar_content.toolbar_content__editor { +[lr-cloud-image-editor] > .wrapper > .toolbar > .toolbar_content.toolbar_content__editor { display: flex; } -:host(.lr-cloud-image-editor) > .wrapper > .viewport > .info_pan, -.lr-cloud-image-editor > .wrapper > .viewport > .info_pan { +[lr-cloud-image-editor] > .wrapper > .viewport > .info_pan { position: absolute; user-select: none; } -:host(.lr-cloud-image-editor) > .wrapper > .viewport > .file_type_outer, -.lr-cloud-image-editor > .wrapper > .viewport > .file_type_outer { +[lr-cloud-image-editor] > .wrapper > .viewport > .file_type_outer { position: absolute; z-index: 2; display: flex; @@ -267,13 +219,11 @@ user-select: none; } -:host(.lr-cloud-image-editor) > .wrapper > .viewport > .file_type_outer > .file_type, -.lr-cloud-image-editor > .wrapper > .viewport > .file_type_outer > .file_type { +[lr-cloud-image-editor] > .wrapper > .viewport > .file_type_outer > .file_type { padding: 4px 0.8em; } -:host(.lr-cloud-image-editor) > .wrapper > .network_problems_splash, -.lr-cloud-image-editor > .wrapper > .network_problems_splash { +[lr-cloud-image-editor] > .wrapper > .network_problems_splash { position: absolute; z-index: 4; display: flex; @@ -283,8 +233,7 @@ background-color: var(--color-fill-contrast); } -:host(.lr-cloud-image-editor) > .wrapper > .network_problems_splash > .network_problems_content, -.lr-cloud-image-editor > .wrapper > .network_problems_splash > .network_problems_content { +[lr-cloud-image-editor] > .wrapper > .network_problems_splash > .network_problems_content { display: flex; flex: 1; flex-direction: column; @@ -292,34 +241,24 @@ justify-content: center; } -:host(.lr-cloud-image-editor) - > .wrapper - > .network_problems_splash - > .network_problems_content - > .network_problems_icon, -.lr-cloud-image-editor > .wrapper > .network_problems_splash > .network_problems_content > .network_problems_icon { +[lr-cloud-image-editor] > .wrapper > .network_problems_splash > .network_problems_content > .network_problems_icon { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; - color: rgba(var(--rgb-text-base), 0.6); - background-color: rgba(var(--rgb-fill-shaded)); + color: var(--uc-foreground); + background-color: var(--uc-muted); border-radius: 50%; } -:host(.lr-cloud-image-editor) - > .wrapper - > .network_problems_splash - > .network_problems_content - > .network_problems_text, -.lr-cloud-image-editor > .wrapper > .network_problems_splash > .network_problems_content > .network_problems_text { +[lr-cloud-image-editor] > .wrapper > .network_problems_splash > .network_problems_content > .network_problems_text { margin-top: var(--cldtr-gap-max); font-size: var(--font-size-ui); + color: var(--uc-foreground); } -:host(.lr-cloud-image-editor) > .wrapper > .network_problems_splash > .network_problems_footer, -.lr-cloud-image-editor > .wrapper > .network_problems_splash > .network_problems_footer { +[lr-cloud-image-editor] > .wrapper > .network_problems_splash > .network_problems_footer { display: flex; align-items: center; justify-content: center; @@ -382,20 +321,25 @@ lr-editor-button-control, lr-editor-crop-button-control, lr-editor-filter-control, lr-editor-operation-control { - --l-base-min-width: 40px; - --l-base-height: var(--l-base-min-width); + --l-base-min-width: var(--uc-button-size); + --l-base-height: var(--uc-button-size); --opacity-effect: var(--idle-opacity); --color-effect: var(--idle-color-rgb); + --background-effect: var(--idle-background); --filter-effect: var(--idle-filter); - --idle-color-rgb: var(--rgb-text-base); - --idle-opacity: 0.05; + + --idle-color-rgb: var(--uc-secondary-foreground); + --idle-opacity: 1; --idle-filter: 1; - --hover-color-rgb: var(--idle-color-rgb); - --hover-opacity: 0.08; + --idle-background: var(--uc-secondary); + --hover-color-rgb: var(--uc-secondary-foreground); + --hover-opacity: 1; --hover-filter: 0.8; + --hover-background: var(--uc-secondary-hover); --down-color-rgb: var(--hover-color-rgb); - --down-opacity: 0.12; + --down-opacity: 1; --down-filter: 0.6; + --down-background: var(--uc-secondary); position: relative; display: grid; @@ -403,7 +347,8 @@ lr-editor-operation-control { grid-template-rows: 100%; align-items: center; height: var(--l-base-height); - color: rgba(var(--idle-color-rgb)); + color: var(--color-effect); + opacity: var(--opacity-effect); outline: none; cursor: pointer; transition: var(--l-width-transition); @@ -412,8 +357,8 @@ lr-editor-operation-control { :where(lr-editor-button-control, lr-editor-crop-button-control, lr-editor-filter-control, lr-editor-operation-control) > lr-icon > svg { - width: 20px; - height: 20px; + width: var(--size-icon); + height: var(--size-icon); } lr-editor-filter-control > lr-icon.original-icon > svg { @@ -425,7 +370,12 @@ lr-editor-button-control.active, lr-editor-operation-control.active, lr-editor-crop-button-control.active, lr-editor-filter-control.active { - --idle-color-rgb: var(--rgb-primary-accent); + --idle-color-rgb: var(--uc-primary); + --idle-background: var(--uc-primary-transparent); + --idle-opacity: 0.9; + --hover-color-rgb: var(--uc-primary); + --hover-background: var(--uc-primary-transparent); + --hover-opacity: 1; } lr-editor-filter-control.not_active .preview[loaded] { @@ -440,7 +390,7 @@ lr-editor-button-control.not_active, lr-editor-operation-control.not_active, lr-editor-crop-button-control.not_active, lr-editor-filter-control.not_active { - --idle-color-rgb: var(--rgb-text-base); + --idle-color-rgb: var(--uc-secondary-foreground); } lr-editor-button-control > .before, @@ -453,7 +403,7 @@ lr-editor-filter-control > .before { z-index: -1; width: 100%; height: 100%; - background-color: rgba(var(--color-effect), var(--opacity-effect)); + background-color: var(--background-effect); border-radius: var(--border-radius-editor); transition: var(--transition-duration-3); } @@ -484,7 +434,7 @@ lr-editor-filter-control > .preview { } lr-editor-filter-control > .original-icon { - color: var(--color-text-base); + color: var(--color-effect); opacity: 0.3; } @@ -499,6 +449,7 @@ lr-editor-image-cropper { opacity: 0; pointer-events: none; touch-action: none; + color: var(--color-crop-guides); } lr-editor-image-cropper.active_from_editor { @@ -611,7 +562,7 @@ lr-editor-slider { align-items: center; justify-content: center; width: 100%; - height: 66px; + height: var(--size-panel-heading); } lr-editor-toolbar { @@ -623,16 +574,16 @@ lr-editor-toolbar { @media only screen and (max-width: 600px) { lr-editor-toolbar { --l-tab-gap: var(--cldtr-gap-mid-1); - --l-slider-padding: var(--cldtr-gap-min); - --l-controls-padding: var(--cldtr-gap-min); + --l-slider-padding: var(--uc-padding); + --l-controls-padding: var(--uc-padding); } } @media only screen and (min-width: 601px) { lr-editor-toolbar { - --l-tab-gap: calc(var(--cldtr-gap-mid-1) + var(--cldtr-gap-max)); - --l-slider-padding: var(--cldtr-gap-mid-1); - --l-controls-padding: var(--cldtr-gap-mid-1); + --l-tab-gap: var(--cldtr-gap-max); + --l-slider-padding: var(--uc-padding); + --l-controls-padding: var(--uc-padding); } } @@ -697,7 +648,7 @@ lr-editor-toolbar > .toolbar-container > .sub-toolbar > .controls-row > .tab-tog left: 0px; width: var(--size-touch-area); height: 2px; - background-color: var(--color-primary-accent); + background-color: var(--uc-secondary-foreground); transform: translateX(0px); transition: transform var(--transition-duration-3); } @@ -741,7 +692,7 @@ lr-editor-toolbar > .toolbar-container > .sub-toolbar > .controls-row > .tab-tog } lr-editor-toolbar > .toolbar-container > .sub-toolbar > .controls-row > .tab-toggles > .tab-toggle > lr-btn-ui { - width: 40px; + width: var(--uc-button-size); } lr-editor-toolbar @@ -753,8 +704,8 @@ lr-editor-toolbar > lr-btn-ui > lr-icon > svg { - width: 100%; - height: 100%; + width: var(--size-icon); + height: var(--size-icon); } lr-editor-toolbar > .toolbar-container > .sub-toolbar > .tab-content-row > .tab-content .controls-list_align { @@ -763,14 +714,14 @@ lr-editor-toolbar > .toolbar-container > .sub-toolbar > .tab-content-row > .tab- grid-template-columns: 1fr auto 1fr; box-sizing: border-box; min-width: 100%; - padding-left: var(--cldtr-gap-max); + padding-left: var(--uc-padding); } lr-editor-toolbar > .toolbar-container > .sub-toolbar > .tab-content-row > .tab-content .controls-list_inner { display: grid; grid-area: inner; grid-auto-flow: column; - grid-gap: calc((var(--cldtr-gap-min) - 1px) * 3); + gap: 6px; } lr-editor-toolbar @@ -779,7 +730,7 @@ lr-editor-toolbar > .tab-content-row > .tab-content .controls-list_inner:last-child { - padding-right: var(--cldtr-gap-max); + padding-right: var(--uc-padding); } lr-editor-toolbar .controls-list_last-item { @@ -807,10 +758,7 @@ lr-editor-toolbar .info-tooltip_wrapper { lr-editor-toolbar .info-tooltip { z-index: 3; - padding-top: calc(var(--cldtr-gap-min) / 2); - padding-right: var(--cldtr-gap-min); - padding-bottom: calc(var(--cldtr-gap-min) / 2); - padding-left: var(--cldtr-gap-min); + padding: 3px 6px; color: var(--color-text-base); font-size: 0.7em; letter-spacing: 1px; @@ -836,15 +784,25 @@ lr-btn-ui { --filter-effect: var(--idle-brightness); --opacity-effect: var(--idle-opacity); --color-effect: var(--idle-color-rgb); - --l-transition-effect: var(--css-transition, color var(--transition-duration-2), filter var(--transition-duration-2)); + --background-effect: var(--idle-background); + --l-transition-effect: var( + --css-transition, + color var(--transition-duration-2), + background-color var(--transition-duration-2), + filter var(--transition-duration-2) + ); display: inline-flex; align-items: center; box-sizing: var(--css-box-sizing, border-box); - height: var(--css-height, var(--size-touch-area)); - padding-right: var(--css-padding-right, var(--cldtr-gap-mid-1)); - padding-left: var(--css-padding-left, var(--cldtr-gap-mid-1)); - color: rgba(var(--color-effect), var(--opacity-effect)); + height: var(--css-height, var(--uc-button-size)); + padding-right: var(--css-padding-right, 14px); + padding-left: var(--css-padding-left, 14px); + font-size: 1em; + color: var(--color-effect); + background-color: var(--background-effect); + border-radius: var(--uc-radius); + opacity: var(--opacity-effect); outline: none; cursor: pointer; filter: brightness(var(--filter-effect)); @@ -860,7 +818,7 @@ lr-btn-ui .icon { display: flex; align-items: center; justify-content: center; - color: rgba(var(--color-effect), var(--opacity-effect)); + color: var(--color-effect); filter: brightness(var(--filter-effect)); transition: var(--l-transition-effect); } @@ -886,48 +844,126 @@ lr-btn-ui .icon_hidden { } lr-btn-ui.primary { - --idle-color-rgb: var(--rgb-primary-accent); + --idle-color-rgb: var(--uc-primary-foreground); --idle-brightness: 1; - --idle-opacity: 0.6; - --hover-color-rgb: var(--idle-color-rgb); + --idle-opacity: 1; + --idle-background: var(--uc-primary); + --hover-color-rgb: var(--uc-primary-foreground); --hover-brightness: 1; --hover-opacity: 1; - --down-color-rgb: var(--hover-color-rgb); + --hover-background: var(--uc-primary-hover); + --down-color-rgb: var(--uc-primary-foreground); --down-brightness: 0.75; --down-opacity: 1; - --active-color-rgb: var(--rgb-primary-accent); + --down-background: var(--uc-primary); + --active-color-rgb: var(--uc-primary-foreground); --active-brightness: 1; --active-opacity: 1; + --active-background: var(--uc-primary); } -lr-btn-ui.boring { - --idle-color-rgb: var(--rgb-text-base); +lr-btn-ui.primary-icon { + --idle-color-rgb: var(--uc-primary); --idle-brightness: 1; - --idle-opacity: 0.6; - --hover-color-rgb: var(--rgb-text-base); + --idle-opacity: 1; + --idle-background: transparent; + --hover-color-rgb: var(--uc-primary); --hover-brightness: 1; --hover-opacity: 1; - --down-color-rgb: var(--hover-color-rgb); + --hover-background: var(--uc-primary-transparent); + --down-color-rgb: var(--uc-primary); + --down-brightness: 0.75; + --down-opacity: 1; + --down-background: var(--uc-primary-transparent); + --active-color-rgb: var(--uc-primary-foreground); + --active-brightness: 1; + --active-opacity: 1; + --active-background: var(--uc-primary); + + padding: 0; + width: var(--uc-button-size); +} + +lr-btn-ui.secondary { + --idle-color-rgb: var(--uc-secondary-foreground); + --idle-brightness: 1; + --idle-opacity: 1; + --idle-background: var(--uc-secondary); + --hover-color-rgb: var(--uc-secondary-foreground); + --hover-brightness: 1; + --hover-opacity: 1; + --hover-background: var(--uc-secondary-hover); + --down-color-rgb: var(--uc-secondary-foreground); --down-brightness: 1; --down-opacity: 1; - --active-color-rgb: var(--rgb-primary-accent); + --down-background: var(--uc-secondary-hover); + --active-color-rgb: var(--uc-secondary-foreground); --active-brightness: 1; --active-opacity: 1; + --active-background: transparent; +} + +lr-btn-ui.secondary-icon { + --idle-color-rgb: var(--uc-secondary-foreground); + --idle-brightness: 1; + --idle-opacity: 1; + --idle-background: transparent; + --hover-color-rgb: var(--uc-secondary-foreground); + --hover-brightness: 1; + --hover-opacity: 1; + --hover-background: var(--uc-secondary); + --down-color-rgb: var(--uc-secondary-foreground); + --down-brightness: 1; + --down-opacity: 1; + --down-background: var(--uc-secondary); + --active-color-rgb: var(--uc-secondary-foreground); + --active-brightness: 1; + --active-opacity: 1; + --active-background: transparent; + + padding: 0; + width: var(--uc-button-size); +} + +lr-btn-ui.tab { + --idle-color-rgb: var(--uc-secondary-foreground); + --idle-brightness: 1; + --idle-opacity: 1; + --idle-background: transparent; + --hover-color-rgb: var(--uc-secondary-foreground); + --hover-brightness: 1; + --hover-opacity: 1; + --hover-background: var(--uc-secondary); + --down-color-rgb: var(--uc-secondary-foreground); + --down-brightness: 1; + --down-opacity: 1; + --down-background: var(--uc-secondary); + --active-color-rgb: var(--uc-secondary-foreground); + --active-brightness: 1; + --active-opacity: 1; + --active-background: transparent; + + padding: 0; + width: var(--uc-button-size); } lr-btn-ui.default { - --idle-color-rgb: var(--rgb-text-base); + --idle-color-rgb: var(--uc-secondary-foreground); --idle-brightness: 1; - --idle-opacity: 0.6; - --hover-color-rgb: var(--rgb-primary-accent); + --idle-opacity: 1; + --idle-background: var(--uc-secondary); + --hover-color-rgb: var(--uc-secondary-foreground); --hover-brightness: 1; --hover-opacity: 1; - --down-color-rgb: var(--hover-color-rgb); + --hover-background: var(--uc-secondary-hover); + --down-color-rgb: var(--uc-secondary-foreground); --down-brightness: 0.75; --down-opacity: 1; - --active-color-rgb: var(--rgb-primary-accent); + --down-background: var(--uc-secondary); + --active-color-rgb: var(--uc-primary); --active-brightness: 1; --active-opacity: 1; + --active-background: var(--uc-primary-transparent); } lr-line-loader-ui { @@ -949,7 +985,7 @@ lr-line-loader-ui .inner { lr-line-loader-ui .line { width: 100%; height: 100%; - background-color: var(--color-primary-accent); + background-color: var(--uc-primary); transform: translateX(-101%); transition: transform 1s; } @@ -958,11 +994,11 @@ lr-slider-ui { --l-thumb-size: 24px; --l-zero-dot-size: 5px; --l-zero-dot-offset: 2px; - --idle-color-rgb: var(--rgb-text-base); - --hover-color-rgb: var(--rgb-primary-accent); - --down-color-rgb: var(--rgb-primary-accent); + --idle-color-rgb: var(--uc-foreground); + --hover-color-rgb: var(--uc-primary); + --down-color-rgb: var(--uc-primary); --color-effect: var(--idle-color-rgb); - --l-color: rgb(var(--color-effect)); + --l-color: var(--color-effect); position: relative; display: flex; @@ -981,7 +1017,9 @@ lr-slider-ui .thumb { border-radius: 50%; transform: translateX(0px); opacity: 1; - transition: opacity var(--transition-duration-2); + transition: + opacity var(--transition-duration-2), + background-color var(--transition-duration-2); } lr-slider-ui .steps { @@ -1001,7 +1039,7 @@ lr-slider-ui .border-step { height: 10px; border-right: 1px solid var(--l-color); opacity: 0.6; - transition: var(--transition-duration-2); + transition: border-color var(--transition-duration-2); } lr-slider-ui .minor-step { @@ -1009,7 +1047,7 @@ lr-slider-ui .minor-step { height: 4px; border-right: 1px solid var(--l-color); opacity: 0.2; - transition: var(--transition-duration-2); + transition: border-color var(--transition-duration-2); } lr-slider-ui .zero-dot { @@ -1049,19 +1087,7 @@ lr-presence-toggle.hidden { pointer-events: none; } -/* TODO: remove ctx-provider */ -/* stylelint-disable-next-line plugin/stylelint-force-app-name-prefix */ -ctx-provider { - --color-text-base: black; - --color-primary-accent: blue; - - display: flex; - align-items: center; - justify-content: center; - width: 190px; - height: 40px; - padding-right: 10px; - padding-left: 10px; - background-color: #f5f5f5; - border-radius: 3px; +lr-presence-toggle.initial { + display: none !important; + transition: none !important; } diff --git a/blocks/CloudImageEditor/src/css/icons.css b/blocks/CloudImageEditor/src/css/icons.css index bedf8eb19..7fa07e5fa 100644 --- a/blocks/CloudImageEditor/src/css/icons.css +++ b/blocks/CloudImageEditor/src/css/icons.css @@ -1,7 +1,12 @@ -.lr-cloud-image-editor lr-icon { +:where([lr-cloud-image-editor]) lr-icon { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; } + +:where([lr-cloud-image-editor]) lr-icon svg { + width: calc(var(--uc-button-size) / 2); + height: calc(var(--uc-button-size) / 2); +} diff --git a/blocks/CloudImageEditor/src/elements/presence-toggle/PresenceToggle.js b/blocks/CloudImageEditor/src/elements/presence-toggle/PresenceToggle.js index 35b16e57c..575aabe53 100644 --- a/blocks/CloudImageEditor/src/elements/presence-toggle/PresenceToggle.js +++ b/blocks/CloudImageEditor/src/elements/presence-toggle/PresenceToggle.js @@ -55,14 +55,17 @@ export class PresenceToggle extends Block { initCallback() { super.initCallback(); - this.setAttribute('hidden', ''); + + this.classList.toggle('initial', true); if (!this._externalTransitions) { this.classList.add(DEFAULT_STYLE.transition); } this._handleVisible(); - setTimeout(() => this.removeAttribute('hidden'), 0); + setTimeout(() => { + this.classList.toggle('initial', false); + }, 0); } } -PresenceToggle.template = /* HTML */ ` `; +PresenceToggle.template = /* HTML */ ` `; diff --git a/blocks/CloudImageEditor/src/icons/closeMax.svg b/blocks/CloudImageEditor/src/icons/closeMax.svg index 3e621f4de..88e57184c 100644 --- a/blocks/CloudImageEditor/src/icons/closeMax.svg +++ b/blocks/CloudImageEditor/src/icons/closeMax.svg @@ -1,3 +1,3 @@ - - + + diff --git a/blocks/CloudImageEditor/src/icons/done.svg b/blocks/CloudImageEditor/src/icons/done.svg index 87a628a61..78ff9b54e 100644 --- a/blocks/CloudImageEditor/src/icons/done.svg +++ b/blocks/CloudImageEditor/src/icons/done.svg @@ -1,3 +1,3 @@ - - + + diff --git a/blocks/CloudImageEditor/src/icons/edit-file.svg b/blocks/CloudImageEditor/src/icons/edit-file.svg new file mode 100644 index 000000000..c88b71952 --- /dev/null +++ b/blocks/CloudImageEditor/src/icons/edit-file.svg @@ -0,0 +1,3 @@ + + + diff --git a/blocks/CloudImageEditor/src/icons/original.svg b/blocks/CloudImageEditor/src/icons/original.svg index abe71893a..906db13f9 100644 --- a/blocks/CloudImageEditor/src/icons/original.svg +++ b/blocks/CloudImageEditor/src/icons/original.svg @@ -1,3 +1,3 @@ - + diff --git a/blocks/CloudImageEditor/src/svg-sprite.js b/blocks/CloudImageEditor/src/svg-sprite.js index 89542dbfc..ac2f498be 100644 --- a/blocks/CloudImageEditor/src/svg-sprite.js +++ b/blocks/CloudImageEditor/src/svg-sprite.js @@ -1 +1 @@ -export default ""; +export default ""; \ No newline at end of file diff --git a/blocks/CloudImageEditorActivity/index.css b/blocks/CloudImageEditorActivity/index.css index 58dd3fb84..8ad271e8d 100644 --- a/blocks/CloudImageEditorActivity/index.css +++ b/blocks/CloudImageEditorActivity/index.css @@ -4,10 +4,10 @@ lr-cloud-image-editor-activity { width: 100%; height: 100%; overflow: hidden; - background-color: var(--clr-background-light); + background-color: var(--uc-background); } -lr-modal lr-cloud-image-editor-activity { - width: min(calc(var(--modal-max-w) - var(--gap-mid) * 2), calc(100vw - var(--gap-mid) * 2)); +[lr-modal] lr-cloud-image-editor-activity { + width: min(calc(var(--uc-dialog-max-width) - var(--uc-padding) * 2), calc(100vw - var(--uc-padding) * 2)); height: var(--modal-content-height-fill, 100%); } diff --git a/blocks/Color/Color.js b/blocks/Color/Color.js deleted file mode 100644 index 479d30d0e..000000000 --- a/blocks/Color/Color.js +++ /dev/null @@ -1,17 +0,0 @@ -import { Block } from '../../abstract/Block.js'; - -export class Color extends Block { - init$ = { - ...this.init$, - inputOpacity: 0, - '*selectedColor': '#f00', - onChange: () => { - this.$['*selectedColor'] = this.ref.input['value']; - }, - }; -} - -Color.template = /* HTML */ ` - -
-`; diff --git a/blocks/Color/color.css b/blocks/Color/color.css deleted file mode 100644 index a79312818..000000000 --- a/blocks/Color/color.css +++ /dev/null @@ -1,32 +0,0 @@ -lr-color { - position: relative; - display: inline-flex; - align-items: center; - justify-content: center; - width: var(--ui-size); - height: var(--ui-size); - overflow: hidden; - background-color: var(--clr-background); - cursor: pointer; -} - -lr-color[current] { - background-color: var(--clr-txt); -} - -lr-color input[type='color'] { - position: absolute; - display: block; - width: 100%; - height: 100%; - opacity: 0; -} - -lr-color .current-color { - position: absolute; - width: 50%; - height: 50%; - border: 2px solid #fff; - border-radius: 100%; - pointer-events: none; -} diff --git a/blocks/ConfirmationDialog/ConfirmationDialog.js b/blocks/ConfirmationDialog/ConfirmationDialog.js deleted file mode 100644 index 8391f9028..000000000 --- a/blocks/ConfirmationDialog/ConfirmationDialog.js +++ /dev/null @@ -1,77 +0,0 @@ -import { ActivityBlock } from '../../abstract/ActivityBlock.js'; - -export class UiConfirmation { - captionL10nStr = 'confirm-your-action'; - messageL10Str = 'are-you-sure'; - confirmL10nStr = 'yes'; - denyL10nStr = 'no'; - confirmAction() { - console.log('Confirmed'); - } - denyAction() { - this['historyBack'](); - } -} - -export class ConfirmationDialog extends ActivityBlock { - activityType = ActivityBlock.activities.CONFIRMATION; - - /** @private */ - _defaults = new UiConfirmation(); - - init$ = { - ...this.init$, - activityCaption: '', - messageTxt: '', - confirmBtnTxt: '', - denyBtnTxt: '', - '*confirmation': null, - onConfirm: this._defaults.confirmAction, - onDeny: this._defaults.denyAction.bind(this), - }; - - initCallback() { - super.initCallback(); - this.set$({ - messageTxt: this.l10n(this._defaults.messageL10Str), - confirmBtnTxt: this.l10n(this._defaults.confirmL10nStr), - denyBtnTxt: this.l10n(this._defaults.denyL10nStr), - }); - this.sub('*confirmation', (/** @type {UiConfirmation} */ cfn) => { - if (!cfn) { - return; - } - this.set$({ - '*currentActivity': ActivityBlock.activities.CONFIRMATION, - activityCaption: this.l10n(cfn.captionL10nStr), - messageTxt: this.l10n(cfn.messageL10Str), - confirmBtnTxt: this.l10n(cfn.confirmL10nStr), - denyBtnTxt: this.l10n(cfn.denyL10nStr), - onDeny: () => { - cfn.denyAction(); - }, - onConfirm: () => { - cfn.confirmAction(); - }, - }); - }); - } -} - -ConfirmationDialog.template = /* HTML */ ` - - - {{activityCaption}} - - - -
{{messageTxt}}
-
- - -
-`; diff --git a/blocks/ConfirmationDialog/confirmation.css b/blocks/ConfirmationDialog/confirmation.css deleted file mode 100644 index f84b3a22d..000000000 --- a/blocks/ConfirmationDialog/confirmation.css +++ /dev/null @@ -1,21 +0,0 @@ -lr-confirmation-dialog { - display: block; - padding: var(--gap-mid); - padding-top: var(--gap-max); -} - -lr-confirmation-dialog .message { - display: flex; - justify-content: center; - padding: var(--gap-mid); - padding-bottom: var(--gap-max); - font-weight: 500; - font-size: 1.1em; -} - -lr-confirmation-dialog .toolbar { - display: grid; - grid-template-columns: 1fr 1fr; - gap: var(--gap-mid); - margin-top: var(--gap-mid); -} diff --git a/blocks/Copyright/copyright.css b/blocks/Copyright/copyright.css index 919645431..037e291d6 100644 --- a/blocks/Copyright/copyright.css +++ b/blocks/Copyright/copyright.css @@ -1,17 +1,27 @@ lr-copyright { display: flex; - align-items: flex-end; + width: 100%; + justify-content: center; } lr-copyright .credits { - padding: 0 var(--gap-mid) var(--gap-mid) calc(var(--gap-mid) * 1.5); - color: var(--clr-txt-lightest); + all: unset; + position: absolute; + bottom: 12px; + background-color: var(--uc-background); + padding: 2px 5px; + border-radius: 6px; + color: var(--uc-muted-foreground); font-weight: normal; - font-size: 0.85em; - opacity: 0.7; - transition: var(--transition-duration) ease; + font-size: 12px; + opacity: 0.9; + cursor: pointer; + transition: + opacity var(--uc-transition), + background-color var(--uc-transition); } lr-copyright .credits:hover { opacity: 1; + background-color: var(--uc-muted); } diff --git a/blocks/DropArea/DropArea.js b/blocks/DropArea/DropArea.js index 01225a655..a48620ddc 100644 --- a/blocks/DropArea/DropArea.js +++ b/blocks/DropArea/DropArea.js @@ -12,6 +12,7 @@ const GLOBAL_CTX_NAME = 'lr-drop-area'; const REGISTRY_KEY = `${GLOBAL_CTX_NAME}/registry`; export class DropArea extends UploaderBlock { + static styleAttrs = [...super.styleAttrs, 'lr-drop-area']; constructor() { super(); diff --git a/blocks/DropArea/drop-area.css b/blocks/DropArea/drop-area.css index 636fa1239..2e44584be 100644 --- a/blocks/DropArea/drop-area.css +++ b/blocks/DropArea/drop-area.css @@ -1,13 +1,15 @@ -lr-drop-area { - padding: var(--gap-min); +:where([lr-drop-area]) { + padding: 2px; overflow: hidden; - border: var(--border-dashed); - border-radius: var(--border-radius-frame); - transition: var(--transition-duration) ease; + border: 1px dashed var(--uc-border); + border-radius: calc(var(--uc-radius) * 1.75); + transition: + border var(--uc-transition), + border-radius var(--uc-transition); } -lr-drop-area, -lr-drop-area .content-wrapper { +:where([lr-drop-area]), +:where([lr-drop-area]) .content-wrapper { display: flex; align-items: center; justify-content: center; @@ -15,122 +17,127 @@ lr-drop-area .content-wrapper { height: 100%; } -lr-drop-area .text { +:where([lr-drop-area]) .text { position: relative; - margin: var(--gap-mid); - color: var(--clr-txt-light); - transition: var(--transition-duration) ease; + margin: var(--uc-padding); + color: var(--uc-muted-foreground); + transition: color var(--uc-transition); } -lr-drop-area[ghost][drag-state='inactive'] { +:where([lr-drop-area])[ghost][drag-state='inactive'] { display: none; - opacity: 0; } -lr-drop-area[ghost]:not([fullscreen]):is([drag-state='active'], [drag-state='near'], [drag-state='over']) { - background: var(--clr-background); +:where([lr-drop-area])[ghost]:not([fullscreen]):is([drag-state='active'], [drag-state='near'], [drag-state='over']) { + background: var(--uc-background); } -lr-drop-area[with-icon] +:where([lr-drop-area])[with-icon] > .content-wrapper:is([drag-state='active'], [drag-state='near'], [drag-state='over']) :is(.text, .icon-container) { - color: var(--clr-accent); + color: var(--uc-primary); } -lr-drop-area:is([drag-state='active'], [drag-state='near'], [drag-state='over'], :hover) { - color: var(--clr-accent); - background: var(--clr-accent-lightest); - border-color: var(--clr-accent-light); +:where([lr-drop-area]):is([drag-state='active'], [drag-state='near'], [drag-state='over'], :hover) { + color: var(--uc-primary); + background: var(--uc-primary-transparent); + border-color: var(--uc-primary-transparent); } -lr-drop-area:is([drag-state='active'], [drag-state='near']) { +:where([lr-drop-area]):is([drag-state='active'], [drag-state='near']) { opacity: 1; } -lr-drop-area[drag-state='over'] { - border-color: var(--clr-accent); +:where([lr-drop-area])[drag-state='over'] { + border-color: var(--uc-primary); opacity: 1; } -lr-drop-area[with-icon] { - min-height: calc(var(--ui-size) * 6); +:where([lr-drop-area])[with-icon] { + min-height: 180px; } -lr-drop-area[with-icon] .content-wrapper { +:where([lr-drop-area])[with-icon] .content-wrapper { display: flex; flex-direction: column; } -lr-drop-area[with-icon] .text { - color: var(--clr-txt); +:where([lr-drop-area])[with-icon] .text { + color: var(--uc-foreground); font-weight: 500; font-size: 1.1em; } -lr-drop-area[with-icon] .icon-container { +:where([lr-drop-area])[with-icon] .icon-container { position: relative; - width: calc(var(--ui-size) * 2); - height: calc(var(--ui-size) * 2); - margin: var(--gap-mid); + width: 64px; + height: 64px; + margin: var(--uc-padding); overflow: hidden; - color: var(--clr-txt); - background-color: var(--clr-background); + color: var(--uc-foreground); + background-color: var(--uc-muted); border-radius: 50%; - transition: var(--transition-duration) ease; + transition: + color var(--uc-transition), + background-color var(--uc-transition); } -lr-drop-area[with-icon] lr-icon { +:where([lr-drop-area])[with-icon] lr-icon { position: absolute; - top: calc(50% - var(--ui-size) / 2); - left: calc(50% - var(--ui-size) / 2); - transition: var(--transition-duration) ease; + width: 32px; + height: 32px; + top: calc(50% - 16px); + left: calc(50% - 16px); + transition: transform var(--uc-transition); } -lr-drop-area[with-icon] lr-icon:last-child { - transform: translateY(calc(var(--ui-size) * 1.5)); +:where([lr-drop-area])[with-icon] lr-icon:last-child { + transform: translateY(48px); } -lr-drop-area[with-icon]:hover .icon-container, -lr-drop-area[with-icon]:hover .text { - color: var(--clr-accent); +:where([lr-drop-area])[with-icon]:hover .icon-container, +:where([lr-drop-area])[with-icon]:hover .text { + color: var(--uc-primary); } -lr-drop-area[with-icon]:hover .icon-container { - background-color: var(--clr-accent-lightest); +:where([lr-drop-area])[with-icon]:hover .icon-container { + background-color: var(--uc-primary-transparent); } -lr-drop-area[with-icon] +:where([lr-drop-area])[with-icon] > .content-wrapper:is([drag-state='active'], [drag-state='near'], [drag-state='over']) .icon-container { - color: white; - background-color: var(--clr-accent); + color: var(--uc-primary-foreground); + background-color: var(--uc-primary); } -lr-drop-area[with-icon] > .content-wrapper:is([drag-state='active'], [drag-state='near'], [drag-state='over']) .text { - color: var(--clr-accent); +:where([lr-drop-area])[with-icon] + > .content-wrapper:is([drag-state='active'], [drag-state='near'], [drag-state='over']) + .text { + color: var(--uc-primary); } -lr-drop-area[with-icon] +:where([lr-drop-area])[with-icon] > .content-wrapper:is([drag-state='active'], [drag-state='near'], [drag-state='over']) lr-icon:first-child { - transform: translateY(calc(var(--ui-size) * -1.5)); + transform: translateY(-48px); } -lr-drop-area[with-icon] +:where([lr-drop-area])[with-icon] > .content-wrapper:is([drag-state='active'], [drag-state='near'], [drag-state='over']) lr-icon:last-child { transform: translateY(0); } -lr-drop-area[with-icon] > .content-wrapper[drag-state='near'] lr-icon:last-child { +:where([lr-drop-area])[with-icon] > .content-wrapper[drag-state='near'] lr-icon:last-child { transform: scale(1.3); } -lr-drop-area[with-icon] > .content-wrapper[drag-state='over'] lr-icon:last-child { +:where([lr-drop-area])[with-icon] > .content-wrapper[drag-state='over'] lr-icon:last-child { transform: scale(1.5); } -lr-drop-area[fullscreen] { +:where([lr-drop-area])[fullscreen] { position: fixed; top: 0; right: 0; @@ -140,37 +147,42 @@ lr-drop-area[fullscreen] { display: flex; align-items: center; justify-content: center; - width: calc(100vw - var(--gap-mid) * 2); - height: calc(100vh - var(--gap-mid) * 2); - margin: var(--gap-mid); + width: calc(100vw - var(--uc-padding) * 2); + height: calc(100vh - var(--uc-padding) * 2); + margin: var(--uc-padding); } -lr-drop-area[fullscreen] .content-wrapper { +:where([lr-drop-area])[fullscreen] .content-wrapper { width: 100%; - max-width: calc(var(--modal-normal-w) * 0.8); - height: calc(var(--ui-size) * 6); - color: var(--clr-txt); - background-color: var(--clr-background-light); - border-radius: var(--border-radius-frame); - box-shadow: var(--modal-shadow); - transition: var(--transition-duration) ease; -} - -lr-drop-area[with-icon][fullscreen][drag-state='active'] > .content-wrapper, -lr-drop-area[with-icon][fullscreen][drag-state='near'] > .content-wrapper { - transform: translateY(var(--gap-mid)); + max-width: calc(var(--uc-dialog-width) * 0.8); + height: 180px; + color: var(--uc-foreground); + background-color: var(--uc-background); + border-radius: calc(var(--uc-radius) * 1.75); + box-shadow: var(--uc-dialog-shadow); + transition: + color var(--uc-transition), + background-color var(--uc-transition), + box-shadow var(--uc-transition), + border-radius var(--uc-transition), + transform var(--uc-transition); +} + +:where([lr-drop-area])[with-icon][fullscreen][drag-state='active'] > .content-wrapper, +:where([lr-drop-area])[with-icon][fullscreen][drag-state='near'] > .content-wrapper { + transform: translateY(10px); opacity: 0; } -lr-drop-area[with-icon][fullscreen][drag-state='over'] > .content-wrapper { +:where([lr-drop-area])[with-icon][fullscreen][drag-state='over'] > .content-wrapper { transform: translateY(0px); opacity: 1; } -:is(lr-drop-area[with-icon][fullscreen]) > .content-wrapper lr-icon:first-child { - transform: translateY(calc(var(--ui-size) * -1.5)); +:is(:where([lr-drop-area])[with-icon][fullscreen]) > .content-wrapper lr-icon:first-child { + transform: translateY(-48px); } -lr-drop-area[clickable] { +:where([lr-drop-area])[clickable] { cursor: pointer; } diff --git a/blocks/EditableCanvas/CanMan.js b/blocks/EditableCanvas/CanMan.js deleted file mode 100644 index 2918f76c4..000000000 --- a/blocks/EditableCanvas/CanMan.js +++ /dev/null @@ -1,209 +0,0 @@ -// Canvas Manipulator -import { applyStyles, applyAttributes } from '@symbiotejs/symbiote'; -const SVGNS = 'http://www.w3.org/2000/svg'; - -export class CanMan { - _syncSvgSize() { - let rect = this.svgGroupEl.getBoundingClientRect(); - applyAttributes(this.svgEl, { - viewBox: `0, 0, ${rect.width}, ${rect.height}`, - width: rect.width, - height: rect.height, - }); - } - - _syncCanvas() { - return new Promise((resolve, reject) => { - let url = URL.createObjectURL( - new Blob([this.svgEl.outerHTML], { - type: 'image/svg+xml', - }), - ); - this.vImg.onload = () => { - this.can.height = this.vImg.height; - this.can.width = this.vImg.width; - this.ctx.drawImage(this.vImg, 0, 0, this.vImg.width, this.vImg.height); - resolve(); - }; - this.vImg.onerror = () => { - reject(); - }; - this.vImg.src = url; - }); - } - - _backSyncSvg() { - this.svgGroupEl.style.transform = null; - this.svgGroupEl.style.filter = null; - applyAttributes(this.svgEl, { - viewBox: `0, 0, ${this.can.width}, ${this.can.height}`, - width: this.can.width, - height: this.can.height, - }); - applyAttributes(this.svgImgEl, { - href: this.can.toDataURL('image/png'), - width: this.can.width, - height: this.can.height, - }); - this._addedObjects.forEach((obj) => { - obj.remove(); - }); - return new Promise((resolve, reject) => { - this.svgImgEl.onload = () => { - resolve(); - }; - this.svgImgEl.onerror = () => { - reject(); - }; - }); - } - - async _syncAll() { - this._syncSvgSize(); - await this._syncCanvas(); - await this._backSyncSvg(); - } - - /** @param {import('./EditableCanvas.js').RefMap} refMap */ - constructor(refMap) { - /** @type {HTMLCanvasElement} */ - this.can = refMap.canvas; - /** @type {SVGElement} */ - this.svgEl = refMap.svg; - this.svgGroupEl = refMap.svgGroup; - this.svgImgEl = refMap.svgImg; - this.vImg = new Image(); - - this.ctx = refMap.canvCtx; - - this.currentColor = CanMan.defaultColor; - - this._addedObjects = new Set(); - - window.setTimeout(() => { - this._backSyncSvg(); - }, 100); - } - - applyCss(cssMap) { - applyStyles(this.svgGroupEl, cssMap); - } - - getImg() { - let img = new Image(); - img.src = this.can.toDataURL('image/png'); - return new Promise((resolve, reject) => { - img.onload = () => { - resolve(img); - }; - img.onerror = () => { - reject(img); - }; - }); - } - - rotate() { - this.applyCss({ - 'transform-origin': '0 0', - transform: `rotate(90deg) translateY(-${this.can.height}px)`, - }); - this._syncAll(); - } - - /** @param {'vertical' | 'horizontal'} type */ - flip(type) { - this.applyCss({ - 'transform-origin': '50% 50%', - transform: `scale(${type === 'vertical' ? '1, -1' : '-1, 1'})`, - }); - this._syncAll(); - } - - brightness(val) { - this.applyCss({ - filter: `brightness(${val}%)`, - }); - } - - contrast(val) { - this.applyCss({ - filter: `contrast(${val}%)`, - }); - } - - saturate(val) { - this.applyCss({ - filter: `saturate(${val}%)`, - }); - } - - setColor(val) { - this.currentColor = val; - } - - startText() { - let onStart = (e) => { - let text = document.createElementNS(SVGNS, 'text'); - // @ts-ignore - applyAttributes(text, { - fill: this.currentColor, - x: e.offsetX, - y: e.offsetY, - }); - (text.textContent = 'TEXT'), this.svgGroupEl.appendChild(text); - this._addedObjects.add(text); - text.focus(); - this.svgEl.removeEventListener('mousedown', onStart); - }; - this.svgEl.addEventListener('mousedown', onStart); - } - - stopText() { - this.bake(); - } - - startDraw() { - this.svgEl.addEventListener('mousedown', (e) => { - let pLine = document.createElementNS(SVGNS, 'polyline'); - // @ts-ignore - applyAttributes(pLine, { - fill: 'none', - stroke: this.currentColor, - 'stroke-width': '4px', - }); - this.svgGroupEl.appendChild(pLine); - this._addedObjects.add(pLine); - let points = []; - this.svgEl.onmousemove = (e) => { - points.push(`${e.offsetX},${e.offsetY}`); - pLine.setAttribute('points', points.join(' ')); - }; - }); - window.addEventListener('mouseup', () => { - this.svgEl.onmousemove = null; - this.bake(); - }); - window.addEventListener('mouseleave', () => { - this.svgEl.onmousemove = null; - this.bake(); - }); - } - - /** @param {Boolean} val */ - removeMode(val) { - if (val) { - } - } - - resize() {} - - crop() {} - - bake() { - this._syncAll(); - } - - restore() {} -} - -CanMan.defaultColor = '#f00'; diff --git a/blocks/EditableCanvas/EditableCanvas.js b/blocks/EditableCanvas/EditableCanvas.js deleted file mode 100644 index d42b76ea5..000000000 --- a/blocks/EditableCanvas/EditableCanvas.js +++ /dev/null @@ -1,104 +0,0 @@ -import { Block } from '../../abstract/Block.js'; -import { applyStyles } from '@symbiotejs/symbiote'; -import { checkerboardCssBg } from '../svg-backgrounds/svg-backgrounds.js'; - -/** - * @typedef {Object} RefMap - * @property {import('./EditableCanvas.js').EditableCanvas} parent - * @property {HTMLCanvasElement} canvas - * @property {CanvasRenderingContext2D} canvCtx - * @property {SVGElement} svg - * @property {SVGElement} svgGroup - * @property {SVGImageElement} svgImg - */ - -export class EditableCanvas extends Block { - init$ = { - ...this.init$, - refMap: null, - disabled: true, - toolbarHidden: true, - checkerboard: false, - }; - - constructor() { - super(); - applyStyles(this, { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - }); - } - - initCallback() { - super.initCallback(); - this.sub('disabled', () => { - this.$.toolbarHidden = this.hasAttribute('disabled') && this.getAttribute('disabled') !== 'false'; - }); - this.sub('checkerboard', () => { - this.style.backgroundImage = this.hasAttribute('checkerboard') ? `url(${checkerboardCssBg()})` : 'unset'; - }); - /** @type {HTMLCanvasElement} */ - // @ts-ignore - this.canvas = this.ref.cvs; - this.canvCtx = this.canvas.getContext('2d'); - this.$.refMap = { - parent: this, - canvas: this.canvas, - canvCtx: this.canvCtx, - svg: this.ref.svg, - svgGroup: this.ref.svg_g, - svgImg: this.ref.svg_img, - }; - } - - /** @param {HTMLImageElement} img */ - setImage(img) { - if (img.height && img.width) { - this.canvas.height = img.height; - this.canvas.width = img.width; - this.canvCtx.drawImage(img, 0, 0, img.width, img.height); - } else { - this.clear(); - img.onload = () => { - this.canvas.height = img.height; - this.canvas.width = img.width; - this.canvCtx.drawImage(img, 0, 0, img.width, img.height); - }; - } - } - - /** @param {File} imgFile */ - setImageFile(imgFile) { - let img = new Image(); - let url = URL.createObjectURL(imgFile); - img.src = url; - this.setImage(img); - } - - /** @param {String} url */ - setImageUrl(url) { - let img = new Image(); - img.src = url; - this.setImage(img); - } - - clear() { - this.canvCtx.clearRect(0, 0, this.canvas.width, this.canvas.height); - } -} - -EditableCanvas.template = /* HTML */ ` - - - - - - - -`; - -EditableCanvas.bindAttributes({ - disabled: 'disabled', - checkerboard: 'checkerboard', -}); diff --git a/blocks/EditableCanvas/EditableCanvasToolbar.js b/blocks/EditableCanvas/EditableCanvasToolbar.js deleted file mode 100644 index da4151b6f..000000000 --- a/blocks/EditableCanvas/EditableCanvasToolbar.js +++ /dev/null @@ -1,143 +0,0 @@ -import { Block } from '../../abstract/Block.js'; -import { CanMan } from './CanMan.js'; -import { Range } from '../Range/Range.js'; -import { Color } from '../Color/Color.js'; - -import { getButtons } from './buttons.js'; - -// TODO: get rid of side effects -Range.reg('range'); -Color.reg('color'); - -const FS_ICON = { - FS: 'fullscreen', - EXIT: 'fullscreen-exit', -}; - -export class EditorToolbar extends Block { - get actionsMap() { - return { - fullscreen: () => { - if (document.fullscreenElement === this.rMap.parent) { - document.exitFullscreen(); - this.$.fsIcon = FS_ICON.FS; - } else { - this.rMap.parent.requestFullscreen(); - this.$.fsIcon = FS_ICON.EXIT; - } - }, - rotate_cw: () => { - this.canMan.rotate(); - }, - flip_v: () => { - this.canMan.flip('vertical'); - }, - flip_h: () => { - this.canMan.flip('horizontal'); - }, - brightness: () => { - this.rangeCtx = 'brightness'; - this.set$({ - rangeActive: true, - }); - this.bindL10n('rangeCaption', () => this.l10n('brightness')); - }, - contrast: () => { - this.rangeCtx = 'contrast'; - this.set$({ - rangeActive: true, - }); - this.bindL10n('rangeCaption', () => this.l10n('contrast')); - }, - saturation: () => { - this.rangeCtx = 'saturate'; - this.set$({ - rangeActive: true, - }); - this.bindL10n('rangeCaption', () => this.l10n('saturation')); - }, - resize: () => { - this.canMan.resize(); - }, - crop: () => { - this.canMan.crop(); - }, - color: () => { - this.ref.color.dispatchEvent(new MouseEvent('click')); - }, - text: () => { - this.canMan.startText(); - }, - draw: () => { - this.canMan.startDraw(); - }, - cancel: () => { - this.canMan.restore(); - }, - }; - } - - init$ = { - ...this.init$, - fsIcon: FS_ICON.FS, - rangeActive: false, - rangeCaption: '', - - onBtnClick: (e) => { - this.canMan.stopText(); - this.rangeCtx = null; - - this.set$({ - rangeActive: false, - rangeCaption: '', - '*rangeValue': 100, - }); - /** @type {HTMLButtonElement} */ - let btnEl = /** @type {Element} */ (e.target).closest('[action]'); - if (btnEl) { - this.buttons.add(btnEl); - this.buttons.forEach((btn) => { - if (btn === btnEl) { - btn.setAttribute('current', ''); - } else { - btn.removeAttribute('current', ''); - } - }); - } - let action = btnEl.getAttribute('action'); - console.log(action); - if (!action) { - return; - } - this.actionsMap[action](); - }, - onColor: () => false, - }; - - buttons = new Set(); - /** @type {import('./EditableCanvas.js').EditableCanvas} */ - editor = null; - - initCallback() { - super.initCallback(); - this.defineAccessor('refMap', (/** @type {import('./EditableCanvas.js').RefMap} */ rMap) => { - if (!rMap) { - return; - } - this.rMap = rMap; - /** @type {CanMan} */ - this.canMan = new CanMan(rMap); - // console.log(rMap); - }); - this.sub('*rangeValue', (val) => { - this.canMan?.[this.rangeCtx]?.(val); - }); - this.sub('*selectedColor', (val) => { - this.canMan?.setColor(val); - }); - } -} -EditorToolbar.template = /* HTML */ ` -
${getButtons()}
- -`; diff --git a/blocks/EditableCanvas/buttons.js b/blocks/EditableCanvas/buttons.js deleted file mode 100644 index 1abdfb725..000000000 --- a/blocks/EditableCanvas/buttons.js +++ /dev/null @@ -1,109 +0,0 @@ -export const buttonsModel = [ - { - action: 'fullscreen', - icon: '', - l10n_name: 'toggle-fullscreen', - set: '@name: fsIcon', - }, - // { - // action: 'guides', - // icon: 'edit-guides', - // l10n_name: 'toggle-guides', - // set: '', - // }, - { - action: 'rotate_cw', - icon: 'edit-rotate', - l10n_name: 'rotate', - set: '', - }, - { - action: 'flip_v', - icon: 'edit-flip-v', - l10n_name: 'flip-vertical', - set: '', - }, - { - action: 'flip_h', - icon: 'edit-flip-h', - l10n_name: 'flip-horizontal', - set: '', - }, - { - action: 'brightness', - icon: 'edit-brightness', - l10n_name: 'brightness', - set: '', - }, - { - action: 'contrast', - icon: 'edit-contrast', - l10n_name: 'contrast', - set: '', - }, - { - action: 'saturation', - icon: 'edit-saturation', - l10n_name: 'saturation', - set: '', - }, - // { - // action: 'resize', - // icon: 'edit-resize', - // l10n_name: 'resize', - // set: '', - // }, - // { - // action: 'crop', - // icon: 'edit-crop', - // l10n_name: 'crop', - // set: '', - // }, - { - clr: true, - }, - { - action: 'text', - icon: 'edit-text', - l10n_name: 'text', - set: '', - }, - { - action: 'draw', - icon: 'edit-draw', - l10n_name: 'draw', - set: '', - }, - { - action: 'cancel', - icon: 'close', - l10n_name: 'cancel-edit', - set: '', - }, -]; - -function getBthHtml(btn) { - return /* HTML */ ``.trim(); -} - -const clrHtml = /* HTML */ ``; - -export function getButtons() { - return buttonsModel.reduce((acc, btn) => { - return (acc += btn.clr ? clrHtml : getBthHtml(btn)); - }, ''); -} diff --git a/blocks/EditableCanvas/editable-canvas.css b/blocks/EditableCanvas/editable-canvas.css deleted file mode 100644 index 2808e694a..000000000 --- a/blocks/EditableCanvas/editable-canvas.css +++ /dev/null @@ -1,80 +0,0 @@ -lr-editable-canvas { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - display: flex; - align-items: center; - justify-content: center; -} - -lr-editable-canvas > .img-view { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - width: 100%; - max-width: 100%; - height: 100%; - max-height: 100%; - object-fit: scale-down; -} - -lr-editable-canvas-toolbar { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 10000; - display: flex; - align-items: center; - justify-content: center; - overflow: hidden; - pointer-events: none; -} - -lr-editable-canvas-toolbar .btns { - position: absolute; - left: var(--gap-mid); - display: grid; - pointer-events: all; -} - -lr-editable-canvas-toolbar .btns > button { - display: inline-flex; - width: var(--ui-size); - height: var(--ui-size); - color: var(--clr-txt); - background-color: var(--clr-background); - border-radius: 0; -} - -lr-editable-canvas-toolbar .btns > button:first-of-type { - border-top-left-radius: var(--border-radius-element); - border-top-right-radius: var(--border-radius-element); -} - -lr-editable-canvas-toolbar .btns > button:last-of-type { - border-bottom-right-radius: var(--border-radius-element); - border-bottom-left-radius: var(--border-radius-element); -} - -lr-editable-canvas-toolbar .btns > button[current] { - color: var(--clr-txt); - background-color: var(--clr-background); -} - -lr-editable-canvas-toolbar > lr-range { - position: absolute !important; - bottom: 0; - width: 100%; - transition: 0.2s; - pointer-events: all; -} - -lr-editable-canvas-toolbar > lr-range:not([visible]) { - transform: translateY(60px); -} diff --git a/blocks/EditableCanvas/test/test.htm b/blocks/EditableCanvas/test/test.htm deleted file mode 100644 index 62b40b5ba..000000000 --- a/blocks/EditableCanvas/test/test.htm +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - LocalEditor - - - - - - - - diff --git a/blocks/EditableCanvas/test/test.jpg b/blocks/EditableCanvas/test/test.jpg deleted file mode 100644 index f5b07c5fe5ea02d0beae310c4a1deef070c91fbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40740 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
{{counter}}
- + `; diff --git a/blocks/ExternalSource/buildStyles.js b/blocks/ExternalSource/buildStyles.js index 7ebb7af1a..388d349f4 100644 --- a/blocks/ExternalSource/buildStyles.js +++ b/blocks/ExternalSource/buildStyles.js @@ -1,8 +1,14 @@ -let styleToCss = (style) => { - let css = Object.keys(style).reduce((acc, selector) => { - let propertiesObj = style[selector]; - let propertiesStr = Object.keys(propertiesObj).reduce((acc, prop) => { - let value = propertiesObj[prop]; +// @ts-check + +/** + * @param {Record>} style + * @returns + */ +const styleToCss = (style) => { + const css = Object.keys(style).reduce((acc, selector) => { + const propertiesObj = style[selector]; + const propertiesStr = Object.keys(propertiesObj).reduce((acc, prop) => { + const value = propertiesObj[prop]; return acc + `${prop}: ${value};`; }, ''); return acc + `${selector}{${propertiesStr}}`; @@ -10,14 +16,41 @@ let styleToCss = (style) => { return css; }; -export function buildStyles({ textColor, backgroundColor, linkColor, linkColorHover, shadeColor }) { - let border = `solid 1px ${shadeColor}`; +/** + * @param {{ + * textColor: string; + * backgroundColor: string; + * linkColor: string; + * linkColorHover: string; + * secondaryColor: string; + * secondaryHover: string; + * secondaryForegroundColor: string; + * fontFamily: string; + * fontSize: string; + * radius: string; + * }} options + */ +export function buildStyles({ + textColor, + backgroundColor, + linkColor, + linkColorHover, + secondaryColor, + secondaryHover, + secondaryForegroundColor, + fontFamily, + fontSize, + radius, +}) { + const border = `solid 1px ${secondaryColor}`; // TODO: we need to update source source styles, add css custom properties to control theme return styleToCss({ body: { color: textColor, 'background-color': backgroundColor, + 'font-family': fontFamily, + 'font-size': fontSize, }, '.side-bar': { background: 'inherit', @@ -36,7 +69,7 @@ export function buildStyles({ textColor, backgroundColor, linkColor, linkColorHo color: 'inherit', }, '.list-table-row:hover': { - background: shadeColor, + background: secondaryColor, }, '.list-table-row .list-table-cell-a, .list-table-row .list-table-cell-b': { 'border-top': border, @@ -55,7 +88,7 @@ export function buildStyles({ textColor, backgroundColor, linkColor, linkColorHo 'background-size': '25px 25px', }, '.list-icons-item': { - 'background-color': shadeColor, + 'background-color': secondaryColor, }, '.source-gdrive .side-bar-menu a, .source-gphotos .side-bar-menu a': { color: linkColor, @@ -80,5 +113,21 @@ export function buildStyles({ textColor, backgroundColor, linkColor, linkColorHo color: linkColorHover, background: 'none', }, + 'input[type=submit], .button, button': { + color: secondaryForegroundColor, + background: secondaryColor, + 'box-shadow': 'none', + border: 'none', + 'border-radius': radius, + }, + 'input[type=submit]:hover, .button:hover, button:hover': { + background: secondaryHover, + }, + '.text-field, input[type=search], input[type=text], input[type=url], textarea': { + color: secondaryForegroundColor, + 'border-radius': radius, + background: secondaryColor, + border, + }, }); } diff --git a/blocks/ExternalSource/external-source.css b/blocks/ExternalSource/external-source.css index 1739a0588..53cec0065 100644 --- a/blocks/ExternalSource/external-source.css +++ b/blocks/ExternalSource/external-source.css @@ -3,12 +3,15 @@ lr-external-source { flex-direction: column; width: 100%; height: 100%; - background-color: var(--clr-background-light); + background-color: var(--uc-background); overflow: hidden; } -lr-modal lr-external-source { - width: min(calc(var(--modal-max-w) - var(--gap-mid) * 2), calc(100vw - var(--gap-mid) * 2)); +[lr-modal] lr-external-source { + width: min( + calc(var(--uc-dialog-max-width) - var(--uc-padding) * 2), + calc(var(--uc-dialog-max-width) - var(--uc-padding) * 2) + ); height: var(--modal-content-height-fill, 100%); max-height: var(--modal-max-content-height); } @@ -22,7 +25,7 @@ lr-external-source > .content { @media only screen and (max-width: 430px) { lr-external-source { - width: calc(100vw - var(--gap-mid) * 2); + width: calc(100vw - var(--uc-padding) * 2); height: var(--modal-content-height-fill, 100%); } } @@ -40,12 +43,12 @@ lr-external-source .iframe-wrapper { lr-external-source .toolbar { display: grid; - grid-gap: var(--gap-mid); + grid-gap: var(--uc-padding); grid-template-columns: max-content 1fr max-content max-content; align-items: center; width: 100%; - padding: var(--gap-mid); - border-top: var(--border-light); + padding: var(--uc-padding); + border-top: 1px solid var(--uc-border); } lr-external-source .back-btn { @@ -54,9 +57,9 @@ lr-external-source .back-btn { lr-external-source .selected-counter { display: flex; - grid-gap: var(--gap-mid); + grid-gap: var(--uc-padding); align-items: center; justify-content: space-between; - padding: var(--gap-mid); - color: var(--clr-txt-light); + padding: var(--uc-padding); + color: var(--uc-muted-foreground); } diff --git a/blocks/FileItem/FileItem.js b/blocks/FileItem/FileItem.js index d9ca7ad3c..ea143310b 100644 --- a/blocks/FileItem/FileItem.js +++ b/blocks/FileItem/FileItem.js @@ -155,11 +155,11 @@ export class FileItem extends UploaderBlock { let thumbUrl = await generateThumb(entry.getValue('file'), this.cfg.thumbSize); entry.setValue('thumbUrl', thumbUrl); } catch (err) { - let color = window.getComputedStyle(this).getPropertyValue('--clr-generic-file-icon'); + let color = window.getComputedStyle(this).getPropertyValue('--uc-muted-foreground'); entry.setValue('thumbUrl', fileCssBg(color)); } } else { - let color = window.getComputedStyle(this).getPropertyValue('--clr-generic-file-icon'); + let color = window.getComputedStyle(this).getPropertyValue('--uc-muted-foreground'); entry.setValue('thumbUrl', fileCssBg(color)); } } @@ -310,8 +310,6 @@ export class FileItem extends UploaderBlock { /** @private */ this._observer = new window.IntersectionObserver(this._observerCallback.bind(this), { - root: this.parentElement, - rootMargin: '50% 0px 50% 0px', threshold: [0, 1], }); this._observer.observe(this); diff --git a/blocks/FileItem/file-item.css b/blocks/FileItem/file-item.css index 30c2157d8..0c8d65dd0 100644 --- a/blocks/FileItem/file-item.css +++ b/blocks/FileItem/file-item.css @@ -1,23 +1,31 @@ lr-file-item { + --uc-file-item-gap: 4px; + --uc-file-item-height: calc(var(--uc-preview-size) + var(--uc-padding) * 2 + var(--uc-file-item-gap)); + display: block; + content-visibility: auto; + height: var(--uc-file-item-height); + contain-intrinsic-size: auto var(--uc-file-item-height); + overflow: hidden; +} + +lr-file-item:last-of-type { + --uc-file-item-gap: 0; } + lr-file-item > .inner { position: relative; display: grid; - grid-template-columns: 32px 1fr max-content; - gap: var(--gap-min); + grid-template-columns: var(--uc-preview-size) 1fr max-content; + gap: 2px; align-items: center; - margin-bottom: var(--gap-small); - padding: var(--gap-mid); + margin-bottom: var(--uc-file-item-gap); + padding: var(--uc-padding); overflow: hidden; - font-size: 0.95em; - background-color: var(--clr-background); - border-radius: var(--border-radius-element); - transition: var(--transition-duration); -} - -lr-file-item:last-of-type > .inner { - margin-bottom: 0; + font-size: 0.925em; + background-color: var(--uc-muted); + border-radius: var(--uc-radius); + transition: background-color var(--uc-transition); } lr-file-item > .inner[focused] { @@ -29,18 +37,18 @@ lr-file-item > .inner[uploading] .edit-btn { } lr-file-item > :where(.inner[failed], .inner[limit-overflow]) { - background-color: var(--clr-error-lightest); + background-color: var(--uc-destructive); } lr-file-item .thumb { position: relative; display: inline-flex; - width: var(--ui-size); - height: var(--ui-size); - background-color: var(--clr-shade-lv1); + width: var(--uc-preview-size); + height: var(--uc-preview-size); + background-color: var(--uc-secondary); background-position: center center; background-size: cover; - border-radius: var(--border-radius-thumb); + border-radius: var(--uc-radius); } lr-file-item .file-name-wrapper { @@ -49,11 +57,10 @@ lr-file-item .file-name-wrapper { align-items: flex-start; justify-content: center; max-width: 100%; - padding-right: var(--gap-mid); - padding-left: var(--gap-mid); + padding-right: var(--uc-padding); + padding-left: var(--uc-padding); overflow: hidden; - color: var(--clr-txt-light); - transition: color var(--transition-duration); + color: var(--uc-muted-foreground); } lr-file-item .file-name { @@ -65,36 +72,33 @@ lr-file-item .file-name { lr-file-item .file-error { display: none; - color: var(--clr-error); + color: var(--uc-destructive-foreground); font-size: 0.85em; - line-height: 130%; } lr-file-item button.remove-btn, lr-file-item button.edit-btn { - color: var(--clr-txt-lightest) !important; /* todo: remove after refactoring of common.css */ + color: var(--uc-muted-foreground); } lr-file-item button.upload-btn { display: none; } -lr-file-item button:hover { - color: var(--clr-txt-light); -} - lr-file-item .badge { position: absolute; - top: calc(var(--ui-size) * -0.13); - right: calc(var(--ui-size) * -0.13); - width: calc(var(--ui-size) * 0.44); - height: calc(var(--ui-size) * 0.44); - color: var(--clr-background-light); - background-color: var(--clr-txt); + bottom: 2px; + right: 2px; + width: 14px; + height: 14px; + color: var(--uc-background); + background-color: var(--uc-foreground); border-radius: 50%; transform: scale(0.3); opacity: 0; - transition: var(--transition-duration) ease; + transition: + opacity var(--uc-transition), + transform var(--uc-transition); display: flex; justify-content: center; align-items: center; @@ -105,12 +109,8 @@ lr-file-item > .inner:where([failed], [limit-overflow], [finished]) .badge { opacity: 1; } -lr-file-item > .inner[finished] .badge { - background-color: var(--clr-confirm); -} - lr-file-item > .inner:where([failed], [limit-overflow]) .badge { - background-color: var(--clr-error); + background-color: var(--uc-destructive-foreground); } lr-file-item > .inner:where([failed], [limit-overflow]) .file-error { @@ -124,13 +124,14 @@ lr-file-item .badge lr-icon svg { } lr-file-item .progress-bar { + opacity: 0.5; top: calc(100% - 2px); height: 2px; } lr-file-item .file-actions { display: flex; - gap: var(--gap-min); + gap: 2px; align-items: center; justify-content: center; } diff --git a/blocks/FilePreview/FilePreview.js b/blocks/FilePreview/FilePreview.js deleted file mode 100644 index 1bcfef193..000000000 --- a/blocks/FilePreview/FilePreview.js +++ /dev/null @@ -1,55 +0,0 @@ -import { Block } from '../../abstract/Block.js'; -import { checkerboardCssBg } from '../svg-backgrounds/svg-backgrounds.js'; -import { TRANSPARENT_PIXEL_SRC } from '../../utils/transparentPixelSrc.js'; - -export class FilePreview extends Block { - init$ = { - ...this.init$, - checkerboard: false, - src: TRANSPARENT_PIXEL_SRC, - }; - - constructor() { - super(); - } - - initCallback() { - super.initCallback(); - this.sub('checkerboard', () => { - this.style.backgroundImage = this.hasAttribute('checkerboard') ? `url(${checkerboardCssBg()})` : 'unset'; - }); - } - - destroyCallback() { - super.destroyCallback(); - URL.revokeObjectURL(this._lastObjectUrl); - } - - /** @param {HTMLImageElement} img */ - setImage(img) { - this.$.src = img.src; - } - - /** @param {File} imgFile */ - setImageFile(imgFile) { - let url = URL.createObjectURL(imgFile); - this.$.src = url; - this._lastObjectUrl = url; - } - - /** @param {String} url */ - setImageUrl(url) { - this.$.src = url; - } - - clear() { - URL.revokeObjectURL(this._lastObjectUrl); - this.$.src = TRANSPARENT_PIXEL_SRC; - } -} - -FilePreview.template = /* HTML */ ` `; - -FilePreview.bindAttributes({ - checkerboard: 'checkerboard', -}); diff --git a/blocks/FilePreview/file-preview.css b/blocks/FilePreview/file-preview.css deleted file mode 100644 index 266baa4c5..000000000 --- a/blocks/FilePreview/file-preview.css +++ /dev/null @@ -1,27 +0,0 @@ -lr-file-preview { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - display: flex; - align-items: center; - justify-content: center; -} - -lr-file-preview > lr-img { - display: contents; -} - -lr-file-preview > lr-img > .img-view { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - width: 100%; - max-width: 100%; - height: 100%; - max-height: 100%; - object-fit: scale-down; -} diff --git a/blocks/Icon/icon.css b/blocks/Icon/icon.css index 8259f816f..032c266d5 100644 --- a/blocks/Icon/icon.css +++ b/blocks/Icon/icon.css @@ -2,11 +2,11 @@ lr-icon { display: inline-flex; align-items: center; justify-content: center; - width: var(--ui-size); - height: var(--ui-size); + width: var(--uc-button-size); + height: var(--uc-button-size); } lr-icon svg { - width: calc(var(--ui-size) / 2); - height: calc(var(--ui-size) / 2); + width: calc(var(--uc-button-size) / 2); + height: calc(var(--uc-button-size) / 2); } diff --git a/blocks/LiveHtml/LiveHtml.js b/blocks/LiveHtml/LiveHtml.js deleted file mode 100644 index 6b0c52c70..000000000 --- a/blocks/LiveHtml/LiveHtml.js +++ /dev/null @@ -1,273 +0,0 @@ -import { Block } from '../../abstract/Block.js'; - -const INIT_HTML = /* HTML */ ` - - - - - - - Document - - - CONTENT - - -`.trim(); - -class Caret { - static getPosition(parentElement) { - let selection = window.getSelection(); - let charCount = -1; - let node; - - if (selection.focusNode) { - if (Caret._isChildOf(selection.focusNode, parentElement)) { - node = selection.focusNode; - charCount = selection.focusOffset; - - while (node) { - if (node === parentElement) { - break; - } - if (node.previousSibling) { - node = node.previousSibling; - charCount += node.textContent.length; - } else { - node = node.parentNode; - if (node === null) { - break; - } - } - } - } - } - return charCount; - } - - static setPosition(chars, element) { - if (chars >= 0) { - let selection = window.getSelection(); - - let range = Caret._createRange(element, { - count: chars, - }); - - if (range) { - range.collapse(false); - selection.removeAllRanges(); - selection.addRange(range); - } - } - } - - static _createRange(node, chars, range) { - if (!range) { - range = document.createRange(); - range.selectNode(node); - range.setStart(node, 0); - } - - if (chars.count === 0) { - range.setEnd(node, chars.count); - } else if (node && chars.count > 0) { - if (node.nodeType === Node.TEXT_NODE) { - if (node.textContent.length < chars.count) { - chars.count -= node.textContent.length; - } else { - range.setEnd(node, chars.count); - chars.count = 0; - } - } else { - for (let lp = 0; lp < node.childNodes.length; lp++) { - range = Caret._createRange(node.childNodes[lp], chars, range); - - if (chars.count === 0) { - break; - } - } - } - } - return range; - } - - static _isChildOf(node, parentElement) { - while (node !== null) { - if (node === parentElement) { - return true; - } - node = node.parentNode; - } - return false; - } -} - -const headerHtml = /* HTML */ ` - -`; - -export class LiveHtml extends Block { - async hl() { - let offset = Caret.getPosition(this.ref.editor); - - this.ref.editor.textContent = this.ref.editor.textContent; - - let html = this.ref.editor.textContent; - let hljs = await import( - 'https://cdn.skypack.dev/pin/highlight.js@v11.6.0-4W1e4sNTmpsDP0C1l7xy/mode=imports,min/optimized/highlightjs.js' - ); - // @ts-ignore - html = hljs.default.highlight(this.ref.editor.textContent, { language: 'html' }).value; - this.ref.editor.innerHTML = html; - - Caret.setPosition(offset, this.ref.editor); - // this.ref.editor.focus(); - } - - sync() { - this.hl(); - if (this._updTimeout) { - window.clearTimeout(this._updTimeout); - } - this._updTimeout = window.setTimeout(() => { - // @ts-ignore - this.ref.vp.srcdoc = headerHtml + (this.importmapHtml || '') + this.ref.editor.textContent; - if (this.hasAttribute('console-output')) { - /** @type {Window} */ - // @ts-ignore - let docWin = this.ref.vp.contentWindow; - this.ref.vp.onload = () => { - console.dirxml(docWin.document.body); - }; - } - }, 300); - } - - init$ = { - ...this.init$, - src: '', - code: INIT_HTML, - spellcheck: false, - onInput: () => { - this.sync(); - }, - onKeydown: (e) => { - if (e.keyCode === 13) { - e.preventDefault(); - document.execCommand('insertHTML', false, '\n'); - } else if (e.keyCode === 9) { - e.preventDefault(); - document.execCommand('insertHTML', false, ' '); - } - }, - onNewTabClick: () => { - const url = new URL(document.location.toString()); - url.hash = ''; - const baseUrl = url.toString(); - - const code = ` - - - - -${this.ref.vp.srcdoc} - - `; - const winUrl = URL.createObjectURL(new Blob([code], { type: 'text/html' })); - window.open(winUrl); - }, - // onPaste: (e) => { - // e.preventDefault(); - // let text = e.clipboardData.getData('text/plain'); - // document.execCommand('insertText', false, text); - // }, - }; - - connectedCallback() { - if (this.innerHTML.trim()) { - let lines = this.innerHTML.split('\n'); - let commonTabSize = 1000; - lines.forEach((line) => { - if (!line.trim()) { - return; - } - if (!line.startsWith(' ')) { - commonTabSize = 0; - return; - } - let tabs = line.match(/^ +/); - if (tabs) { - commonTabSize = Math.min(commonTabSize, tabs[0].length); - } - }); - /** @private */ - this.__innerHtml = lines - .map((line) => { - for (let i = 0; i < commonTabSize; i++) { - if (line.startsWith(' ')) { - line = line.replace(' ', ''); - } - } - return line; - }) - .join('\n'); - this.innerHTML = ''; - } - super.connectedCallback(); - } - - initCallback() { - let docImportMap = document.querySelector('script[type="importmap"]'); - if (docImportMap) { - let shimScriptHtml = ''; - let shimScriptEl = document.querySelector('script[src*="es-module-shims.js"]'); - if (shimScriptEl) { - shimScriptHtml = shimScriptEl.outerHTML; - } - this.importmapHtml = shimScriptHtml + docImportMap.outerHTML; - } - if (this.hasAttribute('src')) { - this.sub('src', (val) => { - if (val) { - window.fetch(val).then(async (resp) => { - let code = await resp.text(); - this.$.code = code; - this.sync(); - }); - } else { - this.$.code = INIT_HTML; - } - }); - } else if (this.__innerHtml) { - this.$.code = this.__innerHtml; - this.sync(); - } else { - this.$.code = INIT_HTML; - } - } -} - -LiveHtml.bindAttributes({ - src: 'src', -}); - -LiveHtml.template = /* HTML */ ` -
- - -`; diff --git a/blocks/LiveHtml/live-html.css b/blocks/LiveHtml/live-html.css deleted file mode 100644 index 9d43e2dfd..000000000 --- a/blocks/LiveHtml/live-html.css +++ /dev/null @@ -1,68 +0,0 @@ -lr-live-html { - position: relative; - display: grid; - grid-template-columns: 50% 50%; - box-shadow: 0 5px 16px rgb(0 0 0 / 60%); -} - -lr-live-html [contenteditable] { - padding: 20px; - overflow: auto; - color: rgb(255 255 255); - font-size: 14px; - font-family: monospace; - white-space: pre; - background-color: #000; - outline: none; -} - -lr-live-html [contenteditable] .hljs-string { - color: rgb(251, 182, 79); -} -lr-live-html [contenteditable] .hljs-comment { - color: rgb(149, 149, 149); - font-style: italic; -} -lr-live-html [contenteditable] .hljs-attr { - color: rgb(138, 218, 172); -} -lr-live-html [contenteditable] .hljs-function { - color: rgb(239, 235, 149); -} -lr-live-html [contenteditable] .hljs-variable { - color: rgb(121, 183, 255); -} -lr-live-html [contenteditable] .hljs-title { - color: rgb(180, 243, 255); -} -lr-live-html [contenteditable] .hljs-property { - color: rgb(238, 131, 252); -} -lr-live-html [contenteditable] .hljs-keyword { - color: rgb(254, 165, 176); -} -lr-live-html [contenteditable] .hljs-tag { - color: rgb(254, 165, 176); -} -lr-live-html [contenteditable] .hljs-name { - color: rgb(165, 245, 254); -} - -lr-live-html iframe { - display: block; - width: 100%; - height: 100%; - background-color: #fff; - border: 0; -} - -lr-live-html > .open-new-tab-btn { - position: absolute; - top: 6px; - left: 6px; - display: none; -} - -lr-live-html:hover > .open-new-tab-btn { - display: block; -} diff --git a/blocks/Modal/Modal.js b/blocks/Modal/Modal.js index cd7e96c20..1f06eb5c4 100644 --- a/blocks/Modal/Modal.js +++ b/blocks/Modal/Modal.js @@ -2,6 +2,7 @@ import { Block } from '../../abstract/Block.js'; export class Modal extends Block { + static styleAttrs = [...super.styleAttrs, 'lr-modal']; static StateConsumerScope = 'modal'; constructor() { diff --git a/blocks/Modal/modal.css b/blocks/Modal/modal.css index 593ae5200..ced041b1d 100644 --- a/blocks/Modal/modal.css +++ b/blocks/Modal/modal.css @@ -1,9 +1,11 @@ -lr-modal { - --modal-max-content-height: calc(var(--uploadcare-blocks-window-height, 100vh) - 4 * var(--gap-mid) - var(--ui-size)); +:where([lr-modal]) { + --modal-max-content-height: calc( + var(--uploadcare-blocks-window-height, 100vh) - 4 * var(--uc-padding) - var(--uc-button-size) + ); --modal-content-height-fill: var(--uploadcare-blocks-window-height, 100vh); } -lr-modal[dialog-fallback] { +:where([lr-modal])[dialog-fallback] { --lr-z-max: 2147483647; position: fixed; @@ -17,12 +19,12 @@ lr-modal[dialog-fallback] { inset: 0; } -lr-modal[dialog-fallback] dialog[open] { +:where([lr-modal])[dialog-fallback] dialog[open] { z-index: var(--lr-z-max); pointer-events: auto; } -lr-modal[dialog-fallback] dialog[open] + .backdrop { +:where([lr-modal])[dialog-fallback] dialog[open] + .backdrop { position: fixed; top: 0px; left: 0px; @@ -31,58 +33,60 @@ lr-modal[dialog-fallback] dialog[open] + .backdrop { justify-content: center; width: 100vw; height: 100vh; - background-color: var(--clr-curtain); + background-color: oklch(0 0 0 / 0.1); pointer-events: auto; } -lr-modal[strokes][dialog-fallback] dialog[open] + .backdrop { +:where([lr-modal])[strokes][dialog-fallback] dialog[open] + .backdrop { background-image: var(--modal-backdrop-background-image); } @supports selector(dialog::backdrop) { - lr-modal > dialog::backdrop { + :where([lr-modal]) > dialog::backdrop { /* backdrop don't inherit theme properties */ - background-color: rgba(0, 0, 0, 10%); + background-color: oklch(0 0 0 / 0.1); } - lr-modal[strokes] > dialog::backdrop { + :where([lr-modal])[strokes] > dialog::backdrop { /* TODO: it's not working, fix it */ background-image: var(--modal-backdrop-background-image); } } -lr-modal > dialog[open] { +:where([lr-modal]) > dialog[open] { transform: translateY(0px); visibility: visible; opacity: 1; } -lr-modal > dialog:not([open]) { +:where([lr-modal]) > dialog:not([open]) { transform: translateY(20px); visibility: hidden; opacity: 0; } -lr-modal > dialog { +:where([lr-modal]) > dialog { display: flex; flex-direction: column; /* there was `fit-content` but it doesn't reduce width after activity change */ width: max-content; - max-width: min(calc(100% - var(--gap-mid) * 2), calc(var(--modal-max-w) - var(--gap-mid) * 2)); - min-height: var(--ui-size); - max-height: calc(var(--modal-max-h) - var(--gap-mid) * 2); + max-width: min(calc(100% - var(--uc-padding) * 2), calc(var(--uc-dialog-max-width) - var(--uc-padding) * 2)); + min-height: var(--uc-button-size); + max-height: calc(var(--uc-dialog-max-height) - var(--uc-padding) * 2); margin: auto; padding: 0; overflow: hidden; - background-color: var(--clr-background-light); + background-color: var(--uc-background); border: 0; - border-radius: var(--border-radius-frame); - box-shadow: var(--modal-shadow); - transition: transform calc(var(--transition-duration) * 2); + border-radius: calc(var(--uc-radius) * 1.75); + box-shadow: var(--uc-dialog-shadow); + transition: + transform 0.4s ease, + opacity 0.4s ease; } @media only screen and (max-width: 430px), only screen and (max-height: 600px) { - lr-modal > dialog > .content { + :where([lr-modal]) > dialog > .content { height: var(--modal-max-content-height); } } diff --git a/blocks/ProgressBar/progress-bar.css b/blocks/ProgressBar/progress-bar.css index 896e55097..7a82eaeb4 100644 --- a/blocks/ProgressBar/progress-bar.css +++ b/blocks/ProgressBar/progress-bar.css @@ -12,7 +12,7 @@ lr-progress-bar { lr-progress-bar .progress { width: calc(var(--l-width) * 1%); height: 100%; - background-color: var(--clr-accent-light); + background-color: var(--uc-primary); transform: translateX(0); opacity: 1; transition: diff --git a/blocks/ProgressBarCommon/progress-bar-common.css b/blocks/ProgressBarCommon/progress-bar-common.css index 297bcb164..a9de92ebd 100644 --- a/blocks/ProgressBarCommon/progress-bar-common.css +++ b/blocks/ProgressBarCommon/progress-bar-common.css @@ -5,8 +5,8 @@ lr-progress-bar-common { left: 0; z-index: 10000; display: block; - height: var(--gap-mid); - background-color: var(--clr-background); + height: 10px; + background-color: var(--uc-background); transition: opacity 0.3s; } diff --git a/blocks/Range/range.css b/blocks/Range/range.css index 418a698fc..d190cd664 100644 --- a/blocks/Range/range.css +++ b/blocks/Range/range.css @@ -3,7 +3,7 @@ lr-range { display: inline-flex; align-items: center; justify-content: center; - height: var(--ui-size); + height: var(--uc-button-size); } lr-range datalist { diff --git a/blocks/Select/select.css b/blocks/Select/select.css index f688b1d29..7cc0a5c91 100644 --- a/blocks/Select/select.css +++ b/blocks/Select/select.css @@ -7,9 +7,8 @@ lr-select > button { display: inline-flex; align-items: center; padding-right: 0 !important; /* todo: get rid of important */ - color: var(--clr-btn-txt-secondary); - background-color: var(--clr-btn-bgr-secondary); - box-shadow: var(--shadow-btn-secondary); + color: var(--uc-secondary-foreground); + background-color: var(--uc-secondary); } lr-select > button > select { diff --git a/blocks/SimpleBtn/SimpleBtn.js b/blocks/SimpleBtn/SimpleBtn.js index 31121093b..236ea9668 100644 --- a/blocks/SimpleBtn/SimpleBtn.js +++ b/blocks/SimpleBtn/SimpleBtn.js @@ -3,6 +3,7 @@ import { UploaderBlock } from '../../abstract/UploaderBlock.js'; import { asBoolean } from '../Config/normalizeConfigValue.js'; export class SimpleBtn extends UploaderBlock { + static styleAttrs = [...super.styleAttrs, 'lr-simple-btn']; couldBeCtxOwner = true; constructor() { super(); diff --git a/blocks/SimpleBtn/simple-btn.css b/blocks/SimpleBtn/simple-btn.css index 0c8e3a756..3173e637c 100644 --- a/blocks/SimpleBtn/simple-btn.css +++ b/blocks/SimpleBtn/simple-btn.css @@ -1,32 +1,37 @@ -lr-simple-btn { +:where([lr-simple-btn]) { position: relative; display: inline-flex; } -lr-simple-btn button { - padding-left: 0.2em !important; - color: var(--clr-btn-txt-secondary); - background-color: var(--clr-btn-bgr-secondary); - box-shadow: var(--shadow-btn-secondary); +:where([lr-simple-btn]) button { + height: auto; + gap: 0.5em; + padding: var(--uc-simple-btn-padding); + background-color: var(--uc-simple-btn); + color: var(--uc-simple-btn-foreground); + font-size: var(--uc-simple-btn-font-size); + font-family: var(--uc-simple-btn-font-family); } -lr-simple-btn button lr-icon svg { - transform: scale(0.8); +:where([lr-simple-btn]) button lr-icon { + width: auto; + height: auto; } -lr-simple-btn button:hover { - background-color: var(--clr-btn-bgr-secondary-hover); +:where([lr-simple-btn]) button lr-icon svg { + width: 0.9em; + height: 0.9em; } -lr-simple-btn button:active { - background-color: var(--clr-btn-bgr-secondary-active); +:where([lr-simple-btn]) button:hover { + background-color: var(--uc-simple-btn-hover); } -lr-simple-btn > lr-drop-area { +:where([lr-simple-btn]) > lr-drop-area { display: contents; } -lr-simple-btn .visual-drop-area { +:where([lr-simple-btn]) .visual-drop-area { position: absolute; top: 0px; left: 0px; @@ -35,55 +40,25 @@ lr-simple-btn .visual-drop-area { justify-content: center; width: 100%; height: 100%; - padding: var(--gap-min); - border: var(--border-dashed); + padding: var(--uc-simple-btn-padding); + background-color: transparent; + color: transparent; + font-size: var(--uc-simple-btn-font-size); + border: 1px dashed var(--uc-simple-btn-foreground); border-radius: inherit; opacity: 0; - transition: - border-color var(--transition-duration) ease, - background-color var(--transition-duration) ease, - opacity var(--transition-duration) ease; + transition: opacity var(--uc-transition); } -lr-simple-btn .visual-drop-area::before { - position: absolute; - top: 0px; - left: 0px; - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - color: var(--clr-txt-light); - background-color: var(--clr-background); - border-radius: inherit; -} - -lr-simple-btn > lr-drop-area[drag-state='active'] .visual-drop-area { - background-color: var(--clr-accent-lightest); +:where([lr-simple-btn]) > lr-drop-area[drag-state='active'] .visual-drop-area { opacity: 1; } -lr-simple-btn > lr-drop-area[drag-state='inactive'] .visual-drop-area { - background-color: var(--clr-shade-lv1); +:where([lr-simple-btn]) > lr-drop-area[drag-state='inactive'] .visual-drop-area { opacity: 0; } -lr-simple-btn > lr-drop-area[drag-state='near'] .visual-drop-area { - background-color: var(--clr-accent-lightest); - border-color: var(--clr-accent-light); +:where([lr-simple-btn]) > lr-drop-area[drag-state='near'] .visual-drop-area { opacity: 1; } -lr-simple-btn > lr-drop-area[drag-state='over'] .visual-drop-area { - background-color: var(--clr-accent-lightest); - border-color: var(--clr-accent); +:where([lr-simple-btn]) > lr-drop-area[drag-state='over'] .visual-drop-area { opacity: 1; } - -lr-simple-btn - > :where(lr-drop-area[drag-state='active'], lr-drop-area[drag-state='near'], lr-drop-area[drag-state='over']) - button { - box-shadow: none; -} - -lr-simple-btn > lr-drop-area::after { - content: ''; -} diff --git a/blocks/SourceBtn/source-btn.css b/blocks/SourceBtn/source-btn.css index 1412153a5..0d2fbf401 100644 --- a/blocks/SourceBtn/source-btn.css +++ b/blocks/SourceBtn/source-btn.css @@ -1,32 +1,32 @@ lr-source-btn { display: flex; align-items: center; - margin-bottom: var(--gap-min); - padding: var(--gap-min) var(--gap-mid); - color: var(--clr-txt-mid); - border-radius: var(--border-radius-element); + margin-bottom: 2px; + padding: 2px var(--uc-padding); + color: var(--uc-foreground); + border-radius: var(--uc-radius); cursor: pointer; - transition-duration: var(--transition-duration); - transition-property: background-color, color; + transition: + background-color var(--uc-transition), + color var(--uc-transition); user-select: none; } -lr-source-btn:hover { - color: var(--clr-accent); - background-color: var(--clr-accent-lightest); +lr-source-btn:last-child { + margin-bottom: 0; } -lr-source-btn:active { - color: var(--clr-accent); - background-color: var(--clr-accent-light); +lr-source-btn:hover { + color: var(--uc-primary); + background-color: var(--uc-primary-transparent); } lr-source-btn lr-icon { display: inline-flex; flex-grow: 1; justify-content: center; - min-width: var(--ui-size); - margin-right: var(--gap-mid); + min-width: var(--uc-button-size); + margin-right: var(--uc-padding); opacity: 0.8; } @@ -35,7 +35,7 @@ lr-source-btn .txt { align-items: center; box-sizing: border-box; width: 100%; - height: var(--ui-size); + height: var(--uc-button-size); padding: 0; white-space: nowrap; border: none; diff --git a/blocks/StartFrom/start-from.css b/blocks/StartFrom/start-from.css index a7e518f3e..889319b44 100644 --- a/blocks/StartFrom/start-from.css +++ b/blocks/StartFrom/start-from.css @@ -6,13 +6,27 @@ lr-start-from { lr-start-from .content { display: grid; grid-auto-flow: row; - gap: var(--gap-max); + gap: calc(var(--uc-padding) * 2); width: 100%; height: 100%; - padding: var(--gap-max); - background-color: var(--clr-background-light); + padding: calc(var(--uc-padding) * 2); + background-color: var(--uc-background); } -lr-modal lr-start-from { - width: min(calc(var(--modal-normal-w) - var(--gap-mid) * 2), calc(100vw - var(--gap-mid) * 2)); +[lr-modal] lr-start-from { + width: min( + calc(var(--uc-dialog-width) - var(--uc-padding) * 2), + calc(var(--uc-dialog-max-width) - var(--uc-padding) * 2), + calc(100vw - var(--uc-padding) * 2) + ); +} + +[lr-modal] lr-start-from lr-drop-area { + border-radius: var(--uc-radius); +} + +@media only screen and (max-width: 430px) { + [lr-modal] lr-start-from lr-drop-area { + display: none; + } } diff --git a/blocks/Tabs/Tabs.js b/blocks/Tabs/Tabs.js deleted file mode 100644 index a5b1e6790..000000000 --- a/blocks/Tabs/Tabs.js +++ /dev/null @@ -1,78 +0,0 @@ -import { Block } from '../../abstract/Block.js'; -import { create } from '@symbiotejs/symbiote'; -import { stringToArray } from '../../utils/stringToArray.js'; - -export class Tabs extends Block { - /** @param {String} tabL10nStr */ - setCurrentTab(tabL10nStr) { - if (!tabL10nStr) { - return; - } - let ctxList = [...this.ref.context.querySelectorAll('[tab-ctx]')]; - ctxList.forEach((ctxEl) => { - if (ctxEl.getAttribute('tab-ctx') === tabL10nStr) { - ctxEl.removeAttribute('hidden'); - } else { - ctxEl.setAttribute('hidden', ''); - } - }); - for (let lStr in this._tabMap) { - if (lStr === tabL10nStr) { - this._tabMap[lStr].setAttribute('current', ''); - } else { - this._tabMap[lStr].removeAttribute('current'); - } - } - } - - initCallback() { - super.initCallback(); - /** - * @private - * @type {Object} - */ - this._tabMap = {}; - this.defineAccessor('tab-list', (/** @type {String} */ val) => { - if (!val) { - return; - } - let tabList = stringToArray(val); - tabList.forEach((tabL10nStr) => { - let tabEl = create({ - tag: 'div', - attributes: { - class: 'tab', - }, - properties: { - onclick: () => { - this.setCurrentTab(tabL10nStr); - }, - }, - }); - tabEl.textContent = this.l10n(tabL10nStr); - this.ref.row.appendChild(tabEl); - this._tabMap[tabL10nStr] = tabEl; - }); - }); - - this.defineAccessor('default', (val) => { - this.setCurrentTab(val); - }); - - if (!this.hasAttribute('default')) { - this.setCurrentTab(Object.keys(this._tabMap)[0]); - } - } -} - -Tabs.bindAttributes({ - 'tab-list': null, - default: null, -}); - -Tabs.template = /* HTML */ ` -
-
- -
-`; diff --git a/blocks/Tabs/tabs.css b/blocks/Tabs/tabs.css deleted file mode 100644 index 12593cf7b..000000000 --- a/blocks/Tabs/tabs.css +++ /dev/null @@ -1,33 +0,0 @@ -lr-tabs { - display: grid; - grid-template-rows: min-content minmax(var(--ui-size), auto); - height: 100%; - overflow: hidden; - color: var(--clr-txt-lightest); -} - -lr-tabs > .tabs-row { - display: flex; - grid-template-columns: minmax(); - background-color: var(--clr-background-light); -} - -lr-tabs > .tabs-context { - overflow-y: auto; -} - -lr-tabs .tabs-row > .tab { - display: flex; - flex-grow: 1; - align-items: center; - justify-content: center; - height: var(--ui-size); - border-bottom: var(--border-light); - cursor: pointer; - transition: var(--transition-duration); -} - -lr-tabs .tabs-row > .tab[current] { - color: var(--clr-txt); - border-color: var(--clr-txt); -} diff --git a/blocks/UploadList/upload-list.css b/blocks/UploadList/upload-list.css index 842eac64b..01fba9992 100644 --- a/blocks/UploadList/upload-list.css +++ b/blocks/UploadList/upload-list.css @@ -4,39 +4,39 @@ lr-upload-list { width: 100%; height: 100%; overflow: hidden; - background-color: var(--clr-background-light); - transition: opacity var(--transition-duration); + background-color: var(--uc-background); + transition: opacity var(--uc-transition); } -lr-modal lr-upload-list { - width: min(calc(var(--modal-normal-w) - var(--gap-mid) * 2), calc(100vw - var(--gap-mid) * 2)); +[lr-modal] lr-upload-list { + width: min( + calc(var(--uc-dialog-width) - var(--uc-padding) * 2), + calc(var(--uc-dialog-max-width) - var(--uc-padding) * 2), + calc(100vw - var(--uc-padding) * 2) + ); height: max-content; max-height: var(--modal-max-content-height); } lr-upload-list .no-files { - height: var(--ui-size); - padding: var(--gap-max); + height: 32px; + padding: 20px; } lr-upload-list .files { display: block; flex: 1; - min-height: var(--ui-size); - padding: 0 var(--gap-mid); + min-height: 32px; + padding: 0 var(--uc-padding); overflow: auto; } lr-upload-list .toolbar { display: flex; - gap: var(--gap-small); + gap: 4px; justify-content: space-between; - padding: var(--gap-mid); - background-color: var(--clr-background-light); -} - -lr-upload-list .toolbar .add-more-btn { - padding-left: 0.2em; + padding: var(--uc-padding); + background-color: var(--uc-background); } lr-upload-list .toolbar-spacer { @@ -47,24 +47,28 @@ lr-upload-list lr-drop-area { position: absolute; top: 0; left: 0; - width: calc(100% - var(--gap-mid) * 2); - height: calc(100% - var(--gap-mid) * 2); - margin: var(--gap-mid); - border-radius: var(--border-radius-element); + width: calc(100% - var(--uc-padding) * 2); + height: calc(100% - var(--uc-padding) * 2); + margin: var(--uc-padding); + border-radius: var(--uc-radius); } lr-upload-list lr-activity-header > .header-text { - padding: 0 var(--gap-mid); + padding: 0 var(--uc-padding); } lr-upload-list .common-error { - border-radius: var(--border-radius-element); - color: var(--clr-error); - background-color: var(--clr-error-message-bgr); + border-radius: var(--uc-radius); + color: var(--uc-destructive-foreground); + background-color: var(--uc-destructive); display: flex; align-items: center; justify-content: center; - padding: var(--gap-mid); - margin: var(--gap-small) var(--gap-mid) 0 var(--gap-mid); - font-size: 0.95em; + padding: var(--uc-padding); + margin: 4px var(--uc-padding) 0 var(--uc-padding); + font-size: 0.925em; +} + +lr-upload-list .add-more-btn lr-icon { + display: none; } diff --git a/blocks/UrlSource/url-source.css b/blocks/UrlSource/url-source.css index fa3c9ff33..ba3e33b4d 100644 --- a/blocks/UrlSource/url-source.css +++ b/blocks/UrlSource/url-source.css @@ -1,17 +1,21 @@ lr-url-source { display: block; - background-color: var(--clr-background-light); + background-color: var(--uc-background); } -lr-modal lr-url-source { - width: min(calc(var(--modal-normal-w) - var(--gap-mid) * 2), calc(100vw - var(--gap-mid) * 2)); +[lr-modal] lr-url-source { + width: min( + calc(var(--uc-dialog-width) - var(--uc-padding) * 2), + calc(var(--uc-dialog-max-width) - var(--uc-padding) * 2), + calc(100vw - var(--uc-padding) * 2) + ); } lr-url-source > .content { display: grid; - grid-gap: var(--gap-small); + grid-gap: 4px; grid-template-columns: 1fr min-content; - padding: var(--gap-mid); + padding: var(--uc-padding); padding-top: 0; } diff --git a/blocks/Video/Video.js b/blocks/Video/Video.js deleted file mode 100644 index 93f9539a1..000000000 --- a/blocks/Video/Video.js +++ /dev/null @@ -1,299 +0,0 @@ -import { Block } from '../../abstract/Block.js'; - -/** @enum {String} */ -const ICO_MAP = { - PLAY: 'play', - PAUSE: 'pause', - FS_ON: 'fullscreen-on', - FS_OFF: 'fullscreen-off', - VOL_ON: 'unmute', - VOL_OFF: 'mute', - CAP_ON: 'captions', - CAP_OFF: 'captions-off', -}; - -// TODO: refactor and move fullscreen adapter to utils: -const FSAPI = { - requestFullscreen: (el) => { - if (el.requestFullscreen) { - el.requestFullscreen(); - } else if (el.webkitRequestFullscreen) { - el.webkitRequestFullscreen(); - } - }, - exitFullscreen: () => { - if (document.exitFullscreen) { - document.exitFullscreen(); - } else if (document['webkitExitFullscreen']) { - document['webkitExitFullscreen'](); - } - }, -}; - -export class Video extends Block { - togglePlay() { - if (this._video.paused || this._video.ended) { - this._video.play(); - } else { - this._video.pause(); - } - } - - toggleFullscreen() { - if ((document.fullscreenElement || document['webkitFullscreenElement']) === this) { - FSAPI.exitFullscreen(); - } else { - FSAPI.requestFullscreen(this); - } - } - - toggleCaptions() { - if (this.$.capIcon === ICO_MAP.CAP_OFF) { - this.$.capIcon = ICO_MAP.CAP_ON; - this._video.textTracks[0].mode = 'showing'; - window.localStorage.setItem(Video.is + ':captions', '1'); - } else { - this.$.capIcon = ICO_MAP.CAP_OFF; - this._video.textTracks[0].mode = 'hidden'; - window.localStorage.removeItem(Video.is + ':captions'); - } - } - - toggleSound() { - if (this.$.volIcon === ICO_MAP.VOL_ON) { - this.$.volIcon = ICO_MAP.VOL_OFF; - this.$.volumeDisabled = true; - this._video.muted = true; - } else { - this.$.volIcon = ICO_MAP.VOL_ON; - this.$.volumeDisabled = false; - this._video.muted = false; - } - } - - setVolume(val) { - window.localStorage.setItem(Video.is + ':volume', val); - let volume = val ? val / 100 : 0; - this._video.volume = volume; - } - - /** @type {HTMLElement} */ - get progress() { - return this.ref.progress; - } - - init$ = { - ...this.init$, - src: '', - ppIcon: ICO_MAP.PLAY, - fsIcon: ICO_MAP.FS_ON, - volIcon: ICO_MAP.VOL_ON, - capIcon: ICO_MAP.CAP_OFF, - totalTime: '00:00', - currentTime: '00:00', - progressCssWidth: '0', - hasSubtitles: false, - volumeDisabled: false, - volumeValue: 0, - onPP: () => { - this.togglePlay(); - }, - onFs: () => { - this.toggleFullscreen(); - }, - onCap: () => { - this.toggleCaptions(); - }, - onMute: () => { - this.toggleSound(); - }, - onVolChange: (e) => { - // TODO: cast range.value instead of range.$.value - let val = parseFloat(e.currentTarget.$.value); - this.setVolume(val); - }, - progressClicked: (e) => { - let progressRect = this.progress.getBoundingClientRect(); - this._video.currentTime = this._video.duration * (e.offsetX / progressRect.width); - }, - }; - - /** - * @private - * @param {String} input - */ - _getUrl(input) { - return input.includes('/') ? input : `https://ucarecdn.com/${input}/`; - } - - /** - * @private - * @param {Object} desc - */ - _desc2attrs(desc) { - let attrs = []; - for (let attr in desc) { - let val = attr === 'src' ? this._getUrl(desc[attr]) : desc[attr]; - attrs.push(`${attr}="${val}"`); - } - return attrs.join(' '); - } - - /** - * @private - * @param {Number} seconds - */ - _timeFmt(seconds) { - // TODO: add hours - let date = new Date(Math.round(seconds) * 1000); - return [date.getMinutes(), date.getSeconds()] - .map((n) => { - return n < 10 ? '0' + n : n; - }) - .join(':'); - } - - /** @private */ - _initTracks() { - [...this._video.textTracks].forEach((track) => { - track.mode = 'hidden'; - }); - if (window.localStorage.getItem(Video.is + ':captions')) { - this.toggleCaptions(); - } - } - - /** @private */ - _castAttributes() { - let toCast = ['autoplay', 'loop', 'muted']; - [...this.attributes].forEach((attr) => { - if (toCast.includes(attr.name)) { - this._video.setAttribute(attr.name, attr.value); - } - }); - } - - initCallback() { - super.initCallback(); - /** - * @private - * @type {HTMLVideoElement} - */ - this._video = this.ref.video; - - this._castAttributes(); - - this._video.addEventListener('play', () => { - this.$.ppIcon = ICO_MAP.PAUSE; - this.setAttribute('playback', ''); - }); - - this._video.addEventListener('pause', () => { - this.$.ppIcon = ICO_MAP.PLAY; - this.removeAttribute('playback'); - }); - - this.addEventListener('fullscreenchange', (e) => { - console.log(e); - if (document.fullscreenElement === this) { - this.$.fsIcon = ICO_MAP.FS_OFF; - } else { - this.$.fsIcon = ICO_MAP.FS_ON; - } - }); - - this.sub('src', (src) => { - if (!src) { - return; - } - let url = this._getUrl(src); - this._video.src = url; - }); - - this.sub('video', async (descPath) => { - if (!descPath) { - return; - } - let desc = await (await window.fetch(this._getUrl(descPath))).json(); - - if (desc.poster) { - this._video.poster = this._getUrl(desc.poster); - } - - let html = ''; - desc?.sources.forEach((srcDesc) => { - html += /* HTML */ ``; - }); - - if (desc.tracks) { - desc.tracks.forEach((trackDesc) => { - html += /* HTML */ ``; - }); - this.$.hasSubtitles = true; - } - - this._video.innerHTML += html; - - this._initTracks(); - console.log(desc); - }); - - this._video.addEventListener('loadedmetadata', (e) => { - this.$.currentTime = this._timeFmt(this._video.currentTime); - this.$.totalTime = this._timeFmt(this._video.duration); - }); - - this._video.addEventListener('timeupdate', (e) => { - let perc = Math.round(100 * (this._video.currentTime / this._video.duration)); - this.$.progressCssWidth = perc + '%'; - this.$.currentTime = this._timeFmt(this._video.currentTime); - }); - - let volume = window.localStorage.getItem(Video.is + ':volume'); - if (volume) { - let vol = parseFloat(volume); - this.setVolume(vol); - this.$.volumeValue = vol; - } - } -} - -Video.template = /* HTML */ ` -
- -
- -
-
-
-
- -
- -
{{currentTime}} / {{totalTime}}
-
- -
- - - - - - - -
-
-`; - -Video.bindAttributes({ - video: 'video', - src: 'src', -}); diff --git a/blocks/Video/test-track.vtt b/blocks/Video/test-track.vtt deleted file mode 100644 index 1141e5b6a..000000000 --- a/blocks/Video/test-track.vtt +++ /dev/null @@ -1,10 +0,0 @@ -WEBVTT - -00:01.000 --> 00:04.000 -- Hello lr-video! - -00:05.000 --> 00:15.000 -- This is subtitles test. - -00:16.000 --> 00:30.000 -- Try to turn off and then turn on subtitles... \ No newline at end of file diff --git a/blocks/Video/video.css b/blocks/Video/video.css deleted file mode 100644 index 85499ee3c..000000000 --- a/blocks/Video/video.css +++ /dev/null @@ -1,106 +0,0 @@ -@import url('../Range/range.css'); - -lr-video { - --color-accent: rgb(196, 243, 255); - - display: inline-grid; - grid-template-rows: 1fr min-content; - max-height: var(--uploadcare-blocks-window-height, 100vh); - overflow: hidden; - font-family: monospace; - background-color: #000; - border-radius: 6px; -} - -lr-video [hidden] { - display: none !important; -} - -lr-video lr-range[disabled] { - opacity: 0.4; - pointer-events: none; -} - -lr-video .video-wrapper { - overflow: hidden; -} - -lr-video video { - display: inline-block; - width: 100%; - max-width: 100%; - height: 100%; - margin: 0; - padding: 0; - background-color: #ccc; - background-color: #000; -} - -lr-video lr-icon { - --icon-play: 'M8,5.14V19.14L19,12.14L8,5.14Z'; - --icon-pause: 'M14,19H18V5H14M6,19H10V5H6V19Z'; - --icon-mute: 'M12,4L9.91,6.09L12,8.18M4.27,3L3,4.27L7.73,9H3V15H7L12,20V13.27L16.25,17.53C15.58,18.04 14.83,18.46 14,18.7V20.77C15.38,20.45 16.63,19.82 17.68,18.96L19.73,21L21,19.73L12,10.73M19,12C19,12.94 18.8,13.82 18.46,14.64L19.97,16.15C20.62,14.91 21,13.5 21,12C21,7.72 18,4.14 14,3.23V5.29C16.89,6.15 19,8.83 19,12M16.5,12C16.5,10.23 15.5,8.71 14,7.97V10.18L16.45,12.63C16.5,12.43 16.5,12.21 16.5,12Z'; - --icon-unmute: 'M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z'; - --icon-fullscreen-on: 'M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z'; - --icon-fullscreen-off: 'M14,14H19V16H16V19H14V14M5,14H10V19H8V16H5V14M8,5H10V10H5V8H8V5M19,8V10H14V5H16V8H19Z'; - --icon-captions: 'M18,11H16.5V10.5H14.5V13.5H16.5V13H18V14A1,1 0 0,1 17,15H14A1,1 0 0,1 13,14V10A1,1 0 0,1 14,9H17A1,1 0 0,1 18,10M11,11H9.5V10.5H7.5V13.5H9.5V13H11V14A1,1 0 0,1 10,15H7A1,1 0 0,1 6,14V10A1,1 0 0,1 7,9H10A1,1 0 0,1 11,10M19,4H5C3.89,4 3,4.89 3,6V18A2,2 0 0,0 5,20H19A2,2 0 0,0 21,18V6C21,4.89 20.1,4 19,4Z'; - --icon-captions-off: 'M5,4C4.45,4 4,4.18 3.59,4.57C3.2,4.96 3,5.44 3,6V18C3,18.56 3.2,19.04 3.59,19.43C4,19.82 4.45,20 5,20H19C19.5,20 20,19.81 20.39,19.41C20.8,19 21,18.53 21,18V6C21,5.47 20.8,5 20.39,4.59C20,4.19 19.5,4 19,4H5M4.5,5.5H19.5V18.5H4.5V5.5M7,9C6.7,9 6.47,9.09 6.28,9.28C6.09,9.47 6,9.7 6,10V14C6,14.3 6.09,14.53 6.28,14.72C6.47,14.91 6.7,15 7,15H10C10.27,15 10.5,14.91 10.71,14.72C10.91,14.53 11,14.3 11,14V13H9.5V13.5H7.5V10.5H9.5V11H11V10C11,9.7 10.91,9.47 10.71,9.28C10.5,9.09 10.27,9 10,9H7M14,9C13.73,9 13.5,9.09 13.29,9.28C13.09,9.47 13,9.7 13,10V14C13,14.3 13.09,14.53 13.29,14.72C13.5,14.91 13.73,15 14,15H17C17.3,15 17.53,14.91 17.72,14.72C17.91,14.53 18,14.3 18,14V13H16.5V13.5H14.5V10.5H16.5V11H18V10C18,9.7 17.91,9.47 17.72,9.28C17.53,9.09 17.3,9 17,9H14Z'; - - display: inline-flex; - align-items: center; - justify-content: center; - fill: currentColor; -} - -lr-video:not([controls]) .toolbar { - display: none; -} - -lr-video .toolbar { - position: relative; - z-index: 10000; - display: flex; - align-items: center; - justify-content: space-between; - color: var(--color-accent); - background-color: #000; - transition: 0.4s; -} -lr-video[playback] .toolbar { - opacity: 0.2; -} -lr-video .toolbar:hover { - opacity: 1; -} - -lr-video .toolbar .tb-block { - display: flex; - align-items: center; -} - -lr-video .toolbar .tb-block button { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 40px; - height: 40px; - color: var(--color-accent); - background-color: transparent; - border: none; - cursor: pointer; -} -lr-video .progress { - position: absolute; - top: -18px; - right: 0; - left: 0; - display: flex; - align-items: flex-end; - height: 20px; - cursor: pointer; -} -lr-video .progress .bar { - height: 2px; - background-color: var(--color-accent); - transition: 0.5s; -} diff --git a/blocks/Video/video.json b/blocks/Video/video.json deleted file mode 100644 index 180578666..000000000 --- a/blocks/Video/video.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "sources": [ - { - "label": "HQ", - "src": "d52902bb-c7d3-4e00-9f80-ed489dda9a3f", - "type": "video/mp4" - }, - { - "label": "MQ", - "src": "d52902bb-c7d3-4e00-9f80-ed489dda9a3f", - "type": "video/mp4" - }, - { - "label": "LQ", - "src": "d52902bb-c7d3-4e00-9f80-ed489dda9a3f", - "type": "video/mp4" - } - ], - "tracks": [ - { - "kind": "subtitles", - "src": "bd8fd88a-a2ea-49a7-825b-4a68c355667c", - "srclang": "en", - "label": "EN", - "default": true - } - ], - "poster": "89409d82-8939-4c6f-8410-d4b6bcb404d9" -} diff --git a/blocks/svg-backgrounds/svg-backgrounds.js b/blocks/svg-backgrounds/svg-backgrounds.js index 5d35812f7..042fc17c9 100644 --- a/blocks/svg-backgrounds/svg-backgrounds.js +++ b/blocks/svg-backgrounds/svg-backgrounds.js @@ -39,7 +39,7 @@ export function strokesCssBg(color = 'rgba(0, 0, 0, .1)') { export function fileCssBg(color = 'hsl(209, 21%, 65%)', width = 32, height = 32) { return createSvgBlobUrl(/*svg*/ ` - + `); } diff --git a/blocks/themes/lr-basic/README.md b/blocks/themes/lr-basic/README.md deleted file mode 100644 index 81b41591f..000000000 --- a/blocks/themes/lr-basic/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# Basic theme for blocks - -There are 4 levels of abstraction: - -- [Base values](#base-values) -- [Derivative values](#derivative-values]) -- [Common styles](#common-styles) -- [Component styles](#component-styles) - -### HSL color space - -We use HSL color space because it allows us to easily calculate derivative colors. That's what prefixes `--h-`, `--s-`, and `--l-` are stand for. - -### Quick styling - -In most cases switching the dark mode on or off and changing the accent color is enough to make blocks match your design. - - - -```css ---darkmode: 1; -``` - -```css ---h-accent: 211; ---s-accent: 100%; ---l-accent: calc(50% - 5% * var(--darkmode)); -``` - -## Base values - -- `--darkmode` — `1`: dark mode enabled, `0`: disabled; -- `--*-foreground` — text color, borders, and shaders. It should be in contrast to the background; -- `--*-background` — background color and its variations; -- `--*-accent` — colors of buttons, links, and text input borders (hover and focus). It should be in contrast to the background; -- `--*-confirm` — the color of confirmation notifications and badges; -- `--*-error` — the color of error notifications and badges; -- `--opacity-*` — opacity of different states of small icon buttons; -- `--ui-size` — minimum size of a clickable element. Also used to calculate the size of the elements, which should be proportional to it; -- `--gap-*` — paddings and margins; -- `--gap-table` — the gap between elements in lists (for example, in upload-list); -- `--borders` — `1`: borders enabled, `0`: disabled. Can be fractional, for example, 0.5 will make borders half as opaque; -- `--border-radius-element` — border radius of buttons and inputs; -- `--border-radius-frame` — border radius of modal windows and drop area; -- `--border-radius-thumb` — border radius of thumbnails; -- `--transition-duration` — duration of all animated transitions; -- `--shadows` — `1`: shadows enabled, `0`: disabled. Can be fractional, for example 0.5, will make shadows half as opaque; -- `--*-shadow` — the color of box shadows; -- `--modal-max-w`, `--modal-max-h` — the maximum size of the modal window. - -## Derivative values - -Derivative values are calculated from the base values. - -- `--darkmode-minus` — used for dark mode color calculations. Gives `-1` when dark mode is enabled, `1` when disabled; -- `--clr-background*` — lightness variations of the background color; -- `--clr-accent*` — opacity variations of the accent color; -- `--clr-confirm` — confirmation notifications color; -- `--clr-error` — opacity and lighness variations of the error notifications color; -- `--clr-txt*` — lightness variations of the text color; -- `--clr-shade-lv*` — shading colors (foreground color with a low opacity variations); -- `--border-*` — border variations; -- `--clr-curtain` — color of the background behind the modal window; -- `--clr-btn-bgr-primary*`, `--clr-btn-txt-primary`, `--shadow-btn-primary` — primary action button values; -- `--clr-btn-bgr-secondary*`, `--clr-btn-txt-secondary`, `--shadow-btn-secondary` — secondary action button values; -- `--clr-btn-bgr-disabled`, `--clr-btn-txt-disabled`, `--shadow-btn-disabled` — disabled button values. - -## Common styles - -Common styles define similar UI elements across different blocks: buttons, inputs, and links. - -## Component styles - -Component styles are the most specific. - - diff --git a/blocks/themes/lr-basic/common.css b/blocks/themes/lr-basic/common.css index a9ec63f5f..748d2d343 100644 --- a/blocks/themes/lr-basic/common.css +++ b/blocks/themes/lr-basic/common.css @@ -1,167 +1,116 @@ -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) { - color: var(--clr-txt); - - /* font-size and family for testing purposes, to be removed */ - font-size: 14px; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', - 'Helvetica Neue', sans-serif; +:where([lr-wgt-common]) { + color: var(--uc-foreground); + font-size: var(--uc-font-size); + line-height: var(--uc-line-height); + font-family: var(--uc-font-family); } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) * { +:where([lr-wgt-common]) * { box-sizing: border-box; } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - [hidden] { +:where([lr-wgt-common]) [hidden] { display: none !important; } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - [activity]:not([active]) { +:where([lr-wgt-common]) [activity]:not([active]) { display: none; } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - dialog:not([open]) - [activity] { +:where([lr-wgt-common]) dialog:not([open]) [activity] { display: none; } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - button { +:where([lr-wgt-common]) button { display: flex; align-items: center; justify-content: center; - height: var(--ui-size); - padding-right: 1.4em; - padding-left: 1.4em; + height: var(--uc-button-size); + padding-right: 14px; + padding-left: 14px; font-size: 1em; font-family: inherit; white-space: nowrap; border: none; - border-radius: var(--border-radius-element); + border-radius: var(--uc-radius); cursor: pointer; user-select: none; + transition: background-color var(--uc-transition); } -@media only screen and (max-width: 800px) { - :where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - button { - padding-right: 1em; - padding-left: 1em; - } -} - -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - button.primary-btn { - color: var(--clr-btn-txt-primary); - background-color: var(--clr-btn-bgr-primary); - box-shadow: var(--shadow-btn-primary); - transition: background-color var(--transition-duration); -} - -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - button.primary-btn:hover { - background-color: var(--clr-btn-bgr-primary-hover); -} - -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - button.primary-btn:active { - background-color: var(--clr-btn-bgr-primary-active); +:where([lr-wgt-common]) button.primary-btn { + color: var(--uc-primary-foreground); + background-color: var(--uc-primary); } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - button.secondary-btn { - color: var(--clr-btn-txt-secondary); - background-color: var(--clr-btn-bgr-secondary); - box-shadow: var(--shadow-btn-secondary); - transition: background-color var(--transition-duration); +:where([lr-wgt-common]) button.primary-btn:hover { + background-color: var(--uc-primary-hover); } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - button.secondary-btn:hover { - background-color: var(--clr-btn-bgr-secondary-hover); +:where([lr-wgt-common]) button.secondary-btn { + color: var(--uc-secondary-foreground); + background-color: var(--uc-secondary); } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - button.secondary-btn:active { - background-color: var(--clr-btn-bgr-secondary-active); +:where([lr-wgt-common]) button.secondary-btn:hover { + background-color: var(--uc-secondary-hover); } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - button.mini-btn { - width: var(--ui-size); - height: var(--ui-size); +:where([lr-wgt-common]) button.mini-btn { + height: var(--uc-button-size); padding: 0; background-color: transparent; - border: none; - cursor: pointer; - transition: var(--transition-duration) ease; - color: var(--clr-txt); -} - -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - button.mini-btn:hover { - background-color: var(--clr-shade-lv1); + color: var(--uc-secondary-foreground); } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - button.mini-btn:active { - background-color: var(--clr-shade-lv2); +:where([lr-wgt-common]) button.mini-btn:hover { + background-color: var(--uc-secondary); } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - :is(button[disabled], button.primary-btn[disabled], button.secondary-btn[disabled]) { - color: var(--clr-btn-txt-disabled); - background-color: var(--clr-btn-bgr-disabled); - box-shadow: var(--shadow-btn-disabled); +:where([lr-wgt-common]) :is(button[disabled], button.primary-btn[disabled], button.secondary-btn[disabled]) { + opacity: 0.5; pointer-events: none; } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) a { - color: var(--clr-accent); +:where([lr-wgt-common]) a { + color: var(--uc-primary); text-decoration: none; } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - a[disabled] { +/* TODO: if we're using disabled
somewhere, we should stop */ +:where([lr-wgt-common]) a[disabled] { pointer-events: none; } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - input[type='text'] { +:where([lr-wgt-common]) input[type='text'] { display: flex; width: 100%; - height: var(--ui-size); - padding-right: 0.6em; - padding-left: 0.6em; - color: var(--clr-txt); + height: var(--uc-button-size); + padding-right: 10px; + padding-left: 10px; + color: var(--uc-foreground); font-size: 1em; font-family: inherit; - background-color: var(--clr-background-light); - border: var(--border-light); - border-radius: var(--border-radius-element); - transition: var(--transition-duration); -} - -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - input[type='text']::placeholder { - color: var(--clr-txt-lightest); + background-color: var(--uc-background); + border: 1px solid var(--uc-border); + outline: 1px solid transparent; + border-radius: var(--uc-radius); + transition: + border-color var(--uc-transition), + outline-color var(--uc-transition); } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - input[type='text']:hover { - border-color: var(--clr-accent-light); +:where([lr-wgt-common]) input[type='text']::placeholder { + color: var(--uc-muted-foreground); } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - input[type='text']:focus { - border-color: var(--clr-accent); - outline: none; +:where([lr-wgt-common]) input[type='text']:focus { + outline-color: var(--uc-primary-hover); + border-color: var(--uc-primary-hover); } -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) - input[disabled] { +/* TODO: check if there's any necessity of disabled input */ +:where([lr-wgt-common]) input[disabled] { opacity: 0.6; pointer-events: none; } diff --git a/blocks/themes/lr-basic/config.css b/blocks/themes/lr-basic/config.css index 36e30bc6e..06b54affb 100644 --- a/blocks/themes/lr-basic/config.css +++ b/blocks/themes/lr-basic/config.css @@ -1,47 +1,4 @@ -:where(.lr-wgt-cfg, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) { - --cfg-pubkey: 'YOUR_PUBLIC_KEY'; - --cfg-multiple: 1; - --cfg-multiple-min: 0; - --cfg-multiple-max: 0; - - --cfg-confirm-upload: 0; - --cfg-img-only: 0; - --cfg-accept: ''; - --cfg-external-sources-preferred-types: ''; - --cfg-store: 'auto'; - --cfg-camera-mirror: 1; - --cfg-source-list: 'local, url, camera, dropbox, gdrive'; - --cfg-max-local-file-size-bytes: 0; - --cfg-thumb-size: 76; - --cfg-show-empty-list: 0; - --cfg-use-local-image-editor: 0; - --cfg-use-cloud-image-editor: 1; - --cfg-remove-copyright: 0; - - --cfg-modal-scroll-lock: 1; - --cfg-modal-backdrop-strokes: 0; - - --cfg-source-list-wrap: 1; - +:where([lr-wgt-common]) { --cfg-init-activity: 'start-from'; --cfg-done-activity: ''; - - --cfg-remote-tab-session-key: ''; - --cfg-cdn-cname: 'https://ucarecdn.com'; - --cfg-base-url: 'https://upload.uploadcare.com'; - --cfg-social-base-url: 'https://social.uploadcare.com'; - --cfg-secure-signature: ''; - --cfg-secure-expire: ''; - --cfg-secure-delivery-proxy: ''; - --cfg-retry-throttled-request-max-times: 1; - --cfg-multipart-min-file-size: 26214400; /* 25MB */ - --cfg-multipart-chunk-size: 5242880; /* 5MB */ - --cfg-max-concurrent-requests: 10; - --cfg-multipart-max-concurrent-requests: 4; - --cfg-multipart-max-attempts: 3; - --cfg-check-for-url-duplicates: 0; - --cfg-save-url-for-recurrent-uploads: 0; - - --cfg-group-output: 0; - --cfg-user-agent-integration: ''; } diff --git a/blocks/themes/lr-basic/icons/check.svg b/blocks/themes/lr-basic/icons/check.svg deleted file mode 100644 index c09d48bb7..000000000 --- a/blocks/themes/lr-basic/icons/check.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/detail.svg b/blocks/themes/lr-basic/icons/detail.svg deleted file mode 100644 index 55759bca2..000000000 --- a/blocks/themes/lr-basic/icons/detail.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/dots.svg b/blocks/themes/lr-basic/icons/dots.svg deleted file mode 100644 index f5b2f365e..000000000 --- a/blocks/themes/lr-basic/icons/dots.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-brightness.svg b/blocks/themes/lr-basic/icons/edit-brightness.svg deleted file mode 100644 index dde83dd28..000000000 --- a/blocks/themes/lr-basic/icons/edit-brightness.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-color.svg b/blocks/themes/lr-basic/icons/edit-color.svg deleted file mode 100644 index 72ba8de67..000000000 --- a/blocks/themes/lr-basic/icons/edit-color.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-contrast.svg b/blocks/themes/lr-basic/icons/edit-contrast.svg deleted file mode 100644 index af76cee71..000000000 --- a/blocks/themes/lr-basic/icons/edit-contrast.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-crop.svg b/blocks/themes/lr-basic/icons/edit-crop.svg deleted file mode 100644 index 64e3c5b4d..000000000 --- a/blocks/themes/lr-basic/icons/edit-crop.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-draw.svg b/blocks/themes/lr-basic/icons/edit-draw.svg deleted file mode 100644 index fe1d72141..000000000 --- a/blocks/themes/lr-basic/icons/edit-draw.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-file.svg b/blocks/themes/lr-basic/icons/edit-file.svg deleted file mode 100644 index 9188f9785..000000000 --- a/blocks/themes/lr-basic/icons/edit-file.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-flip-h.svg b/blocks/themes/lr-basic/icons/edit-flip-h.svg deleted file mode 100644 index f44f858ad..000000000 --- a/blocks/themes/lr-basic/icons/edit-flip-h.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-flip-v.svg b/blocks/themes/lr-basic/icons/edit-flip-v.svg deleted file mode 100644 index b1794aa6b..000000000 --- a/blocks/themes/lr-basic/icons/edit-flip-v.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-guides.svg b/blocks/themes/lr-basic/icons/edit-guides.svg deleted file mode 100644 index 8b392fc93..000000000 --- a/blocks/themes/lr-basic/icons/edit-guides.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-resize.svg b/blocks/themes/lr-basic/icons/edit-resize.svg deleted file mode 100644 index 759ccc880..000000000 --- a/blocks/themes/lr-basic/icons/edit-resize.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-rotate.svg b/blocks/themes/lr-basic/icons/edit-rotate.svg deleted file mode 100644 index be7ac2f30..000000000 --- a/blocks/themes/lr-basic/icons/edit-rotate.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-saturation.svg b/blocks/themes/lr-basic/icons/edit-saturation.svg deleted file mode 100644 index 3b26e45ef..000000000 --- a/blocks/themes/lr-basic/icons/edit-saturation.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit-text.svg b/blocks/themes/lr-basic/icons/edit-text.svg deleted file mode 100644 index 7f351d4f0..000000000 --- a/blocks/themes/lr-basic/icons/edit-text.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/edit.svg b/blocks/themes/lr-basic/icons/edit.svg deleted file mode 100644 index 5dc4b2ebf..000000000 --- a/blocks/themes/lr-basic/icons/edit.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/fullscreen-exit.svg b/blocks/themes/lr-basic/icons/fullscreen-exit.svg deleted file mode 100644 index b6003ee18..000000000 --- a/blocks/themes/lr-basic/icons/fullscreen-exit.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/fullscreen.svg b/blocks/themes/lr-basic/icons/fullscreen.svg deleted file mode 100644 index 09d822573..000000000 --- a/blocks/themes/lr-basic/icons/fullscreen.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/remove.svg b/blocks/themes/lr-basic/icons/remove.svg deleted file mode 100644 index d21bfd88e..000000000 --- a/blocks/themes/lr-basic/icons/remove.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/icons/trash-file.svg b/blocks/themes/lr-basic/icons/trash-file.svg deleted file mode 100644 index d21bfd88e..000000000 --- a/blocks/themes/lr-basic/icons/trash-file.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/blocks/themes/lr-basic/index.css b/blocks/themes/lr-basic/index.css index 91190d231..a6c16b8ec 100644 --- a/blocks/themes/lr-basic/index.css +++ b/blocks/themes/lr-basic/index.css @@ -9,9 +9,7 @@ /* UI COMPONENTS: */ @import url('../../Icon/icon.css'); -@import url('../../Tabs/tabs.css'); @import url('../../Range/range.css'); -@import url('../../Color/color.css'); /* BLOCKS: */ @import url('../../Config/config.css'); @@ -25,10 +23,6 @@ @import url('../../UploadList/upload-list.css'); @import url('../../StartFrom/start-from.css'); @import url('../../FileItem/file-item.css'); - -/* @import url('../../EditableCanvas/editable-canvas.css'); */ -@import url('../../FilePreview/file-preview.css'); -@import url('../../ConfirmationDialog/confirmation.css'); @import url('../../ProgressBarCommon/progress-bar-common.css'); @import url('../../ProgressBar/progress-bar.css'); @import url('../../ActivityHeader/activity-header.css'); diff --git a/blocks/themes/lr-basic/svg-sprite.js b/blocks/themes/lr-basic/svg-sprite.js index 2171ed888..c5906653f 100644 --- a/blocks/themes/lr-basic/svg-sprite.js +++ b/blocks/themes/lr-basic/svg-sprite.js @@ -1 +1 @@ -export default ""; +export default ""; \ No newline at end of file diff --git a/blocks/themes/lr-basic/theme.css b/blocks/themes/lr-basic/theme.css index fc711339c..0673d3ad4 100644 --- a/blocks/themes/lr-basic/theme.css +++ b/blocks/themes/lr-basic/theme.css @@ -1,181 +1,232 @@ -:where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) { - /* Base values */ - - --darkmode: 0; - - --h-foreground: 208; - --s-foreground: 4%; - --l-foreground: calc(10% + 78% * var(--darkmode)); - - --h-background: 208; - --s-background: 4%; - --l-background: calc(97% - 85% * var(--darkmode)); - - --h-accent: 211; - --s-accent: 100%; - --l-accent: calc(50% - 5% * var(--darkmode)); - - --h-confirm: 137; - --s-confirm: 85%; - --l-confirm: 53%; - - --h-error: 358; - --s-error: 100%; - --l-error: 66%; - - --shadows: 1; - - --h-shadow: 0; - --s-shadow: 0%; - --l-shadow: 0%; - - --opacity-normal: 0.6; - --opacity-hover: 0.9; - --opacity-active: 1; - - --ui-size: 32px; - - --gap-min: 2px; - --gap-small: 4px; - --gap-mid: 10px; - --gap-max: 20px; - --gap-table: 0px; - - --borders: 1; - - --border-radius-element: 8px; - --border-radius-frame: 12px; - --border-radius-thumb: 6px; - - --transition-duration: 0.2s; - - --modal-max-w: 800px; - --modal-max-h: 600px; - --modal-normal-w: 430px; - - /* Derivative values */ - - --darkmode-minus: calc(1 + var(--darkmode) * -2); - - --clr-background: hsl(var(--h-background), var(--s-background), var(--l-background)); - --clr-background-dark: hsl( - var(--h-background), - var(--s-background), - calc(var(--l-background) - 3% * var(--darkmode-minus)) - ); - --clr-background-light: hsl( - var(--h-background), - var(--s-background), - calc(var(--l-background) + 3% * var(--darkmode-minus)) - ); - - --clr-accent: hsl(var(--h-accent), var(--s-accent), calc(var(--l-accent) + 15% * var(--darkmode))); - --clr-accent-light: hsla(var(--h-accent), var(--s-accent), var(--l-accent), 30%); - --clr-accent-lightest: hsla(var(--h-accent), var(--s-accent), var(--l-accent), 10%); - --clr-accent-light-opaque: hsl(var(--h-accent), var(--s-accent), calc(var(--l-accent) + 45% * var(--darkmode-minus))); - --clr-accent-lightest-opaque: hsl( - var(--h-accent), - var(--s-accent), - calc(var(--l-accent) + 47% * var(--darkmode-minus)) - ); - - --clr-confirm: hsl(var(--h-confirm), var(--s-confirm), var(--l-confirm)); - - --clr-error: hsl(var(--h-error), var(--s-error), var(--l-error)); - --clr-error-light: hsla(var(--h-error), var(--s-error), var(--l-error), 15%); - --clr-error-lightest: hsla(var(--h-error), var(--s-error), var(--l-error), 5%); - --clr-error-message-bgr: hsl(var(--h-error), var(--s-error), calc(var(--l-error) + 31% * var(--darkmode-minus))); - - --clr-txt: hsl(var(--h-foreground), var(--s-foreground), var(--l-foreground)); - --clr-txt-mid: hsl(var(--h-foreground), var(--s-foreground), calc(var(--l-foreground) + 20% * var(--darkmode-minus))); - --clr-txt-light: hsl( - var(--h-foreground), - var(--s-foreground), - calc(var(--l-foreground) + 30% * var(--darkmode-minus)) - ); - --clr-txt-lightest: hsl( - var(--h-foreground), - var(--s-foreground), - calc(var(--l-foreground) + 50% * var(--darkmode-minus)) - ); - - --clr-shade-lv1: hsla(var(--h-foreground), var(--s-foreground), var(--l-foreground), 5%); - --clr-shade-lv2: hsla(var(--h-foreground), var(--s-foreground), var(--l-foreground), 8%); - --clr-shade-lv3: hsla(var(--h-foreground), var(--s-foreground), var(--l-foreground), 12%); - - --clr-generic-file-icon: var(--clr-txt-lightest); - - --border-light: 1px solid - hsla( - var(--h-foreground), - var(--s-foreground), - var(--l-foreground), - calc((0.1 - 0.05 * var(--darkmode)) * var(--borders)) - ); - --border-mid: 1px solid - hsla( - var(--h-foreground), - var(--s-foreground), - var(--l-foreground), - calc((0.2 - 0.1 * var(--darkmode)) * var(--borders)) - ); - --border-accent: 1px solid hsla(var(--h-accent), var(--s-accent), var(--l-accent), 1 * var(--borders)); - --border-dashed: 1px dashed - hsla(var(--h-foreground), var(--s-foreground), var(--l-foreground), calc(0.2 * var(--borders))); - - --clr-curtain: hsla(var(--h-background), var(--s-background), calc(var(--l-background)), 60%); - - --hsl-shadow: var(--h-shadow), var(--s-shadow), var(--l-shadow); - - --modal-shadow: 0px 0px 1px hsla(var(--hsl-shadow), calc((0.3 + 0.65 * var(--darkmode)) * var(--shadows))), - 0px 6px 20px hsla(var(--hsl-shadow), calc((0.1 + 0.4 * var(--darkmode)) * var(--shadows))); - - --clr-btn-bgr-primary: var(--clr-accent); - --clr-btn-bgr-primary-hover: hsl( - var(--h-accent), - var(--s-accent), - calc(var(--l-accent) - 4% * var(--darkmode-minus)) - ); - --clr-btn-bgr-primary-active: hsl( - var(--h-accent), - var(--s-accent), - calc(var(--l-accent) - 8% * var(--darkmode-minus)) - ); - --clr-btn-txt-primary: hsl(var(--h-accent), var(--s-accent), 98%); - --shadow-btn-primary: none; +:where([lr-wgt-common]) { + /* Font */ + --uc-font-family: system-ui; + --uc-font-size: 14px; + --uc-line-height: normal; + --uc-simple-btn-font-family: system-ui; + --uc-simple-btn-font-size: 14px; + + /* Sizes */ + --uc-button-size: 32px; + --uc-preview-size: 32px; + --uc-padding: 10px; + --uc-radius: 8px; + --uc-transition: 0.2s ease; + --uc-dialog-width: 430px; + --uc-dialog-max-width: 800px; + --uc-dialog-max-height: 600px; + --uc-simple-btn-padding: 7px 14px; + + /* Default colors, in case of media query failure */ + --uc-background: var(--uc-background-light); + --uc-foreground: var(--uc-foreground-light); + --uc-primary: var(--uc-primary-light); + --uc-primary-hover: var(--uc-primary-hover-light); + --uc-primary-transparent: var(--uc-primary-transparent-light); + --uc-primary-foreground: var(--uc-primary-foreground-light); + --uc-secondary: var(--uc-secondary-light); + --uc-secondary-hover: var(--uc-secondary-hover-light); + --uc-secondary-foreground: var(--uc-secondary-foreground-light); + --uc-muted: var(--uc-muted-light); + --uc-muted-foreground: var(--uc-muted-foreground-light); + --uc-destructive: var(--uc-destructive-light); + --uc-destructive-foreground: var(--uc-destructive-foreground-light); + --uc-border: var(--uc-border-light); + --uc-dialog-shadow: var(--uc-dialog-shadow-light); + --uc-simple-btn: var(--uc-simple-btn-light); + --uc-simple-btn-hover: var(--uc-simple-btn-hover-light); + --uc-simple-btn-foreground: var(--uc-simple-btn-foreground-light); +} - --clr-btn-bgr-secondary: hsl( - var(--h-background), - var(--s-background), - calc(var(--l-background) - 3% * var(--darkmode-minus)) - ); - --clr-btn-bgr-secondary-hover: hsl( - var(--h-background), - var(--s-background), - calc(var(--l-background) - 7% * var(--darkmode-minus)) - ); - --clr-btn-bgr-secondary-active: hsl( - var(--h-background), - var(--s-background), - calc(var(--l-background) - 12% * var(--darkmode-minus)) - ); - --clr-btn-txt-secondary: var(--clr-txt-mid); - --shadow-btn-secondary: none; +@supports not (color: oklch(0% 0 0)) { + :where([lr-wgt-common]) { + /* Light colors RGB fallback */ + --uc-primary-rgb-light: 54 112 253; + --uc-primary-light: rgb(var(--uc-primary-rgb-light)); + --uc-primary-hover-light: rgb(var(--uc-primary-rgb-light) / 90%); + --uc-primary-transparent-light: rgb(var(--uc-primary-rgb-light) / 10%); + --uc-background-light: rgb(255 255 255); + --uc-foreground-light: rgb(24 24 24); + --uc-primary-foreground-light: #fff; + --uc-secondary-light: rgb(24 24 24 / 5%); + --uc-secondary-hover-light: rgb(24 24 24 / 8%); + --uc-secondary-foreground-light: rgb(24 24 24); + --uc-muted-light: rgb(245 245 245); + --uc-muted-foreground-light: rgb(113 113 113); + --uc-destructive-light: rgb(232 19 20 / 5%); + --uc-destructive-foreground-light: rgb(232 19 20); + --uc-border-light: rgb(228 228 232); + --uc-dialog-shadow-light: 0px 6px 20px rgb(0 0 0 / 10%); + --uc-simple-btn-light: rgb(235 235 235); + --uc-simple-btn-hover-light: rgb(228 228 228); + --uc-simple-btn-foreground-light: rgb(24 24 24); + + /* Dark colors RGB fallback */ + --uc-primary-rgb-dark: 87 154 255; + --uc-primary-dark: rgb(var(--uc-primary-rgb-dark)); + --uc-primary-hover-dark: rgb(var(--uc-primary-rgb-dark) / 90%); + --uc-primary-transparent-dark: rgb(var(--uc-primary-rgb-dark) / 7%); + --uc-background-dark: rgb(27 27 27); + --uc-foreground-dark: rgb(225 225 225); + --uc-primary-foreground-dark: rgb(0 0 0); + --uc-secondary-dark: rgb(225 225 225 / 7%); + --uc-secondary-hover-dark: rgb(225 225 225 / 10%); + --uc-secondary-foreground-dark: rgb(225 225 225); + --uc-muted-dark: rgb(36 36 36); + --uc-muted-foreground-dark: rgb(152 152 152); + --uc-destructive-dark: rgb(244 90 79 / 10%); + --uc-destructive-foreground-dark: rgb(244 90 79); + --uc-border-dark: rgb(61 61 61); + --uc-dialog-shadow-dark: 0px 6px 20px rgb(0 0 0 / 25%); + --uc-simple-btn-dark: rgb(36 36 36); + --uc-simple-btn-hover-dark: rgb(43 43 43); + --uc-simple-btn-foreground-dark: rgb(255 255 255); + } +} - --clr-btn-bgr-disabled: var(--clr-background); - --clr-btn-txt-disabled: var(--clr-txt-lightest); - --shadow-btn-disabled: none; +@supports (color: oklch(0% 0 0)) { + :where([lr-wgt-common]) { + /* Light colors OKLCH */ + --uc-primary-oklch-light: 59% 0.22 264; /* Quick customization: change this value to your brand color */ + --uc-primary-light: oklch(var(--uc-primary-oklch-light)); + --uc-primary-hover-light: oklch(var(--uc-primary-oklch-light) / 90%); + --uc-primary-transparent-light: oklch(var(--uc-primary-oklch-light) / 10%); + --uc-background-light: oklch(100% 0 0); + --uc-foreground-light: oklch(21% 0 0); + --uc-primary-foreground-light: oklch(100% 0 0); + --uc-secondary-light: oklch(21% 0 0 / 0.05); + --uc-secondary-hover-light: oklch(21% 0 0 / 0.08); + --uc-secondary-foreground-light: oklch(21% 0 0); + --uc-muted-light: oklch(97% 0 0); + --uc-muted-foreground-light: oklch(55% 0 0); + --uc-destructive-light: oklch(59% 0.235 28.5 / 0.05); + --uc-destructive-foreground-light: oklch(59% 0.235 28.5); + --uc-border-light: oklch(92% 0 0); + --uc-dialog-shadow-light: 0px 6px 20px oklch(0% 0 0 / 0.1); + --uc-simple-btn-light: oklch(94% 0 0); + --uc-simple-btn-hover-light: oklch(92% 0 0); + --uc-simple-btn-foreground-light: oklch(20% 0 0); + + /* Dark colors OKLCH */ + --uc-primary-oklch-dark: 69% 0.1768 258.4; /* Quick customization: change this value to your brand color */ + --uc-primary-dark: oklch(var(--uc-primary-oklch-dark)); + --uc-primary-hover-dark: oklch(var(--uc-primary-oklch-dark) / 90%); + --uc-primary-transparent-dark: oklch(var(--uc-primary-oklch-dark) / 7%); + --uc-background-dark: oklch(22% 0 0); + --uc-foreground-dark: oklch(91% 0 0); + --uc-primary-foreground-dark: oklch(0% 0 0); + --uc-secondary-dark: oklch(91% 0 0 / 0.07); + --uc-secondary-hover-dark: oklch(91% 0 0 / 0.1); + --uc-secondary-foreground-dark: oklch(91% 0 0); + --uc-muted-dark: oklch(26% 0 0); + --uc-muted-foreground-dark: oklch(68% 0 0); + --uc-destructive-dark: oklch(67% 0.191 27.5 / 0.1); + --uc-destructive-foreground-dark: oklch(67% 0.191 27.5); + --uc-border-dark: oklch(36% 0 0); + --uc-dialog-shadow-dark: 0px 6px 20px oklch(0% 0 0 / 0.25); + --uc-simple-btn-dark: oklch(26% 0 0); + --uc-simple-btn-hover-dark: oklch(29% 0 0); + --uc-simple-btn-foreground-dark: oklch(100% 0 0); + } } @media only screen and (max-height: 600px) { - :where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) { - --modal-max-h: 100%; + :where([lr-wgt-common]) { + --uc-dialog-max-height: 100%; } } @media only screen and (max-width: 430px) { - :where(.lr-wgt-theme, .lr-wgt-common, lr-file-uploader-minimal, lr-file-uploader-inline, lr-file-uploader-regular) { - --modal-max-w: 100vw; - --modal-max-h: var(--uploadcare-blocks-window-height); + :where([lr-wgt-common]) { + --uc-dialog-max-width: 100vw; + --uc-dialog-max-height: var(--uploadcare-blocks-window-height); } } + +@media (prefers-color-scheme: light) { + :where([lr-wgt-common]) { + --uc-background: var(--uc-background-light); + --uc-foreground: var(--uc-foreground-light); + --uc-primary: var(--uc-primary-light); + --uc-primary-hover: var(--uc-primary-hover-light); + --uc-primary-transparent: var(--uc-primary-transparent-light); + --uc-primary-foreground: var(--uc-primary-foreground-light); + --uc-secondary: var(--uc-secondary-light); + --uc-secondary-hover: var(--uc-secondary-hover-light); + --uc-secondary-foreground: var(--uc-secondary-foreground-light); + --uc-muted: var(--uc-muted-light); + --uc-muted-foreground: var(--uc-muted-foreground-light); + --uc-destructive: var(--uc-destructive-light); + --uc-destructive-foreground: var(--uc-destructive-foreground-light); + --uc-border: var(--uc-border-light); + --uc-dialog-shadow: var(--uc-dialog-shadow-light); + --uc-simple-btn: var(--uc-simple-btn-light); + --uc-simple-btn-hover: var(--uc-simple-btn-hover-light); + --uc-simple-btn-foreground: var(--uc-simple-btn-foreground-light); + } +} + +@media (prefers-color-scheme: dark) { + :where([lr-wgt-common]) { + --uc-background: var(--uc-background-dark); + --uc-foreground: var(--uc-foreground-dark); + --uc-primary: var(--uc-primary-dark); + --uc-primary-hover: var(--uc-primary-hover-dark); + --uc-primary-transparent: var(--uc-primary-transparent-dark); + --uc-primary-foreground: var(--uc-primary-foreground-dark); + --uc-secondary: var(--uc-secondary-dark); + --uc-secondary-hover: var(--uc-secondary-hover-dark); + --uc-secondary-foreground: var(--uc-secondary-foreground-dark); + --uc-muted: var(--uc-muted-dark); + --uc-muted-foreground: var(--uc-muted-foreground-dark); + --uc-destructive: var(--uc-destructive-dark); + --uc-destructive-foreground: var(--uc-destructive-foreground-dark); + --uc-border: var(--uc-border-dark); + --uc-dialog-shadow: var(--uc-dialog-shadow-dark); + --uc-simple-btn: var(--uc-simple-btn-dark); + --uc-simple-btn-hover: var(--uc-simple-btn-hover-dark); + --uc-simple-btn-foreground: var(--uc-simple-btn-foreground-dark); + } +} + +:where(.uc-light) { + --uc-background: var(--uc-background-light); + --uc-foreground: var(--uc-foreground-light); + --uc-primary: var(--uc-primary-light); + --uc-primary-hover: var(--uc-primary-hover-light); + --uc-primary-transparent: var(--uc-primary-transparent-light); + --uc-primary-foreground: var(--uc-primary-foreground-light); + --uc-secondary: var(--uc-secondary-light); + --uc-secondary-hover: var(--uc-secondary-hover-light); + --uc-secondary-foreground: var(--uc-secondary-foreground-light); + --uc-muted: var(--uc-muted-light); + --uc-muted-foreground: var(--uc-muted-foreground-light); + --uc-destructive: var(--uc-destructive-light); + --uc-destructive-foreground: var(--uc-destructive-foreground-light); + --uc-border: var(--uc-border-light); + --uc-dialog-shadow: var(--uc-dialog-shadow-light); + --uc-simple-btn: var(--uc-simple-btn-light); + --uc-simple-btn-hover: var(--uc-simple-btn-hover-light); + --uc-simple-btn-foreground: var(--uc-simple-btn-foreground-light); +} + +:where(.uc-dark) { + --uc-background: var(--uc-background-dark); + --uc-foreground: var(--uc-foreground-dark); + --uc-primary: var(--uc-primary-dark); + --uc-primary-hover: var(--uc-primary-hover-dark); + --uc-primary-transparent: var(--uc-primary-transparent-dark); + --uc-primary-foreground: var(--uc-primary-foreground-dark); + --uc-secondary: var(--uc-secondary-dark); + --uc-secondary-hover: var(--uc-secondary-hover-dark); + --uc-secondary-foreground: var(--uc-secondary-foreground-dark); + --uc-muted: var(--uc-muted-dark); + --uc-muted-foreground: var(--uc-muted-foreground-dark); + --uc-destructive: var(--uc-destructive-dark); + --uc-destructive-foreground: var(--uc-destructive-foreground-dark); + --uc-border: var(--uc-border-dark); + --uc-dialog-shadow: var(--uc-dialog-shadow-dark); + --uc-simple-btn: var(--uc-simple-btn-dark); + --uc-simple-btn-hover: var(--uc-simple-btn-hover-dark); + --uc-simple-btn-foreground: var(--uc-simple-btn-foreground-dark); +} diff --git a/demo/cloud-image-editor.html b/demo/cloud-image-editor.html index cdffa5e61..6e507fe7b 100644 --- a/demo/cloud-image-editor.html +++ b/demo/cloud-image-editor.html @@ -1,9 +1,9 @@ - + - + - - + diff --git a/demo/form.html b/demo/form.html index 090432cff..15d42b2e1 100644 --- a/demo/form.html +++ b/demo/form.html @@ -30,15 +30,16 @@ - + + + +
- - - +

diff --git a/demo/inline-mode.html b/demo/inline-mode.html deleted file mode 100644 index 66a71b121..000000000 --- a/demo/inline-mode.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - -
- - - - - - - - - - - -
- - diff --git a/demo/raw-build.html b/demo/raw-build.html deleted file mode 100644 index 8a5f2099a..000000000 --- a/demo/raw-build.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - diff --git a/demo/raw-inline.html b/demo/raw-inline.html index c14256f9b..8a2f1d608 100644 --- a/demo/raw-inline.html +++ b/demo/raw-inline.html @@ -5,10 +5,10 @@ diff --git a/demo/raw-inline.html b/demo/raw-inline.html index 8a2f1d608..1c76c07ef 100644 --- a/demo/raw-inline.html +++ b/demo/raw-inline.html @@ -20,7 +20,8 @@ "imports": { "@symbiotejs/symbiote": "./node_modules/@symbiotejs/symbiote/build/symbiote.js", "@uploadcare/upload-client": "./node_modules/@uploadcare/upload-client/dist/esm/index.browser.mjs", - "@uploadcare/image-shrink": "./node_modules/@uploadcare/image-shrink/dist/esm/index.browser.mjs" + "@uploadcare/image-shrink": "./node_modules/@uploadcare/image-shrink/dist/esm/index.browser.mjs", + "keyux": "./node_modules/keyux/index.js" } } diff --git a/demo/raw-minimal.html b/demo/raw-minimal.html index 6b8bf75a6..0d30c6652 100644 --- a/demo/raw-minimal.html +++ b/demo/raw-minimal.html @@ -20,7 +20,8 @@ "imports": { "@symbiotejs/symbiote": "./node_modules/@symbiotejs/symbiote/build/symbiote.js", "@uploadcare/upload-client": "./node_modules/@uploadcare/upload-client/dist/esm/index.browser.mjs", - "@uploadcare/image-shrink": "./node_modules/@uploadcare/image-shrink/dist/esm/index.browser.mjs" + "@uploadcare/image-shrink": "./node_modules/@uploadcare/image-shrink/dist/esm/index.browser.mjs", + "keyux": "./node_modules/keyux/index.js" } } diff --git a/demo/raw-regular.html b/demo/raw-regular.html index 80f7c6279..cb6cc9539 100644 --- a/demo/raw-regular.html +++ b/demo/raw-regular.html @@ -20,7 +20,8 @@ "imports": { "@symbiotejs/symbiote": "./node_modules/@symbiotejs/symbiote/build/symbiote.js", "@uploadcare/upload-client": "./node_modules/@uploadcare/upload-client/dist/esm/index.browser.mjs", - "@uploadcare/image-shrink": "./node_modules/@uploadcare/image-shrink/dist/esm/index.browser.mjs" + "@uploadcare/image-shrink": "./node_modules/@uploadcare/image-shrink/dist/esm/index.browser.mjs", + "keyux": "./node_modules/keyux/index.js" } } diff --git a/locales/file-uploader/ar.js b/locales/file-uploader/ar.js index afb6b6568..c66d40c07 100644 --- a/locales/file-uploader/ar.js +++ b/locales/file-uploader/ar.js @@ -108,4 +108,6 @@ export default { 'images-only-accepted': 'يتم قبول ملفات الصور فقط.', 'file-type-not-allowed': 'رفع هذه أنواع الملفات غير مسموح به.', 'some-files-were-not-uploaded': 'لم يتم رفع بعض الملفات.', + 'file-item-edit-button': 'زر التحرير', + 'file-item-remove-button': 'زر الإزالة', }; diff --git a/locales/file-uploader/az.js b/locales/file-uploader/az.js index 85458955c..ff03049fe 100644 --- a/locales/file-uploader/az.js +++ b/locales/file-uploader/az.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': 'Yalnız şəkil faylları qəbul edilir.', 'file-type-not-allowed': 'Bu fayl növlərinin yüklənməsinə icazə verilmir.', 'some-files-were-not-uploaded': 'Bəzi fayllar yüklənmədi.', + 'file-item-edit-button': 'Düzəliş düyməsi', + 'file-item-remove-button': 'Sil düyməsi', }; diff --git a/locales/file-uploader/ca.js b/locales/file-uploader/ca.js index aabba7237..47623d000 100644 --- a/locales/file-uploader/ca.js +++ b/locales/file-uploader/ca.js @@ -103,4 +103,6 @@ export default { 'images-only-accepted': "Només s'accepten fitxers d'imatge.", 'file-type-not-allowed': "No està permès pujar fitxers d'aquest tipus.", 'some-files-were-not-uploaded': "Alguns fitxers no s'han pujat.", + 'file-item-edit-button': "Botó d'edició", + 'file-item-remove-button': 'Botó de supressió', }; diff --git a/locales/file-uploader/cs.js b/locales/file-uploader/cs.js index 3b6a9df2d..3191d4973 100644 --- a/locales/file-uploader/cs.js +++ b/locales/file-uploader/cs.js @@ -105,4 +105,6 @@ export default { 'images-only-accepted': 'Přijímány jsou pouze obrázkové soubory.', 'file-type-not-allowed': 'Nahrávání těchto typů souborů není povoleno.', 'some-files-were-not-uploaded': 'Některé soubory nebyly nahrány.', + 'file-item-edit-button': 'Tlačítko upravit', + 'file-item-remove-button': 'Tlačítko odstranit', }; diff --git a/locales/file-uploader/da.js b/locales/file-uploader/da.js index b751b580d..bacde66df 100644 --- a/locales/file-uploader/da.js +++ b/locales/file-uploader/da.js @@ -101,4 +101,6 @@ export default { 'images-only-accepted': 'Kun billedfiler accepteres.', 'file-type-not-allowed': 'Upload af denne filtype er ikke tilladt.', 'some-files-were-not-uploaded': 'Nogle filer blev ikke uploadet.', + 'file-item-edit-button': 'Redigeringsknap', + 'file-item-remove-button': 'Fjernknap', }; diff --git a/locales/file-uploader/de.js b/locales/file-uploader/de.js index b8a18b6c0..ae74b0a43 100644 --- a/locales/file-uploader/de.js +++ b/locales/file-uploader/de.js @@ -102,4 +102,6 @@ export default { 'images-only-accepted': 'Nur Bilddateien werden akzeptiert.', 'file-type-not-allowed': 'Das Hochladen dieser Dateitypen ist nicht erlaubt.', 'some-files-were-not-uploaded': 'Einige Dateien wurden nicht hochgeladen.', + 'file-item-edit-button': 'Bearbeiten-Taste', + 'file-item-remove-button': 'Entfernen-Taste', }; diff --git a/locales/file-uploader/el.js b/locales/file-uploader/el.js index ad4bb0f27..1efa060b8 100644 --- a/locales/file-uploader/el.js +++ b/locales/file-uploader/el.js @@ -102,4 +102,6 @@ export default { 'images-only-accepted': 'Επιτρέπονται μόνο αρχεία εικόνων.', 'file-type-not-allowed': 'Η μεταφόρτωση αυτών των τύπων αρχείων δεν επιτρέπεται.', 'some-files-were-not-uploaded': 'Κάποια αρχεία δεν μεταφορτώθηκαν.', + 'file-item-edit-button': 'Κουμπί επεξεργασίας', + 'file-item-remove-button': 'Κουμπί αφαίρεσης', }; diff --git a/locales/file-uploader/en.js b/locales/file-uploader/en.js index 34b12595e..a3ea59e09 100644 --- a/locales/file-uploader/en.js +++ b/locales/file-uploader/en.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': 'Only image files are accepted.', 'file-type-not-allowed': 'Uploading of these file types is not allowed.', 'some-files-were-not-uploaded': 'Some files were not uploaded.', + 'file-item-edit-button': 'Edit button', + 'file-item-remove-button': 'Remove button', }; diff --git a/locales/file-uploader/es.js b/locales/file-uploader/es.js index 97710287e..1165729f4 100644 --- a/locales/file-uploader/es.js +++ b/locales/file-uploader/es.js @@ -103,4 +103,6 @@ export default { 'images-only-accepted': 'Solo se aceptan archivos de imagen.', 'file-type-not-allowed': 'No se permite la subida de estos tipos de archivos.', 'some-files-were-not-uploaded': 'Algunos archivos no fueron subidos.', + 'file-item-edit-button': 'Botón de edición', + 'file-item-remove-button': 'Botón de eliminación', }; diff --git a/locales/file-uploader/et.js b/locales/file-uploader/et.js index 810c8df46..591d774f7 100644 --- a/locales/file-uploader/et.js +++ b/locales/file-uploader/et.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': 'Aktsepteeritud on ainult pildifailid.', 'file-type-not-allowed': 'Nende failitüüpide üleslaadimine pole lubatud.', 'some-files-were-not-uploaded': 'Mõned failid ei laetud üles.', + 'file-item-edit-button': 'Muuda nupp', + 'file-item-remove-button': 'Eemalda nupp', }; diff --git a/locales/file-uploader/fr.js b/locales/file-uploader/fr.js index b7962eaf6..b25224a41 100644 --- a/locales/file-uploader/fr.js +++ b/locales/file-uploader/fr.js @@ -103,4 +103,6 @@ export default { 'images-only-accepted': 'Seuls les fichiers image sont acceptés.', 'file-type-not-allowed': "Le téléchargement de ces types de fichiers n'est pas autorisé.", 'some-files-were-not-uploaded': "Certains fichiers n'ont pas été téléchargés.", + 'file-item-edit-button': "Bouton d'édition", + 'file-item-remove-button': 'Bouton de suppression', }; diff --git a/locales/file-uploader/he.js b/locales/file-uploader/he.js index 472b5db82..cd0cd44a3 100644 --- a/locales/file-uploader/he.js +++ b/locales/file-uploader/he.js @@ -102,4 +102,6 @@ export default { 'images-only-accepted': 'מתקבלים רק קבצי תמונות.', 'file-type-not-allowed': 'העלאת סוגי קבצים אלו אינה מורשית.', 'some-files-were-not-uploaded': 'חלק מהקבצים לא הועלו.', + 'file-item-edit-button': 'כפתור עריכה', + 'file-item-remove-button': 'כפתור הסרה', }; diff --git a/locales/file-uploader/hy.js b/locales/file-uploader/hy.js index 65cc725a8..a67b827e5 100644 --- a/locales/file-uploader/hy.js +++ b/locales/file-uploader/hy.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': 'Միայն պատկերային ֆայլերը ընդունվում են։', 'file-type-not-allowed': 'Այս ֆայլի տեսակների բեռնումը թույլատրված չէ։', 'some-files-were-not-uploaded': 'Որոշ ֆայլեր բեռնված չեն։', + 'file-item-edit-button': 'Խմբագրել կոճակը', + 'file-item-remove-button': 'Հեռացման կոճակը', }; diff --git a/locales/file-uploader/is.js b/locales/file-uploader/is.js index 5bbd9e842..bfa5080d3 100644 --- a/locales/file-uploader/is.js +++ b/locales/file-uploader/is.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': 'Aðeins myndaskrár eru samþykktar.', 'file-type-not-allowed': 'Ekki er leyft að hlaða upp þessum skráartegundum.', 'some-files-were-not-uploaded': 'Sumar skrár voru ekki hlaðnar upp.', + 'file-item-edit-button': 'Breyta hnappur', + 'file-item-remove-button': 'Fjarlægja hnappur', }; diff --git a/locales/file-uploader/it.js b/locales/file-uploader/it.js index bc2dfca02..5077ef43b 100644 --- a/locales/file-uploader/it.js +++ b/locales/file-uploader/it.js @@ -103,4 +103,6 @@ export default { 'images-only-accepted': 'Sono accettati solo file immagine.', 'file-type-not-allowed': 'Il caricamento di questo tipo di file non è permesso.', 'some-files-were-not-uploaded': 'Alcuni file non sono stati caricati.', + 'file-item-edit-button': 'Pulsante di modifica', + 'file-item-remove-button': 'Pulsante di rimozione', }; diff --git a/locales/file-uploader/ja.js b/locales/file-uploader/ja.js index a37be2096..497a1c3b1 100644 --- a/locales/file-uploader/ja.js +++ b/locales/file-uploader/ja.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': '画像ファイルのみ受け付けます。', 'file-type-not-allowed': 'このファイルタイプのアップロードは許可されていません。', 'some-files-were-not-uploaded': '一部のファイルはアップロードされませんでした。', + 'file-item-edit-button': '編集ボタン', + 'file-item-remove-button': '削除ボタン', }; diff --git a/locales/file-uploader/ka.js b/locales/file-uploader/ka.js index d0ea2e4b0..5d5e64b20 100644 --- a/locales/file-uploader/ka.js +++ b/locales/file-uploader/ka.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': 'მხოლოდ სურათის ფაილები იღება.', 'file-type-not-allowed': 'ამ ფაილის ტიპების ატვირთვა არ არის დასაშვები.', 'some-files-were-not-uploaded': 'ზოგიერთი ფაილი არ ატვირთულა.', + 'file-item-edit-button': 'რედაქტირების ღილაკი', + 'file-item-remove-button': 'წაშლის ღილაკი', }; diff --git a/locales/file-uploader/kk.js b/locales/file-uploader/kk.js index d46b9d54e..c73b45f6a 100644 --- a/locales/file-uploader/kk.js +++ b/locales/file-uploader/kk.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': 'Тек сурет файлдары қабылданады.', 'file-type-not-allowed': 'Осы файл түрлерін жүктеуге рұқсат етілмейді.', 'some-files-were-not-uploaded': 'Кейбір файлдар жүктелген жоқ.', + 'file-item-edit-button': 'Өңдеу түймесі', + 'file-item-remove-button': 'Жою түймесі', }; diff --git a/locales/file-uploader/ko.js b/locales/file-uploader/ko.js index 6a32ddb83..f4ad486ae 100644 --- a/locales/file-uploader/ko.js +++ b/locales/file-uploader/ko.js @@ -99,4 +99,6 @@ export default { 'images-only-accepted': '이미지 파일만 허용됩니다.', 'file-type-not-allowed': '이 파일 유형의 업로드가 허용되지 않습니다.', 'some-files-were-not-uploaded': '일부 파일이 업로드되지 않았습니다.', + 'file-item-edit-button': '편집 버튼', + 'file-item-remove-button': '제거 버튼', }; diff --git a/locales/file-uploader/lv.js b/locales/file-uploader/lv.js index 466540a2d..55aa64ccb 100644 --- a/locales/file-uploader/lv.js +++ b/locales/file-uploader/lv.js @@ -102,4 +102,6 @@ export default { 'images-only-accepted': 'Tiek pieņemti tikai attēlu faili.', 'file-type-not-allowed': 'Šāda tipa failu augšupielāde nav atļauta.', 'some-files-were-not-uploaded': 'Daži faili netika augšupielādēti.', + 'file-item-edit-button': 'Rediģēšanas poga', + 'file-item-remove-button': 'Noņemšanas poga', }; diff --git a/locales/file-uploader/nb.js b/locales/file-uploader/nb.js index 1b5e0f454..07c621f2b 100644 --- a/locales/file-uploader/nb.js +++ b/locales/file-uploader/nb.js @@ -32,9 +32,9 @@ export default { 'no-files': 'Ingen filer valgt', browse: 'Bla gjennom', 'not-uploaded-yet': 'Ikke lastet opp ennå...', - file__one: 'fil', // Norwegian Bokmål uses 'one' for singular - file__other: 'filer', // and 'other' for plural - error__one: 'feil', // Similarly for errors + file__one: 'fil', + file__other: 'filer', + error__one: 'feil', error__other: 'feil', 'header-uploading': 'Laster opp {{count}} {{plural:file(count)}}', 'header-failed': '{{count}} {{plural:error(count)}}', @@ -100,4 +100,6 @@ export default { 'images-only-accepted': 'Kun bildefiler er akseptert.', 'file-type-not-allowed': 'Opplasting av disse filtypene er ikke tillatt.', 'some-files-were-not-uploaded': 'Noen filer ble ikke lastet opp.', + 'file-item-edit-button': 'Redigeringsknapp', + 'file-item-remove-button': 'Fjerningsknapp', }; diff --git a/locales/file-uploader/nl.js b/locales/file-uploader/nl.js index 19274e316..8762c6bab 100644 --- a/locales/file-uploader/nl.js +++ b/locales/file-uploader/nl.js @@ -101,4 +101,6 @@ export default { 'images-only-accepted': 'Alleen afbeeldingsbestanden worden geaccepteerd.', 'file-type-not-allowed': 'Dit bestandstype is niet toegestaan.', 'some-files-were-not-uploaded': 'Sommige bestanden zijn niet geüpload.', + 'file-item-edit-button': 'Bewerkknop', + 'file-item-remove-button': 'Verwijderknop', }; diff --git a/locales/file-uploader/pl.js b/locales/file-uploader/pl.js index ac7d5c7d0..82a82ca70 100644 --- a/locales/file-uploader/pl.js +++ b/locales/file-uploader/pl.js @@ -104,4 +104,6 @@ export default { 'images-only-accepted': 'Akceptowane są tylko pliki obrazów.', 'file-type-not-allowed': 'Przesyłanie tego typu plików jest niedozwolone.', 'some-files-were-not-uploaded': 'Niektóre pliki nie zostały przesłane.', + 'file-item-edit-button': 'Przycisk edycji', + 'file-item-remove-button': 'Przycisk usuwania', }; diff --git a/locales/file-uploader/pt.js b/locales/file-uploader/pt.js index bb7599d92..98f3b1c28 100644 --- a/locales/file-uploader/pt.js +++ b/locales/file-uploader/pt.js @@ -103,4 +103,6 @@ export default { 'images-only-accepted': 'Apenas arquivos de imagem são aceitos.', 'file-type-not-allowed': 'O upload desses tipos de arquivo não é permitido.', 'some-files-were-not-uploaded': 'Alguns arquivos não foram carregados.', + 'file-item-edit-button': 'Botão de edição', + 'file-item-remove-button': 'Botão de remoção', }; diff --git a/locales/file-uploader/ro.js b/locales/file-uploader/ro.js index f6394c727..e96fe363f 100644 --- a/locales/file-uploader/ro.js +++ b/locales/file-uploader/ro.js @@ -103,4 +103,6 @@ export default { 'images-only-accepted': 'Doar fișierele de tip imagine sunt acceptate.', 'file-type-not-allowed': 'Încărcarea acestor tipuri de fișiere nu este permisă.', 'some-files-were-not-uploaded': 'Unele fișiere nu au fost încărcate.', + 'file-item-edit-button': 'Buton de editare', + 'file-item-remove-button': 'Buton de ștergere', }; diff --git a/locales/file-uploader/ru.js b/locales/file-uploader/ru.js index 15c90ae40..7b8990660 100644 --- a/locales/file-uploader/ru.js +++ b/locales/file-uploader/ru.js @@ -104,4 +104,6 @@ export default { 'images-only-accepted': 'Принимаются только изображения.', 'file-type-not-allowed': 'Загрузка файлов этого типа не разрешена.', 'some-files-were-not-uploaded': 'Некоторые файлы не были загружены.', + 'file-item-edit-button': 'Кнопка редактирования', + 'file-item-remove-button': 'Кнопка удаления', }; diff --git a/locales/file-uploader/sk.js b/locales/file-uploader/sk.js index 5a6462761..5abfb7992 100644 --- a/locales/file-uploader/sk.js +++ b/locales/file-uploader/sk.js @@ -104,4 +104,6 @@ export default { 'images-only-accepted': 'Sú akceptované len obrázkové súbory.', 'file-type-not-allowed': 'Nahrávanie tohto typu súborov nie je povolené.', 'some-files-were-not-uploaded': 'Niektoré súbory neboli nahrané.', + 'file-item-edit-button': 'Tlačidlo upraviť', + 'file-item-remove-button': 'Tlačidlo odstrániť', }; diff --git a/locales/file-uploader/sr.js b/locales/file-uploader/sr.js index 22ceace26..5be5121f1 100644 --- a/locales/file-uploader/sr.js +++ b/locales/file-uploader/sr.js @@ -102,4 +102,6 @@ export default { 'images-only-accepted': 'Прихваћене су само слике.', 'file-type-not-allowed': 'Отпремање овог типа датотека није дозвољено.', 'some-files-were-not-uploaded': 'Неке датотеке нису отпремљене.', + 'file-item-edit-button': 'Дугме за уређивање', + 'file-item-remove-button': 'Дугме за уклањање', }; diff --git a/locales/file-uploader/sv.js b/locales/file-uploader/sv.js index bc4dbf66a..7b6e30fb3 100644 --- a/locales/file-uploader/sv.js +++ b/locales/file-uploader/sv.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': 'Endast bildfiler accepteras.', 'file-type-not-allowed': 'Uppladdning av dessa filtyper är inte tillåten.', 'some-files-were-not-uploaded': 'Vissa filer laddades inte upp.', + 'file-item-edit-button': 'Redigeringsknapp', + 'file-item-remove-button': 'Raderingsknapp', }; diff --git a/locales/file-uploader/tr.js b/locales/file-uploader/tr.js index fbdd71a00..ce99c5851 100644 --- a/locales/file-uploader/tr.js +++ b/locales/file-uploader/tr.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': 'Yalnızca resim dosyaları kabul edilir.', 'file-type-not-allowed': 'Bu dosya türlerinin yüklenmesine izin verilmiyor.', 'some-files-were-not-uploaded': 'Bazı dosyalar yüklenemedi.', + 'file-item-edit-button': 'Düzenle düğmesi', + 'file-item-remove-button': 'Silme düğmesi', }; diff --git a/locales/file-uploader/uk.js b/locales/file-uploader/uk.js index a9304357c..c78087cea 100644 --- a/locales/file-uploader/uk.js +++ b/locales/file-uploader/uk.js @@ -104,4 +104,6 @@ export default { 'images-only-accepted': 'Приймаються тільки зображення.', 'file-type-not-allowed': 'Завантаження файлів цього типу заборонено.', 'some-files-were-not-uploaded': 'Деякі файли не були завантажені.', + 'file-item-edit-button': 'Кнопка редагування', + 'file-item-remove-button': 'Кнопка видалення', }; diff --git a/locales/file-uploader/vi.js b/locales/file-uploader/vi.js index 3483dad35..6186b2ccf 100644 --- a/locales/file-uploader/vi.js +++ b/locales/file-uploader/vi.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': 'Chỉ chấp nhận tệp ảnh.', 'file-type-not-allowed': 'Không cho phép tải lên loại tệp này.', 'some-files-were-not-uploaded': 'Một số tệp chưa được tải lên.', + 'file-item-edit-button': 'Nút chỉnh sửa', + 'file-item-remove-button': 'Nút xóa', }; diff --git a/locales/file-uploader/zh-TW.js b/locales/file-uploader/zh-TW.js index 1fc1bd402..acf49ac60 100644 --- a/locales/file-uploader/zh-TW.js +++ b/locales/file-uploader/zh-TW.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': '僅接受圖片檔案。', 'file-type-not-allowed': '不允許上傳這些檔案類型。', 'some-files-were-not-uploaded': '部分檔案未上傳。', + 'file-item-edit-button': '編輯按鈕', + 'file-item-remove-button': '刪除按鈕', }; diff --git a/locales/file-uploader/zh.js b/locales/file-uploader/zh.js index d8ddb1a74..2199e6d3b 100644 --- a/locales/file-uploader/zh.js +++ b/locales/file-uploader/zh.js @@ -100,4 +100,6 @@ export default { 'images-only-accepted': '只接受图像文件。', 'file-type-not-allowed': '不允许上传这些文件类型。', 'some-files-were-not-uploaded': '有些文件未上传。', + 'file-item-edit-button': '編輯按鈕', + 'file-item-remove-button': '刪除按鈕', }; diff --git a/package-lock.json b/package-lock.json index 43bd79d33..0a6b1537b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,8 @@ "dependencies": { "@symbiotejs/symbiote": "^1.11.7", "@uploadcare/image-shrink": "^6.14.1", - "@uploadcare/upload-client": "^6.14.1" + "@uploadcare/upload-client": "^6.14.1", + "keyux": "^0.7.1" }, "devDependencies": { "@babel/eslint-parser": "^7.23.3", @@ -8728,6 +8729,20 @@ "node": ">= 0.6" } }, + "node_modules/keyux": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/keyux/-/keyux-0.7.1.tgz", + "integrity": "sha512-4i0awjBLTiSMNyQluM5+yOQT1zjYe+iXA9lqb3fzBjAO9GxnVfscjaUHbBh8kvq9LmMnSD77K7MmLQJPt2n//w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -20891,6 +20906,11 @@ "tsscmp": "1.0.6" } }, + "keyux": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/keyux/-/keyux-0.7.1.tgz", + "integrity": "sha512-4i0awjBLTiSMNyQluM5+yOQT1zjYe+iXA9lqb3fzBjAO9GxnVfscjaUHbBh8kvq9LmMnSD77K7MmLQJPt2n//w==" + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", diff --git a/package.json b/package.json index a9501f212..8a4799c70 100644 --- a/package.json +++ b/package.json @@ -136,6 +136,7 @@ "dependencies": { "@symbiotejs/symbiote": "^1.11.7", "@uploadcare/image-shrink": "^6.14.1", - "@uploadcare/upload-client": "^6.14.1" + "@uploadcare/upload-client": "^6.14.1", + "keyux": "^0.7.1" } } diff --git a/solutions/cloud-image-editor/CloudImageEditor.js b/solutions/cloud-image-editor/CloudImageEditor.js index 101debf02..2d155f19e 100644 --- a/solutions/cloud-image-editor/CloudImageEditor.js +++ b/solutions/cloud-image-editor/CloudImageEditor.js @@ -3,4 +3,10 @@ import { CloudImageEditorBlock } from '../../blocks/CloudImageEditor/src/CloudIm export class CloudImageEditor extends CloudImageEditorBlock { static styleAttrs = [...super.styleAttrs, 'lr-wgt-common']; + + initCallback() { + super.initCallback(); + + this.a11y?.registerBlock(this); + } } diff --git a/solutions/file-uploader/minimal/FileUploaderMinimal.js b/solutions/file-uploader/minimal/FileUploaderMinimal.js index f32a39cf8..1402a1186 100644 --- a/solutions/file-uploader/minimal/FileUploaderMinimal.js +++ b/solutions/file-uploader/minimal/FileUploaderMinimal.js @@ -39,7 +39,7 @@ export class FileUploaderMinimal extends SolutionBlock { FileUploaderMinimal.template = /* HTML */ ` - + From 4fdf9a0af47da7afb3582b1a54affe6c3725bb03 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 19:48:55 +0300 Subject: [PATCH 7/7] chore: release v0.46.0 (#682) * chore: release v0.46.0 * Update CHANGELOG.md --------- Co-authored-by: github-actions[bot] Co-authored-by: Aleksandr Grenishin --- CHANGELOG.md | 10 ++++++++-- env.js | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69f56fc69..4d9b39101 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,15 @@ +# [0.46.0](https://github.com/uploadcare/blocks/compare/v0.45.0...v0.46.0) (2024-06-24) + +### Features + +- Significant improvements to accessibility and keyboard navigation, enhancing user experience and inclusivity ([#671](https://github.com/uploadcare/blocks/issues/671)) ([4acb8a0](https://github.com/uploadcare/blocks/commit/4acb8a0b7ea9c7a95be415627f7d4e1eb748fcf2)) + # [0.45.0](https://github.com/uploadcare/blocks/compare/v0.44.0...v0.45.0) (2024-06-23) ### BEAKING CHANGES -* The previously deprecated API method `setUploadMetadata` has been removed. Use `metadata` instance property on `lr-config` block instead. See [metadata](https://uploadcare.com/docs/file-uploader/options/#metadata) for more details. -* The previously deprecated API method `addFiles` has been removed. Use `addFileFromObject`, `addFileFromUrl` or `addFileFromUuid` instead. See [File Uploader API](https://uploadcare.com/docs/file-uploader/api/#add-file-from-object) for more details. +- The previously deprecated API method `setUploadMetadata` has been removed. Use `metadata` instance property on `lr-config` block instead. See [metadata](https://uploadcare.com/docs/file-uploader/options/#metadata) for more details. +- The previously deprecated API method `addFiles` has been removed. Use `addFileFromObject`, `addFileFromUrl` or `addFileFromUuid` instead. See [File Uploader API](https://uploadcare.com/docs/file-uploader/api/#add-file-from-object) for more details. See the [migration guide](https://uploadcare.com/docs/file-uploader/migration-to-0.45.0/) for details. diff --git a/env.js b/env.js index 3ef7f4ee3..87d845be8 100644 --- a/env.js +++ b/env.js @@ -1,3 +1,3 @@ /** Do not edit this file manually. It's generated during build process. */ export const PACKAGE_NAME = 'blocks'; -export const PACKAGE_VERSION = '0.45.0'; +export const PACKAGE_VERSION = '0.46.0'; diff --git a/package-lock.json b/package-lock.json index 0a6b1537b..7b3cc16b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@uploadcare/blocks", - "version": "0.45.0", + "version": "0.46.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@uploadcare/blocks", - "version": "0.45.0", + "version": "0.46.0", "license": "MIT", "dependencies": { "@symbiotejs/symbiote": "^1.11.7", diff --git a/package.json b/package.json index 8a4799c70..5399193c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@uploadcare/blocks", - "version": "0.45.0", + "version": "0.46.0", "description": "Building blocks for Uploadcare products integration", "keywords": [ "web components",