diff --git a/ivette/src/dome/renderer/frame/style.css b/ivette/src/dome/renderer/frame/style.css index 25343e43b59d10a0fd6761ceb38540c4e51a2063..ed917a3189b1e5a241f3c41a399c2b7c7b439ecb 100644 --- a/ivette/src/dome/renderer/frame/style.css +++ b/ivette/src/dome/renderer/frame/style.css @@ -6,11 +6,11 @@ .dome-xTabsBar { flex: 0 1 auto ; + flex-flow: row wrap ; position: relative ; height: 20px ; width: calc( 100% + 1px ); /* hides last border */ display: flex ; - flex: row wrap ; border-width: 1px ; border-bottom-style: solid ; } @@ -25,59 +25,57 @@ /* Tab Item */ .dome-xTab { - flex: 1 1 150px ; + display: flex; position: relative ; font-size: 10px ; text-align: center ; - padding: 4px 20px 4px 20px ; + padding: 4px ; border-color: inherit ; border-width: 1px ; border-top-style: none ; border-bottom-style: none ; border-left-style: none ; border-right-style: solid ; + height: 100%; } -.dome-xTab.dome-inactive:hover { - background: var(--background-disabled-hover) ; +.dome-xTab.dome-active { + flex: 1 1 auto ; + background: var(--background-intense); } .dome-xTab.dome-inactive { + flex: 0 1 150px ; color: var(--text-discrete) ; border-color: var(--border) ; - background: var(--background-disabled) ; + background: var(--background-profound); } -/* Closing Tab button */ +.dome-xTab.dome-inactive:hover { + background: var(--background-profound-hover); +} -.dome-xTab-closing { - display: inline ; +.dome-xTab-icon { + flex: 0 0 12px; border-radius: 4px ; - position: absolute ; - width: 12px ; - height: 12px ; - padding: 2px ; - top: 2px ; - opacity: 0 ; - transition: opacity .1s linear 0.1s , background .1s linear 0.1s ; } -.dome-platform-darwin .dome-xTab-closing { - right: initial ; - left: 5px ; +.dome-xTab-icon:hover { + background: var(--background-button-hover); } -.dome-xTab-closing { - right: 5px ; - left: initial ; +.dome-xTab-icon.dome-inactive { + fill: var() } -.dome-xTab-closing:hover { - background: var(--background-button-hover); +.dome-xTab-label { + flex: 0 1 auto; + overflow: hidden; + text-overflow: ellipsis; } -.dome-xTab:hover .dome-xTab-closing { - opacity: 1 ; +.dome-xTab-filler { + flex: 1 1 0px; } /* -------------------------------------------------------------------------- */ diff --git a/ivette/src/dome/renderer/frame/tabs.tsx b/ivette/src/dome/renderer/frame/tabs.tsx index 66034cd9731c5e4e1070bf18ae50f85089c39ccd..50ca8f5509e458c4852de53df404b75296052b35 100644 --- a/ivette/src/dome/renderer/frame/tabs.tsx +++ b/ivette/src/dome/renderer/frame/tabs.tsx @@ -31,6 +31,7 @@ import React from 'react'; import { Icon } from 'dome/controls/icons'; +import { classes } from 'dome/misc/utils'; import './style.css'; @@ -55,48 +56,76 @@ export function TabsBar(props: TabsBarProps): JSX.Element { // --- Single Tab // -------------------------------------------------------------------------- -export interface TabProps<A> { - /** Tab's identifier. */ - value: A; +export interface TabIcon { + icon: string; + title?: string; + display?: boolean; + enabled?: boolean; + onClick?: () => void; +} + +export interface TabProps { + /** Tab's label icon. */ + icon?: string; /** Tab's label. */ label?: string; /** Tab's tooltip text. */ title?: string; - /** Close tab's tooltip text. */ - closing?: string; /** Currently selected tab. */ - selection?: A; + selected: boolean; + headIcons?: TabIcon[]; + tailIcons?: TabIcon[]; /** Selection callback. */ - onSelection?: (value: A) => void; - /** Closing callback. */ - onClose?: (value: A) => void; + onSelection: () => void; } /** Tab Selector. */ -export function Tab<A>(props: TabProps<A>): JSX.Element { - const { value, selection, onSelection, onClose } = props; - const selected = value === selection; +export function Tab(props: TabProps): JSX.Element { + const { icon, selected, onSelection } = props; // --- Tab Rendering - const onSelect = onSelection && (() => onSelection(value)); - const onClosed = onClose && (() => onClose(value)); - const closing = onClose ? ( - <Icon - className="dome-xTab-closing" - title={props.closing || 'Close Tab'} - id="CROSS" - onClick={onClosed} - /> - ) : undefined; - const classes = `dome-xTab${selected ? ' dome-active' : ' dome-inactive'}`; + const { headIcons = [], tailIcons = [] } = props; + const makeIcon = (icn: TabIcon): JSX.Element | null => { + const { icon, title, display = true, enabled = true } = icn; + if (!display) return null; + const className = classes( + 'dome-xTab-icon', + !enabled && 'dome-control-disabled' + ); + return ( + <Icon key={icon} + className={className} + title={title} + id={icon} size={10} offset={1} + onClick={enabled ? icn.onClick : undefined} + /> + ); + }; + const labelIcon = icon ? ( + <Icon key='icon' + className='dome-xTab-icon' + id={icon} size={10} offset={1} /> + ) : null; + const header = selected ? headIcons.map(makeIcon) : null; + const trailer = selected ? tailIcons.map(makeIcon) : null; + const classNames = classes( + 'dome-xTab', + selected ? 'dome-active' : 'dome-inactive' + ); return ( - <label - className={classes} + <div + className={classNames} title={props.title} - onClick={onSelect} + onClick={onSelection} > - {props.label} - {closing} - </label> + {header} + <div className='dome-xTab-filler' /> + {labelIcon} + <label key='name' className='dome-xTab-label'> + {props.label} + </label> + <div className='dome-xTab-filler' /> + {trailer} + </div> ); }