diff --git a/css/60_photos.css b/css/60_photos.css
index dece57cca5..3d4de13417 100644
--- a/css/60_photos.css
+++ b/css/60_photos.css
@@ -1,12 +1,17 @@
/* photo viewer div */
#photoviewer {
position: absolute;
- bottom: 30px;
+ bottom: 40px;
+ left: 10px;
width: 330px;
height: 250px;
padding: 5px;
background-color: #fff;
}
+[dir='rtl'] #photoviewer {
+ left: auto;
+ right: 10px;
+}
@media screen and (min-width: 1600px) {
#photoviewer {
@@ -345,4 +350,3 @@ label.streetside-hires {
background: rgba(0,0,0,0.85);
color: #fff;
}
-
diff --git a/css/80_app.css b/css/80_app.css
index 307eafdfb7..5888cd007d 100644
--- a/css/80_app.css
+++ b/css/80_app.css
@@ -83,17 +83,9 @@ body {
margin-right: 10px;
}
-.limiter {
- position: relative;
- max-width: 1200px;
-}
-
.spinner {
opacity: .5;
- float: right;
-}
-[dir='rtl'] .spinner {
- float: left;
+ display: inline-block;
}
.spinner img {
@@ -446,6 +438,13 @@ button.minor:hover {
padding-right: 10px;
margin: 0;
}
+[dir='rtl'] .button-wrap {
+ padding-left: 10px;
+}
+.button-wrap button {
+ white-space: nowrap;
+ padding: 0px 8px;
+}
.button-wrap button:only-child {
width: 100%;
@@ -456,7 +455,6 @@ button.minor:hover {
}
[dir='rtl'] .button-wrap:last-of-type {
padding-left: 0;
- padding-right: 10px;
}
.joined button {
@@ -511,51 +509,38 @@ button.secondary-action:focus,
button.secondary-action:hover {
background: #cccccc;
}
+.button-wrap.sidebar-collapse,
+.button-wrap.save-wrap {
+ min-width: 33.3333%;
+}
+.button-wrap.modes {
+ width: 100%;
+}
+button.undo-button,
+button.redo-button {
+ width: 44px;
+}
+button.save {
+ padding: 0;
+ display: flex;
+}
+button.save .save-inner-wrap {
+ flex: 1;
+}
button.save .count {
display: none;
}
-
button.save.has-count .count {
- display: block;
- position: absolute;
- top: 5px;
- background: #fff;
- border-color: #fff;
- opacity: 0.5;
+ display: inline-block;
color: #333;
- padding: 10px;
- height: 30px;
- line-height: 12px;
- border-radius: 4px;
- margin: auto;
- margin-left: 9.3333%;
+ border: 0px solid rgba(51, 51, 51, 0.2);
+ border-left-width: 1px;
+ padding: 0px 12px;
}
[dir='rtl'] button.save.has-count .count {
- margin-left: auto;
- margin-right: 8%;
-}
-
-button.save.has-count .count::before {
- content: "";
- margin: auto;
- width: 0;
- height: 0;
- position: absolute;
- left: -6px;
- top: 0;
- bottom: 0;
- border-top: 6px solid transparent;
- border-bottom: 6px solid transparent;
- border-right-width: 6px;
- border-right-style: solid;
- border-right-color: inherit;
-}
-[dir='rtl'] button.save.has-count .count::before {
- border-left: 6px solid rgba(255,255,255,.5);
- border-right: none;
- left: auto;
- right: -6px;
+ border-left-width: 0px;
+ border-right-width: 1px;
}
.help-wrap svg.icon.pre-text.add-note,
@@ -637,21 +622,58 @@ button.add-note svg.icon {
/* Toolbar / Persistent UI Elements
------------------------------------------------------- */
#bar {
- position: fixed;
- padding: 10px 0;
+ position: absolute;
+ padding: 10px;
left: 0;
top: 0;
right: 0;
height: 60px;
z-index: 9;
- min-width: 768px;
+ min-width: 600px;
}
-[dir='rtl'] #bar .spacer,
-[dir='rtl'] #bar .button-wrap,
[dir='rtl'] #bar .button-wrap button {
float: right;
}
+#bar .center-area,
+#bar .trailing-area {
+ min-width: 50%;
+}
+.sidebar-collapsed #bar .leading-area,
+.sidebar-collapsed #bar .center-area,
+.sidebar-collapsed #bar .trailing-area {
+ min-width: 33.3333%;
+}
+#bar .center-area {
+ float: left;
+}
+[dir='rtl'] #bar .center-area {
+ float: right;
+}
+.sidebar-collapsed #bar .center-area {
+ position: absolute;
+ left: 50%;
+ transform: translateX(-50%);
+ float: none;
+}
+#bar .leading-area {
+ float: left;
+ display: none;
+}
+[dir='rtl'] #bar .leading-area {
+ float: right;
+}
+.sidebar-collapsed #bar .leading-area {
+ display: inline-block;
+}
+#bar .trailing-area {
+ float: right;
+ text-align: right;
+}
+[dir='rtl'] #bar .trailing-area {
+ float: left;
+ text-align: left;
+}
/* Header for modals / panes
@@ -779,6 +801,26 @@ a.hide-toggle {
padding-bottom: 5px;
}
+#sidebar-resizer {
+ position: absolute;
+ top: 0;
+ right: -6px;
+ height: 100%;
+ width: 6px;
+ cursor: col-resize;
+}
+.sidebar-collapsed #sidebar-resizer {
+ /* make target wider to avoid the user accidentally resizing window */
+ width: 10px;
+ right: -10px;
+}
+[dir='rtl'] #sidebar-resizer {
+ right: auto;
+ left: -6px;
+}
+.sidebar-collapsed[dir='rtl'] #sidebar-resizer {
+ left: -10px;
+}
/* Sidebar / Inspector
------------------------------------------------------- */
@@ -786,13 +828,16 @@ a.hide-toggle {
position: relative;
float: left;
height: 100%;
- overflow: hidden;
z-index: 10;
background: #f6f6f6;
-ms-user-select: element;
+ border: 0px solid #ccc;
+ border-right-width: 1px;
}
[dir='rtl'] #sidebar {
float: right;
+ border-right-width: 0px;
+ border-left-width: 1px;
}
.sidebar-component {
@@ -828,6 +873,8 @@ a.hide-toggle {
.inspector-wrap {
width: 100%;
height: 100%;
+ overflow: hidden;
+ position: relative;
}
.inspector-hidden {
@@ -2620,9 +2667,10 @@ input.key-trap {
/* Fullscreen Button (disabled)
------------------------------------------------------- */
div.full-screen {
- float: right;
+ display: inline-block;
width: 40px;
margin-right: 10px;
+ display: none;
}
div.full-screen .tooltip {
@@ -4261,6 +4309,7 @@ svg.mouseclick use.right {
display: none;
color: #333;
font-size: 12px;
+ white-space: initial;
}
.tooltip.in {
@@ -4459,13 +4508,6 @@ svg.mouseclick use.right {
}
/* Move over tooltips that are near the edge of screen */
-.add-point .tooltip {
- left: 33.3333% !important;
-}
-[dir='rtl'] .add-point .tooltip {
- left: inherit !important;
-}
-
.add-point .tooltip .tooltip-arrow {
left: 60px;
}
@@ -4590,10 +4632,6 @@ li.hide + li.version .badge .tooltip .tooltip-arrow {
/* Media Queries
------------------------------------------------------- */
-@media only screen and (max-width: 840px) {
- /* override hide for save button */
- #bar .save .label { display: block;}
-}
@media screen and (max-width: 1200px) {
.user-list { display: none !important; }
}
@@ -4797,5 +4835,3 @@ li.hide + li.version .badge .tooltip .tooltip-arrow {
width: 100px;
color: #7092ff;
}
-
-
diff --git a/data/core.yaml b/data/core.yaml
index 55b8468403..045db64960 100644
--- a/data/core.yaml
+++ b/data/core.yaml
@@ -294,6 +294,9 @@ en:
loading_auth: "Connecting to OpenStreetMap..."
report_a_bug: Report a bug
help_translate: Help translate
+ sidebar_button:
+ title: Sidebar
+ tooltip: Open the sidebar.
feature_info:
hidden_warning: "{count} hidden features"
hidden_details: "These features are currently hidden: {details}"
diff --git a/dist/locales/en.json b/dist/locales/en.json
index ec8f839ab0..c70e6600fc 100644
--- a/dist/locales/en.json
+++ b/dist/locales/en.json
@@ -373,6 +373,10 @@
"loading_auth": "Connecting to OpenStreetMap...",
"report_a_bug": "Report a bug",
"help_translate": "Help translate",
+ "sidebar_button": {
+ "title": "Sidebar",
+ "tooltip": "Open the sidebar."
+ },
"feature_info": {
"hidden_warning": "{count} hidden features",
"hidden_details": "These features are currently hidden: {details}"
diff --git a/modules/ui/init.js b/modules/ui/init.js
index 4059f94204..9ce38a0425 100644
--- a/modules/ui/init.js
+++ b/modules/ui/init.js
@@ -2,7 +2,6 @@ import {
event as d3_event,
select as d3_select
} from 'd3-selection';
-import { dispatch as d3_dispatch } from 'd3-dispatch';
import { d3keybinding as d3_keybinding } from '../lib/d3.keybinding.js';
@@ -11,10 +10,8 @@ import { tooltip } from '../util/tooltip';
import { behaviorHash } from '../behavior';
import { modeBrowse } from '../modes';
-import { services } from '../services';
import { svgDefs, svgIcon } from '../svg';
import { utilGetDimensions } from '../util/dimensions';
-import { utilRebind } from '../util';
import { uiAccount } from './account';
import { uiAttribution } from './attribution';
@@ -31,6 +28,7 @@ import { uiMapData } from './map_data';
import { uiMapInMap } from './map_in_map';
import { uiModes } from './modes';
import { uiNotice } from './notice';
+import { uiPhotoviewer } from './photoviewer';
import { uiRestore } from './restore';
import { uiSave } from './save';
import { uiScale } from './scale';
@@ -47,8 +45,6 @@ import { uiCmd } from './cmd';
export function uiInit(context) {
var uiInitCounter = 0;
- var dispatch = d3_dispatch('photoviewerResize');
-
function render(container) {
container
@@ -71,7 +67,6 @@ export function uiInit(context) {
container
.append('div')
.attr('id', 'sidebar')
- .attr('class', 'col4')
.call(ui.sidebar);
var content = container
@@ -95,38 +90,55 @@ export function uiInit(context) {
.call(uiInfo(context))
.call(uiNotice(context));
- bar
+ var leadingArea = bar
.append('div')
- .attr('class', 'spacer col4');
-
- var limiter = bar.append('div')
- .attr('class', 'limiter');
+ .attr('class', 'leading-area');
- limiter
+ var sidebarButton = leadingArea
.append('div')
- .attr('class', 'button-wrap joined col3')
- .call(uiModes(context), limiter);
+ .attr('class', 'button-wrap sidebar-collapse')
+ .append('button')
+ .attr('class', 'col12')
+ .attr('tabindex', -1)
+ .on('click', ui.sidebar.toggleCollapse)
+ .call(tooltip().title(t('sidebar_button.tooltip')).placement('bottom'));
+ var iconSuffix = textDirection === 'rtl' ? 'right' : 'left';
+ sidebarButton
+ .call(svgIcon('#iD-icon-sidebar-'+iconSuffix, 'pre-text'))
+ .append('span')
+ .attr('class', 'label')
+ .text(t('sidebar_button.title'));
- limiter
+ bar
.append('div')
- .attr('class', 'button-wrap joined col1')
- .call(uiUndoRedo(context));
+ .attr('class', 'center-area')
+ .append('div')
+ .attr('class', 'modes button-wrap joined')
+ .call(uiModes(context), bar);
- limiter
+ var trailingArea = bar
.append('div')
- .attr('class', 'button-wrap col1')
- .call(uiSave(context));
+ .attr('class', 'trailing-area');
- bar
+ trailingArea
.append('div')
.attr('class', 'full-screen')
.call(uiFullScreen(context));
- bar
+ trailingArea
.append('div')
.attr('class', 'spinner')
.call(uiSpinner(context));
+ trailingArea
+ .append('div')
+ .attr('class', 'button-wrap joined')
+ .call(uiUndoRedo(context));
+
+ trailingArea
+ .append('div')
+ .attr('class', 'button-wrap save-wrap')
+ .call(uiSave(context));
var controls = bar
.append('div')
@@ -242,46 +254,12 @@ export function uiInit(context) {
.call(uiContributors(context));
- var photoviewer = content
+ content
.append('div')
.attr('id', 'photoviewer')
.classed('al', true) // 'al'=left, 'ar'=right
- .classed('hide', true);
-
- photoviewer
- .append('button')
- .attr('class', 'thumb-hide')
- .on('click', function () {
- if (services.streetside) { services.streetside.hideViewer(); }
- if (services.mapillary) { services.mapillary.hideViewer(); }
- if (services.openstreetcam) { services.openstreetcam.hideViewer(); }
- })
- .append('div')
- .call(svgIcon('#iD-icon-close'));
-
- photoviewer
- .append('button')
- .attr('class', 'resize-handle-xy')
- .on(
- 'mousedown',
- buildResizeListener(photoviewer, 'photoviewerResize', dispatch, { resizeOnX: true, resizeOnY: true })
- );
-
- photoviewer
- .append('button')
- .attr('class', 'resize-handle-x')
- .on(
- 'mousedown',
- buildResizeListener(photoviewer, 'photoviewerResize', dispatch, { resizeOnX: true })
- );
-
- photoviewer
- .append('button')
- .attr('class', 'resize-handle-y')
- .on(
- 'mousedown',
- buildResizeListener(photoviewer, 'photoviewerResize', dispatch, { resizeOnY: true })
- );
+ .classed('hide', true)
+ .call(ui.photoviewer);
var mapDimensions = map.dimensions();
@@ -295,10 +273,9 @@ export function uiInit(context) {
};
d3_select(window)
- .on('resize.editor', onResize);
-
- onResize();
+ .on('resize.editor', ui.onResize);
+ ui.onResize();
var pa = 80; // pan amount
var keybinding = d3_keybinding('main')
@@ -350,83 +327,12 @@ export function uiInit(context) {
}
- function onResize() {
- mapDimensions = utilGetDimensions(content, true);
- map.dimensions(mapDimensions);
-
- // shrink photo viewer if it is too big
- // (-90 preserves space at top and bottom of map used by menus)
- var photoDimensions = utilGetDimensions(photoviewer, true);
- if (photoDimensions[0] > mapDimensions[0] || photoDimensions[1] > (mapDimensions[1] - 90)) {
- var setPhotoDimensions = [
- Math.min(photoDimensions[0], mapDimensions[0]),
- Math.min(photoDimensions[1], mapDimensions[1] - 90),
- ];
-
- photoviewer
- .style('width', setPhotoDimensions[0] + 'px')
- .style('height', setPhotoDimensions[1] + 'px');
-
- dispatch.call('photoviewerResize', photoviewer, setPhotoDimensions);
- }
- }
-
-
function pan(d) {
return function() {
d3_event.preventDefault();
context.pan(d, 100);
};
}
-
- function buildResizeListener(target, eventName, dispatch, options) {
- var resizeOnX = !!options.resizeOnX;
- var resizeOnY = !!options.resizeOnY;
- var minHeight = options.minHeight || 240;
- var minWidth = options.minWidth || 320;
- var startX;
- var startY;
- var startWidth;
- var startHeight;
-
- function startResize() {
- var mapSize = context.map().dimensions();
-
- if (resizeOnX) {
- var maxWidth = mapSize[0];
- var newWidth = clamp((startWidth + d3_event.clientX - startX), minWidth, maxWidth);
- target.style('width', newWidth + 'px');
- }
-
- if (resizeOnY) {
- var maxHeight = mapSize[1] - 90; // preserve space at top/bottom of map
- var newHeight = clamp((startHeight + startY - d3_event.clientY), minHeight, maxHeight);
- target.style('height', newHeight + 'px');
- }
-
- dispatch.call(eventName, target, utilGetDimensions(target, true));
- }
-
- function clamp(num, min, max) {
- return Math.max(min, Math.min(num, max));
- }
-
- function stopResize() {
- d3_select(window)
- .on('.' + eventName, null);
- }
-
- return function initResize() {
- startX = d3_event.clientX;
- startY = d3_event.clientY;
- startWidth = target.node().getBoundingClientRect().width;
- startHeight = target.node().getBoundingClientRect().height;
-
- d3_select(window)
- .on('mousemove.' + eventName, startResize, false)
- .on('mouseup.' + eventName, stopResize, false);
- };
- }
}
@@ -461,5 +367,15 @@ export function uiInit(context) {
ui.sidebar = uiSidebar(context);
- return utilRebind(ui, dispatch, 'on');
+ ui.photoviewer = uiPhotoviewer(context);
+
+ ui.onResize = function() {
+ var content = d3_select('#content');
+ var mapDimensions = utilGetDimensions(content, true);
+ context.map().dimensions(mapDimensions);
+
+ ui.photoviewer.onMapResize();
+ };
+
+ return ui;
}
diff --git a/modules/ui/modes.js b/modules/ui/modes.js
index 25aff9f83f..3ccd5dcaf6 100644
--- a/modules/ui/modes.js
+++ b/modules/ui/modes.js
@@ -91,10 +91,6 @@ export function uiModes(context) {
var showNotes = notesEnabled();
var data = showNotes ? modes : modes.slice(0, 3);
- selection
- .classed('col3', !showNotes) // 25%
- .classed('col4', showNotes); // 33%
-
var buttons = selection.selectAll('button.add-button')
.data(data, function(d) { return d.id; });
diff --git a/modules/ui/photoviewer.js b/modules/ui/photoviewer.js
new file mode 100644
index 0000000000..9be65f7e9c
--- /dev/null
+++ b/modules/ui/photoviewer.js
@@ -0,0 +1,125 @@
+import {
+ event as d3_event,
+ select as d3_select
+} from 'd3-selection';
+
+import { dispatch as d3_dispatch } from 'd3-dispatch';
+import { svgIcon } from '../svg';
+import { utilGetDimensions } from '../util/dimensions';
+import { utilRebind } from '../util';
+import { services } from '../services';
+
+export function uiPhotoviewer(context) {
+
+ var dispatch = d3_dispatch('photoviewerResize');
+
+ function photoviewer(selection) {
+ selection
+ .append('button')
+ .attr('class', 'thumb-hide')
+ .on('click', function () {
+ if (services.streetside) { services.streetside.hideViewer(); }
+ if (services.mapillary) { services.mapillary.hideViewer(); }
+ if (services.openstreetcam) { services.openstreetcam.hideViewer(); }
+ })
+ .append('div')
+ .call(svgIcon('#iD-icon-close'));
+
+ selection
+ .append('button')
+ .attr('class', 'resize-handle-xy')
+ .on(
+ 'mousedown',
+ buildResizeListener(selection, 'photoviewerResize', dispatch, { resizeOnX: true, resizeOnY: true })
+ );
+
+ selection
+ .append('button')
+ .attr('class', 'resize-handle-x')
+ .on(
+ 'mousedown',
+ buildResizeListener(selection, 'photoviewerResize', dispatch, { resizeOnX: true })
+ );
+
+ selection
+ .append('button')
+ .attr('class', 'resize-handle-y')
+ .on(
+ 'mousedown',
+ buildResizeListener(selection, 'photoviewerResize', dispatch, { resizeOnY: true })
+ );
+
+
+ function buildResizeListener(target, eventName, dispatch, options) {
+ var resizeOnX = !!options.resizeOnX;
+ var resizeOnY = !!options.resizeOnY;
+ var minHeight = options.minHeight || 240;
+ var minWidth = options.minWidth || 320;
+ var startX;
+ var startY;
+ var startWidth;
+ var startHeight;
+
+ function startResize() {
+ var mapSize = context.map().dimensions();
+
+ if (resizeOnX) {
+ var maxWidth = mapSize[0];
+ var newWidth = clamp((startWidth + d3_event.clientX - startX), minWidth, maxWidth);
+ target.style('width', newWidth + 'px');
+ }
+
+ if (resizeOnY) {
+ var maxHeight = mapSize[1] - 90; // preserve space at top/bottom of map
+ var newHeight = clamp((startHeight + startY - d3_event.clientY), minHeight, maxHeight);
+ target.style('height', newHeight + 'px');
+ }
+
+ dispatch.call(eventName, target, utilGetDimensions(target, true));
+ }
+
+ function clamp(num, min, max) {
+ return Math.max(min, Math.min(num, max));
+ }
+
+ function stopResize() {
+ d3_select(window)
+ .on('.' + eventName, null);
+ }
+
+ return function initResize() {
+ startX = d3_event.clientX;
+ startY = d3_event.clientY;
+ startWidth = target.node().getBoundingClientRect().width;
+ startHeight = target.node().getBoundingClientRect().height;
+
+ d3_select(window)
+ .on('mousemove.' + eventName, startResize, false)
+ .on('mouseup.' + eventName, stopResize, false);
+ };
+ }
+ }
+
+ photoviewer.onMapResize = function() {
+ var photoviewer = d3_select('#photoviewer');
+ var content = d3_select('#content');
+ var mapDimensions = utilGetDimensions(content, true);
+ // shrink photo viewer if it is too big
+ // (-90 preserves space at top and bottom of map used by menus)
+ var photoDimensions = utilGetDimensions(photoviewer, true);
+ if (photoDimensions[0] > mapDimensions[0] || photoDimensions[1] > (mapDimensions[1] - 90)) {
+ var setPhotoDimensions = [
+ Math.min(photoDimensions[0], mapDimensions[0]),
+ Math.min(photoDimensions[1], mapDimensions[1] - 90),
+ ];
+
+ photoviewer
+ .style('width', setPhotoDimensions[0] + 'px')
+ .style('height', setPhotoDimensions[1] + 'px');
+
+ dispatch.call('photoviewerResize', photoviewer, setPhotoDimensions);
+ }
+ };
+
+ return utilRebind(photoviewer, dispatch, 'on');
+}
diff --git a/modules/ui/save.js b/modules/ui/save.js
index d515b57f84..fa23d30253 100644
--- a/modules/ui/save.js
+++ b/modules/ui/save.js
@@ -69,9 +69,7 @@ export function uiSave(context) {
.style('background', background);
button.select('span.count')
- .text(numChanges)
- .style('background', background)
- .style('border-color', background);
+ .text(numChanges);
}
@@ -88,6 +86,8 @@ export function uiSave(context) {
.call(tooltipBehavior);
button
+ .append('div')
+ .attr('class', 'save-inner-wrap')
.call(svgIcon('#iD-icon-save', 'pre-text'))
.append('span')
.attr('class', 'label')
diff --git a/modules/ui/sidebar.js b/modules/ui/sidebar.js
index 33b3df5c03..da5028682a 100644
--- a/modules/ui/sidebar.js
+++ b/modules/ui/sidebar.js
@@ -1,6 +1,11 @@
import _throttle from 'lodash-es/throttle';
-import { selectAll as d3_selectAll } from 'd3-selection';
+import { drag as d3_drag } from 'd3-drag';
+import {
+ select as d3_select,
+ event as d3_event,
+ selectAll as d3_selectAll
+} from 'd3-selection';
import {
osmEntity,
@@ -14,6 +19,8 @@ import {
uiNoteEditor
} from './index';
+import { textDirection } from '../util/locale';
+
export function uiSidebar(context) {
var inspector = uiInspector(context);
@@ -25,6 +32,46 @@ export function uiSidebar(context) {
function sidebar(selection) {
+
+ var resizer = selection
+ .append('div')
+ .attr('id', 'sidebar-resizer');
+
+ // set the initial width constraints
+ selection.style('min-width', '280px');
+ selection.style('max-width', '400px');
+ selection.style('width', '33.3333%');
+
+ var container = d3_select('#id-container');
+ resizer.call(d3_drag()
+ .container(container.node())
+ .on('drag', function() {
+
+ var containerWidthPx = container.node().getBoundingClientRect().width;
+
+ var xMarginProperty = textDirection === 'rtl' ? 'margin-right' : 'margin-left';
+
+ // subtact 1px so the mouse stays in the div and maintains the col-resize cursor
+ var newWidthPx = textDirection === 'rtl' ? containerWidthPx - d3_event.x-1 : d3_event.x-1;
+
+ var shouldCollapse = newWidthPx < 280;
+ container.classed('sidebar-collapsed', shouldCollapse);
+ // allow large widths
+ selection.style('max-width', '85%');
+ if (shouldCollapse) {
+ selection.style(xMarginProperty,'-400px')
+ .style('width', '400px');
+ }
+ else {
+
+ var newWidthPercent = (newWidthPx / containerWidthPx) * 100;
+ selection.style(xMarginProperty, null)
+ .style('width', newWidthPercent+'%');
+ }
+ context.ui().onResize();
+ })
+ );
+
var featureListWrap = selection
.append('div')
.attr('class', 'feature-list-pane')
@@ -93,6 +140,9 @@ export function uiSidebar(context) {
sidebar.select = function(id, newFeature) {
if (!_current && id) {
+ // uncollapse the sidebar to show the editor
+ sidebar.toggleCollapse(false);
+
featureListWrap
.classed('inspector-hidden', true);
@@ -144,6 +194,51 @@ export function uiSidebar(context) {
if (_current) _current.remove();
_current = null;
};
+
+ sidebar.toggleCollapse = function(shouldCollapse) {
+
+ if (d3_event) {
+ d3_event.preventDefault();
+ }
+
+ var container = d3_select('#id-container');
+ var collapsing;
+ var isCollapsed = container.classed('sidebar-collapsed');
+ if (typeof shouldCollapse !== 'undefined') {
+ if (shouldCollapse === isCollapsed) {
+ return;
+ }
+ collapsing = shouldCollapse;
+ } else {
+ collapsing = !isCollapsed;
+ }
+ var sidebar = d3_select('#sidebar');
+ var xMarginProperty = textDirection === 'rtl' ? 'margin-right' : 'margin-left';
+ if (collapsing) {
+ var preSidebarWidthInPx = sidebar.node().getBoundingClientRect().width;
+ sidebar.style('width', preSidebarWidthInPx+'px');
+ sidebar.transition()
+ .style('width', '400px')
+ .style(xMarginProperty,'-400px')
+ .on('end',function(){
+ context.ui().onResize();
+ });
+ container.classed('sidebar-collapsed', true);
+ } else {
+ var containerWidthPx = container.node().getBoundingClientRect().width;
+ var postSidebarWidthInPx = Math.max(containerWidthPx*0.333333, 280);
+ sidebar.transition()
+ .style('width', postSidebarWidthInPx)
+ .style(xMarginProperty, '0px')
+ .on('end',function(){
+ sidebar.style('width', '33.3333%');
+ context.ui().onResize();
+ });
+ container.classed('sidebar-collapsed', false);
+ }
+ };
+ // toggle the sidebar collapse when double-clicking the resizer
+ resizer.on('dblclick', sidebar.toggleCollapse);
}
@@ -152,6 +247,7 @@ export function uiSidebar(context) {
sidebar.select = function() {};
sidebar.show = function() {};
sidebar.hide = function() {};
+ sidebar.toggleCollapse = function() {};
return sidebar;
}
diff --git a/svg/iD-sprite/icons/icon-sidebar-left.svg b/svg/iD-sprite/icons/icon-sidebar-left.svg
new file mode 100644
index 0000000000..618ce80f0c
--- /dev/null
+++ b/svg/iD-sprite/icons/icon-sidebar-left.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/svg/iD-sprite/icons/icon-sidebar-right.svg b/svg/iD-sprite/icons/icon-sidebar-right.svg
new file mode 100644
index 0000000000..b4ee1d617f
--- /dev/null
+++ b/svg/iD-sprite/icons/icon-sidebar-right.svg
@@ -0,0 +1,7 @@
+
+