From 72c76695514bf972226a32bab04edb9f98fe656a Mon Sep 17 00:00:00 2001 From: Alexey Plutalov Date: Fri, 22 Dec 2023 15:44:39 +0300 Subject: [PATCH 1/3] refactor(ui-layout-view): refactor styles --- .../ui-layout-view/src/UiLayoutView.const.ts | 29 --- .../ui-layout-view/src/UiLayoutView.css.ts | 233 +++++++++--------- .../ui-layout-view/src/UiLayoutView.tsx | 35 +-- 3 files changed, 121 insertions(+), 176 deletions(-) diff --git a/components/ui-layout-view/src/UiLayoutView.const.ts b/components/ui-layout-view/src/UiLayoutView.const.ts index 07b1c309..523d927c 100644 --- a/components/ui-layout-view/src/UiLayoutView.const.ts +++ b/components/ui-layout-view/src/UiLayoutView.const.ts @@ -1,30 +1 @@ -import { - enterLeftSidebar, - enterLeftSidebarActive, - enterRightSidebar, - enterRightSidebarActive, - exitLeftSidebar, - exitLeftSidebarActive, - exitRightSidebar, - exitRightSidebarActive, -} from './UiLayoutView.css'; - export const DURATION = 150; - -export const LEFT_SIDEBAR_CLASS_NAMES = { - enter: enterLeftSidebar, - enterActive: enterLeftSidebarActive, - enterDone: enterLeftSidebarActive, - exit: exitLeftSidebar, - exitActive: exitLeftSidebarActive, - exitDone: exitLeftSidebarActive, -}; - -export const RIGHT_SIDEBAR_CLASS_NAMES = { - enter: enterRightSidebar, - enterActive: enterRightSidebarActive, - enterDone: enterRightSidebarActive, - exit: exitRightSidebar, - exitActive: exitRightSidebarActive, - exitDone: exitRightSidebarActive, -}; diff --git a/components/ui-layout-view/src/UiLayoutView.css.ts b/components/ui-layout-view/src/UiLayoutView.css.ts index bf552f73..eebaea1e 100644 --- a/components/ui-layout-view/src/UiLayoutView.css.ts +++ b/components/ui-layout-view/src/UiLayoutView.css.ts @@ -1,168 +1,161 @@ -import { style } from '@vanilla-extract/css'; +import { assignVars, createGlobalThemeContract, style, styleVariants } from '@vanilla-extract/css'; import { calc } from '@vanilla-extract/css-utils'; import { uiLayers, uiTheme } from '@tabula/ui-theme'; -export const root = style({ - '@layer': { - [uiLayers.components]: { - vars: { - '--duration': uiTheme.duration.moderate[1], - '--entrance-easing': uiTheme.easing.entrance.productive, - '--exit-easing': uiTheme.easing.exit.productive, +const theme = createGlobalThemeContract({ + duration: 'duration', - '--left-sidebar-width': '0px', - '--right-sidebar-width': '0px', - }, + easing: { + entrance: 'entrance-easing', + exit: 'exit-easing', + }, - position: 'relative', - overflow: 'hidden', - }, + width: { + left: 'left-sidebar-width', + right: 'right-sidebar-width', }, }); -// ----- Container and animation styles - -export const container = style({ +export const root = style({ '@layer': { [uiLayers.components]: { - position: 'absolute', - top: 0, - bottom: 0, + vars: assignVars(theme, { + duration: uiTheme.duration.moderate[1], - left: calc.multiply(-1, 'var(--left-sidebar-width)'), - right: calc.multiply(-1, 'var(--right-sidebar-width)'), - willChange: 'left, right', + easing: { + entrance: uiTheme.easing.entrance.productive, + exit: uiTheme.easing.exit.productive, + }, + + width: { + left: '0px', + right: '0px', + }, + }), + + position: 'relative', + overflow: 'hidden', }, }, }); -// ----- Left sidebar styles +// ----- Panel styles -export const withLeftSidebar = style({ - '@layer': { - [uiLayers.components]: { +export const panels = styleVariants( + { + leftSidebar: { left: 0, + zIndex: 1, + width: theme.width.left, + overflow: 'hidden', }, - }, -}); - -export const enterLeftSidebar = style({ - '@layer': { - [uiLayers.components]: { - left: calc.multiply(-1, 'var(--left-sidebar-width)'), + body: { + left: theme.width.left, + right: theme.width.right, + }, + rightSidebar: { + right: 0, + zIndex: 1, + width: theme.width.right, + overflow: 'hidden', }, }, -}); + (styles) => ({ + '@layer': { + [uiLayers.components]: { + position: 'absolute', + top: 0, + bottom: 0, + + ...styles, + }, + }, + }), +); -export const enterLeftSidebarActive = style({ - '@layer': { - [uiLayers.components]: { +// ----- Container and animation styles + +export const leftSidebarStates = styleVariants( + { + enter: { + left: calc.multiply(-1, theme.width.left), + }, + enterActive: { left: 0, - transition: 'left var(--duration) var(--entrance-easing)', + transition: `left ${theme.duration} ${theme.easing.entrance}`, }, - }, -}); - -export const exitLeftSidebar = style({ - '@layer': { - [uiLayers.components]: { + exit: { left: 0, }, - }, -}); - -export const exitLeftSidebarActive = style({ - '@layer': { - [uiLayers.components]: { - left: calc.multiply(-1, 'var(--left-sidebar-width)'), - transition: 'left var(--duration) var(--exit-easing)', + exitActive: { + left: calc.multiply(-1, theme.width.left), + transition: `left ${theme.duration} ${theme.easing.exit}`, }, }, -}); - -// ----- Right sidebar styles - -export const withRightSidebar = style({ - '@layer': { - [uiLayers.components]: { - right: 0, + (styles) => ({ + '@layer': { + [uiLayers.components]: styles, }, - }, -}); + }), +); -export const enterRightSidebar = style({ - '@layer': { - [uiLayers.components]: { - right: calc.multiply(-1, 'var(--right-sidebar-width)'), +export const rightSidebarStates = styleVariants( + { + enter: { + right: calc.multiply(-1, theme.width.right), }, - }, -}); - -export const enterRightSidebarActive = style({ - '@layer': { - [uiLayers.components]: { + enterActive: { right: 0, - transition: 'right var(--duration) var(--entrance-easing)', + transition: `right ${theme.duration} ${theme.easing.entrance}`, }, - }, -}); - -export const exitRightSidebar = style({ - '@layer': { - [uiLayers.components]: { + exit: { right: 0, }, - }, -}); - -export const exitRightSidebarActive = style({ - '@layer': { - [uiLayers.components]: { - right: calc.multiply(-1, 'var(--right-sidebar-width)'), - transition: 'right var(--duration) var(--exit-easing)', + exitActive: { + right: calc.multiply(-1, theme.width.right), + transition: `right ${theme.duration} ${theme.easing.exit}`, }, }, -}); - -// ----- Panel styles - -export const body = style({ - '@layer': { - [uiLayers.components]: { - position: 'absolute', - top: 0, - bottom: 0, - left: 'var(--left-sidebar-width)', - right: 'var(--right-sidebar-width)', + (styles) => ({ + '@layer': { + [uiLayers.components]: styles, }, - }, -}); + }), +); -export const leftSidebar = style({ +export const container = style({ '@layer': { [uiLayers.components]: { position: 'absolute', top: 0, bottom: 0, - left: 0, - zIndex: 1, - width: 'var(--left-sidebar-width)', - overflow: 'hidden', - }, - }, -}); -export const rightSidebar = style({ - '@layer': { - [uiLayers.components]: { - position: 'absolute', - top: 0, - bottom: 0, - right: 0, - zIndex: 1, - width: 'var(--right-sidebar-width)', - overflow: 'hidden', + left: calc.multiply(-1, theme.width.left), + right: calc.multiply(-1, theme.width.right), + willChange: 'left, right', + transition: [ + `left ${theme.duration} ${theme.easing.exit}`, + `right ${theme.duration} ${theme.easing.exit}`, + ].join(', '), + + selectors: { + [`&:has(${panels.leftSidebar}:not(:empty))`]: { + left: 0, + transition: [ + `left ${theme.duration} ${theme.easing.entrance}`, + `right ${theme.duration} ${theme.easing.entrance}`, + ].join(', '), + }, + + [`&:has(${panels.rightSidebar}:not(:empty))`]: { + right: 0, + transition: [ + `left ${theme.duration} ${theme.easing.entrance}`, + `right ${theme.duration} ${theme.easing.entrance}`, + ].join(', '), + }, + }, }, }, }); diff --git a/components/ui-layout-view/src/UiLayoutView.tsx b/components/ui-layout-view/src/UiLayoutView.tsx index 89f56ba6..fec25b68 100644 --- a/components/ui-layout-view/src/UiLayoutView.tsx +++ b/components/ui-layout-view/src/UiLayoutView.tsx @@ -3,21 +3,9 @@ import { ReactElement, createElement, useRef } from 'react'; import clsx from 'clsx'; import { CSSTransition } from 'react-transition-group'; -import { - body, - container, - leftSidebar, - rightSidebar, - root, - withLeftSidebar, - withRightSidebar, -} from './UiLayoutView.css'; +import { container, leftSidebarStates, panels, rightSidebarStates, root } from './UiLayoutView.css'; -import { - DURATION, - LEFT_SIDEBAR_CLASS_NAMES, - RIGHT_SIDEBAR_CLASS_NAMES, -} from './UiLayoutView.const'; +import { DURATION } from './UiLayoutView.const'; import { Props } from './UiLayoutView.types'; export function UiLayoutView({ @@ -40,31 +28,24 @@ export function UiLayoutView({ -
+
{hasLeftSidebar && ( -
+
{isLeftSidebarVisible && createElement(props.leftSidebar, null)}
)} -
{children}
+
{children}
{hasRightSidebar && ( -
+
{isRightSidebarVisible && createElement(props.rightSidebar, null)}
)} From c68eb61f627e1975e6d4c49ed029c64eb4413a7b Mon Sep 17 00:00:00 2001 From: Alexey Plutalov Date: Fri, 22 Dec 2023 15:50:15 +0300 Subject: [PATCH 2/3] fix(ui-layout-view): use transition events instead of timeout fallback --- .../ui-layout-view/src/UiLayoutView.const.ts | 1 - components/ui-layout-view/src/UiLayoutView.tsx | 15 ++++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) delete mode 100644 components/ui-layout-view/src/UiLayoutView.const.ts diff --git a/components/ui-layout-view/src/UiLayoutView.const.ts b/components/ui-layout-view/src/UiLayoutView.const.ts deleted file mode 100644 index 523d927c..00000000 --- a/components/ui-layout-view/src/UiLayoutView.const.ts +++ /dev/null @@ -1 +0,0 @@ -export const DURATION = 150; diff --git a/components/ui-layout-view/src/UiLayoutView.tsx b/components/ui-layout-view/src/UiLayoutView.tsx index fec25b68..9a1d9527 100644 --- a/components/ui-layout-view/src/UiLayoutView.tsx +++ b/components/ui-layout-view/src/UiLayoutView.tsx @@ -5,9 +5,12 @@ import { CSSTransition } from 'react-transition-group'; import { container, leftSidebarStates, panels, rightSidebarStates, root } from './UiLayoutView.css'; -import { DURATION } from './UiLayoutView.const'; import { Props } from './UiLayoutView.types'; +const endListener = (node: HTMLElement, done: () => void) => { + node.addEventListener('transitionend', done, false); +}; + export function UiLayoutView({ rootClassName, bodyClassName, @@ -26,16 +29,14 @@ export function UiLayoutView({ return (
{hasLeftSidebar && ( From 4f211f6628458707499138ad9842a09ecc7a6587 Mon Sep 17 00:00:00 2001 From: Alexey Plutalov Date: Fri, 22 Dec 2023 15:57:49 +0300 Subject: [PATCH 3/3] chore: add changeset --- .changeset/real-owls-marry.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changeset/real-owls-marry.md diff --git a/.changeset/real-owls-marry.md b/.changeset/real-owls-marry.md new file mode 100644 index 00000000..a845151c --- /dev/null +++ b/.changeset/real-owls-marry.md @@ -0,0 +1,2 @@ +--- +---