diff --git a/app/client/components/GristDoc.ts b/app/client/components/GristDoc.ts index 8e0040d4..d5ce9939 100644 --- a/app/client/components/GristDoc.ts +++ b/app/client/components/GristDoc.ts @@ -34,7 +34,7 @@ import {App} from 'app/client/ui/App'; import {DocHistory} from 'app/client/ui/DocHistory'; import {IPageWidget, toPageWidget} from 'app/client/ui/PageWidgetPicker'; import {IPageWidgetLink, linkFromId, selectBy} from 'app/client/ui/selectBy'; -import {testId} from 'app/client/ui2018/cssVars'; +import {mediaSmall, testId} from 'app/client/ui2018/cssVars'; import {IconName} from 'app/client/ui2018/IconList'; import {ActionGroup} from 'app/common/ActionGroup'; import {delay} from 'app/common/delay'; @@ -687,6 +687,11 @@ const cssViewContentPane = styled('div', ` position: relative; min-width: 240px; margin: 12px; + @media ${mediaSmall} { + & { + margin: 4px; + } + } @media print { & { margin: 0px; diff --git a/app/client/components/Layout.css b/app/client/components/Layout.css index 085a1beb..78c6e842 100644 --- a/app/client/components/Layout.css +++ b/app/client/components/Layout.css @@ -17,6 +17,7 @@ display: -webkit-flex; display: flex; min-width: 0px; + flex-grow: var(--flex-grow, 1) !important; } .layout_hbox.layout_fill_window { diff --git a/app/client/components/Layout.js b/app/client/components/Layout.js index e29b02ea..1814d82a 100644 --- a/app/client/components/Layout.js +++ b/app/client/components/Layout.js @@ -140,7 +140,7 @@ LayoutBox.prototype.buildDom = function() { kd.cssClass(wrap(function() { return (self.layout.fillWindow ? 'layout_fill_window' : (self.isLastChild() ? 'layout_last_child' : null)); })), - kd.style('flexGrow', wrap(function() { + kd.style('--flex-grow', wrap(function() { return (self.isVBox() || (self.isHBox() && self.layout.fillWindow)) ? self.flexSize() : ''; })), kd.domData('layoutBox', this), diff --git a/app/client/components/ViewLayout.css b/app/client/components/ViewLayout.css index 66eed240..339b2e9c 100644 --- a/app/client/components/ViewLayout.css +++ b/app/client/components/ViewLayout.css @@ -4,34 +4,15 @@ } .viewsection_title { - background-color: #e5e5e5; - color: black; flex-shrink: 0; align-items: baseline; - line-height: 2; - cursor: default; -} - -.active_section > .viewsection_title { - background-color: #3e568e; - color: white; -} - -.viewsection_content.newui > .viewsection_title { height: 24px; margin-left: -16px; /* to include drag handle that shows up on hover */ color: var(--grist-color-slate); - background-color: unset; font-size: var(--grist-small-font-size); font-weight: 500; text-transform: uppercase; - line-height: inherit; -} - -.active_section.newui > .viewsection_title { - background-color: unset; - color: var(--grist-color-slate); } .viewsection_titletext { @@ -41,14 +22,8 @@ .viewsection_content { background-color: #ffffff; - margin: 4px; overflow: visible; - box-shadow: 0px 1px 3px 0px rgba(0,0,0,0.8); -} - -.viewsection_content.newui { margin: 12px; - box-shadow: none; } .viewsection_title_colorbox { @@ -59,15 +34,10 @@ box-shadow: inset 0px 0px 5px rgba(0,0,0,0.5); } +/* TODO should be switched to use new icon */ .viewsection_drag_indicator { visibility: hidden; - margin: auto; - padding: 0px 2px; top: 0px; -} - -/* TODO should be switched to use new icon */ -.viewsection_drag_indicator.newui { width: 16px; height: 16px; margin: 0; @@ -131,19 +101,16 @@ .view_data_pane_container { position: relative; flex: auto; -} - -.viewsection_content.newui > .view_data_pane_container { border: 1px solid var(--grist-color-dark-grey); } @media not print { -.active_section.newui > .view_data_pane_container { +.active_section > .view_data_pane_container { box-shadow: -2px 0 0 0px var(--grist-color-light-green); border-left: 1px solid var(--grist-color-light-green); } -.active_section.newui > .view_data_pane_container.viewsection_type_detail { +.active_section > .view_data_pane_container.viewsection_type_detail { /* this color is a translucent version of grist-color-light-green */ box-shadow: -2px 0 0 0px var(--grist-color-inactive-cursor); border-left: 1px solid var(--grist-color-inactive-cursor); diff --git a/app/client/components/ViewLayout.ts b/app/client/components/ViewLayout.ts index c089c081..57e58960 100644 --- a/app/client/components/ViewLayout.ts +++ b/app/client/components/ViewLayout.ts @@ -13,11 +13,11 @@ import {createObsArray} from 'app/client/lib/koArrayWrap'; import {ViewRec, ViewSectionRec} from 'app/client/models/DocModel'; import {reportError} from 'app/client/models/errors'; import {viewSectionMenu} from 'app/client/ui/ViewSectionMenu'; -import {testId} from 'app/client/ui2018/cssVars'; +import {colors, mediaSmall, testId} from 'app/client/ui2018/cssVars'; import {editableLabel} from 'app/client/ui2018/editableLabel'; import {DisposableWithEvents} from 'app/common/DisposableWithEvents'; import {mod} from 'app/common/gutil'; -import {computedArray, Disposable, dom, fromKo, Holder, IDomComponent, subscribe} from 'grainjs'; +import {computedArray, Disposable, dom, fromKo, Holder, IDomComponent, styled, subscribe} from 'grainjs'; import * as ko from 'knockout'; import * as _ from 'underscore'; @@ -121,6 +121,21 @@ export class ViewLayout extends DisposableWithEvents implements IDomComponent { // (See https://stackoverflow.com/questions/2381336/detect-click-into-iframe-using-javascript). this.listenTo(this.gristDoc.app, 'clipboard_blur', this._maybeFocusInSection); + const classActive = cssLayoutBox.className + '-active'; + const classInactive = cssLayoutBox.className + '-inactive'; + this.autoDispose(subscribe(fromKo(this.viewModel.activeSectionId), (use, id) => { + this._layout.forEachBox((box: {dom: Element}) => { + box.dom.classList.add(classInactive); + box.dom.classList.remove(classActive); + }); + let elem: Element|null = this._layout.getLeafBox(id)?.dom; + while (elem?.matches('.layout_box')) { + elem.classList.remove(classInactive); + elem.classList.add(classActive); + elem = elem.parentElement; + } + })); + const commandGroup = { deleteSection: () => { this._removeViewSection(this.viewModel.activeSectionId()); }, nextSection: () => { this._otherSection(+1); }, @@ -158,11 +173,13 @@ export class ViewLayout extends DisposableWithEvents implements IDomComponent { const vs: ViewSectionRec = this.docModel.viewSections.getRowModel(sectionRowId); return dom('div.view_leaf.viewsection_content.flexvbox.flexauto', testId(`viewlayout-section-${sectionRowId}`), - this.gristDoc.app.addNewUIClass(), + + cssViewLeaf.cls(''), + cssViewLeafInactive.cls('', (use) => !vs.isDisposed() && !use(vs.hasFocus)), dom.cls('active_section', vs.hasFocus), + dom.maybe((use) => use(vs.viewInstance) !== null, () => dom('div.viewsection_title.flexhbox', dom('span.viewsection_drag_indicator.glyphicon.glyphicon-option-vertical', - this.gristDoc.app.addNewUIClass(), // Makes element grabbable only if grist is not readonly. dom.cls('layout_grabbable', (use) => !use(this.gristDoc.isReadonlyKo))), dom('div.flexitem.flexhbox', @@ -270,3 +287,79 @@ export class ViewLayout extends DisposableWithEvents implements IDomComponent { } } } + +const cssViewLeaf = styled('div', ` + @media ${mediaSmall} { + & { + margin: 4px; + } + } +`); + +const cssViewLeafInactive = styled('div', ` + @media ${mediaSmall} { + & { + overflow: hidden; + background: repeating-linear-gradient( + -45deg, + ${colors.mediumGreyOpaque}, + ${colors.mediumGreyOpaque} 10px, + ${colors.lightGrey} 10px, + ${colors.lightGrey} 20px + ); + border: 1px solid ${colors.darkGrey}; + border-radius: 4px; + padding: 0 2px; + } + &::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + } + &.layout_vbox { + max-width: 32px; + } + &.layout_hbox { + max-height: 32px; + } + & > .viewsection_title.flexhbox { + position: absolute; + } + & > .view_data_pane_container, + & .viewsection_buttons, + & .grist-single-record__menu { + display: none; + } + } +`); + +const cssLayoutBox = styled('div', ` + @media ${mediaSmall} { + &-active, &-inactive { + transition: flex-grow 0.4s; + } + &-active > &-inactive, + &-active > &-inactive.layout_hbox .layout_hbox, + &-active > &-inactive.layout_vbox .layout_vbox { + flex: none !important; + } + + &-active > &-inactive.layout_hbox.layout_leaf, + &-active > &-inactive.layout_hbox .layout_hbox.layout_leaf { + height: 40px; + } + + &-active > &-inactive.layout_vbox.layout_leaf, + &-active > &-inactive.layout_vbox .layout_vbox.layout_leaf { + width: 40px; + } + + &-inactive.layout_leaf { + min-height: 40px; + min-width: 40px; + } + } +`);