CSS editor layout fixes and scrolling

Major CSS improvements to layout at small screen sizes. By adding min-width: 0 and min-height: 0 on the nested display: flex structure, widgets no longer coerce the whole layout into large-scale resizing. Scrollbars are now used to allow correct overflowing of the tab bar (fixes #177), Document Panel options bar, and tool shelf. Improvements to responsive resizing are also included for viewing the UI correctly on mobile now. Additional small fixes to styling of widget colors and corner roundness. The ruler has been darkened one shade to improve text contrast and aesthetics.
This commit is contained in:
Keavon Chambers 2021-12-04 22:30:07 -08:00
parent 9904021744
commit 54590d594a
16 changed files with 105 additions and 20 deletions

View file

@ -70,6 +70,7 @@ body,
height: 100%;
background: var(--color-2-mildblack);
user-select: none;
overscroll-behavior: none;
}
html,
@ -78,6 +79,7 @@ input,
textarea,
button {
font-family: "Source Sans Pro", Arial, sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1;
color: var(--color-e-nearwhite);
@ -104,10 +106,12 @@ img {
// WebKit
&::-webkit-scrollbar {
width: calc(2px + 6px + 2px);
height: calc(2px + 6px + 2px);
}
&:not(:hover)::-webkit-scrollbar {
width: 0;
height: 0;
}
&::-webkit-scrollbar-track {

View file

@ -9,6 +9,8 @@
display: flex;
flex-direction: column;
flex-grow: 1;
min-width: 0;
min-height: 0;
.spacer {
flex: 1 1 100%;

View file

@ -9,6 +9,8 @@
display: flex;
flex-direction: row;
flex-grow: 1;
min-width: 0;
min-height: 0;
.spacer {
flex: 1 1 100%;

View file

@ -1,6 +1,6 @@
<template>
<LayoutCol :class="'document'">
<LayoutRow :class="'options-bar'">
<LayoutRow :class="'options-bar scrollable-x'">
<div class="left side">
<DropdownInput :menuEntries="documentModeEntries" v-model:selectedIndex="documentModeSelectionIndex" :drawIcon="true" />
@ -34,7 +34,7 @@
<Separator :type="SeparatorType.Unrelated" />
<RadioInput :entries="viewModeEntries" v-model:selectedIndex="viewModeIndex" />
<RadioInput :entries="viewModeEntries" v-model:selectedIndex="viewModeIndex" class="combined-after" />
<PopoverButton>
<h3>View Mode</h3>
<p>The contents of this popover menu are coming soon</p>
@ -42,7 +42,7 @@
<Separator :type="SeparatorType.Section" />
<NumberInput @update:value="setRotation" v-model:value="documentRotation" :incrementFactor="15" :unit="`°`" ref="rotation" />
<NumberInput @update:value="setRotation" v-model:value="documentRotation" :incrementFactor="15" :unit="`°`" />
<Separator :type="SeparatorType.Section" />
@ -68,7 +68,7 @@
</LayoutRow>
<LayoutRow :class="'shelf-and-viewport'">
<LayoutCol :class="'shelf'">
<div class="tools">
<div class="tools scrollable-y">
<ShelfItemInput icon="LayoutSelectTool" title="Select Tool (V)" :active="activeTool === 'Select'" :action="() => selectTool('Select')" />
<ShelfItemInput icon="LayoutCropTool" title="Crop Tool" :active="activeTool === 'Crop'" :action="() => comingSoon(289) && selectTool('Crop')" />
<ShelfItemInput icon="LayoutNavigateTool" title="Navigate Tool (Z)" :active="activeTool === 'Navigate'" :action="() => comingSoon(155) && selectTool('Navigate')" />
@ -163,6 +163,10 @@
align-items: center;
margin: 0 4px;
}
.spacer {
min-width: 40px;
}
}
.shelf-and-viewport {
@ -171,7 +175,17 @@
display: flex;
flex-direction: column;
.tools {
flex: 0 1 auto;
}
.spacer {
flex: 1 0 auto;
min-height: 8px;
}
.working-colors .swap-and-reset {
flex: 0 0 auto;
display: flex;
}
}

View file

@ -132,6 +132,7 @@
.layer {
display: flex;
min-width: 0;
align-items: center;
border-radius: 2px;
background: var(--color-5-dullgray);
@ -150,6 +151,7 @@
height: 100%;
background: white;
border-radius: 2px;
flex: 0 0 auto;
svg {
width: calc(100% - 4px);
@ -161,6 +163,20 @@
.layer-type-icon {
margin-left: 8px;
margin-right: 4px;
flex: 0 0 auto;
}
.layer-name {
display: flex;
min-width: 0;
flex: 1 1 100%;
margin-right: 8px;
span {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
}

View file

@ -15,7 +15,10 @@
border: none;
border-radius: 2px;
background: none;
fill: var(--color-e-nearwhite);
svg {
fill: var(--color-e-nearwhite);
}
// The `where` pseudo-class does not contribtue to specificity
& + :where(.icon-button) {
@ -25,7 +28,10 @@
&:hover {
background: var(--color-6-lowergray);
color: var(--color-f-white);
fill: var(--color-f-white);
svg {
fill: var(--color-f-white);
}
}
&.size-12 {

View file

@ -29,11 +29,16 @@
flex-direction: row-reverse;
label {
flex: 0 0 auto;
cursor: text;
flex: 1 1 100%;
line-height: 18px;
margin-left: 8px;
padding: 3px 0;
overflow: hidden;
text-overflow: ellipsis;
}
&:not(.disabled) label {
cursor: text;
}
input {
@ -54,7 +59,6 @@
&:not(:focus).has-label {
text-align: right;
padding-left: 4px;
margin-left: 0;
margin-right: 8px;
}

View file

@ -58,6 +58,11 @@
.text-label {
margin: 0 4px;
}
&.combined-before button:first-of-type,
&.combined-after button:last-of-type {
border-radius: 0;
}
}
</style>

View file

@ -10,7 +10,7 @@
line-height: 18px;
&.bold {
font-weight: bold;
font-weight: 700;
}
&.italic {

View file

@ -37,6 +37,7 @@
.input-key {
font-family: "Inconsolata", monospace;
font-weight: 400;
text-align: center;
color: var(--color-e-nearwhite);
border: 1px;

View file

@ -10,7 +10,7 @@
<style lang="scss">
.canvas-ruler {
flex: 1 1 100%;
background: var(--color-5-dullgray);
background: var(--color-4-dimgray);
overflow: hidden;
position: relative;

View file

@ -44,7 +44,7 @@
.plus {
display: flex;
align-items: center;
font-weight: bold;
font-weight: 700;
}
.user-input-label + .user-input-label {

View file

@ -10,7 +10,10 @@
display: flex;
align-items: center;
padding: 0 8px;
fill: var(--color-e-nearwhite);
svg {
fill: var(--color-e-nearwhite);
}
.text-label {
margin-right: 8px;
@ -19,7 +22,10 @@
&:hover {
background: var(--color-6-lowergray);
color: var(--color-f-white);
fill: var(--color-f-white);
svg {
fill: var(--color-f-white);
}
}
}
</style>

View file

@ -1,14 +1,14 @@
<template>
<div class="panel">
<div class="tab-bar" :class="{ 'min-widths': tabMinWidths }">
<div class="tab-group">
<div class="tab-group scrollable-x">
<div
class="tab"
:class="{ active: tabIndex === tabActiveIndex }"
v-for="(tabLabel, tabIndex) in tabLabels"
:key="tabIndex"
@click.middle="
(e) => {
(e) => {
e.stopPropagation();
closeDocumentWithConfirmation(tabIndex);
}
@ -63,7 +63,17 @@
flex: 1 1 100%;
display: flex;
flex-direction: row;
overflow: hidden;
position: relative;
// This always hangs out at the end of the last tab, providing 16px (15px plus the 1px reserved for the separator line) to the right of the tabs.
// When the last tab is selected, its bottom rounded fillet adds 16px to the width, which stretches the scrollbar width allocation in only that situation.
// This pseudo-element ensures we always reserve that space to prevent the scrollbar from jumping when the last tab is selected.
// There is unfortunately no apparent way to remove that 16px gap from the end of the scroll container, since negative margin does not reduce the scrollbar allocation.
&::after {
content: "";
width: 15px;
flex: 0 0 auto;
}
.tab {
height: 100%;

View file

@ -7,6 +7,7 @@
:tabMinWidths="true"
:tabLabels="documents.documents.map((doc) => doc.displayName)"
:tabActiveIndex="documents.activeDocumentIndex"
ref="documentsPanel"
/>
</LayoutCol>
<LayoutCol class="workspace-grid-resize-gutter"></LayoutCol>
@ -70,5 +71,20 @@ export default defineComponent({
data() {
return {};
},
computed: {
activeDocumentIndex() {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (this as any).documents.activeDocumentIndex;
},
},
watch: {
activeDocumentIndex(newIndex: number) {
this.$nextTick(() => {
const documentsPanel = this.$refs.documentsPanel as typeof Panel;
const newActiveTab = documentsPanel.$el.querySelectorAll(".tab-bar .tab-group .tab")[newIndex];
newActiveTab.scrollIntoView();
});
},
},
});
</script>