From 6c5c1f31605b7d6562ffee807175237182d043be Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Tue, 17 Oct 2023 15:14:43 +0300 Subject: [PATCH 01/42] Initial implementation for the tab move area and the tab header Signed-off-by: Svetozar Mateev --- src/GroupElementCreationWrapper.tsx | 17 +++++++++++------ src/GroupWrapper.tsx | 12 ++++++++++++ src/types/api.ts | 10 ++++++++-- src/types/internal.ts | 23 ++++++++++++++++++++--- src/webGroupsManager.ts | 14 +++++++++++--- 5 files changed, 62 insertions(+), 14 deletions(-) diff --git a/src/GroupElementCreationWrapper.tsx b/src/GroupElementCreationWrapper.tsx index 0b45aec..0e863ee 100644 --- a/src/GroupElementCreationWrapper.tsx +++ b/src/GroupElementCreationWrapper.tsx @@ -8,7 +8,7 @@ import { CustomButtonProps } from "./types/defaultComponents"; import webGroupsManager from "./webGroupsManager"; import webGroupsStore from "./webGroupsStore"; -const GroupElementCreationWrapper: React.FC = ({ components }) => { +const GroupElementCreationWrapper: React.FC = ({ components, styles }) => { const state = useSyncExternalStore(webGroupsStore.subscribe, webGroupsStore.getSnapshot); @@ -165,7 +165,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { let customButtonsProps = new Array(); if (options.customButtons) { - customButtonsProps = options.customButtons.map((cButton) => { + customButtonsProps = options.customButtons.map((cButton) => { return { onClick: () => { webGroupsManager.clickCustomButton(options.targetId, cButton.buttonId); @@ -173,7 +173,9 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { visible: true, imageData: cButton.imageData, tooltip: cButton.tooltip, - buttonId: cButton.buttonId}}); + buttonId: cButton.buttonId + } + }); } const showSelector = (bounds: Bounds) => { @@ -465,7 +467,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { let customButtonsProps = new Array(); if (options.customButtons) { - customButtonsProps = options.customButtons.map((cButton) => { + customButtonsProps = options.customButtons.map((cButton) => { return { onClick: () => { webGroupsManager.clickCustomButton(options.targetId, cButton.buttonId); @@ -473,9 +475,11 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { visible: true, imageData: cButton.imageData, tooltip: cButton.tooltip, - buttonId: cButton.buttonId}}); + buttonId: cButton.buttonId + } + }); } - + return = ({ components }) => { onHideCaptionEditorRequested={webGroupsStore.onHideCaptionEditorRequested} onShowLoadingAnimationRequested={webGroupsStore.onShowLoadingAnimationRequested} onHideLoadingAnimationRequested={webGroupsStore.onHideLoadingAnimationRequested} + styles={styles} /> } diff --git a/src/GroupWrapper.tsx b/src/GroupWrapper.tsx index b1e3537..b334af1 100644 --- a/src/GroupWrapper.tsx +++ b/src/GroupWrapper.tsx @@ -61,6 +61,18 @@ class GroupWrapper extends React.Component { }; webGroupsManager.init(undefined, componentFactory); + webGroupsManager.updateTabHeaderStyles(this.props.styles?.tabs?.header ?? {}); + webGroupsManager.updateTabMoveAreaStyles(this.props.styles?.tabs?.moveArea ?? {}); + } + + componentDidUpdate(prevProps: Readonly, prevState: Readonly<{}>, snapshot?: any): void { + if (this.props.styles?.tabs?.header !== prevProps.styles?.tabs?.header) { + webGroupsManager.updateTabHeaderStyles(this.props.styles?.tabs?.header ?? {}); + } + + if (this.props.styles?.tabs?.moveArea !== prevProps.styles?.tabs?.moveArea) { + webGroupsManager.updateTabMoveAreaStyles(this.props.styles?.tabs?.moveArea ?? {}); + } } componentWillUnmount() { diff --git a/src/types/api.ts b/src/types/api.ts index ecc565d..5053e06 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -1,5 +1,5 @@ -import React from "react"; -import { Bounds, ButtonProps, ToggleButtonProps } from "./internal"; +import React, { CSSProperties } from "react"; +import { Bounds, ButtonProps, StylesOptions, ToggleButtonProps } from "./internal"; import { CustomButtonProps } from "./defaultComponents"; export interface ChannelProps { @@ -154,6 +154,12 @@ export interface GroupProps { Buttons?: React.ComponentType; Below?: React.ComponentType; } + }, + styles?: { + tabs?: { + header?: StylesOptions; + moveArea?: StylesOptions; + } } } diff --git a/src/types/internal.ts b/src/types/internal.ts index f24d94a..a5920c1 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -1,5 +1,8 @@ import React from "react"; +type NonMethodKeys = ({ [P in keyof T]: T[P] extends Function ? never : P })[keyof T]; +type NonMethods = Pick>; + export interface PortalProps { parentElement: HTMLElement; children?: React.ReactNode; @@ -11,7 +14,7 @@ export interface ButtonProps { visible: boolean; } -export interface ToggleButtonProps extends ButtonProps{ +export interface ToggleButtonProps extends ButtonProps { isPressed: boolean; } @@ -70,8 +73,14 @@ export interface GroupWrapperProps { onCommitCaptionEditingRequested?: (targetType: TargetType, targetId: string) => void; onHideCaptionEditorRequested?: (targetType: TargetType, targetId: string) => void; - onShowLoadingAnimationRequested?: (targetType: TargetType ,targetId: string) => void; - onHideLoadingAnimationRequested?: (targetType: TargetType ,targetId: string) => void; + onShowLoadingAnimationRequested?: (targetType: TargetType, targetId: string) => void; + onHideLoadingAnimationRequested?: (targetType: TargetType, targetId: string) => void; + styles?: { + tabs?: { + header?: StylesOptions; + moveArea?: StylesOptions; + } + }; } export interface CreateGroupCaptionBarRequestOptions extends CreateElementRequestOptions { @@ -308,6 +317,9 @@ export interface ExternalLibraryFactory { onCaptionEditorVisibleChanged(targetType: TargetType, targetId: string, visible: boolean): void; onCaptionEditorBoundsChanged(targetType: TargetType, targetId: string, bounds: Bounds): void; commitCaptionEditing(targetType: TargetType, targetId: string, text: string): void; + + updateTabHeaderStyles(styles: any): void; + updateTabMoveAreaStyles(styles: any): void; } export interface WebGroupsManager { @@ -330,3 +342,8 @@ export interface Bounds extends Size { left: number; top: number; } + +export interface StylesOptions { + css?: Partial>; + classes?: string[] +} diff --git a/src/webGroupsManager.ts b/src/webGroupsManager.ts index 44f750b..780cfa8 100644 --- a/src/webGroupsManager.ts +++ b/src/webGroupsManager.ts @@ -1,4 +1,4 @@ -import { Bounds, StandardButtons, TargetType, WebGroupsManager } from "./types/internal"; +import { Bounds, GroupWrapperProps, StandardButtons, StylesOptions, TargetType, WebGroupsManager } from "./types/internal"; import callbackRegistry from "callback-registry"; declare const window: Window & { webGroupsManager: WebGroupsManager }; @@ -79,11 +79,11 @@ class WebGroupsManagerDecorator { window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Frame, targetId, StandardButtons.Unlock); } - public feedbackFrame(targetId: string):void{ + public feedbackFrame(targetId: string): void { window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Frame, targetId, StandardButtons.Feedback); } - public stickyFrame(targetId: string):void{ + public stickyFrame(targetId: string): void { window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Frame, targetId, StandardButtons.Sticky); } @@ -202,6 +202,14 @@ class WebGroupsManagerDecorator { public requestCommitCaptionEditing(targetType: TargetType, targetId: string) { this.registry.execute(`${targetType}-${targetId}`); } + + public updateTabHeaderStyles(styles: StylesOptions) { + window.webGroupsManager.externalLibraryFactory.updateTabHeaderStyles(styles); + } + + public updateTabMoveAreaStyles(styles: StylesOptions) { + window.webGroupsManager.externalLibraryFactory.updateTabMoveAreaStyles(styles); + } } export default new WebGroupsManagerDecorator(); \ No newline at end of file From d1979086cdc3e27dc3c5dd8f198076bead39afc9 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Thu, 19 Oct 2023 15:41:41 +0300 Subject: [PATCH 02/42] Added frame element style customizations Signed-off-by: Svetozar Mateev --- src/GroupWrapper.tsx | 5 +++++ src/types/api.ts | 3 +++ src/types/internal.ts | 8 ++++++-- src/webGroupsManager.ts | 4 ++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/GroupWrapper.tsx b/src/GroupWrapper.tsx index b334af1..28d164d 100644 --- a/src/GroupWrapper.tsx +++ b/src/GroupWrapper.tsx @@ -63,6 +63,7 @@ class GroupWrapper extends React.Component { webGroupsManager.init(undefined, componentFactory); webGroupsManager.updateTabHeaderStyles(this.props.styles?.tabs?.header ?? {}); webGroupsManager.updateTabMoveAreaStyles(this.props.styles?.tabs?.moveArea ?? {}); + webGroupsManager.updateFrameStyles(this.props.styles?.frame?.element ?? {}); } componentDidUpdate(prevProps: Readonly, prevState: Readonly<{}>, snapshot?: any): void { @@ -73,6 +74,10 @@ class GroupWrapper extends React.Component { if (this.props.styles?.tabs?.moveArea !== prevProps.styles?.tabs?.moveArea) { webGroupsManager.updateTabMoveAreaStyles(this.props.styles?.tabs?.moveArea ?? {}); } + + if (this.props.styles?.frame?.element !== prevProps.styles?.frame?.element) { + webGroupsManager.updateFrameStyles(this.props.styles?.frame?.element ?? {}); + } } componentWillUnmount() { diff --git a/src/types/api.ts b/src/types/api.ts index 5053e06..236176c 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -159,6 +159,9 @@ export interface GroupProps { tabs?: { header?: StylesOptions; moveArea?: StylesOptions; + }, + frame?: { + element?: StylesOptions; } } } diff --git a/src/types/internal.ts b/src/types/internal.ts index a5920c1..85bf415 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -79,6 +79,9 @@ export interface GroupWrapperProps { tabs?: { header?: StylesOptions; moveArea?: StylesOptions; + }, + frame?: { + element?: StylesOptions; } }; } @@ -318,8 +321,9 @@ export interface ExternalLibraryFactory { onCaptionEditorBoundsChanged(targetType: TargetType, targetId: string, bounds: Bounds): void; commitCaptionEditing(targetType: TargetType, targetId: string, text: string): void; - updateTabHeaderStyles(styles: any): void; - updateTabMoveAreaStyles(styles: any): void; + updateTabHeaderStyles(styles: StylesOptions): void; + updateTabMoveAreaStyles(styles: StylesOptions): void; + updateFrameStyles(styles: StylesOptions): void; } export interface WebGroupsManager { diff --git a/src/webGroupsManager.ts b/src/webGroupsManager.ts index 780cfa8..2fc67ec 100644 --- a/src/webGroupsManager.ts +++ b/src/webGroupsManager.ts @@ -210,6 +210,10 @@ class WebGroupsManagerDecorator { public updateTabMoveAreaStyles(styles: StylesOptions) { window.webGroupsManager.externalLibraryFactory.updateTabMoveAreaStyles(styles); } + + public updateFrameStyles(styles: StylesOptions) { + window.webGroupsManager.externalLibraryFactory.updateFrameStyles(styles); + } } export default new WebGroupsManagerDecorator(); \ No newline at end of file From faf875fcb59549607999d370ec76f16d09a70b70 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Mon, 26 Feb 2024 13:53:22 +0200 Subject: [PATCH 03/42] 9.2 (#31) * G4 e 6107 html add html buttons (#26) * https://interopio.atlassian.net/browse/G4E-6107 add html buttons supports * https://interopio.atlassian.net/browse/G4E-6107 add removeHtmlButtons functionality * https://interopio.atlassian.net/browse/G4E-6107 add separate style for html buttons element * https://interopio.atlassian.net/browse/G4E-6107 fix PR comments add standard buttons handlers for html buttons add common CreateButtonsOptions for tab, flat and html buttons * https://interopio.atlassian.net/browse/G4E-6107 add common buttons click methods --------- Co-authored-by: dilian bilchev * Released a preview version for 9.2 Signed-off-by: Svetozar Mateev * Release 2.0.2 next Signed-off-by: Svetozar Mateev * G4E-7453 Changed the default for the loading animation to the default component in the library (#28) Signed-off-by: Svetozar Mateev Co-authored-by: Svetozar Mateev * Released 2.0.3 Signed-off-by: Svetozar Mateev * Fixed typo in class name Signed-off-by: Svetozar Mateev * Released 2.0.4 Signed-off-by: Svetozar Mateev * G4 e 6700 application clone button (#29) * https://interopio.atlassian.net/browse/G4E-6700 - Application Clone Button - button added * https://interopio.atlassian.net/browse/G4E-6700 - Application Clone Button - fixing HTML buttons styles * G4E-6700 Updated @interopio/theme to 2.0.5 Signed-off-by: Svetozar Mateev --------- Signed-off-by: Svetozar Mateev Co-authored-by: Elijah Stoykov Co-authored-by: Svetozar Mateev * Released 2.0.5 Signed-off-by: Svetozar Mateev * G4E-7518 Updated the flat channels selector styles (#30) Signed-off-by: Svetozar Mateev Co-authored-by: Svetozar Mateev * Released 2.0.6 Signed-off-by: Svetozar Mateev --------- Signed-off-by: Svetozar Mateev Co-authored-by: dilian bilchev Co-authored-by: Svetozar Mateev Co-authored-by: Elijah Stoykov --- assets/css/groups.css | 99 +++++++--- assets/css/vars.css | 66 +++---- changelog.md | 10 + package-lock.json | 18 +- package.json | 4 +- src/GroupElementCreationWrapper.tsx | 178 +++++++++++++++--- src/GroupWrapper.tsx | 5 +- src/defaultComponents/buttons/CloneButton.tsx | 11 ++ .../flatCaptionBar/FlatButtons.tsx | 4 +- .../htmlButtonsBar/buttons.tsx | 40 ++++ .../FrameLoadingAnimation.tsx | 2 +- .../tabs/TabHeaderButtons.tsx | 4 +- src/index.tsx | 6 + src/types/api.ts | 8 + src/types/defaultComponents.ts | 5 + src/types/internal.ts | 58 ++---- src/webGroupsManager.ts | 88 ++------- src/webGroupsStore.ts | 172 ++++++++++++----- 18 files changed, 523 insertions(+), 255 deletions(-) create mode 100644 src/defaultComponents/buttons/CloneButton.tsx create mode 100644 src/defaultComponents/htmlButtonsBar/buttons.tsx diff --git a/assets/css/groups.css b/assets/css/groups.css index 583b565..4b324dc 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -74,14 +74,14 @@ input { white-space: nowrap; text-align: left; user-select: none; - font-size: var(--g42-font-size); + font-size: var(--io-font-size); } .t42-caption-editor { display: inline-block; color: var(--t42-caption-editor-color); margin: var(--t42-caption-editor-margin); - border: var(--spacing-1) solid hsl(var(--g42-interactive-primary)); + border: var(--spacing-1) solid hsl(var(--io-interactive-primary)); border-radius: var(--border-radius-4); outline: none; min-width: 150px; @@ -112,6 +112,22 @@ input { flex-direction: row; } +.t42-html-buttons-container { + display: flex; + position: absolute; + right: var(--spacing-4); + top: var(--spacing-4); + background-color: var(--t42-html-buttons-bar-background); +} + +.t42-html-buttons-container ul:first-of-type { + padding-left: var(--spacing-4); +} + +.t42-html-buttons-bar-element { + background-color: var(--t42-html-buttons-bar-background); +} + .t42-buttons { display: flex; flex-shrink: 0; @@ -139,13 +155,6 @@ input { position: relative; } -.t42-custom-button { - height: var(--t42-custom-button-size); - width: var(--t42-custom-button-size); - background-size: cover; - position: relative; -} - .t42-standard-button::before, .t42-tab-channel-selector-content::before, .t42-frame-channel-selector-content::before, @@ -162,7 +171,6 @@ input { fill: var(--t42-standard-button-color); } - .t42-caption-bar-button-lock, .t42-caption-bar-button-unlock, .t42-caption-bar-button-feedback, @@ -223,6 +231,10 @@ input { content: "\e91c"; } +.t42-standard-button-clone::before { + content: "\e91f"; +} + .t42-standard-button-sticky::before { content: var(--sticky-icon-off); display: block; @@ -231,7 +243,6 @@ input { line-height: var(--spacing-14); } - .t42-caption-bar-button:hover .t42-standard-button-sticky::before { content: var(--sticky-icon-off-hover); } @@ -308,6 +319,7 @@ input { .t42-frame-channel-selector { align-self: center; + border-radius: var(--t42-frame-channel-selector-border-radius); width: var(--t42-frame-channel-selector-size); height: var(--t42-frame-channel-selector-size); margin: var(--t42-frame-channel-selector-margin); @@ -315,8 +327,8 @@ input { } .t42-frame-channel-selector-content { - width: var(--t42-standard-button-size); - height: var(--t42-standard-button-size); + width: var(--t42-frame-channel-selector-size); + height: var(--t42-frame-channel-selector-size); } .t42-frame-channel-selector-content .t42-standard-button-image { @@ -407,6 +419,7 @@ input { .t42-caption-bar-button-maximize, .t42-caption-bar-button-minimize, .t42-caption-bar-button-restore, +.t42-caption-bar-button-clone, .t42-caption-bar-button-close { width: var(--t42-caption-bar-button-width); height: var(--t42-tab-bar-height); @@ -493,7 +506,7 @@ input { .t42-tab-caption { flex-grow: 1; color: var(--t42-tab-bar-tab-text); - -webkit-mask-image: linear-gradient(90deg, Hsl(var(--g42-bg-00)) 75%, transparent); + -webkit-mask-image: linear-gradient(90deg, Hsl(var(--io-bg-00)) 75%, transparent); } .t42-tab-caption-editor { @@ -529,7 +542,7 @@ input { .t42-tab-close-button-content:hover { background-color: var(--t42-tab-bar-tab-close-button-bg-hover); - color: Hsl(var(--g42-label-primary)); + color: Hsl(var(--io-label-primary)); } @@ -568,12 +581,12 @@ input { } .t42-channel-selector-content-light::before { - color: hsl(var(--g42-white)); + color: hsl(var(--io-white)); transition-property: color; } .t42-channel-selector-content-dark::before { - color: hsl(var(--g42-black)); + color: hsl(var(--io-black)); transition-property: color; } @@ -611,13 +624,57 @@ input { -moz-user-focus: ignore; } -.loader.active { - animation: s3 1.5s infinite linear; + +@keyframes clipMe { + + 0%, + 100% { + clip: rect(0, 25vh, 2px, 0); + } + + 25% { + clip: rect(0, 2px, 25vh, 0); + } + + 50% { + clip: rect(calc(25vh - 2px), 25vh, 25vh, 0); + } + + 75% { + clip: rect(0, 25vh, 25vh, calc(25vh - 2px)); + } } .loader-wrapper { - background-color: var(--t42-background); + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; flex-grow: 1; + gap: 1rem; + background: var(--t42-background); + +} + +.loader-wrapper .loader { + width: 2rem; + height: 2rem; + border-radius: 50%; + background: radial-gradient(farthest-side, #999d9e 94%, rgba(0, 0, 0, 0)) center top / 4px 4px no-repeat, conic-gradient(rgba(0, 0, 0, 0) 15%, #999d9e); + -webkit-mask: radial-gradient(farthest-side, rgba(0, 0, 0, 0) calc(100% - 4px), #000 0px); +} + +.loader-wrapper .loader-text { + margin: 0 auto; + padding: 0 0.833rem; + overflow: hidden; + color: var(--io-secondary-primary); + text-align: center; + text-overflow: ellipsis; +} + +.loader.active { + animation: s3 1.5s infinite linear; } @keyframes s3 { @@ -669,4 +726,4 @@ input { flex-grow: 0; width: 0; } -} \ No newline at end of file +} diff --git a/assets/css/vars.css b/assets/css/vars.css index 05c16ef..f89531e 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -2,58 +2,61 @@ :root { - --t42-body-color: hsl(var(--g42-label-secondary)); + --t42-body-color: hsl(var(--io-label-secondary)); --t42-title-margin: 0 0 0 var(--spacing-8); - --t42-title-color: Hsl(var(--g42-label-primary)); + --t42-title-color: Hsl(var(--io-label-primary)); --t42-caption-editor-margin: 0; - --t42-caption-editor-color: Hsl(var(--g42-label-primary)); + --t42-caption-editor-color: Hsl(var(--io-label-primary)); --t42-move-area-min-width: 30px; --t42-standard-button-size: 10px; - --t42-standard-button-color: hsl(var(--g42-label-secondary)); - --t42-standard-button-hover-color: hsl(var(--g42-label-primary)); + --t42-standard-button-color: hsl(var(--io-label-secondary)); + --t42-standard-button-hover-color: hsl(var(--io-label-primary)); --t42-custom-button-size: 20px; - --t42-group-caption-background: Hsl(var(--g42-bg-01)); + --t42-group-caption-background: Hsl(var(--io-bg-01)); --t42-group-caption-height: 30px; --t42-group-caption-separator-size: 0; --t42-frame-border-size: 0; - --t42-frame-border-color: hsl(var(--g42-border-secondary)); - --t42-focused-frame-border-color: hsl(var(--g42-border-primary)); + --t42-frame-border-color: hsl(var(--io-border-secondary)); + --t42-focused-frame-border-color: hsl(var(--io-border-primary)); - --t42-frame-channel-selector-size: 18px; - --t42-frame-channel-selector-margin: 0px 0px 1px 4px; + --t42-frame-channel-selector-border-radius: var(--spacing-4); + --t42-frame-channel-selector-size: 16px; + --t42-frame-channel-selector-margin: 0 0 0 4px; --t42-frame-caption-height: 30px; --t42-frame-caption-separator-size: 0; - --t42-frame-caption-background: Hsl(var(--g42-bg-01)); + --t42-frame-caption-background: Hsl(var(--io-bg-01)); + + --t42-html-buttons-bar-background: Hsl(var(--io-bg-01)); --t42-tab-bar-height: 32px; --t42-tab-bar-button-size: 26px; --t42-tab-bar-separator-size: 0; - --t42-tab-bar-background: Hsl(var(--g42-bg-01)); - --t42-tab-bar-selected-tab-text: hsl(var(--g42-label-primary)); - --t42-tab-bar-selected-tab-hover-text: hsl(var(--g42-label-primary)); - --t42-tab-bar-selected-tab-hover-background: Hsl(var(--g42-bg-02)); + --t42-tab-bar-background: Hsl(var(--io-bg-01)); + --t42-tab-bar-selected-tab-text: hsl(var(--io-label-primary)); + --t42-tab-bar-selected-tab-hover-text: hsl(var(--io-label-primary)); + --t42-tab-bar-selected-tab-hover-background: Hsl(var(--io-bg-02)); --t42-tab-bar-tabs-margin: var(--spacing-4) 0 0 0; --t42-tab-bar-tab-min-width: 40px; --t42-tab-bar-tab-width: 150px; - --t42-tab-bar-tab-text: hsl(var(--g42-label-secondary)); - --t42-tab-bar-tab-text-hover: hsl(var(--g42-label-primary)); + --t42-tab-bar-tab-text: hsl(var(--io-label-secondary)); + --t42-tab-bar-tab-text-hover: hsl(var(--io-label-primary)); --t42-tab-bar-tab-separator-size: 1px; - --t42-tab-bar-tab-separator-color: hsl(var(--g42-border-primary)); - --t42-tab-bar-tab-selected-separator-color: hsl(var(--g42-border-secondary)); + --t42-tab-bar-tab-separator-color: hsl(var(--io-border-primary)); + --t42-tab-bar-tab-selected-separator-color: hsl(var(--io-border-secondary)); --t42-tab-bar-tab-hover-separator-size: 3px; --t42-tab-bar-tab-selected-separator-size: 3px; - --t42-tab-bar-tab-background: Hsl(var(--g42-bg-01)); - --t42-tab-bar-tab-hover-background: Hsl(var(--g42-bg-02)); + --t42-tab-bar-tab-background: Hsl(var(--io-bg-01)); + --t42-tab-bar-tab-hover-background: Hsl(var(--io-bg-02)); --t42-tab-bar-tab-flashing-background: #DE7337b0; --t42-tab-bar-tab-channels-border-radius: var(--border-radius-4); @@ -68,30 +71,29 @@ --t42-tab-bar-tab-close-button-margin: 0 0 0 var(--spacing-12); --t42-tab-bar-tab-close-button-size: 10px; --t42-tab-bar-tab-close-button-padding: 3px; - --t42-tab-bar-tab-close-button-bg-hover: Hsl(var(--g42-bg-03)); + --t42-tab-bar-tab-close-button-bg-hover: Hsl(var(--io-bg-03)); --t42-approaching-edge-animation-duration: 0.5s; --t42-approaching-edge-size: 4px; - --t42-channels-fill-color: hsl(var(--g42-label-primary)); - ; + --t42-channels-fill-color: hsl(var(--io-label-primary)); - --t42-caption-separator-color: hsl(var(--g42-border-secondary)); - --t42-caption-text-hover-color: hsl(var(--g42-label-primary)); + --t42-caption-separator-color: hsl(var(--io-border-secondary)); + --t42-caption-text-hover-color: hsl(var(--io-label-primary)); --t42-caption-bar-button-width: 40px; --t42-caption-bar-button-background: transparent; - --t42-caption-bar-button-hover-background: hsl(var(--g42-bg-02)); + --t42-caption-bar-button-hover-background: hsl(var(--io-bg-02)); --t42-caption-bar-button-close-hover-background: hsl(355 86% 49%); - --t42-caption-bar-button-close-hover-text: hsl(var(--g42-white)); + --t42-caption-bar-button-close-hover-text: hsl(var(--io-white)); --t42-caption-bar-button-correction: 6px; --t42-approaching-edge-start-color: #4B92FB; - --t42-approaching-edge-end-color: hsl(var(--g42-highlight-Interactive)); + --t42-approaching-edge-end-color: hsl(var(--io-highlight-Interactive)); } .dark { --t42-background: #26282A; - --t42-tab-bar-selected-tab-background: hsl(var(--g42-bg-02)); + --t42-tab-bar-selected-tab-background: hsl(var(--io-bg-02)); --sticky-icon-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23afafaf' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,13.9L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,13.9z M6.5,0h-5 C0.7,0,0,0.7,0,1.5v5C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5 C7,6.8,6.8,7,6.5,7z M14.5,8h-5C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); --sticky-icon-off-hover:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 17'%3E%3Cpath fill='%234B92FB' d='M11.3,3.8L9.5,5.6c-0.2,0.2-0.2,0.5,0,0.7s0.5,0.2,0.7,0L12,4.5c0.2-0.2,0.2-0.5,0-0.7 C11.8,3.6,11.5,3.6,11.3,3.8z M5.6,9.5l-1.8,1.8c-0.2,0.2-0.2,0.5,0,0.7c0.2,0.2,0.5,0.2,0.7,0l1.8-1.8c0.2-0.2,0.2-0.5,0-0.7 S5.8,9.3,5.6,9.5z'/%3E%3Cpath fill='%23AFAFAF' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,14 L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,14z M6.5,0h-5C0.7,0,0,0.7,0,1.5v5 C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5C7,6.8,6.8,7,6.5,7z M14.5,8h-5 C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10 h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A");; @@ -101,11 +103,11 @@ .light { --t42-background: #E8E9ED; - --t42-tab-bar-selected-tab-background: hsl(var(--g42-white)); + --t42-tab-bar-selected-tab-background: hsl(var(--io-white)); --sticky-icon-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23626F81' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,13.9L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,13.9z M6.5,0h-5 C0.7,0,0,0.7,0,1.5v5C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5 C7,6.8,6.8,7,6.5,7z M14.5,8h-5C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); --sticky-icon-off-hover:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 17'%3E%3Cpath fill='%231B6ADE' d='M11.3,3.8L9.5,5.6c-0.2,0.2-0.2,0.5,0,0.7s0.5,0.2,0.7,0L12,4.5c0.2-0.2,0.2-0.5,0-0.7 C11.8,3.6,11.5,3.6,11.3,3.8z M5.6,9.5l-1.8,1.8c-0.2,0.2-0.2,0.5,0,0.7c0.2,0.2,0.5,0.2,0.7,0l1.8-1.8c0.2-0.2,0.2-0.5,0-0.7 S5.8,9.3,5.6,9.5z'/%3E%3Cpath fill='%23626F81' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,14 L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,14z M6.5,0h-5C0.7,0,0,0.7,0,1.5v5 C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5C7,6.8,6.8,7,6.5,7z M14.5,8h-5 C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10 h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A");; --sticky-icon-on:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23626F81' d='M6.5,4h-5C0.7,4,0,4.7,0,5.5v5C0,11.3,0.7,12,1.5,12h5C7.3,12,8,11.3,8,10.5v-5C8,4.7,7.3,4,6.5,4z M6.5,11h-5 C1.2,11,1,10.8,1,10.5V6h6v4.5C7,10.8,6.8,11,6.5,11z M14.5,4h-5C8.7,4,8,4.7,8,5.5v5C8,11.3,8.7,12,9.5,12h5c0.8,0,1.5-0.7,1.5-1.5 v-5C16,4.7,15.3,4,14.5,4z M14.5,11h-5C9.2,11,9,10.8,9,10.5V6h6v4.5C15,10.8,14.8,11,14.5,11z'/%3E%3Cpath fill='%23A4B1C3' d='M6.6,0l2.7,0c0.3,0,0.5,0.3,0.3,0.5L8.5,2.1v1.4C8.5,3.8,8.3,4,8,4C7.7,4,7.5,3.8,7.5,3.5V2.1L6.3,0.5 C6.2,0.3,6.3,0,6.6,0z M7.5,13.9v-1.4C7.5,12.2,7.7,12,8,12c0.3,0,0.5,0.2,0.5,0.5v1.4l1.2,1.6c0.2,0.2,0,0.5-0.3,0.5H6.6 c-0.3,0-0.5-0.3-0.3-0.5L7.5,13.9z M8,11c-0.3,0-0.5-0.2-0.5-0.5v-4C7.5,6.2,7.7,6,8,6c0.3,0,0.5,0.2,0.5,0.5v4 C8.5,10.8,8.3,11,8,11z'/%3E%3C/svg%3E"); --sticky-icon-on-hover:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23626F81' d='M6.5,4h-5C0.7,4,0,4.7,0,5.5v5C0,11.3,0.7,12,1.5,12h5C7.3,12,8,11.3,8,10.5v-5C8,4.7,7.3,4,6.5,4z M6.5,11h-5 C1.2,11,1,10.8,1,10.5V6h6v4.5C7,10.8,6.8,11,6.5,11z M14.5,4h-5C8.7,4,8,4.7,8,5.5v5C8,11.3,8.7,12,9.5,12h5c0.8,0,1.5-0.7,1.5-1.5 v-5C16,4.7,15.3,4,14.5,4z M14.5,11h-5C9.2,11,9,10.8,9,10.5V6h6v4.5C15,10.8,14.8,11,14.5,11z'/%3E%3Cpath fill='%234B92FB' d='M6.6,0l2.7,0c0.3,0,0.5,0.3,0.3,0.5L8.3,2.4c-0.1,0.2-0.4,0.2-0.6,0L6.3,0.5C6.2,0.3,6.3,0,6.6,0z M6.6,16h2.7 c0.3,0,0.5-0.3,0.3-0.5l-1.4-1.9c-0.1-0.2-0.4-0.2-0.6,0l-1.4,1.9C6.2,15.7,6.3,16,6.6,16z'/%3E%3Cpath fill='%234B92FB' d='M8.5,13.5v1C8.5,14.8,8.3,15,8,15c-0.3,0-0.5-0.2-0.5-0.5v-1v-1v-11C7.5,1.2,7.7,1,8,1c0.3,0,0.5,0.2,0.5,0.5 v11V13.5C8.5,13.5,8.5,13.5,8.5,13.5z'/%3E%3C/svg%3E"); -} \ No newline at end of file +} diff --git a/changelog.md b/changelog.md index 6512385..ef40d6f 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,13 @@ +2.0.6 +fix: flat channels selector fix +2.0.4 +fix: typo in loading animation class name +2.0.3 +chore: release process issue +2.0.2 +fix: started using the default loading animation component +2.0.1 +feat: customizable html buttons 2.0.0 feat: rebranding 1.4.0 diff --git a/package-lock.json b/package-lock.json index addbbde..897ef96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@interopio/groups-ui-react", - "version": "1.4.0", + "version": "2.0.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@interopio/groups-ui-react", - "version": "1.4.0", + "version": "2.0.4", "license": "MIT", "dependencies": { - "@interopio/theme": "^1.0.4", + "@interopio/theme": "2.0.5", "callback-registry": "^2.7.2", "color2k": "^2.0.0", "use-sync-external-store": "^1.2.0" @@ -2548,9 +2548,9 @@ } }, "node_modules/@interopio/theme": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@interopio/theme/-/theme-1.0.4.tgz", - "integrity": "sha512-8tqY9P6IJALnIHQ5PI8EYs/8Y3zTpNZ+uQbjY4lRbEjmhyUUf8P1D9N1C7zN/KefEvBsKtSv9vqpqcZjALyQhg==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@interopio/theme/-/theme-2.0.5.tgz", + "integrity": "sha512-zgehz+AG0J81fCDszywdKTEURaFETHVx6Gl/m4mQjWlap5MrS3VXzqeo8WivWyTue2G9EqnURvOYwM2aK19vmQ==" }, "node_modules/@interopio/workspaces-api": { "version": "3.0.2", @@ -22091,9 +22091,9 @@ } }, "@interopio/theme": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@interopio/theme/-/theme-1.0.4.tgz", - "integrity": "sha512-8tqY9P6IJALnIHQ5PI8EYs/8Y3zTpNZ+uQbjY4lRbEjmhyUUf8P1D9N1C7zN/KefEvBsKtSv9vqpqcZjALyQhg==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@interopio/theme/-/theme-2.0.5.tgz", + "integrity": "sha512-zgehz+AG0J81fCDszywdKTEURaFETHVx6Gl/m4mQjWlap5MrS3VXzqeo8WivWyTue2G9EqnURvOYwM2aK19vmQ==" }, "@interopio/workspaces-api": { "version": "3.0.2", diff --git a/package.json b/package.json index 12a1b53..10d9809 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.0.0", + "version": "2.0.6", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io", @@ -33,7 +33,7 @@ "access": "public" }, "dependencies": { - "@interopio/theme": "^1.0.4", + "@interopio/theme": "2.0.5", "callback-registry": "^2.7.2", "color2k": "^2.0.0", "use-sync-external-store": "^1.2.0" diff --git a/src/GroupElementCreationWrapper.tsx b/src/GroupElementCreationWrapper.tsx index 0b45aec..273cfcc 100644 --- a/src/GroupElementCreationWrapper.tsx +++ b/src/GroupElementCreationWrapper.tsx @@ -7,10 +7,12 @@ import { Bounds, ElementCreationWrapperState, TargetType } from "./types/interna import { CustomButtonProps } from "./types/defaultComponents"; import webGroupsManager from "./webGroupsManager"; import webGroupsStore from "./webGroupsStore"; +import FrameLoadingAnimation from "./defaultComponents/loadingAnimation/FrameLoadingAnimation"; const GroupElementCreationWrapper: React.FC = ({ components }) => { const state = useSyncExternalStore(webGroupsStore.subscribe, webGroupsStore.getSnapshot); + const LoadingAnimation = components?.frame?.LoadingAnimation ?? FrameLoadingAnimation; const renderGroupCaptionBar = () => { const GroupCaptionBarCustomElement = components?.group?.CaptionBar; @@ -22,28 +24,28 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { const minimize = { onClick: () => { - webGroupsManager.minimizeGroup(options.targetId); + webGroupsManager.onMinimizeButtonClick(TargetType.Group, options.targetId); }, ...options.minimize } const restore = { onClick: () => { - webGroupsManager.restoreGroup(options.targetId); + webGroupsManager.onRestoreButtonClick(TargetType.Group, options.targetId); }, ...options.restore } const maximize = { onClick: () => { - webGroupsManager.maximizeGroup(options.targetId); + webGroupsManager.onMaximizeButtonClick(TargetType.Group, options.targetId); }, ...options.maximize } const close = { onClick: () => { - webGroupsManager.closeGroup(options.targetId); + webGroupsManager.onCloseButtonClick(TargetType.Group, options.targetId); }, ...options.close } @@ -102,63 +104,70 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { const feedback = { onClick: () => { - webGroupsManager.feedbackFrame(options.targetId); + webGroupsManager.onFeedbackButtonClick(TargetType.Frame, options.targetId); }, ...options.feedback }; + const clone = { + onClick: () => { + webGroupsManager.onCloneButtonClick(TargetType.Frame, options.targetId); + }, + ...options.clone + }; + const sticky = { onClick: () => { - webGroupsManager.stickyFrame(options.targetId); + webGroupsManager.onStickyButtonClick(TargetType.Frame, options.targetId); }, ...options.sticky }; const extract = { onClick: () => { - webGroupsManager.extractFrame(options.targetId); + webGroupsManager.onExtractButtonClick(TargetType.Frame, options.targetId); }, ...options.extract }; const lock = { onClick: () => { - webGroupsManager.lockFrame(options.targetId); + webGroupsManager.onLockButtonClick(TargetType.Frame, options.targetId); }, ...options.lock }; const unlock = { onClick: () => { - webGroupsManager.unlockFrame(options.targetId); + webGroupsManager.onUnlockButtonClick(TargetType.Frame, options.targetId); }, ...options.unlock }; const minimize = { onClick: () => { - webGroupsManager.minimizeFrame(options.targetId); + webGroupsManager.onMinimizeButtonClick(TargetType.Frame, options.targetId); }, ...options.minimize } const restore = { onClick: () => { - webGroupsManager.restoreFrame(options.targetId); + webGroupsManager.onRestoreButtonClick(TargetType.Frame, options.targetId); }, ...options.restore } const maximize = { onClick: () => { - webGroupsManager.maximizeFrame(options.targetId); + webGroupsManager.onMaximizeButtonClick(TargetType.Frame, options.targetId); }, ...options.maximize } const close = { onClick: () => { - webGroupsManager.closeFrame(options.targetId); + webGroupsManager.onCloseButtonClick(TargetType.Frame, options.targetId); }, ...options.close } @@ -208,6 +217,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { return = ({ components }) => { } const renderFrameLoadingAnimations = () => { - const LoadingAnimationCustomElement = components?.frame?.LoadingAnimation; + const LoadingAnimationCustomElement = LoadingAnimation; return Object.values(state.frameLoadingAnimations).map((wla) => { if (!LoadingAnimationCustomElement || !wla.parentElement) { return; @@ -402,63 +412,70 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { const feedback = { onClick: () => { - webGroupsManager.feedbackTabBar(options.targetId); + webGroupsManager.onFeedbackButtonClick(TargetType.TabBar, options.targetId); }, ...options.feedback }; + const clone = { + onClick: () => { + webGroupsManager.onCloneButtonClick(TargetType.TabBar, options.targetId); + }, + ...options.clone + }; + const sticky = { onClick: () => { - webGroupsManager.stickyTabBar(options.targetId); + webGroupsManager.onStickyButtonClick(TargetType.TabBar, options.targetId); }, ...options.sticky }; const extract = { onClick: () => { - webGroupsManager.extractTabBar(options.targetId); + webGroupsManager.onExtractButtonClick(TargetType.TabBar, options.targetId); }, ...options.extract }; const lock = { onClick: () => { - webGroupsManager.lockTabBar(options.targetId); + webGroupsManager.onLockButtonClick(TargetType.TabBar, options.targetId); }, ...options.lock } const unlock = { onClick: () => { - webGroupsManager.unlockTabBar(options.targetId); + webGroupsManager.onUnlockButtonClick(TargetType.TabBar, options.targetId); }, ...options.unlock } const minimize = { onClick: () => { - webGroupsManager.minimizeTabBar(options.targetId); + webGroupsManager.onMinimizeButtonClick(TargetType.TabBar, options.targetId); }, ...options.minimize } const restore = { onClick: () => { - webGroupsManager.restoreTabBar(options.targetId); + webGroupsManager.onRestoreButtonClick(TargetType.TabBar, options.targetId); }, ...options.restore } const maximize = { onClick: () => { - webGroupsManager.maximizeTabBar(options.targetId); + webGroupsManager.onMaximizeButtonClick(TargetType.TabBar, options.targetId); }, ...options.maximize } const close = { onClick: () => { - webGroupsManager.closeTabBar(options.targetId); + webGroupsManager.onCloseButtonClick(TargetType.TabBar, options.targetId); }, ...options.close } @@ -478,6 +495,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { return = ({ components }) => { }); } + const renderHtmlButtons = () => { + const HtmlButtonsCustomElement = components?.html?.Buttons; + + return Object.values(state.htmlButtons).map((te) => { + if (!HtmlButtonsCustomElement || !te.parentElement) { + return; + } + const { parentElement, ...options } = te; + + const feedback = { + onClick: () => { + webGroupsManager.onFeedbackButtonClick(TargetType.HtmlButtons, options.targetId); + }, + ...options.feedback + }; + + const clone = { + onClick: () => { + webGroupsManager.onCloneButtonClick(TargetType.HtmlButtons, options.targetId); + }, + ...options.clone + }; + + const sticky = { + onClick: () => { + webGroupsManager.onStickyButtonClick(TargetType.HtmlButtons, options.targetId); + }, + ...options.sticky + }; + + const extract = { + onClick: () => { + webGroupsManager.onExtractButtonClick(TargetType.HtmlButtons, options.targetId); + }, + ...options.extract + }; + + const lock = { + onClick: () => { + webGroupsManager.onLockButtonClick(TargetType.HtmlButtons, options.targetId); + }, + ...options.lock + } + + const unlock = { + onClick: () => { + webGroupsManager.onUnlockButtonClick(TargetType.HtmlButtons, options.targetId); + }, + ...options.unlock + } + + const minimize = { + onClick: () => { + webGroupsManager.onMinimizeButtonClick(TargetType.HtmlButtons, options.targetId); + }, + ...options.minimize + } + + const restore = { + onClick: () => { + webGroupsManager.onRestoreButtonClick(TargetType.HtmlButtons, options.targetId); + }, + ...options.restore + } + + const maximize = { + onClick: () => { + webGroupsManager.onMaximizeButtonClick(TargetType.HtmlButtons, options.targetId); + }, + ...options.maximize + } + + const close = { + onClick: () => { + webGroupsManager.onCloseButtonClick(TargetType.HtmlButtons, options.targetId); + }, + ...options.close + } + + let customButtonsProps = new Array(); + if (options.customButtons) { + customButtonsProps = options.customButtons.map((cButton) => { + return { + onClick: () => { + webGroupsManager.clickCustomButton(options.targetId, cButton.buttonId); + }, + visible: true, + imageData: cButton.imageData, + tooltip: cButton.tooltip, + buttonId: cButton.buttonId}}); + } + + return + }); + } + return <> {renderGroupCaptionBar()} {renderGroupOverlay()} @@ -520,6 +647,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { {renderAfterTabsZones()} {renderTabHeaderButtons()} {renderBelowTabs()} + {renderHtmlButtons()} = ({ components }) => { onCreateFrameWindowOverlayRequested={components?.frame?.Overlay ? webGroupsStore.onCreateFrameWindowOverlayRequested : undefined} onCreateAboveWindowRequested={components?.frame?.AboveWindow ? webGroupsStore.onCreateAboveWindowRequested : undefined} onCreateWindowContentOverlayRequested={components?.frame?.WindowContentOverlay ? webGroupsStore.onCreateWindowContentOverlayRequested : undefined} - onCreateFrameLoadingAnimationRequested={components?.frame?.LoadingAnimation ? webGroupsStore.onCreateFrameLoadingAnimationRequested : undefined} + onCreateFrameLoadingAnimationRequested={LoadingAnimation ? webGroupsStore.onCreateFrameLoadingAnimationRequested : undefined} onCreateBelowWindowRequested={components?.frame?.BelowWindow ? webGroupsStore.onCreateBelowWindowRequested : undefined} onCreateAboveTabsRequested={components?.tabs?.Above ? webGroupsStore.onCreateAboveTabsComponentRequested : undefined} onCreateBeforeTabsComponentRequested={components?.tabs?.Before ? webGroupsStore.onCreateBeforeTabsComponentRequested : undefined} @@ -535,6 +663,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { onCreateAfterTabsComponentRequested={components?.tabs?.After ? webGroupsStore.onCreateAfterTabsComponentRequested : undefined} onCreateTabHeaderButtonsRequested={components?.tabs?.Buttons ? webGroupsStore.onCreateTabHeaderButtonsRequested : undefined} onCreateBelowTabsRequested={components?.tabs?.Below ? webGroupsStore.onCreateBelowTabsComponentRequested : undefined} + onCreateHtmlButtonsRequested={components?.html?.Buttons ? webGroupsStore.onCreateHtmlButtonsRequested : undefined} onUpdateGroupCaptionBarRequested={components?.group?.CaptionBar ? webGroupsStore.onUpdateGroupCaptionBarRequested : undefined} onUpdateFrameWindowOverlayRequested={components?.group?.Overlay ? webGroupsStore.onUpdateFrameWindowOverlayRequested : undefined} onUpdateFrameCaptionBarRequested={components?.flat?.CaptionBar ? webGroupsStore.onUpdateFrameCaptionBarRequested : undefined} @@ -558,6 +687,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { onRemoveAfterTabsComponentRequested={webGroupsStore.onRemoveAfterTabsComponentRequested} onRemoveTabHeaderButtonsRequested={webGroupsStore.onRemoveTabHeaderButtonsRequested} onRemoveBelowTabsRequested={webGroupsStore.onRemoveBelowTabsRequested} + onRemoveHtmlButtonsRequested={webGroupsStore.onRemoveHtmlButtonsRequested} onShowCaptionEditorRequested={webGroupsStore.onShowCaptionEditorRequested} onCommitCaptionEditingRequested={webGroupsStore.onCommitCaptionEditingRequested} onHideCaptionEditorRequested={webGroupsStore.onHideCaptionEditorRequested} diff --git a/src/GroupWrapper.tsx b/src/GroupWrapper.tsx index b1e3537..0acfc37 100644 --- a/src/GroupWrapper.tsx +++ b/src/GroupWrapper.tsx @@ -37,7 +37,10 @@ class GroupWrapper extends React.Component { createTabBarButtonsContainerElement: this.props.onCreateTabHeaderButtonsRequested, createBelowTabs: this.props.onCreateBelowTabsRequested, updateBelowTabs: this.props.onUpdateBelowTabsRequested, - + + createHtmlButtonsContainerElement: this.props.onCreateHtmlButtonsRequested, + destroyHtmlButtonsContainerElement: this.props.onRemoveHtmlButtonsRequested, + updateFrame: this.props.onUpdateFrameRequested, updateStandardButton: this.props.onUpdateStandardButtonRequested, updateCustomButtons: this.props.onUpdateCustomButtonsRequested, diff --git a/src/defaultComponents/buttons/CloneButton.tsx b/src/defaultComponents/buttons/CloneButton.tsx new file mode 100644 index 0000000..a07eba7 --- /dev/null +++ b/src/defaultComponents/buttons/CloneButton.tsx @@ -0,0 +1,11 @@ +import React from "react"; +import { CloneButtonProps } from "../../types/defaultComponents"; +import BaseButton from "./BaseButton"; + +const CloneButton: React.FC = ({ onClick, tooltip }) => { + return +} + +export default CloneButton; \ No newline at end of file diff --git a/src/defaultComponents/flatCaptionBar/FlatButtons.tsx b/src/defaultComponents/flatCaptionBar/FlatButtons.tsx index f5c0bb5..e2aa385 100644 --- a/src/defaultComponents/flatCaptionBar/FlatButtons.tsx +++ b/src/defaultComponents/flatCaptionBar/FlatButtons.tsx @@ -3,6 +3,7 @@ import { FlatButtonsProps } from "../../types/defaultComponents"; import CloseButton from "../buttons/CloseButton"; import ExtractButton from "../buttons/ExtractButton"; import FeedbackButton from "../buttons/FeedbackButton"; +import CloneButton from "../buttons/CloneButton"; import StickyButton from "../buttons/StickyButton"; import LockButton from "../buttons/LockButtons"; import MaximizeButton from "../buttons/MaximizeButton"; @@ -11,7 +12,7 @@ import RestoreButton from "../buttons/RestoreButton"; import UnlockButton from "../buttons/UnlockButton"; import CustomButton from "../buttons/CustomButton"; -const FlatButtons: React.FC = ({ extract, minimize, maximize, restore, close, lock, unlock, feedback, sticky, customButtons }) => { +const FlatButtons: React.FC = ({ extract, minimize, maximize, restore, close, lock, unlock, feedback, clone, sticky, customButtons }) => { return
    { @@ -22,6 +23,7 @@ const FlatButtons: React.FC = ({ extract, minimize, maximize,
    {feedback?.visible && } + {clone?.visible && } {sticky?.visible && } {extract?.visible && } {lock?.visible && } diff --git a/src/defaultComponents/htmlButtonsBar/buttons.tsx b/src/defaultComponents/htmlButtonsBar/buttons.tsx new file mode 100644 index 0000000..da11e1a --- /dev/null +++ b/src/defaultComponents/htmlButtonsBar/buttons.tsx @@ -0,0 +1,40 @@ +import React from "react"; +import { HtmlButtonsProps } from "../../types/api"; +import CloseButton from "../buttons/CloseButton"; +import ExtractButton from "../buttons/ExtractButton"; +import FeedbackButton from "../buttons/FeedbackButton"; +import CloneButton from "../buttons/CloneButton"; +import LockButton from "../buttons/LockButtons"; +import MaximizeButton from "../buttons/MaximizeButton"; +import MinimizeButton from "../buttons/MinimizeButton"; +import RestoreButton from "../buttons/RestoreButton"; +import StickyButton from "../buttons/StickyButton"; +import UnlockButton from "../buttons/UnlockButton"; +import CustomButton from "../buttons/CustomButton"; + +const HtmlButtons: React.FC = ({ extract, minimize, maximize, restore, close, lock, unlock, feedback, clone, sticky, customButtons }) => { + return
    +
      + { + customButtons.map(customButton => { + return customButton.visible && + }) + } +
    +
      + {feedback?.visible && } + {clone?.visible && } + {sticky?.visible && } + {extract?.visible && } + {lock?.visible && } + {unlock?.visible && } + {minimize?.visible && } + {restore?.visible && } + {maximize?.visible && } + {close?.visible && } +
    +
    +}; + + +export default HtmlButtons; \ No newline at end of file diff --git a/src/defaultComponents/loadingAnimation/FrameLoadingAnimation.tsx b/src/defaultComponents/loadingAnimation/FrameLoadingAnimation.tsx index a367286..9dd3344 100644 --- a/src/defaultComponents/loadingAnimation/FrameLoadingAnimation.tsx +++ b/src/defaultComponents/loadingAnimation/FrameLoadingAnimation.tsx @@ -5,7 +5,7 @@ const FrameLoadingAnimation: React.FC = ({show}) => return ( show ? ( -
    +
    Loading...
    diff --git a/src/defaultComponents/tabs/TabHeaderButtons.tsx b/src/defaultComponents/tabs/TabHeaderButtons.tsx index 99fa4ac..9134c6c 100644 --- a/src/defaultComponents/tabs/TabHeaderButtons.tsx +++ b/src/defaultComponents/tabs/TabHeaderButtons.tsx @@ -3,6 +3,7 @@ import { TabHeaderButtonsProps } from "../../types/api"; import CloseButton from "../buttons/CloseButton"; import ExtractButton from "../buttons/ExtractButton"; import FeedbackButton from "../buttons/FeedbackButton"; +import CloneButton from "../buttons/CloneButton"; import LockButton from "../buttons/LockButtons"; import MaximizeButton from "../buttons/MaximizeButton"; import MinimizeButton from "../buttons/MinimizeButton"; @@ -11,7 +12,7 @@ import StickyButton from "../buttons/StickyButton"; import UnlockButton from "../buttons/UnlockButton"; import CustomButton from "../buttons/CustomButton"; -const TabHeaderButtons: React.FC = ({ extract, minimize, maximize, restore, close, lock, unlock, feedback, sticky, customButtons }) => { +const TabHeaderButtons: React.FC = ({ extract, minimize, maximize, restore, close, lock, unlock, feedback, clone, sticky, customButtons }) => { return
      { @@ -22,6 +23,7 @@ const TabHeaderButtons: React.FC = ({ extract, minimize,
      {feedback?.visible && } + {clone?.visible && } {sticky?.visible && } {extract?.visible && } {lock?.visible && } diff --git a/src/index.tsx b/src/index.tsx index 33da5de..81298ba 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -22,6 +22,7 @@ import LockButton from "./defaultComponents/buttons/LockButtons"; import UnlockButton from "./defaultComponents/buttons/UnlockButton"; import ExtractButton from "./defaultComponents/buttons/ExtractButton"; import FeedbackButton from "./defaultComponents/buttons/FeedbackButton"; +import CloneButton from "./defaultComponents/buttons/CloneButton"; import StickyButton from "./defaultComponents/buttons/StickyButton"; import useIOConnectWindow from "./useIOConnectWindow"; import CustomButton from "./defaultComponents/buttons/CustomButton"; @@ -66,6 +67,7 @@ import { GroupComponentVisibilityState, GroupOverlayProps, GroupProps, + HtmlButtonsProps, MoveAreaProps, TabElementProps, TabHeaderButtonsProps, @@ -81,6 +83,7 @@ import useCommitFlatCaptionEditingRequested from "./defaultComponents/flatCaptio import useEditableCaption from "./defaultComponents/captionEditor/useEditableCaption"; import useCaptionEditor from "./defaultComponents/captionEditor/useCaptionEditor"; import FrameLoadingAnimation from "./defaultComponents/loadingAnimation/FrameLoadingAnimation"; +import HtmlButtons from "./defaultComponents/htmlButtonsBar/buttons"; @@ -95,6 +98,7 @@ export { TabCloseButton, TabCaptionEditor, FeedbackButton, + CloneButton, StickyButton, ExtractButton, LockButton, @@ -112,6 +116,7 @@ export { FlatCaptionEditor, TabHeaderButtons, FrameLoadingAnimation, + HtmlButtons, GroupComponentVisibilityState, useIOConnectWindow, useGroupComponentVisibility, @@ -147,6 +152,7 @@ export { TabCloseButtonProps, TabHeaderButtonsProps, TabCaptionEditorProps, + HtmlButtonsProps, FlatCaptionBarProps, FlatCaptionProps, FrameWindowOverlayProps, diff --git a/src/types/api.ts b/src/types/api.ts index ecc565d..76af0c2 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -83,6 +83,7 @@ export interface FlatCaptionBarProps { moveAreaId: string; caption: string; feedback?: ButtonProps; + clone?: ButtonProps; sticky?: ToggleButtonProps; extract?: ButtonProps; lock?: ButtonProps; @@ -117,6 +118,7 @@ export interface AfterTabsProps { export interface TabHeaderButtonsProps { feedback?: ButtonProps; + clone?: ButtonProps; sticky?: ToggleButtonProps; extract?: ButtonProps; lock?: ButtonProps; @@ -130,6 +132,9 @@ export interface TabHeaderButtonsProps { selectedWindow: string; } +export interface HtmlButtonsProps extends TabHeaderButtonsProps { +} + export interface GroupProps { components?: { group?: { @@ -153,6 +158,9 @@ export interface GroupProps { After?: React.ComponentType; Buttons?: React.ComponentType; Below?: React.ComponentType; + }; + html?: { + Buttons?: React.ComponentType; } } } diff --git a/src/types/defaultComponents.ts b/src/types/defaultComponents.ts index e1df10e..96f5df4 100644 --- a/src/types/defaultComponents.ts +++ b/src/types/defaultComponents.ts @@ -26,6 +26,10 @@ export interface StickyButtonProps extends ToggleButtonProps { export interface FeedbackButtonProps extends ButtonProps { } +export interface CloneButtonProps extends ButtonProps { +} + + export interface ExtractButtonProps extends ButtonProps { } @@ -93,6 +97,7 @@ export interface FlatMoveAreaProps { export interface FlatButtonsProps { feedback?: ButtonProps; + clone?: ButtonProps; sticky?: ToggleButtonProps; extract?: ButtonProps; lock?: ButtonProps; diff --git a/src/types/internal.ts b/src/types/internal.ts index f24d94a..0566134 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -44,7 +44,7 @@ export interface GroupWrapperProps { onCreateAfterTabsComponentRequested?: (options: CreateFrameElementRequestOptions) => void; onUpdateAfterTabsComponentRequested?: (options: CreateFrameElementRequestOptions) => void; - onCreateTabHeaderButtonsRequested?: (options: CreateTabHeaderButtonsOptions) => void; + onCreateTabHeaderButtonsRequested?: (options: CreateButtonsOptions) => void; onCreateBelowTabsRequested?: (options: CreateFrameElementRequestOptions) => void; onUpdateBelowTabsRequested?: (options: CreateFrameElementRequestOptions) => void; @@ -53,6 +53,9 @@ export interface GroupWrapperProps { onUpdateStandardButtonRequested?: (options: UpdateStandardButtonRequestOptions) => void; onUpdateCustomButtonsRequested?: (options: UpdateCustomButtonsRequestOptions) => void; + onCreateHtmlButtonsRequested?: (options: CreateButtonsOptions) => void; + onRemoveHtmlButtonsRequested?: (options: RemoveRequestOptions) => void; + onRemoveFrameCaptionBarRequested?: (options: RemoveRequestOptions) => void; onRemoveFrameWindowOverlayRequested?: (options: RemoveRequestOptions) => void; onRemoveAboveWindowRequested?: (options: RemoveRequestOptions) => void; @@ -112,54 +115,16 @@ export interface UpdateFrameCaptionBarRequestOptions extends BaseElementOptions } -export interface CreateFrameCaptionBarRequestOptions extends CreateFrameElementRequestOptions { +export interface CreateFrameCaptionBarRequestOptions extends CreateButtonsOptions { caption: string; moveAreaId: string; channelSelectorVisible: boolean; selectedChannel: string; selectedChannelColor: string; - feedback: { - tooltip: string; - visible: boolean; - }; - sticky: { - tooltip: string; - visible: boolean; - isPressed: boolean; - }; - extract: { - tooltip: string; - visible: boolean; - }; - lock: { - tooltip: string; - visible: boolean; - }; - unlock: { - tooltip: string; - visible: boolean; - }; - minimize: { - tooltip: string; - visible: boolean; - }; - restore: { - tooltip: string; - visible: boolean; - }; - maximize: { - tooltip: string; - visible: boolean; - }; - close: { - tooltip: string; - visible: boolean; - }; captionEditor: { show: boolean; text?: string; }; - customButtons: UpdateCustomButtonOptions[] } export interface CreateTabRequestOptions extends CreateElementRequestOptions { @@ -192,11 +157,15 @@ export interface UpdateCustomButtonOptions { imageData: string; } -export interface CreateTabHeaderButtonsOptions extends CreateFrameElementRequestOptions { +export interface CreateButtonsOptions extends CreateFrameElementRequestOptions { feedback: { tooltip: string; visible: boolean; }; + clone: { + tooltip: string; + visible: boolean; + }; sticky: { tooltip: string; visible: boolean; @@ -261,11 +230,13 @@ export enum TargetType { Group = "group", Frame = "frame", TabBar = "tabBar", - Tab = "tab" + Tab = "tab", + HtmlButtons = "html" } export enum StandardButtons { Feedback = "feedback", + Clone = "clone", Sticky = "sticky", Extract = "extract", Lock = "lock", @@ -289,8 +260,9 @@ export interface ElementCreationWrapperState { beforeTabsZones: { [targetId: string]: CreateFrameElementRequestOptions }; tabElements: { [targetId: string]: CreateTabRequestOptions }; afterTabsZones: { [targetId: string]: CreateFrameElementRequestOptions }; - tabHeaderButtons: { [targetId: string]: CreateTabHeaderButtonsOptions }; + tabHeaderButtons: { [targetId: string]: CreateButtonsOptions }; belowTabsZones: { [targetId: string]: CreateFrameElementRequestOptions }; + htmlButtons: { [targetId: string]: CreateButtonsOptions }; } export interface ExternalLibraryFactory { diff --git a/src/webGroupsManager.ts b/src/webGroupsManager.ts index 44f750b..020324b 100644 --- a/src/webGroupsManager.ts +++ b/src/webGroupsManager.ts @@ -55,92 +55,44 @@ class WebGroupsManagerDecorator { return window.webGroupsManager.externalLibraryFactory.focusGroup(); } - public closeFrame(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Frame, targetId, StandardButtons.Close); + public onCloseButtonClick(targetType: TargetType, targetId: string): void { + window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Close); } - public restoreFrame(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Frame, targetId, StandardButtons.Restore); + public onRestoreButtonClick(targetType: TargetType, targetId: string): void { + window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Restore); } - public maximizeFrame(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Frame, targetId, StandardButtons.Maximize); + public onMaximizeButtonClick(targetType: TargetType, targetId: string): void { + window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Maximize); } - public minimizeFrame(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Frame, targetId, StandardButtons.Minimize); + public onMinimizeButtonClick(targetType: TargetType, targetId: string): void { + window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Minimize); } - public lockFrame(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Frame, targetId, StandardButtons.Lock); + public onLockButtonClick(targetType: TargetType, targetId: string): void { + window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Lock); } - public unlockFrame(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Frame, targetId, StandardButtons.Unlock); + public onUnlockButtonClick(targetType: TargetType, targetId: string): void { + window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Unlock); } - public feedbackFrame(targetId: string):void{ - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Frame, targetId, StandardButtons.Feedback); + public onFeedbackButtonClick(targetType: TargetType, targetId: string):void{ + window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Feedback); } - public stickyFrame(targetId: string):void{ - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Frame, targetId, StandardButtons.Sticky); + public onCloneButtonClick(targetType: TargetType, targetId: string):void{ + window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Clone); } - public extractFrame(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Frame, targetId, StandardButtons.Extract); + public onStickyButtonClick(targetType: TargetType, targetId: string):void{ + window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Sticky); } - public closeTabBar(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.TabBar, targetId, StandardButtons.Close); - } - - public restoreTabBar(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.TabBar, targetId, StandardButtons.Restore); - } - - public maximizeTabBar(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.TabBar, targetId, StandardButtons.Maximize); - } - - public minimizeTabBar(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.TabBar, targetId, StandardButtons.Minimize); - } - - public lockTabBar(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.TabBar, targetId, StandardButtons.Lock); - } - - public unlockTabBar(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.TabBar, targetId, StandardButtons.Unlock); - } - - public feedbackTabBar(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.TabBar, targetId, StandardButtons.Feedback); - } - - public stickyTabBar(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.TabBar, targetId, StandardButtons.Sticky); - } - - public extractTabBar(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.TabBar, targetId, StandardButtons.Extract); - } - - public closeGroup(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Group, targetId, StandardButtons.Close); - } - - public restoreGroup(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Group, targetId, StandardButtons.Restore); - } - - public maximizeGroup(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Group, targetId, StandardButtons.Maximize); - } - - public minimizeGroup(targetId: string): void { - window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(TargetType.Group, targetId, StandardButtons.Minimize); + public onExtractButtonClick(targetType: TargetType, targetId: string): void { + window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Extract); } public closeTab(targetId: string): void { diff --git a/src/webGroupsStore.ts b/src/webGroupsStore.ts index afc8376..1861a13 100644 --- a/src/webGroupsStore.ts +++ b/src/webGroupsStore.ts @@ -3,7 +3,7 @@ import { CreateFrameCaptionBarRequestOptions, CreateFrameElementRequestOptions, CreateGroupCaptionBarRequestOptions, - CreateTabHeaderButtonsOptions, + CreateButtonsOptions, CreateTabRequestOptions, ElementCreationWrapperState, RemoveRequestOptions, @@ -35,6 +35,7 @@ class WebGroupsStore { tabHeaderButtons: {}, // dict frameId to crate tab header buttons options belowTabsZones: {}, // dict frameId to create options frameLoadingAnimations: {}, // dict frameId to create options + htmlButtons: {}, // dict frameId to crate html buttons options } public subscribe = (cb: () => void) => { @@ -229,7 +230,7 @@ class WebGroupsStore { }); } - public onCreateTabHeaderButtonsRequested = (options: CreateTabHeaderButtonsOptions) => { + public onCreateTabHeaderButtonsRequested = (options: CreateButtonsOptions) => { if (options === this.state.tabHeaderButtons[options.targetId] || !options) { return; } @@ -259,6 +260,36 @@ class WebGroupsStore { }); } + public onCreateHtmlButtonsRequested = (options: CreateButtonsOptions) => { + if (options === this.state.htmlButtons[options.targetId] || !options) { + return; + } + this.setState(s => { + return { + ...s, + htmlButtons: { + ...s.htmlButtons, + [options.targetId]: options + } + } + }); + } + + public onUpdateHtmlButtonsRequested = (options: CreateButtonsOptions) => { + if (options === this.state.htmlButtons[options.targetId] || !options) { + return; + } + this.setState(s => { + return { + ...s, + htmlButtons: { + ...s.htmlButtons, + [options.targetId]: { ...s.htmlButtons[options.targetId], ...options } + } + } + }); + } + public onUpdateGroupCaptionBarRequested = (options: UpdateGroupCaptionBarRequestOptions) => { if (options === this.state.groupCaptionBar) { return; @@ -362,7 +393,7 @@ class WebGroupsStore { }); } - public onUpdateTabHeaderButtonsRequested = (options: CreateTabHeaderButtonsOptions) => { + public onUpdateTabHeaderButtonsRequested = (options: CreateButtonsOptions) => { if (options === this.state.tabHeaderButtons[options.targetId] || !options) { return; } @@ -426,59 +457,77 @@ class WebGroupsStore { } public onUpdateStandardButton = (options: UpdateStandardButtonRequestOptions) => { - const isCaptionBar = options.targetType === TargetType.Group; //this.state.groupCaptionBar?.targetId === options.targetId; - const isFrame = options.targetType === TargetType.Frame; - const isTabHeaderButtons = options.targetType === TargetType.TabBar; - - if (isCaptionBar) { - const currentState = this.state.groupCaptionBar || { targetId: options.targetId } as CreateGroupCaptionBarRequestOptions; - const newOptions = { - ...currentState, - [options.buttonId]: { - ...options - } - }; - this.onUpdateGroupCaptionBarRequested(newOptions as UpdateGroupCaptionBarRequestOptions); - } else if (isFrame && options.targetType === TargetType.Frame) { - const currentState = this.state.frameCaptionBars[options.targetId] || { targetId: options.targetId } as CreateTabHeaderButtonsOptions; - const newOptions = { - ...currentState, - [options.buttonId]: { - ...options - } - }; - this.onUpdateFrameCaptionBarRequested(newOptions); - } else if (isTabHeaderButtons && options.targetType === TargetType.TabBar) { - const currentState = this.state.tabHeaderButtons[options.targetId] || { targetId: options.targetId } as CreateTabHeaderButtonsOptions; - const newOptions = { - ...currentState, - [options.buttonId]: { - ...options - } - }; - - this.onUpdateTabHeaderButtonsRequested(newOptions); + const targetState = { targetId: options.targetId }; + switch(options.targetType) { + case TargetType.Group: + const currentGroupState = this.state.groupCaptionBar || targetState as CreateGroupCaptionBarRequestOptions; + const newGroupOptions = { + ...currentGroupState, + [options.buttonId]: { + ...options + } + }; + this.onUpdateGroupCaptionBarRequested(newGroupOptions); + break; + case TargetType.Frame: + const currentFrameState = this.state.frameCaptionBars[options.targetId] || targetState as CreateFrameCaptionBarRequestOptions; + const newFrameOptions = { + ...currentFrameState, + [options.buttonId]: { + ...options + } + }; + this.onUpdateFrameCaptionBarRequested(newFrameOptions); + break; + case TargetType.TabBar: + const currentTabButtonsState = this.state.tabHeaderButtons[options.targetId] || targetState as CreateButtonsOptions; + const newTabButtonsOptions = { + ...currentTabButtonsState, + [options.buttonId]: { + ...options + } + }; + this.onUpdateTabHeaderButtonsRequested(newTabButtonsOptions); + break; + case TargetType.HtmlButtons: + const currentHtmlButtonsState = this.state.htmlButtons[options.targetId] || targetState as CreateButtonsOptions; + const newHtmlButtonsOptions = { + ...currentHtmlButtonsState, + [options.buttonId]: { + ...options + } + }; + this.onUpdateHtmlButtonsRequested(newHtmlButtonsOptions); + break; } } public onUpdateCustomButtons = (options: UpdateCustomButtonsRequestOptions) => { - const isFrame = options.targetType === TargetType.Frame; - const isTabHeaderButtons = options.targetType === TargetType.TabBar; - - if (isFrame && options.targetType === TargetType.Frame) { - const currentState = this.state.frameCaptionBars[options.targetId] || { targetId: options.targetId } as CreateTabHeaderButtonsOptions; - const newOptions = { - ...currentState, - ...options - }; - this.onUpdateFrameCaptionBarRequested(newOptions); - } else if (isTabHeaderButtons && options.targetType === TargetType.TabBar) { - const currentState = this.state.tabHeaderButtons.customButtons || { customButtons: options.customButtons } as CreateTabHeaderButtonsOptions; - const newOptions = { - ...currentState, - ...options - }; - this.onUpdateTabHeaderButtonsRequested(newOptions); + switch(options.targetType) { + case TargetType.Frame: + const currentFrameState = this.state.frameCaptionBars[options.targetId] || { targetId: options.targetId } as CreateButtonsOptions; + const newFrameOptions = { + ...currentFrameState, + ...options + }; + this.onUpdateFrameCaptionBarRequested(newFrameOptions); + break; + case TargetType.TabBar: + const currentTabBarState = this.state.tabHeaderButtons.customButtons || { customButtons: options.customButtons } as CreateButtonsOptions; + const newTabBarOptions = { + ...currentTabBarState, + ...options + }; + this.onUpdateTabHeaderButtonsRequested(newTabBarOptions); + break; + case TargetType.HtmlButtons: + const currentHtmlButtonsState = this.state.htmlButtons.customButtons || { customButtons: options.customButtons } as CreateButtonsOptions; + const newHtmlButtonsOptions = { + ...currentHtmlButtonsState, + ...options + }; + this.onUpdateHtmlButtonsRequested(newHtmlButtonsOptions); + break; } } @@ -709,6 +758,25 @@ class WebGroupsStore { }); } + public onRemoveHtmlButtonsRequested = (options: RemoveRequestOptions) => { + if (!this.state.htmlButtons[options.targetId]) { + return; + } + this.setState(s => { + const newHtmlObj = Object.keys(s.htmlButtons).reduce((acc, targetId) => { + if (targetId != options.targetId) { + acc[targetId] = s.htmlButtons[targetId]; + } + return acc; + }, {}); + + return { + ...s, + htmlButtons: newHtmlObj + } + }); + } + public onShowCaptionEditorRequested = (targetType: TargetType, targetId: string, text: string) => { if (targetType === TargetType.Group) { this.onShowGroupCaptionEditorRequested(targetId, text); From 1132fc3ec759fe57106c8e0e9ac773f4203b362a Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Mon, 26 Feb 2024 13:55:59 +0200 Subject: [PATCH 04/42] Released 2.1.0 Signed-off-by: Svetozar Mateev --- changelog.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index ef40d6f..3f68265 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,5 @@ +2.1.0 +chore: official 9.2 support 2.0.6 fix: flat channels selector fix 2.0.4 diff --git a/package.json b/package.json index 10d9809..091f86d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.0.6", + "version": "2.1.0", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io", From d5b391a728af1479303a781b707a85308856a7d0 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Tue, 26 Mar 2024 09:59:59 +0200 Subject: [PATCH 05/42] G4E-7684 Updated the readme.md (#32) Signed-off-by: Svetozar Mateev Co-authored-by: Svetozar Mateev --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c91f5e2..fbc2e03 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ The following example demonstrates a basic usage of the `` component: ```javascript import React from 'react' import Group from "@interopio/groups-ui-react"; -import "@interopio/groups-ui-react/dist/styles/styles.css"; +import "@interopio/groups-ui-react/dist/styles/groups.css"; const App = () => { return From 423f73513bdb81a2fa1d251ecc23d885dc485a17 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Tue, 28 May 2024 12:41:42 +0300 Subject: [PATCH 06/42] G4 e 7427 make area above tabs draggable (#33) (#34) * G4E-7427 Updated the css * G4E-7427 Updated the css --------- Signed-off-by: Svetozar Mateev Co-authored-by: Svetozar Mateev --- assets/css/groups.css | 7 ++++--- assets/css/vars.css | 26 +++++++++++--------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index 4b324dc..15f6090 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -434,8 +434,9 @@ input { list-style-type: none; position: relative; padding: 0px; - margin: var(--t42-tab-bar-tabs-margin); + margin: 0px; border-top-right-radius: var(--border-radius-4); + -webkit-app-region: drag; } .t42-react-tab { @@ -453,6 +454,7 @@ input { position: relative; padding: 0px var(--spacing-8); margin-right: var(--spacing-2); + margin-top: var(--spacing-4); width: 150px; min-width: var(--t42-tab-bar-tab-min-width); max-width: var(--t42-tab-bar-tab-width); @@ -460,9 +462,8 @@ input { border-top-right-radius: var(--spacing-4); border-top-left-radius: var(--spacing-4); transition-property: padding; - container-type: size; - + -webkit-app-region: no-drag; } .t42-tab::before { diff --git a/assets/css/vars.css b/assets/css/vars.css index f89531e..cf73d73 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -1,7 +1,6 @@ @import "@interopio/theme/dist/io.platform.css"; :root { - --t42-body-color: hsl(var(--io-label-secondary)); --t42-title-margin: 0 0 0 var(--spacing-8); @@ -27,7 +26,7 @@ --t42-focused-frame-border-color: hsl(var(--io-border-primary)); --t42-frame-channel-selector-border-radius: var(--spacing-4); - --t42-frame-channel-selector-size: 16px; + --t42-frame-channel-selector-size: var(--spacing-16); --t42-frame-channel-selector-margin: 0 0 0 4px; --t42-frame-caption-height: 30px; --t42-frame-caption-separator-size: 0; @@ -43,8 +42,6 @@ --t42-tab-bar-selected-tab-hover-text: hsl(var(--io-label-primary)); --t42-tab-bar-selected-tab-hover-background: Hsl(var(--io-bg-02)); - --t42-tab-bar-tabs-margin: var(--spacing-4) 0 0 0; - --t42-tab-bar-tab-min-width: 40px; --t42-tab-bar-tab-width: 150px; --t42-tab-bar-tab-text: hsl(var(--io-label-secondary)); @@ -57,7 +54,7 @@ --t42-tab-bar-tab-background: Hsl(var(--io-bg-01)); --t42-tab-bar-tab-hover-background: Hsl(var(--io-bg-02)); - --t42-tab-bar-tab-flashing-background: #DE7337b0; + --t42-tab-bar-tab-flashing-background: #de7337b0; --t42-tab-bar-tab-channels-border-radius: var(--border-radius-4); --t42-tab-bar-tab-channels-size: var(--spacing-16); @@ -87,27 +84,26 @@ --t42-caption-bar-button-close-hover-text: hsl(var(--io-white)); --t42-caption-bar-button-correction: 6px; - --t42-approaching-edge-start-color: #4B92FB; + --t42-approaching-edge-start-color: #4b92fb; --t42-approaching-edge-end-color: hsl(var(--io-highlight-Interactive)); } .dark { - --t42-background: #26282A; + --t42-background: #26282a; --t42-tab-bar-selected-tab-background: hsl(var(--io-bg-02)); --sticky-icon-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23afafaf' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,13.9L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,13.9z M6.5,0h-5 C0.7,0,0,0.7,0,1.5v5C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5 C7,6.8,6.8,7,6.5,7z M14.5,8h-5C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); - --sticky-icon-off-hover:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 17'%3E%3Cpath fill='%234B92FB' d='M11.3,3.8L9.5,5.6c-0.2,0.2-0.2,0.5,0,0.7s0.5,0.2,0.7,0L12,4.5c0.2-0.2,0.2-0.5,0-0.7 C11.8,3.6,11.5,3.6,11.3,3.8z M5.6,9.5l-1.8,1.8c-0.2,0.2-0.2,0.5,0,0.7c0.2,0.2,0.5,0.2,0.7,0l1.8-1.8c0.2-0.2,0.2-0.5,0-0.7 S5.8,9.3,5.6,9.5z'/%3E%3Cpath fill='%23AFAFAF' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,14 L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,14z M6.5,0h-5C0.7,0,0,0.7,0,1.5v5 C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5C7,6.8,6.8,7,6.5,7z M14.5,8h-5 C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10 h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A");; - --sticky-icon-on:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23AFB2B5' d='M6.5,4h-5C0.7,4,0,4.7,0,5.5v5C0,11.3,0.7,12,1.5,12h5C7.3,12,8,11.3,8,10.5v-5C8,4.7,7.3,4,6.5,4z M6.5,11h-5 C1.2,11,1,10.8,1,10.5V6h6v4.5C7,10.8,6.8,11,6.5,11z M14.5,4h-5C8.7,4,8,4.7,8,5.5v5C8,11.3,8.7,12,9.5,12h5c0.8,0,1.5-0.7,1.5-1.5 v-5C16,4.7,15.3,4,14.5,4z M14.5,11h-5C9.2,11,9,10.8,9,10.5V6h6v4.5C15,10.8,14.8,11,14.5,11z'/%3E%3Cpath fill='%23808389' d='M6.6,0l2.7,0c0.3,0,0.5,0.3,0.3,0.5L8.5,2.1v1.4C8.5,3.8,8.3,4,8,4C7.7,4,7.5,3.8,7.5,3.5V2.1L6.3,0.5 C6.2,0.3,6.3,0,6.6,0z M7.5,13.9v-1.4C7.5,12.2,7.7,12,8,12c0.3,0,0.5,0.2,0.5,0.5v1.4l1.2,1.6c0.2,0.2,0,0.5-0.3,0.5H6.6 c-0.3,0-0.5-0.3-0.3-0.5L7.5,13.9z M8,11c-0.3,0-0.5-0.2-0.5-0.5v-4C7.5,6.2,7.7,6,8,6c0.3,0,0.5,0.2,0.5,0.5v4 C8.5,10.8,8.3,11,8,11z'/%3E%3C/svg%3E"); - --sticky-icon-on-hover:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23AFB2B5' d='M6.5,4h-5C0.7,4,0,4.7,0,5.5v5C0,11.3,0.7,12,1.5,12h5C7.3,12,8,11.3,8,10.5v-5C8,4.7,7.3,4,6.5,4z M6.5,11h-5 C1.2,11,1,10.8,1,10.5V6h6v4.5C7,10.8,6.8,11,6.5,11z M14.5,4h-5C8.7,4,8,4.7,8,5.5v5C8,11.3,8.7,12,9.5,12h5c0.8,0,1.5-0.7,1.5-1.5 v-5C16,4.7,15.3,4,14.5,4z M14.5,11h-5C9.2,11,9,10.8,9,10.5V6h6v4.5C15,10.8,14.8,11,14.5,11z'/%3E%3Cpath fill='%234B92FB' d='M6.6,0l2.7,0c0.3,0,0.5,0.3,0.3,0.5L8.3,2.4c-0.1,0.2-0.4,0.2-0.6,0L6.3,0.5C6.2,0.3,6.3,0,6.6,0z M6.6,16h2.7 c0.3,0,0.5-0.3,0.3-0.5l-1.4-1.9c-0.1-0.2-0.4-0.2-0.6,0l-1.4,1.9C6.2,15.7,6.3,16,6.6,16z'/%3E%3Cpath fill='%234B92FB' d='M8.5,13.5v1C8.5,14.8,8.3,15,8,15c-0.3,0-0.5-0.2-0.5-0.5v-1v-1v-11C7.5,1.2,7.7,1,8,1c0.3,0,0.5,0.2,0.5,0.5 v11V13.5C8.5,13.5,8.5,13.5,8.5,13.5z'/%3E%3C/svg%3E"); + --sticky-icon-off-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 17'%3E%3Cpath fill='%234B92FB' d='M11.3,3.8L9.5,5.6c-0.2,0.2-0.2,0.5,0,0.7s0.5,0.2,0.7,0L12,4.5c0.2-0.2,0.2-0.5,0-0.7 C11.8,3.6,11.5,3.6,11.3,3.8z M5.6,9.5l-1.8,1.8c-0.2,0.2-0.2,0.5,0,0.7c0.2,0.2,0.5,0.2,0.7,0l1.8-1.8c0.2-0.2,0.2-0.5,0-0.7 S5.8,9.3,5.6,9.5z'/%3E%3Cpath fill='%23AFAFAF' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,14 L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,14z M6.5,0h-5C0.7,0,0,0.7,0,1.5v5 C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5C7,6.8,6.8,7,6.5,7z M14.5,8h-5 C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10 h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); + --sticky-icon-on: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23AFB2B5' d='M6.5,4h-5C0.7,4,0,4.7,0,5.5v5C0,11.3,0.7,12,1.5,12h5C7.3,12,8,11.3,8,10.5v-5C8,4.7,7.3,4,6.5,4z M6.5,11h-5 C1.2,11,1,10.8,1,10.5V6h6v4.5C7,10.8,6.8,11,6.5,11z M14.5,4h-5C8.7,4,8,4.7,8,5.5v5C8,11.3,8.7,12,9.5,12h5c0.8,0,1.5-0.7,1.5-1.5 v-5C16,4.7,15.3,4,14.5,4z M14.5,11h-5C9.2,11,9,10.8,9,10.5V6h6v4.5C15,10.8,14.8,11,14.5,11z'/%3E%3Cpath fill='%23808389' d='M6.6,0l2.7,0c0.3,0,0.5,0.3,0.3,0.5L8.5,2.1v1.4C8.5,3.8,8.3,4,8,4C7.7,4,7.5,3.8,7.5,3.5V2.1L6.3,0.5 C6.2,0.3,6.3,0,6.6,0z M7.5,13.9v-1.4C7.5,12.2,7.7,12,8,12c0.3,0,0.5,0.2,0.5,0.5v1.4l1.2,1.6c0.2,0.2,0,0.5-0.3,0.5H6.6 c-0.3,0-0.5-0.3-0.3-0.5L7.5,13.9z M8,11c-0.3,0-0.5-0.2-0.5-0.5v-4C7.5,6.2,7.7,6,8,6c0.3,0,0.5,0.2,0.5,0.5v4 C8.5,10.8,8.3,11,8,11z'/%3E%3C/svg%3E"); + --sticky-icon-on-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23AFB2B5' d='M6.5,4h-5C0.7,4,0,4.7,0,5.5v5C0,11.3,0.7,12,1.5,12h5C7.3,12,8,11.3,8,10.5v-5C8,4.7,7.3,4,6.5,4z M6.5,11h-5 C1.2,11,1,10.8,1,10.5V6h6v4.5C7,10.8,6.8,11,6.5,11z M14.5,4h-5C8.7,4,8,4.7,8,5.5v5C8,11.3,8.7,12,9.5,12h5c0.8,0,1.5-0.7,1.5-1.5 v-5C16,4.7,15.3,4,14.5,4z M14.5,11h-5C9.2,11,9,10.8,9,10.5V6h6v4.5C15,10.8,14.8,11,14.5,11z'/%3E%3Cpath fill='%234B92FB' d='M6.6,0l2.7,0c0.3,0,0.5,0.3,0.3,0.5L8.3,2.4c-0.1,0.2-0.4,0.2-0.6,0L6.3,0.5C6.2,0.3,6.3,0,6.6,0z M6.6,16h2.7 c0.3,0,0.5-0.3,0.3-0.5l-1.4-1.9c-0.1-0.2-0.4-0.2-0.6,0l-1.4,1.9C6.2,15.7,6.3,16,6.6,16z'/%3E%3Cpath fill='%234B92FB' d='M8.5,13.5v1C8.5,14.8,8.3,15,8,15c-0.3,0-0.5-0.2-0.5-0.5v-1v-1v-11C7.5,1.2,7.7,1,8,1c0.3,0,0.5,0.2,0.5,0.5 v11V13.5C8.5,13.5,8.5,13.5,8.5,13.5z'/%3E%3C/svg%3E"); } .light { - --t42-background: #E8E9ED; + --t42-background: #e8e9ed; --t42-tab-bar-selected-tab-background: hsl(var(--io-white)); --sticky-icon-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23626F81' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,13.9L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,13.9z M6.5,0h-5 C0.7,0,0,0.7,0,1.5v5C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5 C7,6.8,6.8,7,6.5,7z M14.5,8h-5C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); - --sticky-icon-off-hover:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 17'%3E%3Cpath fill='%231B6ADE' d='M11.3,3.8L9.5,5.6c-0.2,0.2-0.2,0.5,0,0.7s0.5,0.2,0.7,0L12,4.5c0.2-0.2,0.2-0.5,0-0.7 C11.8,3.6,11.5,3.6,11.3,3.8z M5.6,9.5l-1.8,1.8c-0.2,0.2-0.2,0.5,0,0.7c0.2,0.2,0.5,0.2,0.7,0l1.8-1.8c0.2-0.2,0.2-0.5,0-0.7 S5.8,9.3,5.6,9.5z'/%3E%3Cpath fill='%23626F81' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,14 L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,14z M6.5,0h-5C0.7,0,0,0.7,0,1.5v5 C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5C7,6.8,6.8,7,6.5,7z M14.5,8h-5 C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10 h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A");; - --sticky-icon-on:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23626F81' d='M6.5,4h-5C0.7,4,0,4.7,0,5.5v5C0,11.3,0.7,12,1.5,12h5C7.3,12,8,11.3,8,10.5v-5C8,4.7,7.3,4,6.5,4z M6.5,11h-5 C1.2,11,1,10.8,1,10.5V6h6v4.5C7,10.8,6.8,11,6.5,11z M14.5,4h-5C8.7,4,8,4.7,8,5.5v5C8,11.3,8.7,12,9.5,12h5c0.8,0,1.5-0.7,1.5-1.5 v-5C16,4.7,15.3,4,14.5,4z M14.5,11h-5C9.2,11,9,10.8,9,10.5V6h6v4.5C15,10.8,14.8,11,14.5,11z'/%3E%3Cpath fill='%23A4B1C3' d='M6.6,0l2.7,0c0.3,0,0.5,0.3,0.3,0.5L8.5,2.1v1.4C8.5,3.8,8.3,4,8,4C7.7,4,7.5,3.8,7.5,3.5V2.1L6.3,0.5 C6.2,0.3,6.3,0,6.6,0z M7.5,13.9v-1.4C7.5,12.2,7.7,12,8,12c0.3,0,0.5,0.2,0.5,0.5v1.4l1.2,1.6c0.2,0.2,0,0.5-0.3,0.5H6.6 c-0.3,0-0.5-0.3-0.3-0.5L7.5,13.9z M8,11c-0.3,0-0.5-0.2-0.5-0.5v-4C7.5,6.2,7.7,6,8,6c0.3,0,0.5,0.2,0.5,0.5v4 C8.5,10.8,8.3,11,8,11z'/%3E%3C/svg%3E"); - --sticky-icon-on-hover:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23626F81' d='M6.5,4h-5C0.7,4,0,4.7,0,5.5v5C0,11.3,0.7,12,1.5,12h5C7.3,12,8,11.3,8,10.5v-5C8,4.7,7.3,4,6.5,4z M6.5,11h-5 C1.2,11,1,10.8,1,10.5V6h6v4.5C7,10.8,6.8,11,6.5,11z M14.5,4h-5C8.7,4,8,4.7,8,5.5v5C8,11.3,8.7,12,9.5,12h5c0.8,0,1.5-0.7,1.5-1.5 v-5C16,4.7,15.3,4,14.5,4z M14.5,11h-5C9.2,11,9,10.8,9,10.5V6h6v4.5C15,10.8,14.8,11,14.5,11z'/%3E%3Cpath fill='%234B92FB' d='M6.6,0l2.7,0c0.3,0,0.5,0.3,0.3,0.5L8.3,2.4c-0.1,0.2-0.4,0.2-0.6,0L6.3,0.5C6.2,0.3,6.3,0,6.6,0z M6.6,16h2.7 c0.3,0,0.5-0.3,0.3-0.5l-1.4-1.9c-0.1-0.2-0.4-0.2-0.6,0l-1.4,1.9C6.2,15.7,6.3,16,6.6,16z'/%3E%3Cpath fill='%234B92FB' d='M8.5,13.5v1C8.5,14.8,8.3,15,8,15c-0.3,0-0.5-0.2-0.5-0.5v-1v-1v-11C7.5,1.2,7.7,1,8,1c0.3,0,0.5,0.2,0.5,0.5 v11V13.5C8.5,13.5,8.5,13.5,8.5,13.5z'/%3E%3C/svg%3E"); - + --sticky-icon-off-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 17'%3E%3Cpath fill='%231B6ADE' d='M11.3,3.8L9.5,5.6c-0.2,0.2-0.2,0.5,0,0.7s0.5,0.2,0.7,0L12,4.5c0.2-0.2,0.2-0.5,0-0.7 C11.8,3.6,11.5,3.6,11.3,3.8z M5.6,9.5l-1.8,1.8c-0.2,0.2-0.2,0.5,0,0.7c0.2,0.2,0.5,0.2,0.7,0l1.8-1.8c0.2-0.2,0.2-0.5,0-0.7 S5.8,9.3,5.6,9.5z'/%3E%3Cpath fill='%23626F81' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,14 L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,14z M6.5,0h-5C0.7,0,0,0.7,0,1.5v5 C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5C7,6.8,6.8,7,6.5,7z M14.5,8h-5 C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10 h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); + --sticky-icon-on: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23626F81' d='M6.5,4h-5C0.7,4,0,4.7,0,5.5v5C0,11.3,0.7,12,1.5,12h5C7.3,12,8,11.3,8,10.5v-5C8,4.7,7.3,4,6.5,4z M6.5,11h-5 C1.2,11,1,10.8,1,10.5V6h6v4.5C7,10.8,6.8,11,6.5,11z M14.5,4h-5C8.7,4,8,4.7,8,5.5v5C8,11.3,8.7,12,9.5,12h5c0.8,0,1.5-0.7,1.5-1.5 v-5C16,4.7,15.3,4,14.5,4z M14.5,11h-5C9.2,11,9,10.8,9,10.5V6h6v4.5C15,10.8,14.8,11,14.5,11z'/%3E%3Cpath fill='%23A4B1C3' d='M6.6,0l2.7,0c0.3,0,0.5,0.3,0.3,0.5L8.5,2.1v1.4C8.5,3.8,8.3,4,8,4C7.7,4,7.5,3.8,7.5,3.5V2.1L6.3,0.5 C6.2,0.3,6.3,0,6.6,0z M7.5,13.9v-1.4C7.5,12.2,7.7,12,8,12c0.3,0,0.5,0.2,0.5,0.5v1.4l1.2,1.6c0.2,0.2,0,0.5-0.3,0.5H6.6 c-0.3,0-0.5-0.3-0.3-0.5L7.5,13.9z M8,11c-0.3,0-0.5-0.2-0.5-0.5v-4C7.5,6.2,7.7,6,8,6c0.3,0,0.5,0.2,0.5,0.5v4 C8.5,10.8,8.3,11,8,11z'/%3E%3C/svg%3E"); + --sticky-icon-on-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23626F81' d='M6.5,4h-5C0.7,4,0,4.7,0,5.5v5C0,11.3,0.7,12,1.5,12h5C7.3,12,8,11.3,8,10.5v-5C8,4.7,7.3,4,6.5,4z M6.5,11h-5 C1.2,11,1,10.8,1,10.5V6h6v4.5C7,10.8,6.8,11,6.5,11z M14.5,4h-5C8.7,4,8,4.7,8,5.5v5C8,11.3,8.7,12,9.5,12h5c0.8,0,1.5-0.7,1.5-1.5 v-5C16,4.7,15.3,4,14.5,4z M14.5,11h-5C9.2,11,9,10.8,9,10.5V6h6v4.5C15,10.8,14.8,11,14.5,11z'/%3E%3Cpath fill='%234B92FB' d='M6.6,0l2.7,0c0.3,0,0.5,0.3,0.3,0.5L8.3,2.4c-0.1,0.2-0.4,0.2-0.6,0L6.3,0.5C6.2,0.3,6.3,0,6.6,0z M6.6,16h2.7 c0.3,0,0.5-0.3,0.3-0.5l-1.4-1.9c-0.1-0.2-0.4-0.2-0.6,0l-1.4,1.9C6.2,15.7,6.3,16,6.6,16z'/%3E%3Cpath fill='%234B92FB' d='M8.5,13.5v1C8.5,14.8,8.3,15,8,15c-0.3,0-0.5-0.2-0.5-0.5v-1v-1v-11C7.5,1.2,7.7,1,8,1c0.3,0,0.5,0.2,0.5,0.5 v11V13.5C8.5,13.5,8.5,13.5,8.5,13.5z'/%3E%3C/svg%3E"); } From 58a51ee0d29fb8f401773893eb34a09c815cb841 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Tue, 28 May 2024 12:48:07 +0300 Subject: [PATCH 07/42] Release 2.2.0 Signed-off-by: Svetozar Mateev --- changelog.md | 4 ++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index 3f68265..990cf8e 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,7 @@ +2.2.0 +chore: official 9.3 support +chore: updated the css file name in the readme +feat: added support for defining the drag area with CSS 2.1.0 chore: official 9.2 support 2.0.6 diff --git a/package-lock.json b/package-lock.json index 897ef96..0d4f4ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@interopio/groups-ui-react", - "version": "2.0.4", + "version": "2.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@interopio/groups-ui-react", - "version": "2.0.4", + "version": "2.1.0", "license": "MIT", "dependencies": { "@interopio/theme": "2.0.5", diff --git a/package.json b/package.json index 091f86d..6337dfe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.1.0", + "version": "2.2.0", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io", From 3211085790f5f3740e3751e765068bdc5196e9ac Mon Sep 17 00:00:00 2001 From: Elijah Stoykov Date: Thu, 30 May 2024 17:38:33 +0300 Subject: [PATCH 08/42] https://interopio.atlassian.net/browse/G4E-7798 - WebGroup - Add HTML elements in web group page for inner sizing borders - Add inner sizing borders styles (#36) --- assets/css/groups.css | 59 +++++++++++++++++++++++++++++++++++++++++-- assets/css/vars.css | 4 +++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index 15f6090..bf6dcf2 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -620,14 +620,69 @@ input { width: var(--t42-approaching-edge-size); } +.t42-sizing-border-group { + pointer-events: none; + list-style-type: none; + display: flex; + margin: 0px; + padding: 0px; + flex-grow: 0; + flex-shrink: 0; + position: absolute; + overflow: hidden; + z-index: 100; + background-color: var(--t42-sizing-border-group-color); +} + +.t42-vertical-sizing-border-group { + flex-direction: column; + cursor: ew-resize; +} + +.t42-horizontal-sizing-border-group { + flex-direction: row; + cursor: ns-resize; +} + +.t42-sizing-border-group:hover { + background-color: var(--t42-hover-sizing-border-group-color); +} + +.t42-active-sizing-border-group { + z-index: 200; + background-color: var(--t42-active-sizing-border-group-color); +} + +.t42-active-sizing-border-group:hover { + background-color: var(--t42-active-sizing-border-group-color); +} + +.t42-sizing-border { + pointer-events: auto; + margin: 0px; + padding: 0px; + flex-shrink: 0; +} + +.t42-frame-sizing-border { + flex-grow: 0; +} + +.t42-cross-sizing-border { + flex-grow: 1; + cursor: ne-resize; +} + +.t42-active-sizing-border { + background-color: transparent; +} + .t42-skip-focus { /* We used non-standard rule to have non-empty style */ -moz-user-focus: ignore; } - @keyframes clipMe { - 0%, 100% { clip: rect(0, 25vh, 2px, 0); diff --git a/assets/css/vars.css b/assets/css/vars.css index cf73d73..51e22d4 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -86,6 +86,10 @@ --t42-approaching-edge-start-color: #4b92fb; --t42-approaching-edge-end-color: hsl(var(--io-highlight-Interactive)); + + --t42-sizing-border-group-color: hsl(var(--io-bg-01)); + --t42-hover-sizing-border-group-color: hsl(var(--io-highlight-Interactive)); + --t42-active-sizing-border-group-color: hsl(var(--io-interactive-primary)); } .dark { From d04389c0824084f752a661cd97342e779a836a54 Mon Sep 17 00:00:00 2001 From: Elijah Stoykov Date: Fri, 31 May 2024 11:20:00 +0300 Subject: [PATCH 09/42] G4E-7798 web group add html elements in web group page for inner sizing borders (#37) * https://interopio.atlassian.net/browse/G4E-7798 - WebGroup - Add HTML elements in web group page for inner sizing borders - Add inner sizing borders styles * https://interopio.atlassian.net/browse/G4E-7798 - WebGroup - Add HTML elements in web group page for inner sizing borders - Update interop.io theme --- package-lock.json | 18 +++++++++--------- package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0d4f4ee..600d6bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@interopio/groups-ui-react", - "version": "2.1.0", + "version": "2.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@interopio/groups-ui-react", - "version": "2.1.0", + "version": "2.2.0", "license": "MIT", "dependencies": { - "@interopio/theme": "2.0.5", + "@interopio/theme": "2.1.24", "callback-registry": "^2.7.2", "color2k": "^2.0.0", "use-sync-external-store": "^1.2.0" @@ -2548,9 +2548,9 @@ } }, "node_modules/@interopio/theme": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@interopio/theme/-/theme-2.0.5.tgz", - "integrity": "sha512-zgehz+AG0J81fCDszywdKTEURaFETHVx6Gl/m4mQjWlap5MrS3VXzqeo8WivWyTue2G9EqnURvOYwM2aK19vmQ==" + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/@interopio/theme/-/theme-2.1.24.tgz", + "integrity": "sha512-SZa0UmomoUDg/fblMsMHqNQn/QfIogYarD7DBNcfWR/xoq+2uBH7wST8eKPZn9TxFTwmOASvrjDiS/TppF9nfg==" }, "node_modules/@interopio/workspaces-api": { "version": "3.0.2", @@ -22091,9 +22091,9 @@ } }, "@interopio/theme": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@interopio/theme/-/theme-2.0.5.tgz", - "integrity": "sha512-zgehz+AG0J81fCDszywdKTEURaFETHVx6Gl/m4mQjWlap5MrS3VXzqeo8WivWyTue2G9EqnURvOYwM2aK19vmQ==" + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/@interopio/theme/-/theme-2.1.24.tgz", + "integrity": "sha512-SZa0UmomoUDg/fblMsMHqNQn/QfIogYarD7DBNcfWR/xoq+2uBH7wST8eKPZn9TxFTwmOASvrjDiS/TppF9nfg==" }, "@interopio/workspaces-api": { "version": "3.0.2", diff --git a/package.json b/package.json index 6337dfe..829c3eb 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "access": "public" }, "dependencies": { - "@interopio/theme": "2.0.5", + "@interopio/theme": "2.1.24", "callback-registry": "^2.7.2", "color2k": "^2.0.0", "use-sync-external-store": "^1.2.0" From 910ef879496a6adbe78327572fde0d36ea6e6078 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Tue, 18 Jun 2024 14:45:15 +0300 Subject: [PATCH 10/42] G4E-7633 Overflow button and popup implementation (#38) * G4E-7633 Overflow button and popup implementation Signed-off-by: Svetozar Mateev * G4E-7633 Fixed the default tabs styles Signed-off-by: Svetozar Mateev * G4E-7633 Updated the classNames Signed-off-by: Svetozar Mateev --------- Signed-off-by: Svetozar Mateev Co-authored-by: Svetozar Mateev --- assets/css/groups.css | 68 +++++++++++++++++++ assets/css/vars.css | 31 +++++++++ package-lock.json | 25 +++++-- package.json | 3 +- src/GroupElementCreationWrapper.tsx | 68 ++++++++++++++++--- src/GroupWrapper.tsx | 3 + .../buttons/OverflowButton.tsx | 11 +++ .../popups/TabOverflowPopup.tsx | 42 ++++++++++++ .../tabs/TabHeaderButtons.tsx | 4 +- src/index.tsx | 14 ++-- src/types/api.ts | 12 +++- src/types/defaultComponents.ts | 7 +- src/types/internal.ts | 27 +++++++- src/webGroupsManager.ts | 14 +++- src/webGroupsStore.ts | 53 ++++++++++++--- 15 files changed, 343 insertions(+), 39 deletions(-) create mode 100644 src/defaultComponents/buttons/OverflowButton.tsx create mode 100644 src/defaultComponents/popups/TabOverflowPopup.tsx diff --git a/assets/css/groups.css b/assets/css/groups.css index bf6dcf2..f7ce32d 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -1,4 +1,5 @@ @import "vars.css"; +@import "../../node_modules/overlayscrollbars/styles/overlayscrollbars.css"; * { box-sizing: border-box; @@ -235,6 +236,10 @@ input { content: "\e91f"; } +.t42-standard-button-overflow::before { + content: "\e91d"; +} + .t42-standard-button-sticky::before { content: var(--sticky-icon-off); display: block; @@ -783,3 +788,66 @@ input { width: 0; } } + +.os-scrollbar-horizontal { + z-index: 1001; +} + +.t42-tabs-overflow .t42-tab { + flex-shrink: 0; +} + +.t42-tabs-overflow .t42-tabs { + overflow: auto; +} + +.t42-page-popup { + position: absolute; + z-index: 999; + margin-top: var(--t42-wg-tab-over-top-offset); +} + +.t42-tab-overflow-popup { + display: flex; + flex-direction: column; + min-width: var(--t42-wg-tab-over-min-width); + max-width: var(--t42-wg-tab-over-max-width); + max-height: var(--t42-wg-tab-over-max-height); + padding: var(--t42-wg-tab-over-padding); + border-radius: var(--t42-wg-tab-over-border-radius); + overflow: auto; + background-color: var(--t42-wg-tab-over-background); +} + +.t42-tab-overflow-popup li { + display: flex; + gap: var(--t42-wg-tab-over-item-gap); + align-items: center; + height: var(--t42-wg-tab-over-item-height); + padding: var(--t42-wg-tab-over-item-padding); +} + +.t42-tab-overflow-popup li span { + flex-grow: 1; + overflow: hidden; + text-wrap: nowrap; + text-overflow: clip; +} + +.t42-tab-overflow-popup li:not(.title):hover { + color: var(--t42-wg-tab-over-item-color-hover); + background-color: var(--t42-wg-tab-over-item-background-hover); +} + +.t42-tab-overflow-popup hr { + height: var(--t42-wg-tab-over-separator-size); + margin: var(--t42-wg-tab-over-separator-space); + border: 0; + background-color: var(--t42-wg-tab-over-separator-color); +} + +.t42-tab-overflow-popup .title { + color: var(--t42-wg-tab-over-item-title-color); + font-size: var(--t42-wg-tab-over-item-title-size); + letter-spacing: var(--t42-wg-tab-over-item-title-spacing); +} diff --git a/assets/css/vars.css b/assets/css/vars.css index 51e22d4..845f38e 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -90,11 +90,41 @@ --t42-sizing-border-group-color: hsl(var(--io-bg-01)); --t42-hover-sizing-border-group-color: hsl(var(--io-highlight-Interactive)); --t42-active-sizing-border-group-color: hsl(var(--io-interactive-primary)); + + --t42-wg-tab-over-max-height: 100vh; + --t42-wg-tab-over-max-width: 200px; + --t42-wg-tab-over-min-width: 200px; + --t42-wg-tab-over-top-offset: var(--spacing-4); + --t42-wg-tab-over-border-radius: var(--spacing-8); + --t42-wg-tab-over-padding: var(--spacing-4) 0; + --t42-wg-tab-over-item-background-hover: var(--list-item-background-hover); + --t42-wg-tab-over-item-color-hover: var(--text-states-active); + --t42-wg-tab-over-item-padding: 0 var(--spacing-8) 0 var(--spacing-16); + --t42-wg-tab-over-item-gap: var(--spacing-8); + --t42-wg-tab-over-item-height: var(--spacing-32); + --t42-wg-tab-over-item-title-color: var(--text-inactive-tertiary); + --t42-wg-tab-over-item-title-size: var(--spacing-10); + --t42-wg-tab-over-item-title-spacing: 0.36px; + --t42-wg-tab-over-separator-size: var(--spacing-1); + --t42-wg-tab-over-separator-color: var(--base-border-separator); + --t42-wg-tab-over-separator-space: var(--spacing-8) 0; +} + +/* Scroll vars override */ +.os-theme-dark, +.os-theme-light { + --os-size: var(--spacing-4); + --os-padding-perpendicular: 0; + --os-padding-axis: var(--spacing-1); + --os-handle-bg: var(--base-scroll-background-hover); + --os-handle-bg-hover: var(--base-scroll-background-hover); + --os-handle-bg-active: var(--base-scroll-background-hover); } .dark { --t42-background: #26282a; --t42-tab-bar-selected-tab-background: hsl(var(--io-bg-02)); + --t42-wg-tab-over-background: #26282a; /* for 10.0 - var(--base-panel-background); */ --sticky-icon-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23afafaf' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,13.9L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,13.9z M6.5,0h-5 C0.7,0,0,0.7,0,1.5v5C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5 C7,6.8,6.8,7,6.5,7z M14.5,8h-5C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); --sticky-icon-off-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 17'%3E%3Cpath fill='%234B92FB' d='M11.3,3.8L9.5,5.6c-0.2,0.2-0.2,0.5,0,0.7s0.5,0.2,0.7,0L12,4.5c0.2-0.2,0.2-0.5,0-0.7 C11.8,3.6,11.5,3.6,11.3,3.8z M5.6,9.5l-1.8,1.8c-0.2,0.2-0.2,0.5,0,0.7c0.2,0.2,0.5,0.2,0.7,0l1.8-1.8c0.2-0.2,0.2-0.5,0-0.7 S5.8,9.3,5.6,9.5z'/%3E%3Cpath fill='%23AFAFAF' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,14 L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,14z M6.5,0h-5C0.7,0,0,0.7,0,1.5v5 C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5C7,6.8,6.8,7,6.5,7z M14.5,8h-5 C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10 h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); @@ -105,6 +135,7 @@ .light { --t42-background: #e8e9ed; --t42-tab-bar-selected-tab-background: hsl(var(--io-white)); + --t42-wg-tab-over-background: #e8e9ed; /* for 10.0 - var(--base-panel-background); */ --sticky-icon-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23626F81' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,13.9L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,13.9z M6.5,0h-5 C0.7,0,0,0.7,0,1.5v5C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5 C7,6.8,6.8,7,6.5,7z M14.5,8h-5C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); --sticky-icon-off-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 17'%3E%3Cpath fill='%231B6ADE' d='M11.3,3.8L9.5,5.6c-0.2,0.2-0.2,0.5,0,0.7s0.5,0.2,0.7,0L12,4.5c0.2-0.2,0.2-0.5,0-0.7 C11.8,3.6,11.5,3.6,11.3,3.8z M5.6,9.5l-1.8,1.8c-0.2,0.2-0.2,0.5,0,0.7c0.2,0.2,0.5,0.2,0.7,0l1.8-1.8c0.2-0.2,0.2-0.5,0-0.7 S5.8,9.3,5.6,9.5z'/%3E%3Cpath fill='%23626F81' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,14 L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,14z M6.5,0h-5C0.7,0,0,0.7,0,1.5v5 C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5C7,6.8,6.8,7,6.5,7z M14.5,8h-5 C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10 h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); diff --git a/package-lock.json b/package-lock.json index 600d6bc..73bc591 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,10 @@ "version": "2.2.0", "license": "MIT", "dependencies": { - "@interopio/theme": "2.1.24", + "@interopio/theme": "^2.1.26", "callback-registry": "^2.7.2", "color2k": "^2.0.0", + "overlayscrollbars": "^2.8.3", "use-sync-external-store": "^1.2.0" }, "devDependencies": { @@ -2548,9 +2549,9 @@ } }, "node_modules/@interopio/theme": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/@interopio/theme/-/theme-2.1.24.tgz", - "integrity": "sha512-SZa0UmomoUDg/fblMsMHqNQn/QfIogYarD7DBNcfWR/xoq+2uBH7wST8eKPZn9TxFTwmOASvrjDiS/TppF9nfg==" + "version": "2.1.26", + "resolved": "https://codeartifact-interopio-npm.interop.io/@interopio/theme/-/theme-2.1.26.tgz", + "integrity": "sha512-MBY/GOxhm3VZE2uz36xTy+X8X1gDZ4BiwWgFpwPkqq96D0X6hBMt9MX4Q/gnuecWK7eqSYjhcBUHjbnKNEZprg==" }, "node_modules/@interopio/workspaces-api": { "version": "3.0.2", @@ -14890,6 +14891,11 @@ "node": ">=0.10.0" } }, + "node_modules/overlayscrollbars": { + "version": "2.8.3", + "resolved": "https://codeartifact-interopio-npm.interop.io/overlayscrollbars/-/overlayscrollbars-2.8.3.tgz", + "integrity": "sha512-7JHA1oWm3Gru3RF5wwaeBdgk4keGtc56HMWEQRQi/RdLdY3pZTUDlSfUk1jyv1yQN12otr828n52rT6VNzYO4w==" + }, "node_modules/p-limit": { "version": "1.3.0", "dev": true, @@ -22091,9 +22097,9 @@ } }, "@interopio/theme": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/@interopio/theme/-/theme-2.1.24.tgz", - "integrity": "sha512-SZa0UmomoUDg/fblMsMHqNQn/QfIogYarD7DBNcfWR/xoq+2uBH7wST8eKPZn9TxFTwmOASvrjDiS/TppF9nfg==" + "version": "2.1.26", + "resolved": "https://codeartifact-interopio-npm.interop.io/@interopio/theme/-/theme-2.1.26.tgz", + "integrity": "sha512-MBY/GOxhm3VZE2uz36xTy+X8X1gDZ4BiwWgFpwPkqq96D0X6hBMt9MX4Q/gnuecWK7eqSYjhcBUHjbnKNEZprg==" }, "@interopio/workspaces-api": { "version": "3.0.2", @@ -30037,6 +30043,11 @@ "version": "1.0.2", "dev": true }, + "overlayscrollbars": { + "version": "2.8.3", + "resolved": "https://codeartifact-interopio-npm.interop.io/overlayscrollbars/-/overlayscrollbars-2.8.3.tgz", + "integrity": "sha512-7JHA1oWm3Gru3RF5wwaeBdgk4keGtc56HMWEQRQi/RdLdY3pZTUDlSfUk1jyv1yQN12otr828n52rT6VNzYO4w==" + }, "p-limit": { "version": "1.3.0", "dev": true, diff --git a/package.json b/package.json index 829c3eb..68decfe 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,10 @@ "access": "public" }, "dependencies": { - "@interopio/theme": "2.1.24", + "@interopio/theme": "2.1.26", "callback-registry": "^2.7.2", "color2k": "^2.0.0", + "overlayscrollbars": "^2.8.3", "use-sync-external-store": "^1.2.0" }, "peerDependencies": { diff --git a/src/GroupElementCreationWrapper.tsx b/src/GroupElementCreationWrapper.tsx index 273cfcc..77fa3c6 100644 --- a/src/GroupElementCreationWrapper.tsx +++ b/src/GroupElementCreationWrapper.tsx @@ -12,7 +12,7 @@ import FrameLoadingAnimation from "./defaultComponents/loadingAnimation/FrameLoa const GroupElementCreationWrapper: React.FC = ({ components }) => { const state = useSyncExternalStore(webGroupsStore.subscribe, webGroupsStore.getSnapshot); - const LoadingAnimation = components?.frame?.LoadingAnimation ?? FrameLoadingAnimation; + const LoadingAnimation = components?.frame?.LoadingAnimation ?? FrameLoadingAnimation; const renderGroupCaptionBar = () => { const GroupCaptionBarCustomElement = components?.group?.CaptionBar; @@ -174,7 +174,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { let customButtonsProps = new Array(); if (options.customButtons) { - customButtonsProps = options.customButtons.map((cButton) => { + customButtonsProps = options.customButtons.map((cButton) => { return { onClick: () => { webGroupsManager.clickCustomButton(options.targetId, cButton.buttonId); @@ -182,7 +182,9 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { visible: true, imageData: cButton.imageData, tooltip: cButton.tooltip, - buttonId: cButton.buttonId}}); + buttonId: cButton.buttonId + } + }); } const showSelector = (bounds: Bounds) => { @@ -410,6 +412,13 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { } const { parentElement, ...options } = te; + const overflow = { + onClick: () => { + webGroupsManager.onOverflowButtonClick(TargetType.TabBar, options.targetId); + }, + ...options.overflow + }; + const feedback = { onClick: () => { webGroupsManager.onFeedbackButtonClick(TargetType.TabBar, options.targetId); @@ -482,7 +491,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { let customButtonsProps = new Array(); if (options.customButtons) { - customButtonsProps = options.customButtons.map((cButton) => { + customButtonsProps = options.customButtons.map((cButton) => { return { onClick: () => { webGroupsManager.clickCustomButton(options.targetId, cButton.buttonId); @@ -490,10 +499,13 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { visible: true, imageData: cButton.imageData, tooltip: cButton.tooltip, - buttonId: cButton.buttonId}}); + buttonId: cButton.buttonId + } + }); } - + return = ({ components }) => { }); } + const renderTabOverflowPopups = () => { + const TabOverflowCustomElement = components?.tabs?.OverflowPopup; + + return Object.values(state.tabOverflowPopups).map((top) => { + if (!TabOverflowCustomElement || !top.parentElement) { + return; + } + const { parentElement, ...options } = top; + + const select = (windowId: string) => { + webGroupsManager.selectTab(windowId); + }; + + const close = (windowId: string) => { + webGroupsManager.onCloseButtonClick(TargetType.Tab, windowId); + } + + return + }); + } + const renderBelowTabs = () => { const BelowTabsCustomElement = components?.tabs?.Below; @@ -532,6 +569,13 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { } const { parentElement, ...options } = te; + const overflow = { + onClick: () => { + webGroupsManager.onOverflowButtonClick(TargetType.HtmlButtons, options.targetId); + }, + ...options.overflow + }; + const feedback = { onClick: () => { webGroupsManager.onFeedbackButtonClick(TargetType.HtmlButtons, options.targetId); @@ -604,7 +648,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { let customButtonsProps = new Array(); if (options.customButtons) { - customButtonsProps = options.customButtons.map((cButton) => { + customButtonsProps = options.customButtons.map((cButton) => { return { onClick: () => { webGroupsManager.clickCustomButton(options.targetId, cButton.buttonId); @@ -612,10 +656,13 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { visible: true, imageData: cButton.imageData, tooltip: cButton.tooltip, - buttonId: cButton.buttonId}}); + buttonId: cButton.buttonId + } + }); } - + return = ({ components }) => { {renderTabElements()} {renderAfterTabsZones()} {renderTabHeaderButtons()} + {renderTabOverflowPopups()} {renderBelowTabs()} {renderHtmlButtons()} = ({ components }) => { onCreateTabHeaderButtonsRequested={components?.tabs?.Buttons ? webGroupsStore.onCreateTabHeaderButtonsRequested : undefined} onCreateBelowTabsRequested={components?.tabs?.Below ? webGroupsStore.onCreateBelowTabsComponentRequested : undefined} onCreateHtmlButtonsRequested={components?.html?.Buttons ? webGroupsStore.onCreateHtmlButtonsRequested : undefined} + onCreateTabOverflowPopupRequested={components?.tabs?.OverflowPopup ? webGroupsStore.onCreateTabOverflowPopupRequested : undefined} onUpdateGroupCaptionBarRequested={components?.group?.CaptionBar ? webGroupsStore.onUpdateGroupCaptionBarRequested : undefined} onUpdateFrameWindowOverlayRequested={components?.group?.Overlay ? webGroupsStore.onUpdateFrameWindowOverlayRequested : undefined} onUpdateFrameCaptionBarRequested={components?.flat?.CaptionBar ? webGroupsStore.onUpdateFrameCaptionBarRequested : undefined} @@ -688,6 +737,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { onRemoveTabHeaderButtonsRequested={webGroupsStore.onRemoveTabHeaderButtonsRequested} onRemoveBelowTabsRequested={webGroupsStore.onRemoveBelowTabsRequested} onRemoveHtmlButtonsRequested={webGroupsStore.onRemoveHtmlButtonsRequested} + onRemoveTabOverflowPopupRequested={webGroupsStore.onRemoveTabOverflowPopupRequested} onShowCaptionEditorRequested={webGroupsStore.onShowCaptionEditorRequested} onCommitCaptionEditingRequested={webGroupsStore.onCommitCaptionEditingRequested} onHideCaptionEditorRequested={webGroupsStore.onHideCaptionEditorRequested} diff --git a/src/GroupWrapper.tsx b/src/GroupWrapper.tsx index 0acfc37..ea14543 100644 --- a/src/GroupWrapper.tsx +++ b/src/GroupWrapper.tsx @@ -40,6 +40,9 @@ class GroupWrapper extends React.Component { createHtmlButtonsContainerElement: this.props.onCreateHtmlButtonsRequested, destroyHtmlButtonsContainerElement: this.props.onRemoveHtmlButtonsRequested, + + createTabOverflowPopup:this.props.onCreateTabOverflowPopupRequested, + destroyTabOverflowPopup: this.props.onRemoveTabOverflowPopupRequested, updateFrame: this.props.onUpdateFrameRequested, updateStandardButton: this.props.onUpdateStandardButtonRequested, diff --git a/src/defaultComponents/buttons/OverflowButton.tsx b/src/defaultComponents/buttons/OverflowButton.tsx new file mode 100644 index 0000000..d357a9f --- /dev/null +++ b/src/defaultComponents/buttons/OverflowButton.tsx @@ -0,0 +1,11 @@ +import React from "react"; +import { OverflowButtonProps } from "../../types/defaultComponents"; +import BaseButton from "./BaseButton"; + +const OverflowButton: React.FC = ({ onClick, tooltip }) => { + return +} + +export default OverflowButton; \ No newline at end of file diff --git a/src/defaultComponents/popups/TabOverflowPopup.tsx b/src/defaultComponents/popups/TabOverflowPopup.tsx new file mode 100644 index 0000000..4f6557e --- /dev/null +++ b/src/defaultComponents/popups/TabOverflowPopup.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { TabOverflowPopupProps } from '../../types/api'; +import { OverflowedTabInfo } from '../../types/internal'; + +const TabOverflowPopup: React.FC = ({ + hiddenTabsToTheLeft, + hiddenTabsToTheRight, + close, + select +}) => { + const createSection = (tabs: OverflowedTabInfo[], title: string) => { + return ( +
        +
      • {title}
      • + {tabs.map((tab) => ( +
      • handleTabClick(tab.windowId)}> + {tab.title} +
        handleTabClose(tab.windowId)}>
        +
      • + ))} +
      + ); + }; + + const handleTabClick = (windowId: string) => { + select(windowId); + }; + + const handleTabClose = (windowId: string) => { + close(windowId); + }; + + return ( +
      + {hiddenTabsToTheLeft.length > 0 && createSection(hiddenTabsToTheLeft, "Open left")} + {hiddenTabsToTheLeft.length > 0 && hiddenTabsToTheRight.length > 0 &&
      } + {hiddenTabsToTheRight.length > 0 && createSection(hiddenTabsToTheRight, "Open right")} +
      + ); +}; + +export default TabOverflowPopup; \ No newline at end of file diff --git a/src/defaultComponents/tabs/TabHeaderButtons.tsx b/src/defaultComponents/tabs/TabHeaderButtons.tsx index 9134c6c..e4c5787 100644 --- a/src/defaultComponents/tabs/TabHeaderButtons.tsx +++ b/src/defaultComponents/tabs/TabHeaderButtons.tsx @@ -11,8 +11,9 @@ import RestoreButton from "../buttons/RestoreButton"; import StickyButton from "../buttons/StickyButton"; import UnlockButton from "../buttons/UnlockButton"; import CustomButton from "../buttons/CustomButton"; +import OverflowButton from "../buttons/OverflowButton"; -const TabHeaderButtons: React.FC = ({ extract, minimize, maximize, restore, close, lock, unlock, feedback, clone, sticky, customButtons }) => { +const TabHeaderButtons: React.FC = ({ overflow, extract, minimize, maximize, restore, close, lock, unlock, feedback, clone, sticky, customButtons }) => { return
        { @@ -22,6 +23,7 @@ const TabHeaderButtons: React.FC = ({ extract, minimize, }
        + {overflow?.visible && } {feedback?.visible && } {clone?.visible && } {sticky?.visible && } diff --git a/src/index.tsx b/src/index.tsx index 81298ba..bbb0625 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -24,6 +24,7 @@ import ExtractButton from "./defaultComponents/buttons/ExtractButton"; import FeedbackButton from "./defaultComponents/buttons/FeedbackButton"; import CloneButton from "./defaultComponents/buttons/CloneButton"; import StickyButton from "./defaultComponents/buttons/StickyButton"; +import OverflowButton from "./defaultComponents/buttons/OverflowButton"; import useIOConnectWindow from "./useIOConnectWindow"; import CustomButton from "./defaultComponents/buttons/CustomButton"; import { waitForWindow } from "./utils"; @@ -51,7 +52,8 @@ import { TabCloseButtonProps, UnlockButtonProps, UseCaptionEditorOptions, - UseEditableCaptionOptions + UseEditableCaptionOptions, + OverflowButtonProps } from "./types/defaultComponents"; import { AboveTabsProps, @@ -71,6 +73,7 @@ import { MoveAreaProps, TabElementProps, TabHeaderButtonsProps, + TabOverflowPopupProps, WindowContentOverlayProps, } from "./types/api"; import GroupCaptionEditor from "./defaultComponents/groupCaptionBar/GroupCaptionEditor"; @@ -84,8 +87,7 @@ import useEditableCaption from "./defaultComponents/captionEditor/useEditableCap import useCaptionEditor from "./defaultComponents/captionEditor/useCaptionEditor"; import FrameLoadingAnimation from "./defaultComponents/loadingAnimation/FrameLoadingAnimation"; import HtmlButtons from "./defaultComponents/htmlButtonsBar/buttons"; - - +import TabOverflowPopup from "./defaultComponents/popups/TabOverflowPopup"; export { GroupCaptionBar, @@ -117,6 +119,8 @@ export { TabHeaderButtons, FrameLoadingAnimation, HtmlButtons, + TabOverflowPopup, + OverflowButton, GroupComponentVisibilityState, useIOConnectWindow, useGroupComponentVisibility, @@ -160,6 +164,7 @@ export { FlatChannelSelectorProps, FlatButtonsProps, FlatCaptionEditorProps, + OverflowButtonProps, StickyButtonProps, FeedbackButtonProps, ExtractButtonProps, @@ -178,7 +183,8 @@ export { BelowTabsProps, BeforeTabsProps, AfterTabsProps, - WindowContentOverlayProps + WindowContentOverlayProps, + TabOverflowPopupProps, } export default GroupElementCreationWrapper; diff --git a/src/types/api.ts b/src/types/api.ts index 76af0c2..d14b304 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -1,5 +1,5 @@ import React from "react"; -import { Bounds, ButtonProps, ToggleButtonProps } from "./internal"; +import { Bounds, ButtonProps, OverflowedTabInfo, ToggleButtonProps } from "./internal"; import { CustomButtonProps } from "./defaultComponents"; export interface ChannelProps { @@ -50,6 +50,14 @@ export interface BelowTabsProps { selectedWindow: string; } +export interface TabOverflowPopupProps { + frameId: string; + select: (windowId: string) => void; + close: (windowId: string) => void; + hiddenTabsToTheLeft: OverflowedTabInfo[]; + hiddenTabsToTheRight: OverflowedTabInfo[]; +} + export interface CaptionEditorProps { show: boolean; text?: string; @@ -117,6 +125,7 @@ export interface AfterTabsProps { } export interface TabHeaderButtonsProps { + overflow?: ButtonProps; feedback?: ButtonProps; clone?: ButtonProps; sticky?: ToggleButtonProps; @@ -158,6 +167,7 @@ export interface GroupProps { After?: React.ComponentType; Buttons?: React.ComponentType; Below?: React.ComponentType; + OverflowPopup?: React.ComponentType; }; html?: { Buttons?: React.ComponentType; diff --git a/src/types/defaultComponents.ts b/src/types/defaultComponents.ts index 96f5df4..8131d45 100644 --- a/src/types/defaultComponents.ts +++ b/src/types/defaultComponents.ts @@ -42,6 +42,9 @@ export interface UnlockButtonProps extends ButtonProps { export interface MinimizeButtonProps extends ButtonProps { } +export interface OverflowButtonProps extends ButtonProps { +} + export interface MaximizeButtonProps extends ButtonProps { } @@ -52,8 +55,8 @@ export interface CloseButtonProps extends ButtonProps { } export interface CustomButtonProps extends ButtonProps { - imageData: string; - buttonId: string; + imageData: string; + buttonId: string; } export interface BaseButtonProps { diff --git a/src/types/internal.ts b/src/types/internal.ts index 0566134..cc3d9c4 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -11,7 +11,7 @@ export interface ButtonProps { visible: boolean; } -export interface ToggleButtonProps extends ButtonProps{ +export interface ToggleButtonProps extends ButtonProps { isPressed: boolean; } @@ -46,6 +46,8 @@ export interface GroupWrapperProps { onCreateTabHeaderButtonsRequested?: (options: CreateButtonsOptions) => void; + onCreateTabOverflowPopupRequested?: (options: CreateTabOverflowPopupRequestOptions) => void; + onCreateBelowTabsRequested?: (options: CreateFrameElementRequestOptions) => void; onUpdateBelowTabsRequested?: (options: CreateFrameElementRequestOptions) => void; @@ -67,14 +69,15 @@ export interface GroupWrapperProps { onRemoveTabRequested?: (options: RemoveRequestOptions) => void; onRemoveAfterTabsComponentRequested?: (options: RemoveRequestOptions) => void; onRemoveTabHeaderButtonsRequested?: (options: RemoveRequestOptions) => void; + onRemoveTabOverflowPopupRequested?: (options: RemoveRequestOptions) => void; onRemoveBelowTabsRequested?: (options: RemoveRequestOptions) => void; onShowCaptionEditorRequested?: (targetType: TargetType, targetId: string, text: string) => void; onCommitCaptionEditingRequested?: (targetType: TargetType, targetId: string) => void; onHideCaptionEditorRequested?: (targetType: TargetType, targetId: string) => void; - onShowLoadingAnimationRequested?: (targetType: TargetType ,targetId: string) => void; - onHideLoadingAnimationRequested?: (targetType: TargetType ,targetId: string) => void; + onShowLoadingAnimationRequested?: (targetType: TargetType, targetId: string) => void; + onHideLoadingAnimationRequested?: (targetType: TargetType, targetId: string) => void; } export interface CreateGroupCaptionBarRequestOptions extends CreateElementRequestOptions { @@ -158,6 +161,10 @@ export interface UpdateCustomButtonOptions { } export interface CreateButtonsOptions extends CreateFrameElementRequestOptions { + overflow: { + tooltip: string; + visible: boolean; + }, feedback: { tooltip: string; visible: boolean; @@ -220,6 +227,16 @@ export interface CreateFrameElementRequestOptions extends CreateElementRequestOp selectedWindow: string; } +export interface OverflowedTabInfo { + title: string; + windowId: string; +} + +export interface CreateTabOverflowPopupRequestOptions extends CreateElementRequestOptions { + hiddenTabsToTheLeft: OverflowedTabInfo[]; + hiddenTabsToTheRight: OverflowedTabInfo[]; +} + export interface CreateFrameLoadingAnimationRequestOptions extends CreateFrameElementRequestOptions { show: boolean; } @@ -235,6 +252,7 @@ export enum TargetType { } export enum StandardButtons { + Overflow = "overflow", Feedback = "feedback", Clone = "clone", Sticky = "sticky", @@ -261,6 +279,7 @@ export interface ElementCreationWrapperState { tabElements: { [targetId: string]: CreateTabRequestOptions }; afterTabsZones: { [targetId: string]: CreateFrameElementRequestOptions }; tabHeaderButtons: { [targetId: string]: CreateButtonsOptions }; + tabOverflowPopups: { [targetId: string]: CreateTabOverflowPopupRequestOptions }; belowTabsZones: { [targetId: string]: CreateFrameElementRequestOptions }; htmlButtons: { [targetId: string]: CreateButtonsOptions }; } @@ -280,6 +299,8 @@ export interface ExternalLibraryFactory { onCaptionEditorVisibleChanged(targetType: TargetType, targetId: string, visible: boolean): void; onCaptionEditorBoundsChanged(targetType: TargetType, targetId: string, bounds: Bounds): void; commitCaptionEditing(targetType: TargetType, targetId: string, text: string): void; + + selectTab(windowId: string): void; } export interface WebGroupsManager { diff --git a/src/webGroupsManager.ts b/src/webGroupsManager.ts index 020324b..254c16e 100644 --- a/src/webGroupsManager.ts +++ b/src/webGroupsManager.ts @@ -79,15 +79,19 @@ class WebGroupsManagerDecorator { window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Unlock); } - public onFeedbackButtonClick(targetType: TargetType, targetId: string):void{ + public onOverflowButtonClick(targetType: TargetType, targetId: string): void { + window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Overflow); + } + + public onFeedbackButtonClick(targetType: TargetType, targetId: string): void { window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Feedback); } - public onCloneButtonClick(targetType: TargetType, targetId: string):void{ + public onCloneButtonClick(targetType: TargetType, targetId: string): void { window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Clone); } - public onStickyButtonClick(targetType: TargetType, targetId: string):void{ + public onStickyButtonClick(targetType: TargetType, targetId: string): void { window.webGroupsManager.externalLibraryFactory.onStandardButtonClick(targetType, targetId, StandardButtons.Sticky); } @@ -154,6 +158,10 @@ class WebGroupsManagerDecorator { public requestCommitCaptionEditing(targetType: TargetType, targetId: string) { this.registry.execute(`${targetType}-${targetId}`); } + + public selectTab(windowId: string): void { + window.webGroupsManager.externalLibraryFactory.selectTab(windowId); + } } export default new WebGroupsManagerDecorator(); \ No newline at end of file diff --git a/src/webGroupsStore.ts b/src/webGroupsStore.ts index 1861a13..1853ce0 100644 --- a/src/webGroupsStore.ts +++ b/src/webGroupsStore.ts @@ -13,7 +13,8 @@ import { UpdateStandardButtonRequestOptions, UpdateFrameRequestOptions, CreateFrameLoadingAnimationRequestOptions, - UpdateCustomButtonsRequestOptions + UpdateCustomButtonsRequestOptions, + CreateTabOverflowPopupRequestOptions } from "./types/internal"; import webGroupsManager from "./webGroupsManager"; @@ -33,6 +34,7 @@ class WebGroupsStore { tabElements: {}, // dict windowId to create tab elements options afterTabsZones: {}, // dict frameId to after tabs zones options tabHeaderButtons: {}, // dict frameId to crate tab header buttons options + tabOverflowPopups: {}, // dict frameId to create tab overflow popup options, belowTabsZones: {}, // dict frameId to create options frameLoadingAnimations: {}, // dict frameId to create options htmlButtons: {}, // dict frameId to crate html buttons options @@ -275,6 +277,22 @@ class WebGroupsStore { }); } + public onCreateTabOverflowPopupRequested = (options: CreateTabOverflowPopupRequestOptions) => { + if (options === this.state.tabOverflowPopups[options.targetId] || !options) { + return; + } + + this.setState(s => { + return { + ...s, + tabOverflowPopups: { + ...s.tabOverflowPopups, + [options.targetId]: options + } + } + }); + } + public onUpdateHtmlButtonsRequested = (options: CreateButtonsOptions) => { if (options === this.state.htmlButtons[options.targetId] || !options) { return; @@ -458,7 +476,7 @@ class WebGroupsStore { public onUpdateStandardButton = (options: UpdateStandardButtonRequestOptions) => { const targetState = { targetId: options.targetId }; - switch(options.targetType) { + switch (options.targetType) { case TargetType.Group: const currentGroupState = this.state.groupCaptionBar || targetState as CreateGroupCaptionBarRequestOptions; const newGroupOptions = { @@ -503,7 +521,7 @@ class WebGroupsStore { } public onUpdateCustomButtons = (options: UpdateCustomButtonsRequestOptions) => { - switch(options.targetType) { + switch (options.targetType) { case TargetType.Frame: const currentFrameState = this.state.frameCaptionBars[options.targetId] || { targetId: options.targetId } as CreateButtonsOptions; const newFrameOptions = { @@ -777,6 +795,25 @@ class WebGroupsStore { }); } + public onRemoveTabOverflowPopupRequested = (options: RemoveRequestOptions) => { + if (!this.state.tabOverflowPopups[options.targetId]) { + return; + } + this.setState(s => { + const newTabOverflowPopupsObj = Object.keys(s.tabOverflowPopups).reduce((acc, targetId) => { + if (targetId != options.targetId) { + acc[targetId] = s.tabOverflowPopups[targetId]; + } + return acc; + }, {}); + + return { + ...s, + tabOverflowPopups: newTabOverflowPopupsObj + } + }); + } + public onShowCaptionEditorRequested = (targetType: TargetType, targetId: string, text: string) => { if (targetType === TargetType.Group) { this.onShowGroupCaptionEditorRequested(targetId, text); @@ -801,15 +838,15 @@ class WebGroupsStore { } } - public onShowLoadingAnimationRequested = (targetType: TargetType,targetId: string) => { - if (targetType === TargetType.Frame) { + public onShowLoadingAnimationRequested = (targetType: TargetType, targetId: string) => { + if (targetType === TargetType.Frame) { this.onShowLoadingAnimation(targetId); - } else { + } else { console.warn(`Loading animation for elements other than Frame are not supported`); - } + } } - public onHideLoadingAnimationRequested = (targetType: TargetType,targetId: string) => { + public onHideLoadingAnimationRequested = (targetType: TargetType, targetId: string) => { if (targetType === TargetType.Frame) { this.onHideLoadingAnimation(targetId); } else { From 089ff03551c29a48a9b25455b655ad37117c6620 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Wed, 19 Jun 2024 19:58:27 +0300 Subject: [PATCH 11/42] released 2.2.2 Signed-off-by: Svetozar Mateev --- assets/css/groups.css | 2 +- changelog.md | 4 ++++ package.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index f7ce32d..ec72617 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -1,5 +1,5 @@ @import "vars.css"; -@import "../../node_modules/overlayscrollbars/styles/overlayscrollbars.css"; +@import "overlayscrollbars/styles/overlayscrollbars.css"; * { box-sizing: border-box; diff --git a/changelog.md b/changelog.md index 990cf8e..f215c1d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,7 @@ +2.2.2 +fix: fixed the internal CSS import for the overflow tabs +2.2.1 +feat: added support for overflowing tabs 2.2.0 chore: official 9.3 support chore: updated the css file name in the readme diff --git a/package.json b/package.json index 68decfe..96e0017 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.2.0", + "version": "2.2.1", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io", From 1198ae56c35fffd4e8de641eaeb328d0a4256180 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Mon, 24 Jun 2024 15:27:09 +0300 Subject: [PATCH 12/42] released 2.2.2 Signed-off-by: Svetozar Mateev --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 96e0017..9a5a59b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.2.1", + "version": "2.2.2", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io", From 2058a947093bdeec93165b74929a7078ad6876d1 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Mon, 24 Jun 2024 15:54:05 +0300 Subject: [PATCH 13/42] G4E-7778 Added the parent element as prop to the custom tabs Signed-off-by: Svetozar Mateev --- src/GroupElementCreationWrapper.tsx | 1 + src/defaultComponents/tabs/Tab.tsx | 2 +- src/types/api.ts | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/GroupElementCreationWrapper.tsx b/src/GroupElementCreationWrapper.tsx index 77fa3c6..f47137d 100644 --- a/src/GroupElementCreationWrapper.tsx +++ b/src/GroupElementCreationWrapper.tsx @@ -385,6 +385,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { windowId={options.targetId} captionEditor={captionEditor} notifyCaptionBoundsChanged={notifyCaptionBoundsChanged} + parentElement={parentElement} /> }); diff --git a/src/defaultComponents/tabs/Tab.tsx b/src/defaultComponents/tabs/Tab.tsx index a52084d..dac0ff2 100644 --- a/src/defaultComponents/tabs/Tab.tsx +++ b/src/defaultComponents/tabs/Tab.tsx @@ -5,7 +5,7 @@ import TabCaption from "./TabCaption"; import TabCaptionEditor from "./TabCaptionEditor"; import TabCloseButton from "./TabCloseButton"; -const Tab: React.FC = ({ caption, selected, close, channels, captionEditor, notifyCaptionBoundsChanged, windowId }) => { +const Tab: React.FC> = ({ caption, selected, close, channels, captionEditor, notifyCaptionBoundsChanged, windowId }) => { return
        {channels.visible && } {captionEditor.show ? diff --git a/src/types/api.ts b/src/types/api.ts index d14b304..d5ed47c 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -117,6 +117,7 @@ export interface TabElementProps { channels: ChannelProps; notifyCaptionBoundsChanged: (bounds: Bounds) => void; captionEditor: CaptionEditorProps; + parentElement: HTMLElement; } export interface AfterTabsProps { From 441435a16fb19bc1532ae8f417c5233bab74b6da Mon Sep 17 00:00:00 2001 From: Plamen Petkov Date: Mon, 24 Jun 2024 16:02:25 +0300 Subject: [PATCH 14/42] update styles to match 2.1 with old look --- assets/css/groups.css | 235 ++++++++++++++++++++++-------------------- assets/css/vars.css | 95 ++++++++++------- 2 files changed, 180 insertions(+), 150 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index ec72617..51f87e7 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -1,10 +1,10 @@ -@import "vars.css"; @import "overlayscrollbars/styles/overlayscrollbars.css"; +@import "vars.css"; * { box-sizing: border-box; transition-timing-function: cubic-bezier(0.45, 0, 0.15, 1); - transition-duration: 250ms; + transition-duration: 240ms; transition-property: background-color, color; } @@ -12,43 +12,42 @@ body { max-width: none; max-height: none; overflow: hidden; - background-color: var(--t42-background); color: var(--t42-body-color); + background-color: var(--t42-background); } input { - font-family: var(--t42-font-family); - font-size: var(--t42-font-size); + font-family: var(--io-font-family); } #t42-group-container { display: flex; flex-direction: column; - overflow: hidden; width: 100%; - height: 100%; max-width: none; + height: 100%; max-height: none; - background-color: transparent; border-width: 0; + overflow: hidden; + background-color: transparent; /* DONT TOUCH THIS */ } #t42-frames-container { + position: relative; display: flex; flex-grow: 1; - position: relative; height: 100%; background-color: transparent; } .t42-caption-bar { + position: relative; display: flex; flex-direction: column; flex-grow: 0; flex-shrink: 0; overflow: hidden; - position: relative; } .t42-internal-caption-bar { @@ -60,51 +59,56 @@ input { flex-grow: 1; } -.t42-caption-bar:after { - width: 100%; +.t42-caption-bar::after { + position: absolute; + z-index: 1; display: block; + width: 100%; background-color: var(--t42-caption-separator-color); content: ""; - position: absolute; - z-index: 1; } .t42-caption { - overflow: hidden; align-items: center; + overflow: hidden; + font-size: var(--io-font-size); + line-height: var(--t42-line-height); white-space: nowrap; text-align: left; user-select: none; - font-size: var(--io-font-size); } .t42-caption-editor { display: inline-block; - color: var(--t42-caption-editor-color); - margin: var(--t42-caption-editor-margin); - border: var(--spacing-1) solid hsl(var(--io-interactive-primary)); - border-radius: var(--border-radius-4); - outline: none; min-width: 150px; + height: var(--t42-caption-editor-height); + margin: var(--t42-caption-editor-margin); padding: 0 var(--spacing-2) 0 var(--spacing-2); - white-space: nowrap; + border: var(--t42-caption-editor-border); + border-radius: var(--base-radius-default); overflow-x: hidden; + color: var(--t42-caption-editor-color); + font-size: var(--io-font-size); + white-space: nowrap; + outline: 0; } .t42-caption-editor.t42-group-caption-bar-element, .t42-caption-editor.t42-frame-caption-bar-element { margin: var(--t42-title-margin); + outline: 0; } .t42-title { - color: var(--t42-title-color); margin: var(--t42-title-margin); + color: var(--t42-title-color); + line-height: var(--t42-line-height); } .t42-move-area { - align-items: center; display: flex; flex-grow: 1; + align-items: center; min-width: var(--t42-move-area-min-width); } @@ -114,10 +118,10 @@ input { } .t42-html-buttons-container { - display: flex; position: absolute; - right: var(--spacing-4); top: var(--spacing-4); + right: var(--spacing-4); + display: flex; background-color: var(--t42-html-buttons-bar-background); } @@ -126,16 +130,16 @@ input { } .t42-html-buttons-bar-element { - background-color: var(--t42-html-buttons-bar-background); + background-color: var(--t42-html-buttons-bar-background); } .t42-buttons { display: flex; flex-shrink: 0; align-items: center; + margin: 0; + padding: 0; overflow: hidden; - margin: 0px; - padding: 0px; list-style-type: none; } @@ -150,21 +154,22 @@ input { } .t42-custom-button { - height: var(--t42-custom-button-size); + position: relative; width: var(--t42-custom-button-size); + height: var(--t42-custom-button-size); background-size: cover; - position: relative; } .t42-standard-button::before, .t42-tab-channel-selector-content::before, .t42-frame-channel-selector-content::before, .t42-tab-close-button-content::before { - align-items: center; display: flex; - font-family: "io-icons"; - font-size: var(--spacing-16); + align-items: center; justify-content: center; + font-size: var(--spacing-16); + font-family: "io-icons"; + transition-property: color; content: ""; } @@ -177,8 +182,8 @@ input { .t42-caption-bar-button-feedback, .t42-caption-bar-button-sticky, .t42-caption-bar-button-extract { - margin: var(--spacing-2) var(--spacing-2) 0 0; - border-radius: var(--border-radius-4); + margin: var(--t42-tab-bar-button-margin); + border-radius: var(--t42-tab-bar-button-radius); } .t42-caption-bar-button-lock .t42-standard-button::before, @@ -187,7 +192,7 @@ input { font-size: var(--spacing-14); } -.t42-caption-bar-button:hover .t42-standard-button-close:before { +.t42-caption-bar-button:hover .t42-standard-button-close::before { color: var(--t42-caption-bar-button-close-hover-text); } @@ -208,8 +213,9 @@ input { } .t42-tab-close-button-content::before { - height: var(--t42-tab-bar-tab-close-button-size); width: var(--t42-tab-bar-tab-close-button-size); + height: var(--t42-tab-bar-tab-close-button-size); + font-size: var(--t42-tab-bar-tab-close-button-size); } .t42-standard-button-restore::before { @@ -241,11 +247,11 @@ input { } .t42-standard-button-sticky::before { - content: var(--sticky-icon-off); display: block; - height: var(--spacing-14); width: var(--spacing-14); + height: var(--spacing-14); line-height: var(--spacing-14); + content: var(--sticky-icon-off); } .t42-caption-bar-button:hover .t42-standard-button-sticky::before { @@ -253,10 +259,10 @@ input { } .t42-caption-bar-button.active .t42-standard-button-sticky::before { - content: var(--sticky-icon-on); - height: var(--spacing-16); width: var(--spacing-16); - line-height: var(--spacing-16); + height: var(--spacing-16); + line-height: var(--t42-line-height); + content: var(--sticky-icon-on); } .t42-caption-bar-button.active:hover .t42-standard-button-sticky::before { @@ -265,8 +271,8 @@ input { .t42-tab-channel-selector-content::before, .t42-frame-channel-selector-content::before { + font-size: var(--spacing-14); content: "\e902"; - font-size: var(--spacing-16); } .t42-group-caption-bar { @@ -277,6 +283,10 @@ input { background-color: var(--t42-group-caption-background); } +.t42-group-caption-bar-element:focus-visible { + outline: 0; +} + .t42-group-caption-bar::after { bottom: 0; height: var(--t42-group-caption-separator-size); @@ -288,21 +298,21 @@ input { } .t42-frame { + position: absolute; display: flex; flex-direction: column; flex-grow: 0; flex-shrink: 0; - position: absolute; - overflow: hidden; - background-color: transparent; - border-style: solid; border-color: var(--t42-frame-border-color); + border-style: solid; border-width: var(--t42-frame-border-size); + overflow: hidden; + background-color: transparent; } .t42-frame-html { /* Don't touch this! We don't have borders for 'html' mode frames */ - border-width: 0px; + border-width: 0; } .t42-focused-frame { @@ -324,11 +334,11 @@ input { .t42-frame-channel-selector { align-self: center; - border-radius: var(--t42-frame-channel-selector-border-radius); + justify-content: center; width: var(--t42-frame-channel-selector-size); height: var(--t42-frame-channel-selector-size); margin: var(--t42-frame-channel-selector-margin); - justify-content: center; + border-radius: var(--t42-frame-channel-selector-border-radius); } .t42-frame-channel-selector-content { @@ -347,8 +357,8 @@ input { .t42-frame-window-container { display: flex; - flex-grow: 1; flex-direction: column; + flex-grow: 1; } .t42-frame-window { @@ -365,40 +375,41 @@ input { .t42-frame-window-footer { display: flex; - flex-grow: 0; flex-direction: column; + flex-grow: 0; background-color: var(--t42-background); } .t42-tab-bar { + position: relative; display: flex; flex-direction: column; - position: relative; } .t42-tab-bar::after { - display: block; - content: ""; position: absolute; - z-index: 1; - background-color: var(--t42-caption-separator-color); bottom: 0; - height: var(--t42-tab-bar-separator-size); + z-index: 1; + display: block; width: 100%; + height: var(--t42-tab-bar-separator-size); + background-color: var(--t42-caption-separator-color); + content: ""; } .t42-tab-bar-header { + position: relative; display: flex; flex-direction: row; flex-grow: 0; flex-shrink: 0; - overflow: hidden; - position: relative; height: var(--t42-tab-bar-height); + overflow: hidden; } .t42-tab-bar-element { background-color: var(--t42-tab-bar-background); + transition-property: background-color; } .t42-tab-bar-button { @@ -406,11 +417,10 @@ input { height: var(--t42-tab-bar-button-size); } - .t42-caption-bar-button { position: relative; - background-color: var(--t42-caption-bar-button-background); color: var(--t42-standard-button-color); + background-color: var(--t42-caption-bar-button-background); } .t42-caption-bar-button:hover { @@ -431,16 +441,15 @@ input { } .t42-tabs { + position: relative; display: flex; flex-direction: row; flex-grow: 0; flex-shrink: 1; + align-items: center; + padding: var(--t42-tab-bar-padding); overflow: hidden; list-style-type: none; - position: relative; - padding: 0px; - margin: 0px; - border-top-right-radius: var(--border-radius-4); -webkit-app-region: drag; } @@ -451,38 +460,38 @@ input { } .t42-tab { + position: relative; display: flex; flex-direction: row; flex-grow: 0; flex-shrink: 1; align-items: center; - position: relative; - padding: 0px var(--spacing-8); - margin-right: var(--spacing-2); - margin-top: var(--spacing-4); width: 150px; min-width: var(--t42-tab-bar-tab-min-width); max-width: var(--t42-tab-bar-tab-width); - background-color: var(--t42-tab-bar-tab-background); - border-top-right-radius: var(--spacing-4); + height: var(--t42-tab-bar-tab-height); + margin: var(--t42-tab-bar-tab-margin); + padding: var(--t42-tab-bar-tab-padding); + border-radius: var(--tabs-radius); border-top-left-radius: var(--spacing-4); - transition-property: padding; + border-top-right-radius: var(--spacing-4); + background-color: var(--t42-tab-bar-tab-background); container-type: size; -webkit-app-region: no-drag; } .t42-tab::before { - width: var(--t42-tab-bar-tab-separator-size); - height: var(--spacing-8); position: absolute; left: calc(var(--spacing-2) * -1); + z-index: 10; display: block; - transition: 0.3s; + width: var(--t42-tab-bar-tab-separator-size); + height: var(--t42-tab-bar-tab-separator-height); background-color: var(--t42-tab-bar-tab-separator-color); - content: ""; - z-index: 10; opacity: 1; + transition: 0.3s; transition-property: opacity; + content: ""; } .t42-tab:first-of-type::before { @@ -518,23 +527,28 @@ input { .t42-tab-caption-editor { min-width: unset; -webkit-mask-image: none; + height: var(--spacing-12); +} + +.t42-tab-caption-editor:focus-visible { + outline: 0; } .t42-tab-close-button { margin: var(--t42-tab-bar-tab-close-button-margin); - transition-property: margin; + transition-property: margin, background-color; } .t42-tab-close-button-content { display: flex; + align-items: center; + justify-content: center; width: calc(var(--t42-tab-bar-tab-close-button-size) + var(--t42-tab-bar-tab-close-button-padding) * 2); height: calc(var(--t42-tab-bar-tab-close-button-size) + var(--t42-tab-bar-tab-close-button-padding) * 2); border-radius: 50%; - background-color: transparent; - transition-property: background-color, fill; - justify-content: center; - align-items: center; - font-size: var(--spacing-14); + background-color: var(--t42-tab-bar-tab-close-button-background); + transition-duration: 80ms; + transition-property: background-color, fill, color; } .t42-tab-close-button-content svg { @@ -547,9 +561,8 @@ input { } .t42-tab-close-button-content:hover { + color: var(--t42-tab-bar-tab-text-hover); background-color: var(--t42-tab-bar-tab-close-button-bg-hover); - color: Hsl(var(--io-label-primary)); - } .t42-tab-close-button-content:hover .t42-standard-button-image { @@ -561,20 +574,20 @@ input { } .t42-selected-tab::before, -.t42-selected-tab+.t42-tab::before { +.t42-selected-tab + .t42-tab::before { opacity: 0; } .t42-selected-tab:hover::before { - width: calc(100% - var(--t42-tab-bar-tab-separator-size)); - height: var(--t42-tab-bar-tab-selected-separator-size); position: absolute; - left: 0px; - bottom: 0px; + bottom: 0; + left: 0; + z-index: 10; display: block; + width: calc(100% - var(--t42-tab-bar-tab-separator-size)); + height: var(--t42-tab-bar-tab-selected-separator-size); background-color: var(--t42-tab-bar-tab-selected-separator-color); content: ""; - z-index: 10; } .t42-selected-tab-caption { @@ -607,9 +620,9 @@ input { } .t42-approaching-edge { - display: block; position: absolute; z-index: 100; + display: block; background-color: var(--t42-approaching-edge-start-color); animation: approaching-edge-animation; animation-duration: var(--t42-approaching-edge-animation-duration); @@ -626,17 +639,17 @@ input { } .t42-sizing-border-group { - pointer-events: none; - list-style-type: none; + position: absolute; + z-index: 100; display: flex; - margin: 0px; - padding: 0px; flex-grow: 0; flex-shrink: 0; - position: absolute; + margin: 0; + padding: 0; overflow: hidden; - z-index: 100; + list-style-type: none; background-color: var(--t42-sizing-border-group-color); + pointer-events: none; } .t42-vertical-sizing-border-group { @@ -663,10 +676,10 @@ input { } .t42-sizing-border { - pointer-events: auto; - margin: 0px; - padding: 0px; flex-shrink: 0; + margin: 0; + padding: 0; + pointer-events: auto; } .t42-frame-sizing-border { @@ -708,21 +721,22 @@ input { .loader-wrapper { display: flex; - align-items: center; - justify-content: center; flex-direction: column; flex-grow: 1; gap: 1rem; + align-items: center; + justify-content: center; background: var(--t42-background); - } .loader-wrapper .loader { width: 2rem; height: 2rem; border-radius: 50%; - background: radial-gradient(farthest-side, #999d9e 94%, rgba(0, 0, 0, 0)) center top / 4px 4px no-repeat, conic-gradient(rgba(0, 0, 0, 0) 15%, #999d9e); - -webkit-mask: radial-gradient(farthest-side, rgba(0, 0, 0, 0) calc(100% - 4px), #000 0px); + background: + radial-gradient(farthest-side, #999d9e 94%, rgba(0, 0, 0, 0)) center top / 4px 4px no-repeat, + conic-gradient(rgba(0, 0, 0, 0) 15%, #999d9e); + -webkit-mask: radial-gradient(farthest-side, rgba(0, 0, 0, 0) calc(100% - 4px), #000000 0); } .loader-wrapper .loader-text { @@ -764,8 +778,8 @@ input { .t42-tab-flashing .t42-tab-bar-element, .t42-tab-flashing .t42-tab-caption { + color: var(--t42-tab-bar-tab-flashing-color); background-color: transparent; - color: var(--white); } @container (max-width: 50px) { @@ -773,7 +787,6 @@ input { width: 0; margin: 0; } - } @container (max-width: 40px) { @@ -825,6 +838,8 @@ input { align-items: center; height: var(--t42-wg-tab-over-item-height); padding: var(--t42-wg-tab-over-item-padding); + transition-property: background-color; + transition-duration: 80ms; } .t42-tab-overflow-popup li span { diff --git a/assets/css/vars.css b/assets/css/vars.css index 845f38e..4d3a1c5 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -1,62 +1,75 @@ @import "@interopio/theme/dist/io.platform.css"; :root { - --t42-body-color: hsl(var(--io-label-secondary)); + --t42-body-color: var(--tabs-color-default); + --t42-line-height: var(--spacing-16); --t42-title-margin: 0 0 0 var(--spacing-8); - --t42-title-color: Hsl(var(--io-label-primary)); + --t42-title-color: var(--tabs-color-active); --t42-caption-editor-margin: 0; - --t42-caption-editor-color: Hsl(var(--io-label-primary)); + --t42-caption-editor-color: var(--tabs-color-active); + --t42-caption-editor-border: 0; + --t42-caption-editor-height: var(--spacing-16); --t42-move-area-min-width: 30px; --t42-standard-button-size: 10px; - --t42-standard-button-color: hsl(var(--io-label-secondary)); - --t42-standard-button-hover-color: hsl(var(--io-label-primary)); + --t42-standard-button-color: var(--tabs-color-default); + --t42-standard-button-hover-color: var(--tabs-color-active); --t42-custom-button-size: 20px; - --t42-group-caption-background: Hsl(var(--io-bg-01)); + --t42-group-caption-background: var(--window-header-background); --t42-group-caption-height: 30px; --t42-group-caption-separator-size: 0; --t42-frame-border-size: 0; - --t42-frame-border-color: hsl(var(--io-border-secondary)); - --t42-focused-frame-border-color: hsl(var(--io-border-primary)); + --t42-frame-border-color: var(--base-surface-frame-border); + --t42-focused-frame-border-color: transparent; - --t42-frame-channel-selector-border-radius: var(--spacing-4); + --t42-frame-channel-selector-border-radius: var(--base-radius-default); --t42-frame-channel-selector-size: var(--spacing-16); --t42-frame-channel-selector-margin: 0 0 0 4px; + --t42-frame-caption-height: 30px; --t42-frame-caption-separator-size: 0; - --t42-frame-caption-background: Hsl(var(--io-bg-01)); + --t42-frame-caption-background: var(--window-header-background); - --t42-html-buttons-bar-background: Hsl(var(--io-bg-01)); + --t42-html-buttons-bar-background: var(--window-header-background); - --t42-tab-bar-height: 32px; + --t42-tab-bar-height: 32px; /* for 10.0 - 38px*/ --t42-tab-bar-button-size: 26px; + --t42-tab-bar-button-margin: var(--spacing-2) var(--spacing-2) 0 0; + --t42-tab-bar-button-radius: var(--spacing-4); /* for 10.0 - 50%; */ --t42-tab-bar-separator-size: 0; - --t42-tab-bar-background: Hsl(var(--io-bg-01)); - --t42-tab-bar-selected-tab-text: hsl(var(--io-label-primary)); - --t42-tab-bar-selected-tab-hover-text: hsl(var(--io-label-primary)); - --t42-tab-bar-selected-tab-hover-background: Hsl(var(--io-bg-02)); - - --t42-tab-bar-tab-min-width: 40px; + --t42-tab-bar-padding: 0; /* for 10.0 - 0 0 0 var(--spacing-6); */ + --t42-tab-bar-background: var(--window-header-background); + --t42-tab-bar-selected-tab-text: var(--tabs-color-active); + --t42-tab-bar-selected-tab-hover-text: var(--tabs-color-hover); + --t42-tab-bar-selected-tab-background: var(--window-tabs-background-active); + --t42-tab-bar-selected-tab-hover-background: var(--window-tabs-background-active); + + --t42-tab-bar-tab-height: 28px; /* for 10.0 - var(--spacing-24); */ + --t42-tab-bar-tab-min-width: 48px; --t42-tab-bar-tab-width: 150px; - --t42-tab-bar-tab-text: hsl(var(--io-label-secondary)); - --t42-tab-bar-tab-text-hover: hsl(var(--io-label-primary)); + --t42-tab-bar-tab-padding: 0 var(--spacing-8); + --t42-tab-bar-tab-margin: var(--spacing-4) var(--spacing-2) 0 0; /* for 10.0 - 0 var(--spacing-2) 0 0; */ + --t42-tab-bar-tab-text: var(--tabs-color-default); + --t42-tab-bar-tab-text-hover: var(--tabs-color-hover); --t42-tab-bar-tab-separator-size: 1px; - --t42-tab-bar-tab-separator-color: hsl(var(--io-border-primary)); - --t42-tab-bar-tab-selected-separator-color: hsl(var(--io-border-secondary)); + --t42-tab-bar-tab-separator-height: var(--spacing-8); /* for 10.0 - var(--spacing-12); */ + --t42-tab-bar-tab-separator-color: hsl(var(--io-border-primary)); /* for 10.0 - var(--base-border-separator); */ + --t42-tab-bar-tab-selected-separator-color: var(--window-tabs-background-active); /* bottom underline previous tab version */ --t42-tab-bar-tab-hover-separator-size: 3px; --t42-tab-bar-tab-selected-separator-size: 3px; - --t42-tab-bar-tab-background: Hsl(var(--io-bg-01)); - --t42-tab-bar-tab-hover-background: Hsl(var(--io-bg-02)); - --t42-tab-bar-tab-flashing-background: #de7337b0; + --t42-tab-bar-tab-background: transparent; + --t42-tab-bar-tab-hover-background: transparent; /* non used */ + --t42-tab-bar-tab-flashing-color: var(--io-neutrals-0); + --t42-tab-bar-tab-flashing-background:var(--severity-high); /* color-mix(in srgb, var(--severity-high) 65%, transparent); */ - --t42-tab-bar-tab-channels-border-radius: var(--border-radius-4); + --t42-tab-bar-tab-channels-border-radius: var(--base-radius-default); --t42-tab-bar-tab-channels-size: var(--spacing-16); --t42-tab-bar-tab-channels-margin: 0 var(--spacing-4) 0 0; --t42-tab-bar-tab-channels-content-size: 0; @@ -65,27 +78,28 @@ --t42-tab-bar-tab-close-button-size: 6px; --t42-tab-bar-tab-close-button-padding: 3px; - --t42-tab-bar-tab-close-button-margin: 0 0 0 var(--spacing-12); + --t42-tab-bar-tab-close-button-margin: 0 0 0 var(--spacing-8); --t42-tab-bar-tab-close-button-size: 10px; --t42-tab-bar-tab-close-button-padding: 3px; - --t42-tab-bar-tab-close-button-bg-hover: Hsl(var(--io-bg-03)); + --t42-tab-bar-tab-close-button-background: transparent; + --t42-tab-bar-tab-close-button-bg-hover: var(--icon-background-hover); --t42-approaching-edge-animation-duration: 0.5s; --t42-approaching-edge-size: 4px; - --t42-channels-fill-color: hsl(var(--io-label-primary)); + --t42-channels-fill-color: var(--tabs-color-active); - --t42-caption-separator-color: hsl(var(--io-border-secondary)); - --t42-caption-text-hover-color: hsl(var(--io-label-primary)); - --t42-caption-bar-button-width: 40px; + --t42-caption-separator-color: var(--tabs-border); + --t42-caption-text-hover-color: var(--tabs-color-hover); + --t42-caption-bar-button-width: 48px; --t42-caption-bar-button-background: transparent; - --t42-caption-bar-button-hover-background: hsl(var(--io-bg-02)); - --t42-caption-bar-button-close-hover-background: hsl(355 86% 49%); - --t42-caption-bar-button-close-hover-text: hsl(var(--io-white)); + --t42-caption-bar-button-hover-background:#37383a; /* for 10.0 var(--icon-background-hover); */ + --t42-caption-bar-button-close-hover-background: var(--io-red-700); + --t42-caption-bar-button-close-hover-text: var(--io-neutrals-0); --t42-caption-bar-button-correction: 6px; --t42-approaching-edge-start-color: #4b92fb; - --t42-approaching-edge-end-color: hsl(var(--io-highlight-Interactive)); + --t42-approaching-edge-end-color:var(--io-blue-700); --t42-sizing-border-group-color: hsl(var(--io-bg-01)); --t42-hover-sizing-border-group-color: hsl(var(--io-highlight-Interactive)); @@ -122,8 +136,7 @@ } .dark { - --t42-background: #26282a; - --t42-tab-bar-selected-tab-background: hsl(var(--io-bg-02)); + --t42-background: #28292b; /* for 10.0 - #3d3f43 */ --t42-wg-tab-over-background: #26282a; /* for 10.0 - var(--base-panel-background); */ --sticky-icon-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23afafaf' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,13.9L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,13.9z M6.5,0h-5 C0.7,0,0,0.7,0,1.5v5C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5 C7,6.8,6.8,7,6.5,7z M14.5,8h-5C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); @@ -133,9 +146,11 @@ } .light { - --t42-background: #e8e9ed; - --t42-tab-bar-selected-tab-background: hsl(var(--io-white)); + --t42-background: #e8e9ed; /* for 10.0 - #ffffff */ + /* for 10.0 - --t42-tab-bar-separator-size: 1px; */ + --t42-caption-bar-button-hover-background: #f0f1f4; /* remove for 10.0 */ --t42-wg-tab-over-background: #e8e9ed; /* for 10.0 - var(--base-panel-background); */ + --t42-tab-bar-tab-close-button-bg-hover: var(--io-neutrals-150); --sticky-icon-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16'%3E%3Cpath fill='%23626F81' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,13.9L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,13.9z M6.5,0h-5 C0.7,0,0,0.7,0,1.5v5C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5 C7,6.8,6.8,7,6.5,7z M14.5,8h-5C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); --sticky-icon-off-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 17'%3E%3Cpath fill='%231B6ADE' d='M11.3,3.8L9.5,5.6c-0.2,0.2-0.2,0.5,0,0.7s0.5,0.2,0.7,0L12,4.5c0.2-0.2,0.2-0.5,0-0.7 C11.8,3.6,11.5,3.6,11.3,3.8z M5.6,9.5l-1.8,1.8c-0.2,0.2-0.2,0.5,0,0.7c0.2,0.2,0.5,0.2,0.7,0l1.8-1.8c0.2-0.2,0.2-0.5,0-0.7 S5.8,9.3,5.6,9.5z'/%3E%3Cpath fill='%23626F81' d='M15.9,2L14,0.1c-0.2-0.2-0.5-0.1-0.6,0.2L13,2.6C13,2.8,13.2,3,13.4,3l2.3-0.4C16,2.6,16.1,2.3,15.9,2z M0.1,14 L2,15.9c0.2,0.2,0.5,0.1,0.6-0.2L3,13.4C3,13.2,2.8,13,2.6,13l-2.3,0.4C0,13.4-0.1,13.7,0.1,14z M6.5,0h-5C0.7,0,0,0.7,0,1.5v5 C0,7.3,0.7,8,1.5,8h5C7.3,8,8,7.3,8,6.5v-5C8,0.7,7.3,0,6.5,0z M6.5,7h-5C1.2,7,1,6.8,1,6.5V2h6v4.5C7,6.8,6.8,7,6.5,7z M14.5,8h-5 C8.7,8,8,8.7,8,9.5v5C8,15.3,8.7,16,9.5,16h5c0.8,0,1.5-0.7,1.5-1.5v-5C16,8.7,15.3,8,14.5,8z M14.5,15h-5C9.2,15,9,14.8,9,14.5V10 h6v4.5C15,14.8,14.8,15,14.5,15z'/%3E%3C/svg%3E%0A"); From 32e55b16eebaa464e82f2bfb388706d91ac1e961 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Mon, 24 Jun 2024 18:37:35 +0300 Subject: [PATCH 15/42] G4E-7778 Changed the parentElement to add/remove class methods Signed-off-by: Svetozar Mateev --- src/GroupElementCreationWrapper.tsx | 11 ++++++++++- src/types/api.ts | 3 ++- src/types/internal.ts | 3 +++ src/webGroupsManager.ts | 16 ++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/GroupElementCreationWrapper.tsx b/src/GroupElementCreationWrapper.tsx index f47137d..db6666d 100644 --- a/src/GroupElementCreationWrapper.tsx +++ b/src/GroupElementCreationWrapper.tsx @@ -378,6 +378,14 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { const notifyCaptionBoundsChanged = (bounds: Bounds) => webGroupsManager.onCaptionTextBoundsChanged(TargetType.Tab, options.targetId, bounds); + const addContainerClass = (className: string) => { + webGroupsManager.addTabContainerClass(options.targetId, className); + } + + const removeContainerClass = (className: string) => { + webGroupsManager.removeTabContainerClass(options.targetId, className); + } + return = ({ components }) => { windowId={options.targetId} captionEditor={captionEditor} notifyCaptionBoundsChanged={notifyCaptionBoundsChanged} - parentElement={parentElement} + addContainerClass={addContainerClass} + removeContainerClass={removeContainerClass} /> }); diff --git a/src/types/api.ts b/src/types/api.ts index d5ed47c..b804e20 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -117,7 +117,8 @@ export interface TabElementProps { channels: ChannelProps; notifyCaptionBoundsChanged: (bounds: Bounds) => void; captionEditor: CaptionEditorProps; - parentElement: HTMLElement; + addContainerClass: (className: string) => void; + removeContainerClass: (className: string) => void; } export interface AfterTabsProps { diff --git a/src/types/internal.ts b/src/types/internal.ts index cc3d9c4..6a99a45 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -301,6 +301,9 @@ export interface ExternalLibraryFactory { commitCaptionEditing(targetType: TargetType, targetId: string, text: string): void; selectTab(windowId: string): void; + + addTabContainerClass(windowId: string, className: string): void; + removeTabContainerClass(windowId: string, className: string): void; } export interface WebGroupsManager { diff --git a/src/webGroupsManager.ts b/src/webGroupsManager.ts index 254c16e..6500e76 100644 --- a/src/webGroupsManager.ts +++ b/src/webGroupsManager.ts @@ -162,6 +162,22 @@ class WebGroupsManagerDecorator { public selectTab(windowId: string): void { window.webGroupsManager.externalLibraryFactory.selectTab(windowId); } + + public addTabContainerClass(windowId: string, className: string): void { + if (typeof window.webGroupsManager.externalLibraryFactory.addTabContainerClass !== "function") { + console.warn("The method addTabContainerClass is not supported by the current version of the library"); + return; + } + window.webGroupsManager.externalLibraryFactory.addTabContainerClass(windowId, className); + } + + public removeTabContainerClass(windowId: string, className: string): void { + if (typeof window.webGroupsManager.externalLibraryFactory.removeTabContainerClass !== "function") { + console.warn("The method removeTabContainerClass is not supported by the current version of the library"); + return; + } + window.webGroupsManager.externalLibraryFactory.removeTabContainerClass(windowId, className); + } } export default new WebGroupsManagerDecorator(); \ No newline at end of file From d6fec4e862f76bdb5a8acde71422e767ccaf0de7 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Tue, 25 Jun 2024 18:12:05 +0300 Subject: [PATCH 16/42] Fixed the closeTab function in the tab overflow popup Signed-off-by: Svetozar Mateev --- src/GroupElementCreationWrapper.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GroupElementCreationWrapper.tsx b/src/GroupElementCreationWrapper.tsx index 77fa3c6..9352d24 100644 --- a/src/GroupElementCreationWrapper.tsx +++ b/src/GroupElementCreationWrapper.tsx @@ -536,7 +536,7 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { }; const close = (windowId: string) => { - webGroupsManager.onCloseButtonClick(TargetType.Tab, windowId); + webGroupsManager.closeTab(windowId); } return Date: Wed, 26 Jun 2024 12:36:04 +0300 Subject: [PATCH 17/42] G4E-7778 Cleanup Signed-off-by: Svetozar Mateev --- src/defaultComponents/tabs/Tab.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/defaultComponents/tabs/Tab.tsx b/src/defaultComponents/tabs/Tab.tsx index dac0ff2..a52084d 100644 --- a/src/defaultComponents/tabs/Tab.tsx +++ b/src/defaultComponents/tabs/Tab.tsx @@ -5,7 +5,7 @@ import TabCaption from "./TabCaption"; import TabCaptionEditor from "./TabCaptionEditor"; import TabCloseButton from "./TabCloseButton"; -const Tab: React.FC> = ({ caption, selected, close, channels, captionEditor, notifyCaptionBoundsChanged, windowId }) => { +const Tab: React.FC = ({ caption, selected, close, channels, captionEditor, notifyCaptionBoundsChanged, windowId }) => { return
        {channels.visible && } {captionEditor.show ? From ecd1d8e14cf27d9bbfd878aa021a016489d14930 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Thu, 27 Jun 2024 15:52:32 +0300 Subject: [PATCH 18/42] Released 2.2.4 Signed-off-by: Svetozar Mateev --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9a5a59b..4a11aec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.2.2", + "version": "2.2.4", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io", From bceb4b7755bbbbcb3586b9dadedec948b8617c4b Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Fri, 5 Jul 2024 15:28:19 +0300 Subject: [PATCH 19/42] G4E-8065 AfterTabs and TabHeaderButtons now receive the hiddenTabs props Signed-off-by: Svetozar Mateev --- src/index.tsx | 4 +++- src/types/api.ts | 18 +++++++++++++++--- src/types/internal.ts | 11 +++++++++-- src/webGroupsManager.ts | 10 +++++++++- src/webGroupsStore.ts | 21 +++++++++++++++++++-- 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index bbb0625..8e94264 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -71,6 +71,7 @@ import { GroupProps, HtmlButtonsProps, MoveAreaProps, + OpenTabOverflowPopupOptions, TabElementProps, TabHeaderButtonsProps, TabOverflowPopupProps, @@ -79,7 +80,7 @@ import { import GroupCaptionEditor from "./defaultComponents/groupCaptionBar/GroupCaptionEditor"; import FlatCaptionEditor from "./defaultComponents/flatCaptionBar/FlatCaptionEditor"; import TabCaptionEditor from "./defaultComponents/tabs/TabCaptionEditor"; -import { TargetType } from "./types/internal"; +import { Location, TargetType } from "./types/internal"; import useCommitTabCaptionEditingRequested from "./defaultComponents/tabs/useCommitTabCaptionEditingRequested"; import useCommitGroupCaptionEditingRequested from "./defaultComponents/groupCaptionBar/useCommitGroupCaptionEditingRequested"; import useCommitFlatCaptionEditingRequested from "./defaultComponents/flatCaptionBar/useCommitFlatCaptionEditingRequested"; @@ -136,6 +137,7 @@ export const getGroupId: () => string = () => webGroupsManager?.getGroupId(); export const requestPageFocus: () => void = () => webGroupsManager?.requestPageFocus(); export const requestFrameFocus: (frameId: string) => void = (frameId) => webGroupsManager?.requestFrameFocus(frameId); export const requestGroupFocus: () => void = () => webGroupsManager?.requestGroupFocus(); +export const openTabOverflowPopup: (options: OpenTabOverflowPopupOptions) => void = ({ frameId, location }: OpenTabOverflowPopupOptions) => webGroupsManager.openTabOverflowPopup(frameId, location); export const onCommitGroupCaptionEditingRequested = (targetId: string, cb: () => void) => webGroupsManager.onCommitCaptionEditingRequested(TargetType.Group, targetId, cb); export const onCommitFlatCaptionEditingRequested = (targetId: string, cb: () => void) => webGroupsManager.onCommitCaptionEditingRequested(TargetType.Frame, targetId, cb); diff --git a/src/types/api.ts b/src/types/api.ts index b804e20..9894864 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -1,5 +1,5 @@ import React from "react"; -import { Bounds, ButtonProps, OverflowedTabInfo, ToggleButtonProps } from "./internal"; +import { Bounds, ButtonProps, Location, OverflowedTabInfo, ToggleButtonProps } from "./internal"; import { CustomButtonProps } from "./defaultComponents"; export interface ChannelProps { @@ -124,9 +124,11 @@ export interface TabElementProps { export interface AfterTabsProps { frameId: string; selectedWindow: string; + hiddenTabsToTheLeft?: OverflowedTabInfo[]; + hiddenTabsToTheRight?: OverflowedTabInfo[]; } -export interface TabHeaderButtonsProps { +interface FrameButtonsProps { overflow?: ButtonProps; feedback?: ButtonProps; clone?: ButtonProps; @@ -143,7 +145,12 @@ export interface TabHeaderButtonsProps { selectedWindow: string; } -export interface HtmlButtonsProps extends TabHeaderButtonsProps { +export interface TabHeaderButtonsProps extends FrameButtonsProps { + hiddenTabsToTheLeft: OverflowedTabInfo[]; + hiddenTabsToTheRight: OverflowedTabInfo[]; +} + +export interface HtmlButtonsProps extends FrameButtonsProps { } export interface GroupProps { @@ -183,4 +190,9 @@ export interface MoveAreaProps { export interface GroupComponentVisibilityState { groupCaptionBarVisible?: boolean; +} + +export interface OpenTabOverflowPopupOptions { + frameId: string; + location: Location; } \ No newline at end of file diff --git a/src/types/internal.ts b/src/types/internal.ts index 6a99a45..9947b82 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -241,7 +241,10 @@ export interface CreateFrameLoadingAnimationRequestOptions extends CreateFrameEl show: boolean; } -export type UpdateFrameRequestOptions = CreateFrameElementRequestOptions; +export interface UpdateFrameRequestOptions extends CreateFrameElementRequestOptions { + hiddenTabsToTheLeft: OverflowedTabInfo[]; + hiddenTabsToTheRight: OverflowedTabInfo[]; +} export enum TargetType { Group = "group", @@ -301,6 +304,7 @@ export interface ExternalLibraryFactory { commitCaptionEditing(targetType: TargetType, targetId: string, text: string): void; selectTab(windowId: string): void; + openTabOverflowPopup(frameId: string, location: Location): void addTabContainerClass(windowId: string, className: string): void; removeTabContainerClass(windowId: string, className: string): void; @@ -322,7 +326,10 @@ export interface Size { height: number; } -export interface Bounds extends Size { +export interface Location { left: number; top: number; } + +export interface Bounds extends Size, Location { +} diff --git a/src/webGroupsManager.ts b/src/webGroupsManager.ts index 6500e76..e8f3148 100644 --- a/src/webGroupsManager.ts +++ b/src/webGroupsManager.ts @@ -1,4 +1,4 @@ -import { Bounds, StandardButtons, TargetType, WebGroupsManager } from "./types/internal"; +import { Bounds, Location, StandardButtons, TargetType, WebGroupsManager } from "./types/internal"; import callbackRegistry from "callback-registry"; declare const window: Window & { webGroupsManager: WebGroupsManager }; @@ -178,6 +178,14 @@ class WebGroupsManagerDecorator { } window.webGroupsManager.externalLibraryFactory.removeTabContainerClass(windowId, className); } + + public openTabOverflowPopup(frameId: string, location: Location): void { + if (typeof window.webGroupsManager.externalLibraryFactory.openTabOverflowPopup !== "function") { + console.warn("The method openTabOverflowPopup is not supported by the current version of the library"); + return; + } + window.webGroupsManager.externalLibraryFactory.openTabOverflowPopup(frameId, location); + } } export default new WebGroupsManagerDecorator(); \ No newline at end of file diff --git a/src/webGroupsStore.ts b/src/webGroupsStore.ts index 1853ce0..64a5ddc 100644 --- a/src/webGroupsStore.ts +++ b/src/webGroupsStore.ts @@ -14,7 +14,8 @@ import { UpdateFrameRequestOptions, CreateFrameLoadingAnimationRequestOptions, UpdateCustomButtonsRequestOptions, - CreateTabOverflowPopupRequestOptions + CreateTabOverflowPopupRequestOptions, + OverflowedTabInfo } from "./types/internal"; import webGroupsManager from "./webGroupsManager"; @@ -453,7 +454,20 @@ class WebGroupsStore { if (s[stateProp]![targetId] && s[stateProp]![targetId]?.selectedWindow !== selectedWindow) { newState[stateProp] = { ...s[stateProp], - [targetId]: { ...s[stateProp]![targetId], selectedWindow: selectedWindow } + [targetId]: { ...s[stateProp]![targetId], selectedWindow } + } + } + }; + + const updateHiddenTabs = (stateProp: T, targetId: string, hiddenTabsToTheLeft: OverflowedTabInfo[], hiddenTabsToTheRight: OverflowedTabInfo[]) => { + const oldHiddenToTheLeft = newState[stateProp]![targetId]?.hiddenTabsToTheLeft; + const oldHiddenToTheRight = newState[stateProp]![targetId]?.hiddenTabsToTheRight; + newState[stateProp] = { + ...s[stateProp], + [targetId]: { + ...s[stateProp]![targetId], + hiddenTabsToTheLeft: hiddenTabsToTheLeft || oldHiddenToTheLeft, + hiddenTabsToTheRight: hiddenTabsToTheRight || oldHiddenToTheRight } } }; @@ -470,6 +484,9 @@ class WebGroupsStore { updateSelectionWindow("belowTabsZones", options.targetId, options.selectedWindow); updateSelectionWindow("frameLoadingAnimations", options.targetId, options.selectedWindow); + updateHiddenTabs("afterTabsZones", options.targetId, options.hiddenTabsToTheLeft, options.hiddenTabsToTheRight); + updateHiddenTabs("tabHeaderButtons", options.targetId, options.hiddenTabsToTheLeft, options.hiddenTabsToTheRight); + return newState; }); } From 8f45314bf93a6e80987893f9fdfd34f31d6d2818 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Wed, 10 Jul 2024 12:16:12 +0300 Subject: [PATCH 20/42] G4E-8065 Styling improvements Signed-off-by: Svetozar Mateev --- assets/css/groups.css | 36 ++++++++++++++++++- assets/css/vars.css | 2 ++ .../popups/TabOverflowPopup.tsx | 5 ++- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index 51f87e7..5f7739c 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -814,6 +814,40 @@ input { overflow: auto; } +.t42-tabs-overflow.t42-tabs-fade-right { + -webkit-mask-image: linear-gradient( + -90deg, + rgba(0, 0, 0, 0) 0, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size) + ); +} + +.t42-tabs-overflow.t42-tabs-fade-left { + -webkit-mask-image: linear-gradient( + 90deg, + rgba(0, 0, 0, 0) 0, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size) + ); +} + +.t42-tabs-overflow.t42-tabs-fade-both { + -webkit-mask-image: linear-gradient( + 90deg, + rgba(0, 0, 0, 0) 0%, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size), + rgba(0, 0, 0, 1) calc(100% - var(--t42-tab-bar-fade-size)), + rgba(0, 0, 0, 0.8) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 80)), + rgba(0, 0, 0, 0.3) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 30)), + rgba(0, 0, 0, 0) 100% + ); +} + .t42-page-popup { position: absolute; z-index: 999; @@ -838,8 +872,8 @@ input { align-items: center; height: var(--t42-wg-tab-over-item-height); padding: var(--t42-wg-tab-over-item-padding); - transition-property: background-color; transition-duration: 80ms; + transition-property: background-color; } .t42-tab-overflow-popup li span { diff --git a/assets/css/vars.css b/assets/css/vars.css index 4d3a1c5..0c97e85 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -49,6 +49,7 @@ --t42-tab-bar-selected-tab-hover-text: var(--tabs-color-hover); --t42-tab-bar-selected-tab-background: var(--window-tabs-background-active); --t42-tab-bar-selected-tab-hover-background: var(--window-tabs-background-active); + --t42-tab-bar-fade-size: 24px; --t42-tab-bar-tab-height: 28px; /* for 10.0 - var(--spacing-24); */ --t42-tab-bar-tab-min-width: 48px; @@ -105,6 +106,7 @@ --t42-hover-sizing-border-group-color: hsl(var(--io-highlight-Interactive)); --t42-active-sizing-border-group-color: hsl(var(--io-interactive-primary)); + --t42-wg-tab-over-max-height: 100vh; --t42-wg-tab-over-max-width: 200px; --t42-wg-tab-over-min-width: 200px; diff --git a/src/defaultComponents/popups/TabOverflowPopup.tsx b/src/defaultComponents/popups/TabOverflowPopup.tsx index 4f6557e..7b836ed 100644 --- a/src/defaultComponents/popups/TabOverflowPopup.tsx +++ b/src/defaultComponents/popups/TabOverflowPopup.tsx @@ -15,7 +15,10 @@ const TabOverflowPopup: React.FC = ({ {tabs.map((tab) => (
      • handleTabClick(tab.windowId)}> {tab.title} -
        handleTabClose(tab.windowId)}>
        +
        { + e.stopPropagation(); + handleTabClose(tab.windowId) + }}>
      • ))}
      From dccb66eb9952905adb4a0b9107ad4d979c82cf93 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Fri, 12 Jul 2024 10:47:13 +0300 Subject: [PATCH 21/42] Fixed the state update for update frame Signed-off-by: Svetozar Mateev --- src/webGroupsStore.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/webGroupsStore.ts b/src/webGroupsStore.ts index 64a5ddc..1c2ec1a 100644 --- a/src/webGroupsStore.ts +++ b/src/webGroupsStore.ts @@ -451,10 +451,10 @@ class WebGroupsStore { return; } - if (s[stateProp]![targetId] && s[stateProp]![targetId]?.selectedWindow !== selectedWindow) { + if (newState[stateProp]![targetId] && newState[stateProp]![targetId]?.selectedWindow !== selectedWindow) { newState[stateProp] = { - ...s[stateProp], - [targetId]: { ...s[stateProp]![targetId], selectedWindow } + ...newState[stateProp], + [targetId]: { ...newState[stateProp]![targetId], selectedWindow } } } }; @@ -463,9 +463,9 @@ class WebGroupsStore { const oldHiddenToTheLeft = newState[stateProp]![targetId]?.hiddenTabsToTheLeft; const oldHiddenToTheRight = newState[stateProp]![targetId]?.hiddenTabsToTheRight; newState[stateProp] = { - ...s[stateProp], + ...newState[stateProp], [targetId]: { - ...s[stateProp]![targetId], + ...newState[stateProp]![targetId], hiddenTabsToTheLeft: hiddenTabsToTheLeft || oldHiddenToTheLeft, hiddenTabsToTheRight: hiddenTabsToTheRight || oldHiddenToTheRight } From 0708a68e14416da9aafeda7689a6d1dc9d1f896e Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Tue, 16 Jul 2024 11:11:56 +0300 Subject: [PATCH 22/42] Added the margin property for the tabs element Signed-off-by: Svetozar Mateev --- assets/css/groups.css | 50 ++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index 5f7739c..edc2c8a 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -448,6 +448,7 @@ input { flex-shrink: 1; align-items: center; padding: var(--t42-tab-bar-padding); + margin: 0px; overflow: hidden; list-style-type: none; -webkit-app-region: drag; @@ -574,7 +575,7 @@ input { } .t42-selected-tab::before, -.t42-selected-tab + .t42-tab::before { +.t42-selected-tab+.t42-tab::before { opacity: 0; } @@ -701,6 +702,7 @@ input { } @keyframes clipMe { + 0%, 100% { clip: rect(0, 25vh, 2px, 0); @@ -815,37 +817,31 @@ input { } .t42-tabs-overflow.t42-tabs-fade-right { - -webkit-mask-image: linear-gradient( - -90deg, - rgba(0, 0, 0, 0) 0, - rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), - rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), - rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size) - ); + -webkit-mask-image: linear-gradient(-90deg, + rgba(0, 0, 0, 0) 0, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size)); } .t42-tabs-overflow.t42-tabs-fade-left { - -webkit-mask-image: linear-gradient( - 90deg, - rgba(0, 0, 0, 0) 0, - rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), - rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), - rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size) - ); + -webkit-mask-image: linear-gradient(90deg, + rgba(0, 0, 0, 0) 0, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size)); } .t42-tabs-overflow.t42-tabs-fade-both { - -webkit-mask-image: linear-gradient( - 90deg, - rgba(0, 0, 0, 0) 0%, - rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), - rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), - rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size), - rgba(0, 0, 0, 1) calc(100% - var(--t42-tab-bar-fade-size)), - rgba(0, 0, 0, 0.8) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 80)), - rgba(0, 0, 0, 0.3) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 30)), - rgba(0, 0, 0, 0) 100% - ); + -webkit-mask-image: linear-gradient(90deg, + rgba(0, 0, 0, 0) 0%, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size), + rgba(0, 0, 0, 1) calc(100% - var(--t42-tab-bar-fade-size)), + rgba(0, 0, 0, 0.8) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 80)), + rgba(0, 0, 0, 0.3) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 30)), + rgba(0, 0, 0, 0) 100%); } .t42-page-popup { @@ -899,4 +895,4 @@ input { color: var(--t42-wg-tab-over-item-title-color); font-size: var(--t42-wg-tab-over-item-title-size); letter-spacing: var(--t42-wg-tab-over-item-title-spacing); -} +} \ No newline at end of file From ef72b2faffef1401086e3d14f3ab1753a9f1daa8 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Thu, 25 Jul 2024 13:37:32 +0300 Subject: [PATCH 23/42] Stopped the propagation of mouse events for the overflow button Signed-off-by: Svetozar Mateev --- src/defaultComponents/buttons/OverflowButton.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/defaultComponents/buttons/OverflowButton.tsx b/src/defaultComponents/buttons/OverflowButton.tsx index d357a9f..efaf6f5 100644 --- a/src/defaultComponents/buttons/OverflowButton.tsx +++ b/src/defaultComponents/buttons/OverflowButton.tsx @@ -5,7 +5,11 @@ import BaseButton from "./BaseButton"; const OverflowButton: React.FC = ({ onClick, tooltip }) => { return + outerElement={{ + onMouseDown: (e) => e.stopPropagation(), + onPointerDown: (e) => e.stopPropagation(), + className: "t42-button t42-caption-bar-button t42-tab-bar-button t42-caption-bar-button-overflow", title: tooltip, onClick + }} /> } export default OverflowButton; \ No newline at end of file From f12470caedd857b506d406e0ea66420f098cd470 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Thu, 8 Aug 2024 17:52:15 +0300 Subject: [PATCH 24/42] Release 2.2.8 Signed-off-by: Svetozar Mateev --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4a11aec..0fad097 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.2.4", + "version": "2.2.8", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io", From 234e5074e702971a9bac1361d28f761a5d3024c8 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Fri, 9 Aug 2024 12:47:01 +0300 Subject: [PATCH 25/42] G4E-6623 Added the isPinned flag to the tabs Signed-off-by: Svetozar Mateev --- assets/css/groups.css | 116 ++++++++++++++++++++--------- assets/css/vars.css | 5 ++ src/defaultComponents/tabs/Tab.tsx | 4 +- src/types/api.ts | 1 + src/types/internal.ts | 1 + 5 files changed, 91 insertions(+), 36 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index edc2c8a..0e6ddb1 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -440,7 +440,8 @@ input { height: var(--t42-tab-bar-height); } -.t42-tabs { +.t42-tabs, +.t42-tabs-pinned { position: relative; display: flex; flex-direction: row; @@ -448,7 +449,6 @@ input { flex-shrink: 1; align-items: center; padding: var(--t42-tab-bar-padding); - margin: 0px; overflow: hidden; list-style-type: none; -webkit-app-region: drag; @@ -478,7 +478,11 @@ input { border-top-right-radius: var(--spacing-4); background-color: var(--t42-tab-bar-tab-background); container-type: size; + container-name: normal-tabs; -webkit-app-region: no-drag; + /* transition-property: all; + transition-duration: 260ms; + transition-timing-function: ease-in-out; */ } .t42-tab::before { @@ -522,12 +526,12 @@ input { .t42-tab-caption { flex-grow: 1; color: var(--t42-tab-bar-tab-text); - -webkit-mask-image: linear-gradient(90deg, Hsl(var(--io-bg-00)) 75%, transparent); + mask-image: linear-gradient(90deg, Hsl(var(--io-bg-00)) 75%, transparent); } .t42-tab-caption-editor { min-width: unset; - -webkit-mask-image: none; + mask-image: none; height: var(--spacing-12); } @@ -575,7 +579,7 @@ input { } .t42-selected-tab::before, -.t42-selected-tab+.t42-tab::before { +.t42-selected-tab + .t42-tab::before { opacity: 0; } @@ -702,7 +706,6 @@ input { } @keyframes clipMe { - 0%, 100% { clip: rect(0, 25vh, 2px, 0); @@ -784,20 +787,20 @@ input { background-color: transparent; } -@container (max-width: 50px) { +@container normal-tabs (max-width: 50px) { .t42-tab-channel-selector { - width: 0; - margin: 0; + --t42-tab-bar-tab-channels-size:0; + --t42-tab-bar-tab-channels-margin: 0; } } -@container (max-width: 40px) { +@container normal-tabs (max-width: 40px) { .t42-tab-close-button { margin: auto; } } -@container (max-width: 30px) { +@container normal-tabs (max-width: 30px) { .t42-selected-tab-caption { flex-grow: 0; width: 0; @@ -817,31 +820,37 @@ input { } .t42-tabs-overflow.t42-tabs-fade-right { - -webkit-mask-image: linear-gradient(-90deg, - rgba(0, 0, 0, 0) 0, - rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), - rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), - rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size)); + -webkit-mask-image: linear-gradient( + -90deg, + rgba(0, 0, 0, 0) 0, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size) + ); } .t42-tabs-overflow.t42-tabs-fade-left { - -webkit-mask-image: linear-gradient(90deg, - rgba(0, 0, 0, 0) 0, - rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), - rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), - rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size)); + -webkit-mask-image: linear-gradient( + 90deg, + rgba(0, 0, 0, 0) 0, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size) + ); } .t42-tabs-overflow.t42-tabs-fade-both { - -webkit-mask-image: linear-gradient(90deg, - rgba(0, 0, 0, 0) 0%, - rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), - rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), - rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size), - rgba(0, 0, 0, 1) calc(100% - var(--t42-tab-bar-fade-size)), - rgba(0, 0, 0, 0.8) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 80)), - rgba(0, 0, 0, 0.3) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 30)), - rgba(0, 0, 0, 0) 100%); + -webkit-mask-image: linear-gradient( + 90deg, + rgba(0, 0, 0, 0) 0%, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size), + rgba(0, 0, 0, 1) calc(100% - var(--t42-tab-bar-fade-size)), + rgba(0, 0, 0, 0.8) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 80)), + rgba(0, 0, 0, 0.3) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 30)), + rgba(0, 0, 0, 0) 100% + ); } .t42-page-popup { @@ -850,7 +859,8 @@ input { margin-top: var(--t42-wg-tab-over-top-offset); } -.t42-tab-overflow-popup { +.t42-tab-overflow-popup, +.t42-tab-context-menu { display: flex; flex-direction: column; min-width: var(--t42-wg-tab-over-min-width); @@ -862,7 +872,8 @@ input { background-color: var(--t42-wg-tab-over-background); } -.t42-tab-overflow-popup li { +.t42-tab-overflow-popup li, +.t42-tab-context-menu li { display: flex; gap: var(--t42-wg-tab-over-item-gap); align-items: center; @@ -872,14 +883,16 @@ input { transition-property: background-color; } -.t42-tab-overflow-popup li span { +.t42-tab-overflow-popup li span, +.t42-tab-context-menu li span { flex-grow: 1; overflow: hidden; text-wrap: nowrap; text-overflow: clip; } -.t42-tab-overflow-popup li:not(.title):hover { +.t42-tab-overflow-popup li:not(.title):hover, +.t42-tab-context-menu li:not(.title):hover { color: var(--t42-wg-tab-over-item-color-hover); background-color: var(--t42-wg-tab-over-item-background-hover); } @@ -895,4 +908,39 @@ input { color: var(--t42-wg-tab-over-item-title-color); font-size: var(--t42-wg-tab-over-item-title-size); letter-spacing: var(--t42-wg-tab-over-item-title-spacing); +} + +.t42-tabs-pinned { + min-width: 0; + flex-shrink: 0; +} + +.t42-tabs-pinned .t42-tab { + --t42-tab-bar-tab-margin: var(--t42-wg-pin-tab-margin); + --t42-tab-bar-tab-height: var(--t42-wg-pin-tab-height); + border-radius: var(--t42-wg-pin-tab-border-radius); + width: var(--t42-wg-pin-tab-width); +} + +.t42-tabs-pinned .t42-tab-caption { + mask-image: none; +} + +.t42-tabs-pinned .t42-tab { + container-name: pinned; +} + +@container pinned (min-width:1px) { + .t42-tab-close-button { + background-color: transparent; + } +} + +.t42-tabs-pinned .t42-tab-fade, +.t42-tabs-overflow .t42-tab-fade { + overflow: hidden; + width: 0; + padding: 0; + min-width: 0; + margin: 0; } \ No newline at end of file diff --git a/assets/css/vars.css b/assets/css/vars.css index 0c97e85..b121cc5 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -124,6 +124,11 @@ --t42-wg-tab-over-separator-size: var(--spacing-1); --t42-wg-tab-over-separator-color: var(--base-border-separator); --t42-wg-tab-over-separator-space: var(--spacing-8) 0; + + --t42-wg-pin-tab-border-radius: var(--spacing-4); + --t42-wg-pin-tab-width: 120px; + --t42-wg-pin-tab-margin: var(--spacing-4); + --t42-wg-pin-tab-height: var(--spacing-24); } /* Scroll vars override */ diff --git a/src/defaultComponents/tabs/Tab.tsx b/src/defaultComponents/tabs/Tab.tsx index a52084d..8cc79f5 100644 --- a/src/defaultComponents/tabs/Tab.tsx +++ b/src/defaultComponents/tabs/Tab.tsx @@ -5,13 +5,13 @@ import TabCaption from "./TabCaption"; import TabCaptionEditor from "./TabCaptionEditor"; import TabCloseButton from "./TabCloseButton"; -const Tab: React.FC = ({ caption, selected, close, channels, captionEditor, notifyCaptionBoundsChanged, windowId }) => { +const Tab: React.FC = ({ caption, selected, close, channels, captionEditor, notifyCaptionBoundsChanged, windowId, pinned }) => { return
      {channels.visible && } {captionEditor.show ? : } - + {pinned ? <> : }
      }; diff --git a/src/types/api.ts b/src/types/api.ts index 9894864..b34fc4a 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -113,6 +113,7 @@ export interface TabElementProps { caption: string; selected: boolean; flashing: boolean; + pinned: boolean; close: () => void; channels: ChannelProps; notifyCaptionBoundsChanged: (bounds: Bounds) => void; diff --git a/src/types/internal.ts b/src/types/internal.ts index 9947b82..b30169c 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -134,6 +134,7 @@ export interface CreateTabRequestOptions extends CreateElementRequestOptions { caption: string; selected: boolean; flashing: boolean; + pinned: boolean; channelSelectorVisible: boolean; selectedChannel: string; selectedChannelColor: string; From 98a34f59fafd418c7c97ca6b5f67a1db4dab5236 Mon Sep 17 00:00:00 2001 From: Tsvetan Bratanov Date: Thu, 12 Sep 2024 16:46:51 +0300 Subject: [PATCH 26/42] G4E-7825: Channels || Title area should show channel selected as well as direction - Adding support for labels and channel directions based on channelRestrictions for webgroups --- assets/css/groups.css | 13 +++++++++-- assets/css/vars.css | 7 +++++- src/GroupElementCreationWrapper.tsx | 9 +++++--- .../channelSelector/BaseChannelSelector.tsx | 10 ++++++--- .../channelSelector/FlatChannelSelector.tsx | 9 +++++--- .../channelSelector/TabChannelSelector.tsx | 9 +++++--- .../channelSelector/utils.ts | 22 ++++++++++++++++++- .../flatCaptionBar/FlatCaptionBar.tsx | 5 ++++- src/types/api.ts | 5 +++++ src/types/defaultComponents.ts | 12 ++++++++++ src/types/internal.ts | 10 +++++++++ 11 files changed, 94 insertions(+), 17 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index edc2c8a..4105665 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -511,8 +511,8 @@ input { .t42-tab-channel-selector { justify-content: center; - width: var(--t42-tab-bar-tab-channels-size); - height: var(--t42-tab-bar-tab-channels-size); + width: var(--t42-tab-bar-tab-channels-width); + height: var(--t42-tab-bar-tab-channels-height); margin: var(--t42-tab-bar-tab-channels-margin); border-radius: var(--t42-tab-bar-tab-channels-border-radius); background-color: transparent; @@ -600,6 +600,15 @@ input { fill: var(--t42-tab-bar-selected-tab-text); } +.t42-channel-selector-direction { + width: var(--t42-channel-selector-direction-width); + height: var(--t42-channel-selector-direction-height); +} + +.t42-channel-selector-direction .icon { + gap: var(--t42-channel-selector-direction-gap); +} + .t42-channel-selector-content-light::before { color: hsl(var(--io-white)); transition-property: color; diff --git a/assets/css/vars.css b/assets/css/vars.css index 0c97e85..f0f0463 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -71,7 +71,8 @@ --t42-tab-bar-tab-flashing-background:var(--severity-high); /* color-mix(in srgb, var(--severity-high) 65%, transparent); */ --t42-tab-bar-tab-channels-border-radius: var(--base-radius-default); - --t42-tab-bar-tab-channels-size: var(--spacing-16); + --t42-tab-bar-tab-channels-width: var(--spacing-16); + --t42-tab-bar-tab-channels-height: var(--spacing-16); --t42-tab-bar-tab-channels-margin: 0 var(--spacing-4) 0 0; --t42-tab-bar-tab-channels-content-size: 0; --t42-tab-bar-tab-channels-content-margin: 0; @@ -90,6 +91,10 @@ --t42-channels-fill-color: var(--tabs-color-active); + --t42-channel-selector-direction-width: var(--spacing-24); + --t42-channel-selector-direction-height: var(--spacing-16); + --t42-channel-selector-direction-gap: var(--spacing-1); + --t42-caption-separator-color: var(--tabs-border); --t42-caption-text-hover-color: var(--tabs-color-hover); --t42-caption-bar-button-width: 48px; diff --git a/src/GroupElementCreationWrapper.tsx b/src/GroupElementCreationWrapper.tsx index d7be045..52bfd00 100644 --- a/src/GroupElementCreationWrapper.tsx +++ b/src/GroupElementCreationWrapper.tsx @@ -195,7 +195,9 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { showSelector, visible: options.channelSelectorVisible, selectedChannel: options.selectedChannel, - selectedChannelColor: options.selectedChannelColor + selectedChannelColor: options.selectedChannelColor, + channelRestrictions: options.channelRestrictions, + channelLabel: options.channelLabel } const captionEditor = { @@ -344,7 +346,6 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { const { parentElement, ...options } = te; - const onCloseClick = () => { webGroupsManager.closeTab(options.targetId); } @@ -357,7 +358,9 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { showSelector, visible: options.channelSelectorVisible, selectedChannel: options.selectedChannel, - selectedChannelColor: options.selectedChannelColor ?? options.selectedChannel // TODO remove the null check when the variable has been added + selectedChannelColor: options.selectedChannelColor ?? options.selectedChannel, // TODO remove the null check when the variable has been added + channelRestrictions: options.channelRestrictions, + channelLabel: options.channelLabel }; const captionEditor = { diff --git a/src/defaultComponents/channelSelector/BaseChannelSelector.tsx b/src/defaultComponents/channelSelector/BaseChannelSelector.tsx index eee6e8a..6cd7e84 100644 --- a/src/defaultComponents/channelSelector/BaseChannelSelector.tsx +++ b/src/defaultComponents/channelSelector/BaseChannelSelector.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useRef } from "react"; import { BaseChannelSelectorProps } from "../../types/defaultComponents"; import { IsBlackReadable } from "./utils"; -const BaseChannelSelector: React.FC = ({ outsideClass, contentClass, showSelector, selectedChannel, selectedChannelColor }) => { +const BaseChannelSelector: React.FC = ({ outsideClass, contentClass, showSelector, selectedChannel, selectedChannelColor, direction, channelLabel }) => { const ref = useRef(null); const wrappedOnClick = () => { if (!ref.current) { @@ -36,8 +36,12 @@ const BaseChannelSelector: React.FC = ({ outsideClass, return
      -
      -
      + {channelLabel ? +
      + {channelLabel} + {direction && } +
      :
      +
      }
      }; diff --git a/src/defaultComponents/channelSelector/FlatChannelSelector.tsx b/src/defaultComponents/channelSelector/FlatChannelSelector.tsx index 153fa2f..26d802d 100644 --- a/src/defaultComponents/channelSelector/FlatChannelSelector.tsx +++ b/src/defaultComponents/channelSelector/FlatChannelSelector.tsx @@ -1,13 +1,16 @@ import React from "react"; import { FlatChannelSelectorProps } from "../../types/defaultComponents"; import BaseChannelSelector from "./BaseChannelSelector"; +import { getChannelDirection } from "./utils"; -const FlatChannelSelector: React.FC = ({ showSelector, selectedChannel, selectedChannelColor }) => { - return = ({ showSelector, selectedChannel, selectedChannelColor, channelRestrictions, channelLabel }) => { + return }; diff --git a/src/defaultComponents/channelSelector/TabChannelSelector.tsx b/src/defaultComponents/channelSelector/TabChannelSelector.tsx index 92a51b1..c5c89e1 100644 --- a/src/defaultComponents/channelSelector/TabChannelSelector.tsx +++ b/src/defaultComponents/channelSelector/TabChannelSelector.tsx @@ -1,13 +1,16 @@ import React from "react"; import { TabChannelSelectorProps } from "../../types/defaultComponents"; import BaseChannelSelector from "./BaseChannelSelector"; +import { getChannelDirection } from "./utils"; -const TabChannelSelector: React.FC = ({ showSelector, selectedChannel, selectedChannelColor }) => { - return = ({ showSelector, selectedChannel, selectedChannelColor, channelRestrictions, channelLabel }) => { + return }; diff --git a/src/defaultComponents/channelSelector/utils.ts b/src/defaultComponents/channelSelector/utils.ts index e7e8a6d..9818753 100644 --- a/src/defaultComponents/channelSelector/utils.ts +++ b/src/defaultComponents/channelSelector/utils.ts @@ -23,4 +23,24 @@ export function IsBlackReadable(color: string) { console.error(`Error while checking readable color for '${color}'`, error); } return false; -} \ No newline at end of file +} + +export function getChannelDirection(channelRestrictions: { read: boolean, write: boolean }): string { + if (!channelRestrictions) { + return ""; + } + if (typeof channelRestrictions.read === "boolean" && typeof channelRestrictions.write === "boolean") { + if (channelRestrictions.read && channelRestrictions.write) { + return ""; + } + if (channelRestrictions.read) { + return "subscribe"; + } + if (channelRestrictions.write) { + return "publish" + } + return ""; + } else { + return ""; + } +}; \ No newline at end of file diff --git a/src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx b/src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx index ba21ec1..25c30a0 100644 --- a/src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx +++ b/src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx @@ -12,7 +12,10 @@ const FlatCaptionBar: React.FC = ({ moveAreaId, caption, ch {channels?.visible && } + selectedChannelColor={channels?.selectedChannelColor} + channelRestrictions={channels?.channelRestrictions} + channelLabel={channels?.channelLabel} + />} {captionEditor.show ? : } diff --git a/src/types/api.ts b/src/types/api.ts index 9894864..e842846 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -7,6 +7,11 @@ export interface ChannelProps { selectedChannel: string; showSelector: (bounds: Bounds) => void; selectedChannelColor: string; + channelRestrictions: { + read: boolean, + write: boolean + }; + channelLabel: string; } export interface FrameWindowOverlayProps { diff --git a/src/types/defaultComponents.ts b/src/types/defaultComponents.ts index 8131d45..104a2fc 100644 --- a/src/types/defaultComponents.ts +++ b/src/types/defaultComponents.ts @@ -70,18 +70,30 @@ export interface BaseChannelSelectorProps { contentClass: string; selectedChannel: string; selectedChannelColor: string; + direction: string; + channelLabel: string; } export interface FlatChannelSelectorProps { showSelector: (bounds: Bounds) => void; selectedChannel: string; selectedChannelColor: string; + channelRestrictions: { + read: boolean, + write: boolean + }; + channelLabel: string; } export interface TabChannelSelectorProps { showSelector: (bounds: Bounds) => void; selectedChannel: string; selectedChannelColor: string; + channelRestrictions: { + read: boolean, + write: boolean + }; + channelLabel: string; } export interface FlatCaptionEditorProps { diff --git a/src/types/internal.ts b/src/types/internal.ts index 9947b82..0278a3c 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -128,6 +128,11 @@ export interface CreateFrameCaptionBarRequestOptions extends CreateButtonsOption show: boolean; text?: string; }; + channelRestrictions: { + read: boolean, + write: boolean + }; + channelLabel: string; } export interface CreateTabRequestOptions extends CreateElementRequestOptions { @@ -141,6 +146,11 @@ export interface CreateTabRequestOptions extends CreateElementRequestOptions { show: boolean; text?: string; }; + channelRestrictions: { + read: boolean, + write: boolean + }; + channelLabel: string; } export interface UpdateStandardButtonRequestOptions extends CreateElementRequestOptions { From a5bc673f1a75d6db00200599f82b15b92b164da9 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Fri, 4 Oct 2024 12:00:28 +0300 Subject: [PATCH 27/42] Released 2.4.0 Signed-off-by: Svetozar Mateev --- changelog.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index f215c1d..c0d3294 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,9 @@ +2.4.0 +chore: official 9.5 support +2.3.1 +feat: pinned tabs support +2.3.0 +chore: official 9.4 support 2.2.2 fix: fixed the internal CSS import for the overflow tabs 2.2.1 diff --git a/package.json b/package.json index 0fad097..34986ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.2.8", + "version": "2.4.0", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io", From 344694ffeffabbda213b3f0fa4659f4e915bc118 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Fri, 4 Oct 2024 14:13:11 +0300 Subject: [PATCH 28/42] Released 2.4.1 Signed-off-by: Svetozar Mateev --- changelog.md | 2 ++ package.json | 2 +- src/types/internal.ts | 16 +++++++++------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/changelog.md b/changelog.md index c0d3294..266c51e 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,5 @@ +2.4.1 +feat: directional channels improvement 2.4.0 chore: official 9.5 support 2.3.1 diff --git a/package.json b/package.json index 34986ce..b3444e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.4.0", + "version": "2.4.1", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io", diff --git a/src/types/internal.ts b/src/types/internal.ts index 8d60d21..be7194f 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -129,9 +129,9 @@ export interface CreateFrameCaptionBarRequestOptions extends CreateButtonsOption text?: string; }; channelRestrictions: { - read: boolean, - write: boolean - }; + read: boolean, + write: boolean + }; channelLabel: string; } @@ -148,9 +148,9 @@ export interface CreateTabRequestOptions extends CreateElementRequestOptions { text?: string; }; channelRestrictions: { - read: boolean, - write: boolean - }; + read: boolean, + write: boolean + }; channelLabel: string; } @@ -217,7 +217,9 @@ export interface CreateButtonsOptions extends CreateFrameElementRequestOptions { tooltip: string; visible: boolean; }; - customButtons: UpdateCustomButtonOptions[] + customButtons: UpdateCustomButtonOptions[], + hiddenTabsToTheLeft: OverflowedTabInfo[]; + hiddenTabsToTheRight: OverflowedTabInfo[]; } export interface RemoveRequestOptions { From 2fdcb1337d35a83c1dc59ec1d6c4a568d937491e Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Wed, 16 Oct 2024 11:19:16 +0300 Subject: [PATCH 29/42] done --- assets/css/groups.css | 44 +- assets/css/vars.css | 21 +- src/GroupElementCreationWrapper.tsx | 11 +- .../channelSelector/BaseChannelSelector.tsx | 11 +- .../multi/BaseMultiChannelSelector.tsx | 62 +++ .../multi/FlatMultiChannelSelector.tsx | 13 + .../multi/TabMultiChannelSelector.tsx | 13 + .../flatCaptionBar/FlatCaptionBar.tsx | 10 +- src/defaultComponents/tabs/Tab.tsx | 6 +- src/index.tsx | 388 +++++++++--------- src/types/defaultComponents.ts | 19 +- src/types/internal.ts | 4 + 12 files changed, 392 insertions(+), 210 deletions(-) create mode 100644 src/defaultComponents/channelSelector/multi/BaseMultiChannelSelector.tsx create mode 100644 src/defaultComponents/channelSelector/multi/FlatMultiChannelSelector.tsx create mode 100644 src/defaultComponents/channelSelector/multi/TabMultiChannelSelector.tsx diff --git a/assets/css/groups.css b/assets/css/groups.css index edc2c8a..32b7942 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -895,4 +895,46 @@ input { color: var(--t42-wg-tab-over-item-title-color); font-size: var(--t42-wg-tab-over-item-title-size); letter-spacing: var(--t42-wg-tab-over-item-title-spacing); -} \ No newline at end of file +} + +.t42-multi-channel-selector-content { + width: var(--t42-tab-bar-tab-channels-size); + height: var(--t42-tab-bar-tab-channels-size); + border-radius: var(--t42-tab-bar-tab-channels-border-radius); +} + +.t42-multi-channel-selector-2 { + background-image: conic-gradient( + var(--t42-multi-channel-selector-2-color-1) 0deg, + var(--t42-multi-channel-selector-2-color-1) 180deg, + var(--t42-multi-channel-selector-2-color-2) 180deg, + var(--t42-multi-channel-selector-2-color-2) 0deg + ); + mask-image: var(--t42-multi-channel-selector-2-mask); +} + +.t42-multi-channel-selector-3 { + background-image: conic-gradient( + var(--t42-multi-channel-selector-3-color-1) 0deg, + var(--t42-multi-channel-selector-3-color-1) 120deg, + var(--t42-multi-channel-selector-3-color-2) 120deg, + var(--t42-multi-channel-selector-3-color-2) 240deg, + var(--t42-multi-channel-selector-3-color-3) 240deg, + var(--t42-multi-channel-selector-3-color-3) 0deg + ); + mask-image: var(--t42-multi-channel-selector-3-mask); +} + +.t42-multi-channel-selector-4 { + background-image: conic-gradient( + var(--t42-multi-channel-selector-4-color-1) 0deg, + var(--t42-multi-channel-selector-4-color-1) 90deg, + var(--t42-multi-channel-selector-4-color-2) 90deg, + var(--t42-multi-channel-selector-4-color-2) 180deg, + var(--t42-multi-channel-selector-4-color-3) 180deg, + var(--t42-multi-channel-selector-4-color-3) 270deg, + var(--t42-multi-channel-selector-4-color-4) 270deg, + var(--t42-multi-channel-selector-4-color-4) 0deg + ); + mask-image: var(--t42-multi-channel-selector-4-mask); +} diff --git a/assets/css/vars.css b/assets/css/vars.css index 0c97e85..7cd7ed2 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -51,11 +51,11 @@ --t42-tab-bar-selected-tab-hover-background: var(--window-tabs-background-active); --t42-tab-bar-fade-size: 24px; - --t42-tab-bar-tab-height: 28px; /* for 10.0 - var(--spacing-24); */ + --t42-tab-bar-tab-height: 28px; /* for 10.0 - var(--spacing-24); */ --t42-tab-bar-tab-min-width: 48px; --t42-tab-bar-tab-width: 150px; --t42-tab-bar-tab-padding: 0 var(--spacing-8); - --t42-tab-bar-tab-margin: var(--spacing-4) var(--spacing-2) 0 0; /* for 10.0 - 0 var(--spacing-2) 0 0; */ + --t42-tab-bar-tab-margin: var(--spacing-4) var(--spacing-2) 0 0; /* for 10.0 - 0 var(--spacing-2) 0 0; */ --t42-tab-bar-tab-text: var(--tabs-color-default); --t42-tab-bar-tab-text-hover: var(--tabs-color-hover); --t42-tab-bar-tab-separator-size: 1px; @@ -68,7 +68,7 @@ --t42-tab-bar-tab-background: transparent; --t42-tab-bar-tab-hover-background: transparent; /* non used */ --t42-tab-bar-tab-flashing-color: var(--io-neutrals-0); - --t42-tab-bar-tab-flashing-background:var(--severity-high); /* color-mix(in srgb, var(--severity-high) 65%, transparent); */ + --t42-tab-bar-tab-flashing-background:var(--severity-high); /* color-mix(in srgb, var(--severity-high) 65%, transparent); */ --t42-tab-bar-tab-channels-border-radius: var(--base-radius-default); --t42-tab-bar-tab-channels-size: var(--spacing-16); @@ -106,7 +106,7 @@ --t42-hover-sizing-border-group-color: hsl(var(--io-highlight-Interactive)); --t42-active-sizing-border-group-color: hsl(var(--io-interactive-primary)); - + --t42-wg-tab-over-max-height: 100vh; --t42-wg-tab-over-max-width: 200px; --t42-wg-tab-over-min-width: 200px; @@ -124,6 +124,19 @@ --t42-wg-tab-over-separator-size: var(--spacing-1); --t42-wg-tab-over-separator-color: var(--base-border-separator); --t42-wg-tab-over-separator-space: var(--spacing-8) 0; + + --t42-multi-channel-selector-2-color-1: var(--channels-blue); + --t42-multi-channel-selector-2-color-2: var(--channels-red); + --t42-multi-channel-selector-2-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 16 16'%3E%3Crect width='7.5' height='16'/%3E%3Crect x='8.5' width='7.5' height='16'/%3E%3C/svg%3E"); + --t42-multi-channel-selector-3-color-1: var(--channels-blue); + --t42-multi-channel-selector-3-color-2: var(--channels-red); + --t42-multi-channel-selector-3-color-3: var(--channels-orange); + --t42-multi-channel-selector-3-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 16 16'%3E%3Crect fill='none' width='16' height='16' rx='4' ry='4'/%3E%3Cpath fill='%23000000' d='M16,11.6v-7.6c0-2.2-1.8-4-4-4h-3.5v7.3l7.5,4.3Z'/%3E%3Cpath fill='%23000000' d='M7.5,0h-3.5C1.8,0,0,1.8,0,4v7.9l7.5-4.3V0Z'/%3E%3Cpath fill='%23000000' d='M.1,12.9c.4,1.8,2,3.1,3.9,3.1h8c2,0,3.6-1.4,3.9-3.2l-7.7-4.5L.1,12.9Z'/%3E%3C/svg%3E"); + --t42-multi-channel-selector-4-color-1: var(--channels-blue); + --t42-multi-channel-selector-4-color-2: var(--channels-red); + --t42-multi-channel-selector-4-color-3: var(--channels-orange); + --t42-multi-channel-selector-4-color-4: var(--channels-magenta); + --t42-multi-channel-selector-4-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 16 16'%3E%3Crect width='7.5' height='7.5'/%3E%3Crect x='8.5' width='7.5' height='7.5'/%3E%3Crect x='8.5' y='8.5' width='7.5' height='7.5'/%3E%3Crect y='8.5' width='7.5' height='7.5'/%3E%3C/svg%3E"); } /* Scroll vars override */ diff --git a/src/GroupElementCreationWrapper.tsx b/src/GroupElementCreationWrapper.tsx index d7be045..4e6032b 100644 --- a/src/GroupElementCreationWrapper.tsx +++ b/src/GroupElementCreationWrapper.tsx @@ -10,7 +10,6 @@ import webGroupsStore from "./webGroupsStore"; import FrameLoadingAnimation from "./defaultComponents/loadingAnimation/FrameLoadingAnimation"; const GroupElementCreationWrapper: React.FC = ({ components }) => { - const state = useSyncExternalStore(webGroupsStore.subscribe, webGroupsStore.getSnapshot); const LoadingAnimation = components?.frame?.LoadingAnimation ?? FrameLoadingAnimation; @@ -195,7 +194,9 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { showSelector, visible: options.channelSelectorVisible, selectedChannel: options.selectedChannel, - selectedChannelColor: options.selectedChannelColor + selectedChannelColor: options.selectedChannelColor, + channelsMode: options.channelsMode ?? "single", + selectedChannels : options.selectedChannels } const captionEditor = { @@ -357,7 +358,9 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { showSelector, visible: options.channelSelectorVisible, selectedChannel: options.selectedChannel, - selectedChannelColor: options.selectedChannelColor ?? options.selectedChannel // TODO remove the null check when the variable has been added + selectedChannelColor: options.selectedChannelColor ?? options.selectedChannel, // TODO remove the null check when the variable has been added + channelsMode: options.channelsMode ?? "single", + selectedChannels: options.selectedChannels }; const captionEditor = { @@ -757,4 +760,4 @@ const GroupElementCreationWrapper: React.FC = ({ components }) => { } -export default GroupElementCreationWrapper; \ No newline at end of file +export default GroupElementCreationWrapper; diff --git a/src/defaultComponents/channelSelector/BaseChannelSelector.tsx b/src/defaultComponents/channelSelector/BaseChannelSelector.tsx index eee6e8a..c58f003 100644 --- a/src/defaultComponents/channelSelector/BaseChannelSelector.tsx +++ b/src/defaultComponents/channelSelector/BaseChannelSelector.tsx @@ -18,9 +18,14 @@ const BaseChannelSelector: React.FC = ({ outsideClass, } useEffect(() => { - ref.current?.addEventListener("mousedown", (e) => { + const handler = (e: MouseEvent) => { e.stopPropagation(); - }); + }; + const current = ref.current; + current?.addEventListener("mousedown", handler); + return ()=> { + current?.removeEventListener("mousedown", handler); + } }, [ref]); let className = contentClass; @@ -41,4 +46,4 @@ const BaseChannelSelector: React.FC = ({ outsideClass,
      }; -export default BaseChannelSelector; \ No newline at end of file +export default BaseChannelSelector; diff --git a/src/defaultComponents/channelSelector/multi/BaseMultiChannelSelector.tsx b/src/defaultComponents/channelSelector/multi/BaseMultiChannelSelector.tsx new file mode 100644 index 0000000..aeeb6e1 --- /dev/null +++ b/src/defaultComponents/channelSelector/multi/BaseMultiChannelSelector.tsx @@ -0,0 +1,62 @@ +import React, { useEffect, useRef } from "react"; +import { BaseMultiChannelSelectorProps } from "../../../types/defaultComponents"; +import BaseChannelSelector from "../BaseChannelSelector"; + +const BaseMultiChannelSelector: React.FC = ({ outsideClass, contentClass, showSelector, selectedChannels }) => { + + const ref = useRef(null); + const wrappedOnClick = () => { + if (!ref.current) { + return; + } + + const bounds = ref.current.getBoundingClientRect(); + showSelector({ + left: bounds.left, + top: bounds.top, + width: bounds.width, + height: bounds.height, + }); + } + + useEffect(() => { + const handler = (e: MouseEvent) => { + e.stopPropagation(); + }; + const current = ref.current; + ref.current?.addEventListener("mousedown", handler); + return ()=> { + current?.removeEventListener("mousedown", handler); + } + }); + + const len = selectedChannels.length; + + if (len < 2) { + return ; + } + + const colors = selectedChannels.map((channel) => channel.color) ?? []; + const title = colors.join(", "); + const lenMax4 = Math.min(len, 4); + const cssClass = `t42-multi-channel-selector-content t42-multi-channel-selector-${lenMax4}`; + let style: any = {}; + colors.forEach((color: string, index: number) => { + const colorVarName = `--t42-multi-channel-selector-${lenMax4}-color-${index + 1}`; + style[colorVarName] = color; + }); + + return ( +
      +
      +
      +
      + ); +}; + +export default BaseMultiChannelSelector; diff --git a/src/defaultComponents/channelSelector/multi/FlatMultiChannelSelector.tsx b/src/defaultComponents/channelSelector/multi/FlatMultiChannelSelector.tsx new file mode 100644 index 0000000..1aee058 --- /dev/null +++ b/src/defaultComponents/channelSelector/multi/FlatMultiChannelSelector.tsx @@ -0,0 +1,13 @@ +import React from "react"; +import { FlatMultiChannelSelectorProps } from "../../../types/defaultComponents"; +import BaseMultiChannelSelector from "./BaseMultiChannelSelector"; + +const FlatMultiChannelSelector: React.FC = ({ showSelector, selectedChannels }) => { + return +}; + +export default FlatMultiChannelSelector; diff --git a/src/defaultComponents/channelSelector/multi/TabMultiChannelSelector.tsx b/src/defaultComponents/channelSelector/multi/TabMultiChannelSelector.tsx new file mode 100644 index 0000000..2f94b67 --- /dev/null +++ b/src/defaultComponents/channelSelector/multi/TabMultiChannelSelector.tsx @@ -0,0 +1,13 @@ +import React from "react"; +import { TabMultiChannelSelectorProps } from "../../../types/defaultComponents"; +import BaseMultiChannelSelector from "./BaseMultiChannelSelector"; + +const TabMultiChannelSelector: React.FC = ({ showSelector, selectedChannels }) => { + return +}; + +export default TabMultiChannelSelector; diff --git a/src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx b/src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx index ba21ec1..3672ddd 100644 --- a/src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx +++ b/src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx @@ -5,14 +5,18 @@ import FlatButtons from "./FlatButtons"; import FlatCaption from "./FlatCaption"; import FlatCaptionEditor from "./FlatCaptionEditor"; import FlatMoveArea from "./FlatMoveArea"; +import FlatMultiChannelSelector from "../channelSelector/multi/FlatMultiChannelSelector"; const FlatCaptionBar: React.FC = ({ moveAreaId, caption, channels, captionEditor, notifyCaptionBoundsChanged, ...rest }) => { return ( -
      - {channels?.visible && + {channels?.visible && channels.channelsMode !== "multi" && } + {channels?.visible && channels.channelsMode === "multi" && } {captionEditor.show ? : } @@ -20,4 +24,4 @@ const FlatCaptionBar: React.FC = ({ moveAreaId, caption, ch
      ); }; -export default FlatCaptionBar; \ No newline at end of file +export default FlatCaptionBar; diff --git a/src/defaultComponents/tabs/Tab.tsx b/src/defaultComponents/tabs/Tab.tsx index a52084d..be9f119 100644 --- a/src/defaultComponents/tabs/Tab.tsx +++ b/src/defaultComponents/tabs/Tab.tsx @@ -1,13 +1,15 @@ import React from "react"; import { TabElementProps } from "../../types/api"; import TabChannelSelector from "../channelSelector/TabChannelSelector"; +import TabMultiChannelSelector from "../channelSelector/multi/FlatMultiChannelSelector"; import TabCaption from "./TabCaption"; import TabCaptionEditor from "./TabCaptionEditor"; import TabCloseButton from "./TabCloseButton"; const Tab: React.FC = ({ caption, selected, close, channels, captionEditor, notifyCaptionBoundsChanged, windowId }) => { return
      - {channels.visible && } + {channels.visible && channels.channelsMode !== "multi" && } + {channels.visible && channels.channelsMode === "multi" && } {captionEditor.show ? : } @@ -15,4 +17,4 @@ const Tab: React.FC = ({ caption, selected, close, channels, ca
      }; -export default Tab; \ No newline at end of file +export default Tab; diff --git a/src/index.tsx b/src/index.tsx index 8e94264..d482108 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,192 +1,196 @@ -import CloseButton from "./defaultComponents/buttons/CloseButton"; -import FlatCaptionBar from "./defaultComponents/flatCaptionBar/FlatCaptionBar"; -import GroupCaptionBar from "./defaultComponents/groupCaptionBar/GroupCaptionBar"; -import MaximizeButton from "./defaultComponents/buttons/MaximizeButton"; -import MinimizeButton from "./defaultComponents/buttons/MinimizeButton"; -import Tab from "./defaultComponents/tabs/Tab"; -import TabHeaderButtons from "./defaultComponents/tabs/TabHeaderButtons"; -import TabCaption from "./defaultComponents/tabs/TabCaption"; -import TabCloseButton from "./defaultComponents/tabs/TabCloseButton"; -import GroupElementCreationWrapper from "./GroupElementCreationWrapper"; -import webGroupsManager from "./webGroupsManager"; -import GroupMoveArea from "./defaultComponents/groupCaptionBar/GroupMoveArea"; -import GroupButtons from "./defaultComponents/groupCaptionBar/GroupButtons"; -import FlatMoveArea from "./defaultComponents/flatCaptionBar/FlatMoveArea"; -import FlatButtons from "./defaultComponents/flatCaptionBar/FlatButtons"; -import FlatCaption from "./defaultComponents/flatCaptionBar/FlatCaption"; -import GroupCaption from "./defaultComponents/groupCaptionBar/GroupCaption"; -import FlatChannelSelector from "./defaultComponents/channelSelector/FlatChannelSelector"; -import TabChannelSelector from "./defaultComponents/channelSelector/TabChannelSelector"; -import RestoreButton from "./defaultComponents/buttons/RestoreButton"; -import LockButton from "./defaultComponents/buttons/LockButtons"; -import UnlockButton from "./defaultComponents/buttons/UnlockButton"; -import ExtractButton from "./defaultComponents/buttons/ExtractButton"; -import FeedbackButton from "./defaultComponents/buttons/FeedbackButton"; -import CloneButton from "./defaultComponents/buttons/CloneButton"; -import StickyButton from "./defaultComponents/buttons/StickyButton"; -import OverflowButton from "./defaultComponents/buttons/OverflowButton"; -import useIOConnectWindow from "./useIOConnectWindow"; -import CustomButton from "./defaultComponents/buttons/CustomButton"; -import { waitForWindow } from "./utils"; -import useGroupComponentVisibility from "./useGroupComponentVisibility"; -import { - CloseButtonProps, - ExtractButtonProps, - StickyButtonProps, - FeedbackButtonProps, - FlatButtonsProps, - FlatCaptionEditorProps, - FlatCaptionProps, - FlatChannelSelectorProps, - FlatMoveAreaProps, - GroupButtonsProps, - GroupCaptionEditorProps, - GroupMoveAreaProps, - LockButtonProps, - MaximizeButtonProps, - MinimizeButtonProps, - RestoreButtonProps, - TabCaptionEditorProps, - TabCaptionProps, - TabChannelSelectorProps, - TabCloseButtonProps, - UnlockButtonProps, - UseCaptionEditorOptions, - UseEditableCaptionOptions, - OverflowButtonProps -} from "./types/defaultComponents"; -import { - AboveTabsProps, - AboveWindowProps, - AfterTabsProps, - BeforeTabsProps, - BelowTabsProps, - BelowWindowProps, - FlatCaptionBarProps, - FrameLoadingAnimationProps, - FrameWindowOverlayProps, - GroupCaptionBarProps, - GroupComponentVisibilityState, - GroupOverlayProps, - GroupProps, - HtmlButtonsProps, - MoveAreaProps, - OpenTabOverflowPopupOptions, - TabElementProps, - TabHeaderButtonsProps, - TabOverflowPopupProps, - WindowContentOverlayProps, -} from "./types/api"; -import GroupCaptionEditor from "./defaultComponents/groupCaptionBar/GroupCaptionEditor"; -import FlatCaptionEditor from "./defaultComponents/flatCaptionBar/FlatCaptionEditor"; -import TabCaptionEditor from "./defaultComponents/tabs/TabCaptionEditor"; -import { Location, TargetType } from "./types/internal"; -import useCommitTabCaptionEditingRequested from "./defaultComponents/tabs/useCommitTabCaptionEditingRequested"; -import useCommitGroupCaptionEditingRequested from "./defaultComponents/groupCaptionBar/useCommitGroupCaptionEditingRequested"; -import useCommitFlatCaptionEditingRequested from "./defaultComponents/flatCaptionBar/useCommitFlatCaptionEditingRequested"; -import useEditableCaption from "./defaultComponents/captionEditor/useEditableCaption"; -import useCaptionEditor from "./defaultComponents/captionEditor/useCaptionEditor"; -import FrameLoadingAnimation from "./defaultComponents/loadingAnimation/FrameLoadingAnimation"; -import HtmlButtons from "./defaultComponents/htmlButtonsBar/buttons"; -import TabOverflowPopup from "./defaultComponents/popups/TabOverflowPopup"; - -export { - GroupCaptionBar, - GroupMoveArea, - GroupButtons, - GroupCaptionEditor, - Tab, - TabChannelSelector, - TabCaption, - TabCloseButton, - TabCaptionEditor, - FeedbackButton, - CloneButton, - StickyButton, - ExtractButton, - LockButton, - UnlockButton, - MinimizeButton, - RestoreButton, - MaximizeButton, - CustomButton, - CloseButton, - FlatCaptionBar, - FlatChannelSelector, - FlatCaption, - FlatMoveArea, - FlatButtons, - FlatCaptionEditor, - TabHeaderButtons, - FrameLoadingAnimation, - HtmlButtons, - TabOverflowPopup, - OverflowButton, - GroupComponentVisibilityState, - useIOConnectWindow, - useGroupComponentVisibility, - waitForWindow, - useEditableCaption, - useCaptionEditor, - useCommitGroupCaptionEditingRequested, - useCommitFlatCaptionEditingRequested, - useCommitTabCaptionEditingRequested, -} - -export const getGroupId: () => string = () => webGroupsManager?.getGroupId(); -export const requestPageFocus: () => void = () => webGroupsManager?.requestPageFocus(); -export const requestFrameFocus: (frameId: string) => void = (frameId) => webGroupsManager?.requestFrameFocus(frameId); -export const requestGroupFocus: () => void = () => webGroupsManager?.requestGroupFocus(); -export const openTabOverflowPopup: (options: OpenTabOverflowPopupOptions) => void = ({ frameId, location }: OpenTabOverflowPopupOptions) => webGroupsManager.openTabOverflowPopup(frameId, location); - -export const onCommitGroupCaptionEditingRequested = (targetId: string, cb: () => void) => webGroupsManager.onCommitCaptionEditingRequested(TargetType.Group, targetId, cb); -export const onCommitFlatCaptionEditingRequested = (targetId: string, cb: () => void) => webGroupsManager.onCommitCaptionEditingRequested(TargetType.Frame, targetId, cb); -export const onCommitTabCaptionEditingRequested = (targetId: string, cb: () => void) => webGroupsManager.onCommitCaptionEditingRequested(TargetType.Tab, targetId, cb); - -export { - MoveAreaProps, - GroupProps, - GroupCaption, - GroupCaptionBarProps, - GroupMoveAreaProps, - GroupOverlayProps, - GroupButtonsProps, - GroupCaptionEditorProps, - TabElementProps, - TabChannelSelectorProps, - TabCaptionProps, - TabCloseButtonProps, - TabHeaderButtonsProps, - TabCaptionEditorProps, - HtmlButtonsProps, - FlatCaptionBarProps, - FlatCaptionProps, - FrameWindowOverlayProps, - FlatMoveAreaProps, - FlatChannelSelectorProps, - FlatButtonsProps, - FlatCaptionEditorProps, - OverflowButtonProps, - StickyButtonProps, - FeedbackButtonProps, - ExtractButtonProps, - LockButtonProps, - UnlockButtonProps, - MinimizeButtonProps, - MaximizeButtonProps, - RestoreButtonProps, - CloseButtonProps, - FrameLoadingAnimationProps, - UseCaptionEditorOptions, - UseEditableCaptionOptions, - AboveWindowProps, - BelowWindowProps, - AboveTabsProps, - BelowTabsProps, - BeforeTabsProps, - AfterTabsProps, - WindowContentOverlayProps, - TabOverflowPopupProps, -} - -export default GroupElementCreationWrapper; +import CloseButton from "./defaultComponents/buttons/CloseButton"; +import FlatCaptionBar from "./defaultComponents/flatCaptionBar/FlatCaptionBar"; +import GroupCaptionBar from "./defaultComponents/groupCaptionBar/GroupCaptionBar"; +import MaximizeButton from "./defaultComponents/buttons/MaximizeButton"; +import MinimizeButton from "./defaultComponents/buttons/MinimizeButton"; +import Tab from "./defaultComponents/tabs/Tab"; +import TabHeaderButtons from "./defaultComponents/tabs/TabHeaderButtons"; +import TabCaption from "./defaultComponents/tabs/TabCaption"; +import TabCloseButton from "./defaultComponents/tabs/TabCloseButton"; +import GroupElementCreationWrapper from "./GroupElementCreationWrapper"; +import webGroupsManager from "./webGroupsManager"; +import GroupMoveArea from "./defaultComponents/groupCaptionBar/GroupMoveArea"; +import GroupButtons from "./defaultComponents/groupCaptionBar/GroupButtons"; +import FlatMoveArea from "./defaultComponents/flatCaptionBar/FlatMoveArea"; +import FlatButtons from "./defaultComponents/flatCaptionBar/FlatButtons"; +import FlatCaption from "./defaultComponents/flatCaptionBar/FlatCaption"; +import GroupCaption from "./defaultComponents/groupCaptionBar/GroupCaption"; +import FlatChannelSelector from "./defaultComponents/channelSelector/FlatChannelSelector"; +import TabChannelSelector from "./defaultComponents/channelSelector/TabChannelSelector"; +import RestoreButton from "./defaultComponents/buttons/RestoreButton"; +import LockButton from "./defaultComponents/buttons/LockButtons"; +import UnlockButton from "./defaultComponents/buttons/UnlockButton"; +import ExtractButton from "./defaultComponents/buttons/ExtractButton"; +import FeedbackButton from "./defaultComponents/buttons/FeedbackButton"; +import CloneButton from "./defaultComponents/buttons/CloneButton"; +import StickyButton from "./defaultComponents/buttons/StickyButton"; +import OverflowButton from "./defaultComponents/buttons/OverflowButton"; +import useIOConnectWindow from "./useIOConnectWindow"; +import CustomButton from "./defaultComponents/buttons/CustomButton"; +import { waitForWindow } from "./utils"; +import useGroupComponentVisibility from "./useGroupComponentVisibility"; +import { + CloseButtonProps, + ExtractButtonProps, + StickyButtonProps, + FeedbackButtonProps, + FlatButtonsProps, + FlatCaptionEditorProps, + FlatCaptionProps, + FlatChannelSelectorProps, + FlatMoveAreaProps, + GroupButtonsProps, + GroupCaptionEditorProps, + GroupMoveAreaProps, + LockButtonProps, + MaximizeButtonProps, + MinimizeButtonProps, + RestoreButtonProps, + TabCaptionEditorProps, + TabCaptionProps, + TabChannelSelectorProps, + TabCloseButtonProps, + UnlockButtonProps, + UseCaptionEditorOptions, + UseEditableCaptionOptions, + OverflowButtonProps +} from "./types/defaultComponents"; +import { + AboveTabsProps, + AboveWindowProps, + AfterTabsProps, + BeforeTabsProps, + BelowTabsProps, + BelowWindowProps, + FlatCaptionBarProps, + FrameLoadingAnimationProps, + FrameWindowOverlayProps, + GroupCaptionBarProps, + GroupComponentVisibilityState, + GroupOverlayProps, + GroupProps, + HtmlButtonsProps, + MoveAreaProps, + OpenTabOverflowPopupOptions, + TabElementProps, + TabHeaderButtonsProps, + TabOverflowPopupProps, + WindowContentOverlayProps, +} from "./types/api"; +import GroupCaptionEditor from "./defaultComponents/groupCaptionBar/GroupCaptionEditor"; +import FlatCaptionEditor from "./defaultComponents/flatCaptionBar/FlatCaptionEditor"; +import TabCaptionEditor from "./defaultComponents/tabs/TabCaptionEditor"; +import { Location, TargetType } from "./types/internal"; +import useCommitTabCaptionEditingRequested from "./defaultComponents/tabs/useCommitTabCaptionEditingRequested"; +import useCommitGroupCaptionEditingRequested from "./defaultComponents/groupCaptionBar/useCommitGroupCaptionEditingRequested"; +import useCommitFlatCaptionEditingRequested from "./defaultComponents/flatCaptionBar/useCommitFlatCaptionEditingRequested"; +import useEditableCaption from "./defaultComponents/captionEditor/useEditableCaption"; +import useCaptionEditor from "./defaultComponents/captionEditor/useCaptionEditor"; +import FrameLoadingAnimation from "./defaultComponents/loadingAnimation/FrameLoadingAnimation"; +import HtmlButtons from "./defaultComponents/htmlButtonsBar/buttons"; +import TabOverflowPopup from "./defaultComponents/popups/TabOverflowPopup"; +import TabMultiChannelSelector from "./defaultComponents/channelSelector/multi/TabMultiChannelSelector"; +import FlatMultiChannelSelector from "./defaultComponents/channelSelector/multi/FlatMultiChannelSelector"; + +export { + GroupCaptionBar, + GroupMoveArea, + GroupButtons, + GroupCaptionEditor, + Tab, + TabChannelSelector, + TabCaption, + TabCloseButton, + TabCaptionEditor, + FeedbackButton, + CloneButton, + StickyButton, + ExtractButton, + LockButton, + UnlockButton, + MinimizeButton, + RestoreButton, + MaximizeButton, + CustomButton, + CloseButton, + FlatCaptionBar, + FlatChannelSelector, + FlatCaption, + FlatMoveArea, + FlatButtons, + FlatCaptionEditor, + TabHeaderButtons, + FrameLoadingAnimation, + HtmlButtons, + TabOverflowPopup, + OverflowButton, + GroupComponentVisibilityState, + TabMultiChannelSelector, + FlatMultiChannelSelector, + useIOConnectWindow, + useGroupComponentVisibility, + waitForWindow, + useEditableCaption, + useCaptionEditor, + useCommitGroupCaptionEditingRequested, + useCommitFlatCaptionEditingRequested, + useCommitTabCaptionEditingRequested, +} + +export const getGroupId: () => string = () => webGroupsManager?.getGroupId(); +export const requestPageFocus: () => void = () => webGroupsManager?.requestPageFocus(); +export const requestFrameFocus: (frameId: string) => void = (frameId) => webGroupsManager?.requestFrameFocus(frameId); +export const requestGroupFocus: () => void = () => webGroupsManager?.requestGroupFocus(); +export const openTabOverflowPopup: (options: OpenTabOverflowPopupOptions) => void = ({ frameId, location }: OpenTabOverflowPopupOptions) => webGroupsManager.openTabOverflowPopup(frameId, location); + +export const onCommitGroupCaptionEditingRequested = (targetId: string, cb: () => void) => webGroupsManager.onCommitCaptionEditingRequested(TargetType.Group, targetId, cb); +export const onCommitFlatCaptionEditingRequested = (targetId: string, cb: () => void) => webGroupsManager.onCommitCaptionEditingRequested(TargetType.Frame, targetId, cb); +export const onCommitTabCaptionEditingRequested = (targetId: string, cb: () => void) => webGroupsManager.onCommitCaptionEditingRequested(TargetType.Tab, targetId, cb); + +export { + MoveAreaProps, + GroupProps, + GroupCaption, + GroupCaptionBarProps, + GroupMoveAreaProps, + GroupOverlayProps, + GroupButtonsProps, + GroupCaptionEditorProps, + TabElementProps, + TabChannelSelectorProps, + TabCaptionProps, + TabCloseButtonProps, + TabHeaderButtonsProps, + TabCaptionEditorProps, + HtmlButtonsProps, + FlatCaptionBarProps, + FlatCaptionProps, + FrameWindowOverlayProps, + FlatMoveAreaProps, + FlatChannelSelectorProps, + FlatButtonsProps, + FlatCaptionEditorProps, + OverflowButtonProps, + StickyButtonProps, + FeedbackButtonProps, + ExtractButtonProps, + LockButtonProps, + UnlockButtonProps, + MinimizeButtonProps, + MaximizeButtonProps, + RestoreButtonProps, + CloseButtonProps, + FrameLoadingAnimationProps, + UseCaptionEditorOptions, + UseEditableCaptionOptions, + AboveWindowProps, + BelowWindowProps, + AboveTabsProps, + BelowTabsProps, + BeforeTabsProps, + AfterTabsProps, + WindowContentOverlayProps, + TabOverflowPopupProps, +} + +export default GroupElementCreationWrapper; diff --git a/src/types/defaultComponents.ts b/src/types/defaultComponents.ts index 8131d45..bbade4f 100644 --- a/src/types/defaultComponents.ts +++ b/src/types/defaultComponents.ts @@ -72,18 +72,35 @@ export interface BaseChannelSelectorProps { selectedChannelColor: string; } +export interface BaseMultiChannelSelectorProps { + showSelector: (bounds: Bounds) => void; + outsideClass: string; + contentClass: string; + selectedChannels: { name: string; color: string }[]; +} + export interface FlatChannelSelectorProps { showSelector: (bounds: Bounds) => void; selectedChannel: string; selectedChannelColor: string; } +export interface FlatMultiChannelSelectorProps { + showSelector: (bounds: Bounds) => void; + selectedChannels: { name: string; color: string }[]; +} + export interface TabChannelSelectorProps { showSelector: (bounds: Bounds) => void; selectedChannel: string; selectedChannelColor: string; } +export interface TabMultiChannelSelectorProps { + showSelector: (bounds: Bounds) => void; + selectedChannels: { name: string; color: string }[]; +} + export interface FlatCaptionEditorProps { frameId: string; commitChanges: (title: string) => void; @@ -162,4 +179,4 @@ export interface UseCaptionEditorOptions { export interface UseEditableCaptionOptions { notifyBoundsChanged?: (bounds: Bounds) => void; -} \ No newline at end of file +} diff --git a/src/types/internal.ts b/src/types/internal.ts index 9947b82..03e1c06 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -128,6 +128,8 @@ export interface CreateFrameCaptionBarRequestOptions extends CreateButtonsOption show: boolean; text?: string; }; + channelsMode: "single" | "multi"; + selectedChannels: { name: string; color: string }[]; } export interface CreateTabRequestOptions extends CreateElementRequestOptions { @@ -141,6 +143,8 @@ export interface CreateTabRequestOptions extends CreateElementRequestOptions { show: boolean; text?: string; }; + channelsMode: "single" | "multi"; + selectedChannels: { name: string; color: string }[]; } export interface UpdateStandardButtonRequestOptions extends CreateElementRequestOptions { From 81fbbd95b1e69349b14f044f3522ccc35e3af76a Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Thu, 17 Oct 2024 08:05:46 +0300 Subject: [PATCH 30/42] fixed typo in a className --- src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx b/src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx index 637c8aa..c3f331a 100644 --- a/src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx +++ b/src/defaultComponents/flatCaptionBar/FlatCaptionBar.tsx @@ -9,7 +9,7 @@ import FlatMultiChannelSelector from "../channelSelector/multi/FlatMultiChannelS const FlatCaptionBar: React.FC = ({ moveAreaId, caption, channels, captionEditor, notifyCaptionBoundsChanged, ...rest }) => { return ( -
      +
      {channels?.visible && channels.channelsMode !== "multi" && Date: Thu, 17 Oct 2024 14:48:34 +0300 Subject: [PATCH 31/42] G4E-7825-Channels-Title-area-should-show-channel-selected-as-well-as-direction - Reverting changes to return old theme (2.1.6 rather than 2.2.6) --- assets/css/groups.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/css/groups.css b/assets/css/groups.css index 4105665..bd485c3 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -609,11 +609,13 @@ input { gap: var(--t42-channel-selector-direction-gap); } +.t42-channel-selector-content-light, .t42-channel-selector-content-light::before { color: hsl(var(--io-white)); transition-property: color; } +.t42-channel-selector-content-dark, .t42-channel-selector-content-dark::before { color: hsl(var(--io-black)); transition-property: color; From 8c2ddafa80c1e62af3c069dd23e3c8af787b847c Mon Sep 17 00:00:00 2001 From: Tsvetan Bratanov Date: Fri, 18 Oct 2024 13:03:12 +0300 Subject: [PATCH 32/42] G4E-7825-Channels-Title-area-should-show-channel-selected-as-well-as-direction - Fixing additional styling issues --- assets/css/groups.css | 30 +++++++++++++------ .../channelSelector/BaseChannelSelector.tsx | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index bd485c3..a4ce393 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -5,7 +5,13 @@ box-sizing: border-box; transition-timing-function: cubic-bezier(0.45, 0, 0.15, 1); transition-duration: 240ms; - transition-property: background-color, color; + transition-property: background-color; +} + +*::before, +*::after { + transition-timing-function: cubic-bezier(0.45, 0, 0.15, 1); + transition-duration: 240ms; } body { @@ -548,8 +554,7 @@ input { height: calc(var(--t42-tab-bar-tab-close-button-size) + var(--t42-tab-bar-tab-close-button-padding) * 2); border-radius: 50%; background-color: var(--t42-tab-bar-tab-close-button-background); - transition-duration: 80ms; - transition-property: background-color, fill, color; + transition-property: fill, color; } .t42-tab-close-button-content svg { @@ -566,6 +571,10 @@ input { background-color: var(--t42-tab-bar-tab-close-button-bg-hover); } +.t42-tab-close-button-content:hover::before { + color: var(--t42-tab-bar-tab-text-hover); +} + .t42-tab-close-button-content:hover .t42-standard-button-image { fill: var(--t42-tab-bar-tab-text-hover); } @@ -601,24 +610,27 @@ input { } .t42-channel-selector-direction { - width: var(--t42-channel-selector-direction-width); + width: auto; + min-width: var(--t42-tab-bar-tab-channels-width); height: var(--t42-channel-selector-direction-height); + gap: var(--t42-channel-selector-direction-gap); } .t42-channel-selector-direction .icon { gap: var(--t42-channel-selector-direction-gap); + width: var(--t42-channel-selector-direction-width); } .t42-channel-selector-content-light, -.t42-channel-selector-content-light::before { +.t42-channel-selector-content-light::before, +.t42-channel-selector-content-light i::before { color: hsl(var(--io-white)); - transition-property: color; } .t42-channel-selector-content-dark, -.t42-channel-selector-content-dark::before { +.t42-channel-selector-content-dark::before, +.t42-channel-selector-content-dark i::before { color: hsl(var(--io-black)); - transition-property: color; } @keyframes approaching-edge-animation { @@ -906,4 +918,4 @@ input { color: var(--t42-wg-tab-over-item-title-color); font-size: var(--t42-wg-tab-over-item-title-size); letter-spacing: var(--t42-wg-tab-over-item-title-spacing); -} \ No newline at end of file +} diff --git a/src/defaultComponents/channelSelector/BaseChannelSelector.tsx b/src/defaultComponents/channelSelector/BaseChannelSelector.tsx index 6cd7e84..0504e77 100644 --- a/src/defaultComponents/channelSelector/BaseChannelSelector.tsx +++ b/src/defaultComponents/channelSelector/BaseChannelSelector.tsx @@ -37,7 +37,7 @@ const BaseChannelSelector: React.FC = ({ outsideClass, style={style} onClick={wrappedOnClick} className={`t42-buttons ${outsideClass}`} > {channelLabel ? -
      +
      {channelLabel} {direction && }
      :
      From d8c0a60964a04bf032c348b4b5acc21a6bd3c94b Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Sun, 20 Oct 2024 08:31:32 +0300 Subject: [PATCH 33/42] update css --- assets/css/groups.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index 964cdf9..f80a184 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -622,7 +622,7 @@ input { .t42-channel-selector-direction .icon { gap: var(--t42-channel-selector-direction-gap); - width: var(--t42-channel-selector-direction-width); + width: var(--t42-channel-selector-direction-width); } .t42-channel-selector-content-light, @@ -969,8 +969,8 @@ input { } .t42-multi-channel-selector-content { - width: var(--t42-tab-bar-tab-channels-size); - height: var(--t42-tab-bar-tab-channels-size); + width: var(--t42-tab-bar-tab-channels-width); + height: var(--t42-tab-bar-tab-channels-height); border-radius: var(--t42-tab-bar-tab-channels-border-radius); } From 1434dd67417cd261308a0d9636de35dda77562d8 Mon Sep 17 00:00:00 2001 From: Tsvetan Bratanov Date: Tue, 29 Oct 2024 12:11:00 +0200 Subject: [PATCH 34/42] Revert "Merge remote-tracking branch 'origin' into G4E-7825-Channels-Title-area-should-show-channel-selected-as-well-as-direction" This reverts commit 4428e3c290c55c1b441bd6697479e42db801ddfb, reversing changes made to 8c2ddafa80c1e62af3c069dd23e3c8af787b847c. --- assets/css/groups.css | 116 +++++++++-------------------- assets/css/vars.css | 5 -- changelog.md | 6 -- package.json | 2 +- src/defaultComponents/tabs/Tab.tsx | 4 +- src/types/api.ts | 1 - src/types/internal.ts | 1 - 7 files changed, 37 insertions(+), 98 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index a8878c0..a4ce393 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -446,8 +446,7 @@ input { height: var(--t42-tab-bar-height); } -.t42-tabs, -.t42-tabs-pinned { +.t42-tabs { position: relative; display: flex; flex-direction: row; @@ -455,6 +454,7 @@ input { flex-shrink: 1; align-items: center; padding: var(--t42-tab-bar-padding); + margin: 0px; overflow: hidden; list-style-type: none; -webkit-app-region: drag; @@ -484,11 +484,7 @@ input { border-top-right-radius: var(--spacing-4); background-color: var(--t42-tab-bar-tab-background); container-type: size; - container-name: normal-tabs; -webkit-app-region: no-drag; - /* transition-property: all; - transition-duration: 260ms; - transition-timing-function: ease-in-out; */ } .t42-tab::before { @@ -532,12 +528,12 @@ input { .t42-tab-caption { flex-grow: 1; color: var(--t42-tab-bar-tab-text); - mask-image: linear-gradient(90deg, Hsl(var(--io-bg-00)) 75%, transparent); + -webkit-mask-image: linear-gradient(90deg, Hsl(var(--io-bg-00)) 75%, transparent); } .t42-tab-caption-editor { min-width: unset; - mask-image: none; + -webkit-mask-image: none; height: var(--spacing-12); } @@ -588,7 +584,7 @@ input { } .t42-selected-tab::before, -.t42-selected-tab + .t42-tab::before { +.t42-selected-tab+.t42-tab::before { opacity: 0; } @@ -729,6 +725,7 @@ input { } @keyframes clipMe { + 0%, 100% { clip: rect(0, 25vh, 2px, 0); @@ -810,20 +807,20 @@ input { background-color: transparent; } -@container normal-tabs (max-width: 50px) { +@container (max-width: 50px) { .t42-tab-channel-selector { - --t42-tab-bar-tab-channels-size:0; - --t42-tab-bar-tab-channels-margin: 0; + width: 0; + margin: 0; } } -@container normal-tabs (max-width: 40px) { +@container (max-width: 40px) { .t42-tab-close-button { margin: auto; } } -@container normal-tabs (max-width: 30px) { +@container (max-width: 30px) { .t42-selected-tab-caption { flex-grow: 0; width: 0; @@ -843,37 +840,31 @@ input { } .t42-tabs-overflow.t42-tabs-fade-right { - -webkit-mask-image: linear-gradient( - -90deg, - rgba(0, 0, 0, 0) 0, - rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), - rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), - rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size) - ); + -webkit-mask-image: linear-gradient(-90deg, + rgba(0, 0, 0, 0) 0, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size)); } .t42-tabs-overflow.t42-tabs-fade-left { - -webkit-mask-image: linear-gradient( - 90deg, - rgba(0, 0, 0, 0) 0, - rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), - rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), - rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size) - ); + -webkit-mask-image: linear-gradient(90deg, + rgba(0, 0, 0, 0) 0, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size)); } .t42-tabs-overflow.t42-tabs-fade-both { - -webkit-mask-image: linear-gradient( - 90deg, - rgba(0, 0, 0, 0) 0%, - rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), - rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), - rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size), - rgba(0, 0, 0, 1) calc(100% - var(--t42-tab-bar-fade-size)), - rgba(0, 0, 0, 0.8) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 80)), - rgba(0, 0, 0, 0.3) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 30)), - rgba(0, 0, 0, 0) 100% - ); + -webkit-mask-image: linear-gradient(90deg, + rgba(0, 0, 0, 0) 0%, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size), + rgba(0, 0, 0, 1) calc(100% - var(--t42-tab-bar-fade-size)), + rgba(0, 0, 0, 0.8) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 80)), + rgba(0, 0, 0, 0.3) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 30)), + rgba(0, 0, 0, 0) 100%); } .t42-page-popup { @@ -882,8 +873,7 @@ input { margin-top: var(--t42-wg-tab-over-top-offset); } -.t42-tab-overflow-popup, -.t42-tab-context-menu { +.t42-tab-overflow-popup { display: flex; flex-direction: column; min-width: var(--t42-wg-tab-over-min-width); @@ -895,8 +885,7 @@ input { background-color: var(--t42-wg-tab-over-background); } -.t42-tab-overflow-popup li, -.t42-tab-context-menu li { +.t42-tab-overflow-popup li { display: flex; gap: var(--t42-wg-tab-over-item-gap); align-items: center; @@ -906,16 +895,14 @@ input { transition-property: background-color; } -.t42-tab-overflow-popup li span, -.t42-tab-context-menu li span { +.t42-tab-overflow-popup li span { flex-grow: 1; overflow: hidden; text-wrap: nowrap; text-overflow: clip; } -.t42-tab-overflow-popup li:not(.title):hover, -.t42-tab-context-menu li:not(.title):hover { +.t42-tab-overflow-popup li:not(.title):hover { color: var(--t42-wg-tab-over-item-color-hover); background-color: var(--t42-wg-tab-over-item-background-hover); } @@ -932,38 +919,3 @@ input { font-size: var(--t42-wg-tab-over-item-title-size); letter-spacing: var(--t42-wg-tab-over-item-title-spacing); } - -.t42-tabs-pinned { - min-width: 0; - flex-shrink: 0; -} - -.t42-tabs-pinned .t42-tab { - --t42-tab-bar-tab-margin: var(--t42-wg-pin-tab-margin); - --t42-tab-bar-tab-height: var(--t42-wg-pin-tab-height); - border-radius: var(--t42-wg-pin-tab-border-radius); - width: var(--t42-wg-pin-tab-width); -} - -.t42-tabs-pinned .t42-tab-caption { - mask-image: none; -} - -.t42-tabs-pinned .t42-tab { - container-name: pinned; -} - -@container pinned (min-width:1px) { - .t42-tab-close-button { - background-color: transparent; - } -} - -.t42-tabs-pinned .t42-tab-fade, -.t42-tabs-overflow .t42-tab-fade { - overflow: hidden; - width: 0; - padding: 0; - min-width: 0; - margin: 0; -} diff --git a/assets/css/vars.css b/assets/css/vars.css index 10c629c..f0f0463 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -129,11 +129,6 @@ --t42-wg-tab-over-separator-size: var(--spacing-1); --t42-wg-tab-over-separator-color: var(--base-border-separator); --t42-wg-tab-over-separator-space: var(--spacing-8) 0; - - --t42-wg-pin-tab-border-radius: var(--spacing-4); - --t42-wg-pin-tab-width: 120px; - --t42-wg-pin-tab-margin: var(--spacing-4); - --t42-wg-pin-tab-height: var(--spacing-24); } /* Scroll vars override */ diff --git a/changelog.md b/changelog.md index c0d3294..f215c1d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,9 +1,3 @@ -2.4.0 -chore: official 9.5 support -2.3.1 -feat: pinned tabs support -2.3.0 -chore: official 9.4 support 2.2.2 fix: fixed the internal CSS import for the overflow tabs 2.2.1 diff --git a/package.json b/package.json index 34986ce..0fad097 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.4.0", + "version": "2.2.8", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io", diff --git a/src/defaultComponents/tabs/Tab.tsx b/src/defaultComponents/tabs/Tab.tsx index 8cc79f5..a52084d 100644 --- a/src/defaultComponents/tabs/Tab.tsx +++ b/src/defaultComponents/tabs/Tab.tsx @@ -5,13 +5,13 @@ import TabCaption from "./TabCaption"; import TabCaptionEditor from "./TabCaptionEditor"; import TabCloseButton from "./TabCloseButton"; -const Tab: React.FC = ({ caption, selected, close, channels, captionEditor, notifyCaptionBoundsChanged, windowId, pinned }) => { +const Tab: React.FC = ({ caption, selected, close, channels, captionEditor, notifyCaptionBoundsChanged, windowId }) => { return
      {channels.visible && } {captionEditor.show ? : } - {pinned ? <> : } +
      }; diff --git a/src/types/api.ts b/src/types/api.ts index 53d27f8..e842846 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -118,7 +118,6 @@ export interface TabElementProps { caption: string; selected: boolean; flashing: boolean; - pinned: boolean; close: () => void; channels: ChannelProps; notifyCaptionBoundsChanged: (bounds: Bounds) => void; diff --git a/src/types/internal.ts b/src/types/internal.ts index 8d60d21..0278a3c 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -139,7 +139,6 @@ export interface CreateTabRequestOptions extends CreateElementRequestOptions { caption: string; selected: boolean; flashing: boolean; - pinned: boolean; channelSelectorVisible: boolean; selectedChannel: string; selectedChannelColor: string; From dc0584023deb3fd4a4ef5df35123dd00a1080e15 Mon Sep 17 00:00:00 2001 From: Tsvetan Bratanov Date: Tue, 29 Oct 2024 12:13:11 +0200 Subject: [PATCH 35/42] Revert "Revert "Merge remote-tracking branch 'origin' into G4E-7825-Channels-Title-area-should-show-channel-selected-as-well-as-direction"" This reverts commit 1434dd67417cd261308a0d9636de35dda77562d8. --- assets/css/groups.css | 116 ++++++++++++++++++++--------- assets/css/vars.css | 5 ++ changelog.md | 6 ++ package.json | 2 +- src/defaultComponents/tabs/Tab.tsx | 4 +- src/types/api.ts | 1 + src/types/internal.ts | 1 + 7 files changed, 98 insertions(+), 37 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index a4ce393..a8878c0 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -446,7 +446,8 @@ input { height: var(--t42-tab-bar-height); } -.t42-tabs { +.t42-tabs, +.t42-tabs-pinned { position: relative; display: flex; flex-direction: row; @@ -454,7 +455,6 @@ input { flex-shrink: 1; align-items: center; padding: var(--t42-tab-bar-padding); - margin: 0px; overflow: hidden; list-style-type: none; -webkit-app-region: drag; @@ -484,7 +484,11 @@ input { border-top-right-radius: var(--spacing-4); background-color: var(--t42-tab-bar-tab-background); container-type: size; + container-name: normal-tabs; -webkit-app-region: no-drag; + /* transition-property: all; + transition-duration: 260ms; + transition-timing-function: ease-in-out; */ } .t42-tab::before { @@ -528,12 +532,12 @@ input { .t42-tab-caption { flex-grow: 1; color: var(--t42-tab-bar-tab-text); - -webkit-mask-image: linear-gradient(90deg, Hsl(var(--io-bg-00)) 75%, transparent); + mask-image: linear-gradient(90deg, Hsl(var(--io-bg-00)) 75%, transparent); } .t42-tab-caption-editor { min-width: unset; - -webkit-mask-image: none; + mask-image: none; height: var(--spacing-12); } @@ -584,7 +588,7 @@ input { } .t42-selected-tab::before, -.t42-selected-tab+.t42-tab::before { +.t42-selected-tab + .t42-tab::before { opacity: 0; } @@ -725,7 +729,6 @@ input { } @keyframes clipMe { - 0%, 100% { clip: rect(0, 25vh, 2px, 0); @@ -807,20 +810,20 @@ input { background-color: transparent; } -@container (max-width: 50px) { +@container normal-tabs (max-width: 50px) { .t42-tab-channel-selector { - width: 0; - margin: 0; + --t42-tab-bar-tab-channels-size:0; + --t42-tab-bar-tab-channels-margin: 0; } } -@container (max-width: 40px) { +@container normal-tabs (max-width: 40px) { .t42-tab-close-button { margin: auto; } } -@container (max-width: 30px) { +@container normal-tabs (max-width: 30px) { .t42-selected-tab-caption { flex-grow: 0; width: 0; @@ -840,31 +843,37 @@ input { } .t42-tabs-overflow.t42-tabs-fade-right { - -webkit-mask-image: linear-gradient(-90deg, - rgba(0, 0, 0, 0) 0, - rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), - rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), - rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size)); + -webkit-mask-image: linear-gradient( + -90deg, + rgba(0, 0, 0, 0) 0, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size) + ); } .t42-tabs-overflow.t42-tabs-fade-left { - -webkit-mask-image: linear-gradient(90deg, - rgba(0, 0, 0, 0) 0, - rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), - rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), - rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size)); + -webkit-mask-image: linear-gradient( + 90deg, + rgba(0, 0, 0, 0) 0, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size) + ); } .t42-tabs-overflow.t42-tabs-fade-both { - -webkit-mask-image: linear-gradient(90deg, - rgba(0, 0, 0, 0) 0%, - rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), - rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), - rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size), - rgba(0, 0, 0, 1) calc(100% - var(--t42-tab-bar-fade-size)), - rgba(0, 0, 0, 0.8) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 80)), - rgba(0, 0, 0, 0.3) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 30)), - rgba(0, 0, 0, 0) 100%); + -webkit-mask-image: linear-gradient( + 90deg, + rgba(0, 0, 0, 0) 0%, + rgba(0, 0, 0, 0.3) calc(var(--t42-tab-bar-fade-size) / 100 * 30), + rgba(0, 0, 0, 0.8) calc(var(--t42-tab-bar-fade-size) / 100 * 80), + rgba(0, 0, 0, 1) var(--t42-tab-bar-fade-size), + rgba(0, 0, 0, 1) calc(100% - var(--t42-tab-bar-fade-size)), + rgba(0, 0, 0, 0.8) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 80)), + rgba(0, 0, 0, 0.3) calc(100% - (var(--t42-tab-bar-fade-size) / 100 * 30)), + rgba(0, 0, 0, 0) 100% + ); } .t42-page-popup { @@ -873,7 +882,8 @@ input { margin-top: var(--t42-wg-tab-over-top-offset); } -.t42-tab-overflow-popup { +.t42-tab-overflow-popup, +.t42-tab-context-menu { display: flex; flex-direction: column; min-width: var(--t42-wg-tab-over-min-width); @@ -885,7 +895,8 @@ input { background-color: var(--t42-wg-tab-over-background); } -.t42-tab-overflow-popup li { +.t42-tab-overflow-popup li, +.t42-tab-context-menu li { display: flex; gap: var(--t42-wg-tab-over-item-gap); align-items: center; @@ -895,14 +906,16 @@ input { transition-property: background-color; } -.t42-tab-overflow-popup li span { +.t42-tab-overflow-popup li span, +.t42-tab-context-menu li span { flex-grow: 1; overflow: hidden; text-wrap: nowrap; text-overflow: clip; } -.t42-tab-overflow-popup li:not(.title):hover { +.t42-tab-overflow-popup li:not(.title):hover, +.t42-tab-context-menu li:not(.title):hover { color: var(--t42-wg-tab-over-item-color-hover); background-color: var(--t42-wg-tab-over-item-background-hover); } @@ -919,3 +932,38 @@ input { font-size: var(--t42-wg-tab-over-item-title-size); letter-spacing: var(--t42-wg-tab-over-item-title-spacing); } + +.t42-tabs-pinned { + min-width: 0; + flex-shrink: 0; +} + +.t42-tabs-pinned .t42-tab { + --t42-tab-bar-tab-margin: var(--t42-wg-pin-tab-margin); + --t42-tab-bar-tab-height: var(--t42-wg-pin-tab-height); + border-radius: var(--t42-wg-pin-tab-border-radius); + width: var(--t42-wg-pin-tab-width); +} + +.t42-tabs-pinned .t42-tab-caption { + mask-image: none; +} + +.t42-tabs-pinned .t42-tab { + container-name: pinned; +} + +@container pinned (min-width:1px) { + .t42-tab-close-button { + background-color: transparent; + } +} + +.t42-tabs-pinned .t42-tab-fade, +.t42-tabs-overflow .t42-tab-fade { + overflow: hidden; + width: 0; + padding: 0; + min-width: 0; + margin: 0; +} diff --git a/assets/css/vars.css b/assets/css/vars.css index f0f0463..10c629c 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -129,6 +129,11 @@ --t42-wg-tab-over-separator-size: var(--spacing-1); --t42-wg-tab-over-separator-color: var(--base-border-separator); --t42-wg-tab-over-separator-space: var(--spacing-8) 0; + + --t42-wg-pin-tab-border-radius: var(--spacing-4); + --t42-wg-pin-tab-width: 120px; + --t42-wg-pin-tab-margin: var(--spacing-4); + --t42-wg-pin-tab-height: var(--spacing-24); } /* Scroll vars override */ diff --git a/changelog.md b/changelog.md index f215c1d..c0d3294 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,9 @@ +2.4.0 +chore: official 9.5 support +2.3.1 +feat: pinned tabs support +2.3.0 +chore: official 9.4 support 2.2.2 fix: fixed the internal CSS import for the overflow tabs 2.2.1 diff --git a/package.json b/package.json index 0fad097..34986ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.2.8", + "version": "2.4.0", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io", diff --git a/src/defaultComponents/tabs/Tab.tsx b/src/defaultComponents/tabs/Tab.tsx index a52084d..8cc79f5 100644 --- a/src/defaultComponents/tabs/Tab.tsx +++ b/src/defaultComponents/tabs/Tab.tsx @@ -5,13 +5,13 @@ import TabCaption from "./TabCaption"; import TabCaptionEditor from "./TabCaptionEditor"; import TabCloseButton from "./TabCloseButton"; -const Tab: React.FC = ({ caption, selected, close, channels, captionEditor, notifyCaptionBoundsChanged, windowId }) => { +const Tab: React.FC = ({ caption, selected, close, channels, captionEditor, notifyCaptionBoundsChanged, windowId, pinned }) => { return
      {channels.visible && } {captionEditor.show ? : } - + {pinned ? <> : }
      }; diff --git a/src/types/api.ts b/src/types/api.ts index e842846..53d27f8 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -118,6 +118,7 @@ export interface TabElementProps { caption: string; selected: boolean; flashing: boolean; + pinned: boolean; close: () => void; channels: ChannelProps; notifyCaptionBoundsChanged: (bounds: Bounds) => void; diff --git a/src/types/internal.ts b/src/types/internal.ts index 0278a3c..8d60d21 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -139,6 +139,7 @@ export interface CreateTabRequestOptions extends CreateElementRequestOptions { caption: string; selected: boolean; flashing: boolean; + pinned: boolean; channelSelectorVisible: boolean; selectedChannel: string; selectedChannelColor: string; From 9bcbcf01b3ed7d15d07e2904f42bf27b00c3f3de Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Wed, 13 Nov 2024 15:49:00 +0200 Subject: [PATCH 36/42] G4E-6634 Changed classes to handle channel labels and improved the dependency array Signed-off-by: Svetozar Mateev --- .../channelSelector/BaseChannelSelector.tsx | 5 ++++- .../multi/BaseMultiChannelSelector.tsx | 17 ++++++++++------- .../multi/FlatMultiChannelSelector.tsx | 8 +++++--- .../multi/TabMultiChannelSelector.tsx | 8 +++++--- src/defaultComponents/tabs/Tab.tsx | 2 +- src/types/defaultComponents.ts | 5 +++++ 6 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/defaultComponents/channelSelector/BaseChannelSelector.tsx b/src/defaultComponents/channelSelector/BaseChannelSelector.tsx index 0406031..7b00531 100644 --- a/src/defaultComponents/channelSelector/BaseChannelSelector.tsx +++ b/src/defaultComponents/channelSelector/BaseChannelSelector.tsx @@ -5,6 +5,7 @@ import { IsBlackReadable } from "./utils"; const BaseChannelSelector: React.FC = ({ outsideClass, contentClass, showSelector, selectedChannel, selectedChannelColor, direction, channelLabel }) => { const ref = useRef(null); const wrappedOnClick = () => { + console.log("single shwoing selector"); if (!ref.current) { return; } @@ -18,12 +19,14 @@ const BaseChannelSelector: React.FC = ({ outsideClass, } useEffect(() => { + console.log("single subscribing for mousedown"); const handler = (e: MouseEvent) => { e.stopPropagation(); }; const current = ref.current; current?.addEventListener("mousedown", handler); - return ()=> { + return () => { + console.log("single unsubscribing for mousedown"); current?.removeEventListener("mousedown", handler); } }, [ref]); diff --git a/src/defaultComponents/channelSelector/multi/BaseMultiChannelSelector.tsx b/src/defaultComponents/channelSelector/multi/BaseMultiChannelSelector.tsx index 9326b77..d79cfe8 100644 --- a/src/defaultComponents/channelSelector/multi/BaseMultiChannelSelector.tsx +++ b/src/defaultComponents/channelSelector/multi/BaseMultiChannelSelector.tsx @@ -1,11 +1,12 @@ -import React, { useEffect, useRef } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { BaseMultiChannelSelectorProps } from "../../../types/defaultComponents"; import BaseChannelSelector from "../BaseChannelSelector"; import { getChannelDirection } from "../utils"; const BaseMultiChannelSelector: React.FC = ({ outsideClass, contentClass, showSelector, selectedChannels, channelLabel, channelRestrictions }) => { - const ref = useRef(null); + const len = selectedChannels.length; + const showBaseChannelSelector = len < 2; const wrappedOnClick = () => { if (!ref.current) { return; @@ -21,19 +22,21 @@ const BaseMultiChannelSelector: React.FC = ({ out } useEffect(() => { + if (showBaseChannelSelector) { + return; + } + const handler = (e: MouseEvent) => { e.stopPropagation(); }; const current = ref.current; ref.current?.addEventListener("mousedown", handler); - return ()=> { + return () => { current?.removeEventListener("mousedown", handler); } - }); - - const len = selectedChannels.length; + }, [ref, showBaseChannelSelector]); - if (len < 2) { + if (showBaseChannelSelector) { return = ({ showSelector, selectedChannels }) => { - return = ({ showSelector, selectedChannels, channelRestrictions, channelLabel }) => { + return }; diff --git a/src/defaultComponents/channelSelector/multi/TabMultiChannelSelector.tsx b/src/defaultComponents/channelSelector/multi/TabMultiChannelSelector.tsx index 2f94b67..64a156d 100644 --- a/src/defaultComponents/channelSelector/multi/TabMultiChannelSelector.tsx +++ b/src/defaultComponents/channelSelector/multi/TabMultiChannelSelector.tsx @@ -2,11 +2,13 @@ import React from "react"; import { TabMultiChannelSelectorProps } from "../../../types/defaultComponents"; import BaseMultiChannelSelector from "./BaseMultiChannelSelector"; -const TabMultiChannelSelector: React.FC = ({ showSelector, selectedChannels }) => { - return = ({ showSelector, selectedChannels, channelRestrictions, channelLabel }) => { + return }; diff --git a/src/defaultComponents/tabs/Tab.tsx b/src/defaultComponents/tabs/Tab.tsx index e127a81..4274329 100644 --- a/src/defaultComponents/tabs/Tab.tsx +++ b/src/defaultComponents/tabs/Tab.tsx @@ -1,7 +1,7 @@ import React from "react"; import { TabElementProps } from "../../types/api"; import TabChannelSelector from "../channelSelector/TabChannelSelector"; -import TabMultiChannelSelector from "../channelSelector/multi/FlatMultiChannelSelector"; +import TabMultiChannelSelector from "../channelSelector/multi/TabMultiChannelSelector"; import TabCaption from "./TabCaption"; import TabCaptionEditor from "./TabCaptionEditor"; import TabCloseButton from "./TabCloseButton"; diff --git a/src/types/defaultComponents.ts b/src/types/defaultComponents.ts index 00f1d91..ac62fe3 100644 --- a/src/types/defaultComponents.ts +++ b/src/types/defaultComponents.ts @@ -121,6 +121,11 @@ export interface TabChannelSelectorProps { export interface TabMultiChannelSelectorProps { showSelector: (bounds: Bounds) => void; selectedChannels: { name: string; color: string }[]; + channelRestrictions: { + read: boolean, + write: boolean + }; + channelLabel: string; } export interface FlatCaptionEditorProps { From e6bfa686069d81f4a5719a503d3321354c74108c Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Wed, 13 Nov 2024 15:50:42 +0200 Subject: [PATCH 37/42] G4E-6634 Cleanup Signed-off-by: Svetozar Mateev --- .../channelSelector/BaseChannelSelector.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/defaultComponents/channelSelector/BaseChannelSelector.tsx b/src/defaultComponents/channelSelector/BaseChannelSelector.tsx index 7b00531..0406031 100644 --- a/src/defaultComponents/channelSelector/BaseChannelSelector.tsx +++ b/src/defaultComponents/channelSelector/BaseChannelSelector.tsx @@ -5,7 +5,6 @@ import { IsBlackReadable } from "./utils"; const BaseChannelSelector: React.FC = ({ outsideClass, contentClass, showSelector, selectedChannel, selectedChannelColor, direction, channelLabel }) => { const ref = useRef(null); const wrappedOnClick = () => { - console.log("single shwoing selector"); if (!ref.current) { return; } @@ -19,14 +18,12 @@ const BaseChannelSelector: React.FC = ({ outsideClass, } useEffect(() => { - console.log("single subscribing for mousedown"); const handler = (e: MouseEvent) => { e.stopPropagation(); }; const current = ref.current; current?.addEventListener("mousedown", handler); - return () => { - console.log("single unsubscribing for mousedown"); + return ()=> { current?.removeEventListener("mousedown", handler); } }, [ref]); From bada6340addaaf7d51d6ac2d8af46851c84bad30 Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Wed, 13 Nov 2024 15:57:36 +0200 Subject: [PATCH 38/42] Release 2.5.0 --- changelog.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 266c51e..57ad2ec 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +2.5.0 +chore: official 9.6 support +feat: multi channels support 2.4.1 feat: directional channels improvement 2.4.0 diff --git a/package.json b/package.json index b3444e2..6c32474 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.4.1", + "version": "2.5.0", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io", From 88e3fad8b8ae8fbfd72e7cc64c1fc0f38a4cb0ae Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Thu, 14 Nov 2024 10:24:51 +0200 Subject: [PATCH 39/42] G4E-8203 Updated the CSS to reduce the tab width before triggering the overflow --- assets/css/groups.css | 46 ++++++++++++++++--------------------------- assets/css/vars.css | 17 ++++++++-------- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index f80a184..5d2db66 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -5,13 +5,7 @@ box-sizing: border-box; transition-timing-function: cubic-bezier(0.45, 0, 0.15, 1); transition-duration: 240ms; - transition-property: background-color; -} - -*::before, -*::after { - transition-timing-function: cubic-bezier(0.45, 0, 0.15, 1); - transition-duration: 240ms; + transition-property: background-color, color; } body { @@ -558,7 +552,8 @@ input { height: calc(var(--t42-tab-bar-tab-close-button-size) + var(--t42-tab-bar-tab-close-button-padding) * 2); border-radius: 50%; background-color: var(--t42-tab-bar-tab-close-button-background); - transition-property: fill, color; + transition-duration: 80ms; + transition-property: background-color, fill, color; } .t42-tab-close-button-content svg { @@ -575,10 +570,6 @@ input { background-color: var(--t42-tab-bar-tab-close-button-bg-hover); } -.t42-tab-close-button-content:hover::before { - color: var(--t42-tab-bar-tab-text-hover); -} - .t42-tab-close-button-content:hover .t42-standard-button-image { fill: var(--t42-tab-bar-tab-text-hover); } @@ -613,28 +604,24 @@ input { fill: var(--t42-tab-bar-selected-tab-text); } +.t42-channel-selector-content-light::before { + color: hsl(var(--io-white)); + transition-property: color; +} + +.t42-channel-selector-content-dark::before { + color: hsl(var(--io-black)); + transition-property: color; +} + .t42-channel-selector-direction { - width: auto; - min-width: var(--t42-tab-bar-tab-channels-width); + width: var(--t42-channel-selector-direction-width); height: var(--t42-channel-selector-direction-height); gap: var(--t42-channel-selector-direction-gap); } .t42-channel-selector-direction .icon { gap: var(--t42-channel-selector-direction-gap); - width: var(--t42-channel-selector-direction-width); -} - -.t42-channel-selector-content-light, -.t42-channel-selector-content-light::before, -.t42-channel-selector-content-light i::before { - color: hsl(var(--io-white)); -} - -.t42-channel-selector-content-dark, -.t42-channel-selector-content-dark::before, -.t42-channel-selector-content-dark i::before { - color: hsl(var(--io-black)); } @keyframes approaching-edge-animation { @@ -812,7 +799,8 @@ input { @container normal-tabs (max-width: 50px) { .t42-tab-channel-selector { - --t42-tab-bar-tab-channels-size:0; + --t42-tab-bar-tab-channels-height:0; + --t42-tab-bar-tab-channels-width: 0; --t42-tab-bar-tab-channels-margin: 0; } } @@ -835,7 +823,7 @@ input { } .t42-tabs-overflow .t42-tab { - flex-shrink: 0; + min-width: var(--t42-tab-bar-tab-overflowable-min-width); } .t42-tabs-overflow .t42-tabs { diff --git a/assets/css/vars.css b/assets/css/vars.css index 97f467c..c07e062 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -51,11 +51,12 @@ --t42-tab-bar-selected-tab-hover-background: var(--window-tabs-background-active); --t42-tab-bar-fade-size: 24px; - --t42-tab-bar-tab-height: 28px; /* for 10.0 - var(--spacing-24); */ + --t42-tab-bar-tab-height: 28px; /* for 10.0 - var(--spacing-24); */ --t42-tab-bar-tab-min-width: 48px; + --t42-tab-bar-tab-overflowable-min-width: 96px; --t42-tab-bar-tab-width: 150px; --t42-tab-bar-tab-padding: 0 var(--spacing-8); - --t42-tab-bar-tab-margin: var(--spacing-4) var(--spacing-2) 0 0; /* for 10.0 - 0 var(--spacing-2) 0 0; */ + --t42-tab-bar-tab-margin: var(--spacing-4) var(--spacing-2) 0 0; /* for 10.0 - 0 var(--spacing-2) 0 0; */ --t42-tab-bar-tab-text: var(--tabs-color-default); --t42-tab-bar-tab-text-hover: var(--tabs-color-hover); --t42-tab-bar-tab-separator-size: 1px; @@ -68,7 +69,7 @@ --t42-tab-bar-tab-background: transparent; --t42-tab-bar-tab-hover-background: transparent; /* non used */ --t42-tab-bar-tab-flashing-color: var(--io-neutrals-0); - --t42-tab-bar-tab-flashing-background:var(--severity-high); /* color-mix(in srgb, var(--severity-high) 65%, transparent); */ + --t42-tab-bar-tab-flashing-background:var(--severity-high); /* color-mix(in srgb, var(--severity-high) 65%, transparent); */ --t42-tab-bar-tab-channels-border-radius: var(--base-radius-default); --t42-tab-bar-tab-channels-width: var(--spacing-16); @@ -78,6 +79,10 @@ --t42-tab-bar-tab-channels-content-margin: 0; --t42-tab-bar-tab-caption-margin: 0; + --t42-channel-selector-direction-width: var(--spacing-24); + --t42-channel-selector-direction-height: var(--spacing-16); + --t42-channel-selector-direction-gap: var(--spacing-1); + --t42-tab-bar-tab-close-button-size: 6px; --t42-tab-bar-tab-close-button-padding: 3px; --t42-tab-bar-tab-close-button-margin: 0 0 0 var(--spacing-8); @@ -91,10 +96,6 @@ --t42-channels-fill-color: var(--tabs-color-active); - --t42-channel-selector-direction-width: var(--spacing-24); - --t42-channel-selector-direction-height: var(--spacing-16); - --t42-channel-selector-direction-gap: var(--spacing-1); - --t42-caption-separator-color: var(--tabs-border); --t42-caption-text-hover-color: var(--tabs-color-hover); --t42-caption-bar-button-width: 48px; @@ -111,7 +112,7 @@ --t42-hover-sizing-border-group-color: hsl(var(--io-highlight-Interactive)); --t42-active-sizing-border-group-color: hsl(var(--io-interactive-primary)); - + --t42-wg-tab-over-max-height: 100vh; --t42-wg-tab-over-max-width: 200px; --t42-wg-tab-over-min-width: 200px; From 4e473fa6e030cea37041425797008ebb215f54fb Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Thu, 14 Nov 2024 15:16:59 +0200 Subject: [PATCH 40/42] G4E-8203 Updated the css --- assets/css/groups.css | 2 +- assets/css/vars.css | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/assets/css/groups.css b/assets/css/groups.css index 5d2db66..5db947f 100644 --- a/assets/css/groups.css +++ b/assets/css/groups.css @@ -823,7 +823,7 @@ input { } .t42-tabs-overflow .t42-tab { - min-width: var(--t42-tab-bar-tab-overflowable-min-width); + min-width: var(--t42-tab-bar-tab-overflowable-min-width); } .t42-tabs-overflow .t42-tabs { diff --git a/assets/css/vars.css b/assets/css/vars.css index c07e062..c14e264 100644 --- a/assets/css/vars.css +++ b/assets/css/vars.css @@ -51,12 +51,12 @@ --t42-tab-bar-selected-tab-hover-background: var(--window-tabs-background-active); --t42-tab-bar-fade-size: 24px; - --t42-tab-bar-tab-height: 28px; /* for 10.0 - var(--spacing-24); */ + --t42-tab-bar-tab-height: 28px; /* for 10.0 - var(--spacing-24); */ --t42-tab-bar-tab-min-width: 48px; --t42-tab-bar-tab-overflowable-min-width: 96px; --t42-tab-bar-tab-width: 150px; --t42-tab-bar-tab-padding: 0 var(--spacing-8); - --t42-tab-bar-tab-margin: var(--spacing-4) var(--spacing-2) 0 0; /* for 10.0 - 0 var(--spacing-2) 0 0; */ + --t42-tab-bar-tab-margin: var(--spacing-4) var(--spacing-2) 0 0; /* for 10.0 - 0 var(--spacing-2) 0 0; */ --t42-tab-bar-tab-text: var(--tabs-color-default); --t42-tab-bar-tab-text-hover: var(--tabs-color-hover); --t42-tab-bar-tab-separator-size: 1px; @@ -69,7 +69,7 @@ --t42-tab-bar-tab-background: transparent; --t42-tab-bar-tab-hover-background: transparent; /* non used */ --t42-tab-bar-tab-flashing-color: var(--io-neutrals-0); - --t42-tab-bar-tab-flashing-background:var(--severity-high); /* color-mix(in srgb, var(--severity-high) 65%, transparent); */ + --t42-tab-bar-tab-flashing-background:var(--severity-high); /* color-mix(in srgb, var(--severity-high) 65%, transparent); */ --t42-tab-bar-tab-channels-border-radius: var(--base-radius-default); --t42-tab-bar-tab-channels-width: var(--spacing-16); @@ -112,7 +112,7 @@ --t42-hover-sizing-border-group-color: hsl(var(--io-highlight-Interactive)); --t42-active-sizing-border-group-color: hsl(var(--io-interactive-primary)); - + --t42-wg-tab-over-max-height: 100vh; --t42-wg-tab-over-max-width: 200px; --t42-wg-tab-over-min-width: 200px; @@ -135,6 +135,7 @@ --t42-wg-pin-tab-width: 120px; --t42-wg-pin-tab-margin: var(--spacing-4); --t42-wg-pin-tab-height: var(--spacing-24); + --t42-multi-channel-selector-2-color-1: var(--channels-blue); --t42-multi-channel-selector-2-color-2: var(--channels-red); --t42-multi-channel-selector-2-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 16 16'%3E%3Crect width='7.5' height='16'/%3E%3Crect x='8.5' width='7.5' height='16'/%3E%3C/svg%3E"); @@ -147,6 +148,7 @@ --t42-multi-channel-selector-4-color-3: var(--channels-orange); --t42-multi-channel-selector-4-color-4: var(--channels-magenta); --t42-multi-channel-selector-4-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 16 16'%3E%3Crect width='7.5' height='7.5'/%3E%3Crect x='8.5' width='7.5' height='7.5'/%3E%3Crect x='8.5' y='8.5' width='7.5' height='7.5'/%3E%3Crect y='8.5' width='7.5' height='7.5'/%3E%3C/svg%3E"); + } /* Scroll vars override */ From 2643bdf806da0a62b2f4c34faa55b85cd4150a2d Mon Sep 17 00:00:00 2001 From: Tsvetan Bratanov Date: Tue, 19 Nov 2024 15:10:55 +0200 Subject: [PATCH 41/42] G4E-8476: Channel selector directional channel icon not showing direction due to missing icons (older version of the theme) - Adding version "@interopio/theme": "^2.1.32", to include directional arrows --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 6c32474..806c6d1 100644 --- a/package.json +++ b/package.json @@ -27,13 +27,14 @@ "bundle:css": "node ./scripts/bundlecss.js", "prepublishOnly": "npm run build", "preversion": "npm run build", - "version": "npm run build" + "version": "npm run build", + "clean": "rimraf ./node_modules/react && rimraf ./node_modules/react-dom && rimraf ./node_modules/@interopio/react-hooks" }, "publishConfig": { "access": "public" }, "dependencies": { - "@interopio/theme": "2.1.26", + "@interopio/theme": "^2.1.32", "callback-registry": "^2.7.2", "color2k": "^2.0.0", "overlayscrollbars": "^2.8.3", From 547545a75305d7a2db4dc4c50769f28d5b83264f Mon Sep 17 00:00:00 2001 From: Svetozar Mateev Date: Wed, 18 Dec 2024 11:13:17 +0200 Subject: [PATCH 42/42] Released 2.6.0 --- changelog.md | 3 +++ package-lock.json | 18 +++++++++--------- package.json | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/changelog.md b/changelog.md index 57ad2ec..f2e18f0 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +2.6.0 +chore: official 9.7 support +feat: overflow tabs dynamic width 2.5.0 chore: official 9.6 support feat: multi channels support diff --git a/package-lock.json b/package-lock.json index 73bc591..a7eb9c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@interopio/groups-ui-react", - "version": "2.2.0", + "version": "2.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@interopio/groups-ui-react", - "version": "2.2.0", + "version": "2.5.0", "license": "MIT", "dependencies": { - "@interopio/theme": "^2.1.26", + "@interopio/theme": "^2.1.32", "callback-registry": "^2.7.2", "color2k": "^2.0.0", "overlayscrollbars": "^2.8.3", @@ -2549,9 +2549,9 @@ } }, "node_modules/@interopio/theme": { - "version": "2.1.26", - "resolved": "https://codeartifact-interopio-npm.interop.io/@interopio/theme/-/theme-2.1.26.tgz", - "integrity": "sha512-MBY/GOxhm3VZE2uz36xTy+X8X1gDZ4BiwWgFpwPkqq96D0X6hBMt9MX4Q/gnuecWK7eqSYjhcBUHjbnKNEZprg==" + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/@interopio/theme/-/theme-2.1.32.tgz", + "integrity": "sha512-r2jh6B2d8vGEcVKzU4eJMnQxnue8/4eb9MZYo98+3R1r7/iY1Z1Qk1lSm19KzG+BfM0o9DVUEAjwS+2YUTea9w==" }, "node_modules/@interopio/workspaces-api": { "version": "3.0.2", @@ -22097,9 +22097,9 @@ } }, "@interopio/theme": { - "version": "2.1.26", - "resolved": "https://codeartifact-interopio-npm.interop.io/@interopio/theme/-/theme-2.1.26.tgz", - "integrity": "sha512-MBY/GOxhm3VZE2uz36xTy+X8X1gDZ4BiwWgFpwPkqq96D0X6hBMt9MX4Q/gnuecWK7eqSYjhcBUHjbnKNEZprg==" + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/@interopio/theme/-/theme-2.1.32.tgz", + "integrity": "sha512-r2jh6B2d8vGEcVKzU4eJMnQxnue8/4eb9MZYo98+3R1r7/iY1Z1Qk1lSm19KzG+BfM0o9DVUEAjwS+2YUTea9w==" }, "@interopio/workspaces-api": { "version": "3.0.2", diff --git a/package.json b/package.json index 806c6d1..7be207c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interopio/groups-ui-react", - "version": "2.5.0", + "version": "2.6.0", "description": "React library for building a Web Group App for io.Connect Desktop.", "author": { "name": "interop.io",