From 958d7fac4fd8a5806d9aaad1f17388b7c9d7f284 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 28 Nov 2018 18:15:38 -0500 Subject: [PATCH 1/5] wip changing all fields to use flexbox everywhere --- css/80_app.css | 837 ++++++++++++++-------------- modules/lib/d3.combobox.js | 4 +- modules/ui/fields/access.js | 5 +- modules/ui/fields/address.js | 6 +- modules/ui/fields/check.js | 3 +- modules/ui/fields/combo.js | 17 +- modules/ui/fields/cycleway.js | 2 +- modules/ui/fields/input.js | 47 +- modules/ui/fields/lanes.js | 2 +- modules/ui/fields/localized.js | 8 +- modules/ui/fields/maxspeed.js | 36 +- modules/ui/fields/radio.js | 4 +- modules/ui/fields/restrictions.js | 2 +- modules/ui/fields/textarea.js | 10 +- modules/ui/fields/wikipedia.js | 35 +- modules/ui/raw_member_editor.js | 2 +- modules/ui/raw_membership_editor.js | 4 +- modules/ui/raw_tag_editor.js | 2 +- 18 files changed, 522 insertions(+), 504 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index e2c7383cd..6bc06047a 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -72,9 +72,12 @@ a, button, input, textarea { -webkit-touch-callout: none; } +ul li { + list-style: none; +} + a, button, -.checkselect label:hover, .radial-menu-item { cursor: pointer; } @@ -193,6 +196,7 @@ input[type="radio"] { height: 14px; margin-right: 5px; margin-top: 3px; + cursor: pointer; } [dir='rtl'] input[type="checkbox"], [dir='rtl'] input[type="radio"] { @@ -201,14 +205,6 @@ input[type="radio"] { margin-right: 0; } - -/* remove bottom border radius when combobox is open */ -.combobox + * textarea:focus, -.combobox + * input:focus { - border-bottom-left-radius: 0 !important; - border-bottom-right-radius: 0 !important; -} - /* tables */ table { background-color: #fff; @@ -234,39 +230,6 @@ table.tags, table.tags td, table.tags th { .col8 { float: left; width: 66.6666%; } .col12 { float: left; width: 100.0000%; } -/* UI Lists -------------------------------------------------------- */ -ul li { list-style: none;} - -.toggle-list > label { - position: relative; - padding: 5px 10px; - display: block; - height: 30px; - background-color: #fff; - color: #7092ff; - cursor: pointer; -} - -.toggle-list > label:hover { - background-color: #ececec; -} -.toggle-list > label:not(:last-child) { - border-bottom: 1px solid #ccc; -} -.toggle-list > label:last-child { - border-radius: 0 0 3px 3px; -} -.toggle-list label > span { - display: block; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} -.toggle-list > label.active { - background: #e8ebff; -} - /* Utility Classes ------------------------------------------------------- */ @@ -308,11 +271,9 @@ li.hide { .deemphasize { color: #a9a9a9; } - .content { box-shadow: 0 0 30px 0 rgba(0, 0, 0, 0.25); } - .loading { background: url(img/loader_bg.gif); background-size: 5px 5px; @@ -338,29 +299,10 @@ button:focus, button:hover { background-color: #ececec; } - button.active { background: #7092ff; } - -button.minor { - height: 100%; - border-radius: 0; - background-color: #fafafa; -} -[dir='rtl'] button.minor { - right: auto; -} - -button.minor .icon { - opacity: .5; -} -button.minor:hover { - background-color: #f1f1f1; -} - -button.disabled, -button.minor.disabled { +button.disabled { background-color: rgba(255,255,255,.25); color: rgba(0,0,0,.4); cursor: not-allowed; @@ -829,15 +771,15 @@ a.hide-toggle { bottom: 0; } -.feature-list-pane .inspector-body { - top: 120px; +.inspector-border { + border-bottom: 1px solid #ccc } + +.feature-list-pane .inspector-body, .preset-list-pane .inspector-body { top: 120px; } -.entity-editor-pane .inspector-body { - top: 60px; -} +.entity-editor-pane .inspector-body, .selection-list-pane .inspector-body { top: 60px; } @@ -874,7 +816,6 @@ a.hide-toggle { } - /* Feature List / Search Results ------------------------------------------------------- */ .feature-list { @@ -907,15 +848,12 @@ a.hide-toggle { height: 40px; line-height: 20px; } - .feature-list-item:hover { background-color: #ececec; } - .feature-list-item button { background: transparent; } - .feature-list-item .label { text-align: left; padding: 10px 10px; @@ -931,24 +869,19 @@ a.hide-toggle { .feature-list-item .label .icon { opacity: .5; } - .feature-list-item .close { float: right; padding: 10px; } - .feature-list-item .close .icon { opacity: 1; } - .feature-list-item .entity-type { color: #7092ff; } - .feature-list-item:hover .entity-type { color: #597be7; } - .feature-list-item .entity-name { font-weight: normal; color: #666; @@ -1158,6 +1091,17 @@ a.hide-toggle { opacity: .5; } +img.tag-reference-wiki-image { + float: right; + width: 33.3333%; + width: -webkit-calc(33.3333% - 10px); + width: calc(33.3333% - 10px); + border-radius: 4px; + max-height: 200px; + margin: 10px 5px 15px 20px; +} + + .current .preset-list-button, .current .preset-list-button .label { background-color: #e8ebff; @@ -1221,9 +1165,30 @@ a.hide-toggle { margin-bottom: 0; } +/* + The parts of a field: + - `.form-field` is a `div` wraps the entire thing + - `.form-field-label` is a `label` that wraps the top part, it contains; + - `span` classed `label-text` + - 0..n buttons for "remove", "modified", "tag reference" + - `.form-field-input-wrap` is a `label` or `div` that wraps the bottom part, it contains; + - usually an `input` + - sometimes some buttons (translate, increment, decrement) + - or could just be a `div` with anything really + - `.tag-reference-body` at the bottom (usually hidden) + + .------------------. - + | Name | i | <- .form-field-label | + +------------------+ | + | Starbucks | + | <- .form-field-input-wrap > .form-field + '------------------' | + tag reference <- .tag-reference-body | + - +*/ + .form-field { display: flex; - flex-wrap: wrap; + flex-flow: row wrap; margin-bottom: 10px; width: 100%; -webkit-transition: margin-bottom 200ms; @@ -1237,15 +1202,17 @@ a.hide-toggle { margin-bottom: 0; } +/* A `label` element that wraps the top section */ .form-field-label { - flex: 1 1 100%; display: flex; + flex-flow: row nowrap; + flex: 1 1 100%; height: 30px; position: relative; font-weight: bold; color: #333; background: #f6f6f6; - border: 1px solid #cfcfcf; + border: 1px solid #ccc; border-radius: 4px 4px 0 0; overflow: hidden; } @@ -1257,15 +1224,8 @@ a.hide-toggle { padding: 5px 10px 5px 0; } -.form-field-label .tag-reference-button { - border-radius: 0 3px 0 0; -} - -.form-field-label .icon { - opacity: .5; -} - .form-field-label button { + flex: 0 0 32px; border-left: 1px solid #ccc; width: 32px; height: 100%; @@ -1275,248 +1235,106 @@ a.hide-toggle { [dir='rtl'] .form-field-label button { border-left: none; border-right: 1px solid #ccc; - border-radius: 4px 0 0 0; } .form-field-label button:hover { background: #f1f1f1; } - -.form-field-label .modified-icon, -.form-field .remove-icon { - display: none; +.form-field-label .icon { + opacity: .5; } +.form-field-label .modified-icon, +.form-field-label .remove-icon { + display: none; +} .modified .form-field-label .modified-icon, .present .form-field-label .remove-icon { display: inline-block; } -.form-field > input, -.form-field > textarea, -.form-field .localized-input-wrap > input, -.form-field .form-field-input-wrap { - border: 1px solid #ccc; +/* A `div` element that wraps the bottom section */ +.form-field-input-wrap { + display: flex; + flex-flow: row nowrap; + flex: 1 1 100%; min-height: 30px; border-top: 0; border-radius: 0 0 4px 4px; +} + +.form-field-input-wrap > input, +.form-field-input-wrap > label, +.form-field-input-wrap > textarea, +.form-field-input-wrap > ul.chiplist { + flex: 1 1 auto; + min-height: 30px; + border: 1px solid #ccc; + border-top: 0; + border-radius: 0; overflow: hidden; position: relative; - flex: 1; } - -.form-field textarea { +.form-field-input-wrap > textarea { height: 65px; + border-radius: 0 0 4px 4px; } -.inspector-border { - border-bottom: 1px solid #ccc -} - -/* Fields - corner radius for fields with following elements on the same line -------------------------------------------------------- */ -[dir='ltr'] .inspector-wrap:not(.inspector-hover) .form-field .wiki-title, -[dir='ltr'] .inspector-wrap:not(.inspector-hover) .form-field .localized-main, -[dir='ltr'] .inspector-wrap:not(.inspector-hover) .form-field .member-role, -[dir='ltr'] .inspector-wrap:not(.inspector-hover) .form-field .spin-control button:first-child, -[dir='ltr'] .inspector-wrap:not(.inspector-hover) .form-field input[type='text'].number, -[dir='ltr'] #preset-input-maxspeed, -[dir='ltr'] #preset-input-maxspeed_advisory { - border-bottom-right-radius: 0; -} -[dir='rtl'] .inspector-wrap:not(.inspector-hover) .form-field .wiki-title, -[dir='rtl'] .inspector-wrap:not(.inspector-hover) .form-field .localized-main, -[dir='rtl'] .inspector-wrap:not(.inspector-hover) .form-field .member-role, -[dir='rtl'] .inspector-wrap:not(.inspector-hover) .form-field .spin-control button:first-child, -[dir='rtl'] .inspector-wrap:not(.inspector-hover) .form-field input[type='text'].number, -[dir='rtl'] #preset-input-maxspeed, -[dir='rtl'] #preset-input-maxspeed_advisory { - border-bottom-left-radius: 0; -} - -/* Inspector (hover styles) -------------------------------------------------------- */ -.inspector-hover .checkselect label:last-of-type, -.inspector-hover .form-field-input-wrap .label, -.inspector-hover .form-field-multicombo, -.inspector-hover .structure-extras-wrap, -.inspector-hover .comments-container .comment, -.inspector-hover input, -.inspector-hover textarea, -.inspector-hover label { - background: #ececec; -} - -.inspector-hover a, -.inspector-hover .form-field-multicombo .chips, -.inspector-hover .checkselect label:last-of-type { - color: #666; -} - -.inspector-hover .form-field-multicombo .chips { - background: #eee; - border: 1px solid #ccc; -} - -/* no scrollbars */ -.inspector-hover div { - overflow-x: hidden; - overflow-y: hidden; -} - -/* hide and remove from layout */ -.inspector-hidden, -.inspector-hover label input[type="checkbox"], -.inspector-hover label input[type="radio"], -.inspector-hover .toggle-list label, -.inspector-hover .toggle-list label span, -.inspector-hover .inspector-inner .add-tag, -.inspector-hover .inspector-inner .add-relation, -.inspector-hover .form-field-multicombo .combobox-input, -.inspector-hover .toggle-list label.remove .icon { - height: 0; - width: 0; - overflow: hidden; - opacity: 0 !important; - border-width: 0; - margin: 0; - padding: 0; -} - -/* hide but preserve in layout */ -.inspector-hover .combobox-caret, -.inspector-hover .header button, -.inspector-hover .spin-control, -.inspector-hover .form-field-multicombo .chips .remove, -.inspector-hover .hide-toggle:before, -.inspector-hover .more-fields, -.inspector-hover .form-field-label button, -.inspector-hover .tag-reference-button, -.inspector-hover .footer * { - opacity: 0; -} -/* hide and do not affect layout */ -.inspector-hover .entity-editor-pane button.minor { - display: none; -} - -/* Styles for raw tag inspector on hover */ -.inspector-hover .tag-row .key-wrap, -.inspector-hover .tag-row .input-wrap-position { - height: 31px; -} - -.inspector-hover .tag-row:first-child input.value { - border-top-right-radius: 4px; -} -[dir='rtl'] .inspector-hover .tag-row:first-child input.value { - border-top-right-radius: 0; - border-top-left-radius: 4px; -} - -.inspector-hover .tag-row:last-child input.value { - border-bottom-right-radius: 4px; -} -[dir='rtl'] .inspector-hover .tag-row:last-child input.value { - border-bottom-right-radius: 0; - border-bottom-left-radius: 4px; -} - -.inspector-hover .tag-row:last-child input.key { - border-bottom-left-radius: 4px; -} -[dir='rtl'] .inspector-hover .tag-row:last-child input.key { - border-bottom-left-radius: 0; - border-bottom-right-radius: 4px; -} - -.inspector-hover .more-fields { - max-height: 0; - margin-bottom: -10px; -} - -/* Unstyle button fields */ -.inspector-hover .toggle-list label.active, -.inspector-hover .entity-editor-pane a.hide-toggle { - opacity: 1; - background-color: transparent; - color: #666; - padding-left: 0; - border-width: 0; -} - -.inspector-hover .toggle-list button.active { - padding-left: 10px; -} - -/* Add placeholder only on hover for radio buttons */ -.inspector-hover .toggle-list .placeholder { - color: #a9a9a9; - padding: 5px 10px; - opacity: 1; - line-height: 20px; - width: 100%; -} - -/* Hide placeholder for radio buttons if another is active, or not in hover state */ -.toggle-list label.active ~ .placeholder, -.toggle-list .placeholder { - padding: 0; - opacity: 0; - width: 0; - line-height: 0; - display: block; - overflow: hidden; -} - -/* More Fields dropdown -------------------------------------------------------- */ -.more-fields { - padding: 0 20px 20px 20px; - font-weight: bold; -} -.changeset-editor .more-fields { - padding: 15px 20px 0 20px; -} - -.more-fields label { - display: flex; - flex-flow: row nowrap; - justify-content: space-between; - align-items: center; -} - -.more-fields input { - margin-left: 10px; - flex: 1 1 50%; -} -[dir='rtl'] .more-fields input { - margin-left: auto; - margin-right: 10px; -} - -.form-field-input-wrap .label { +/* Buttons inside fields */ +.form-field-button { + flex: 0 0 32px; height: 30px; - background: #F6F6F6; - padding: 5px 10px; + width: 32px; + position: relative; + background-color: #fff; + border: 1px solid #ccc; + border-radius: 0; + border-top-width: 0; + border-left-width: 0; + vertical-align: top; +} +[dir='rtl'] .form-field-button { + border-left-width: 1px; + border-right-width: 0; +} +.form-field-button:hover { + background-color: #f1f1f1; +} +.form-field-button .icon { + opacity: .5; +} + + +/* round corners of first/last child elements */ +[dir='ltr'] .form-field-input-wrap > input:first-of-type { + border-bottom-left-radius: 4px; +} +[dir='rtl'] .form-field-input-wrap > input:first-of-type { + border-bottom-right-radius: 4px; +} +[dir='ltr'] .form-field-input-wrap > button:last-of-type { + border-bottom-right-radius: 4px; +} +[dir='rtl'] .form-field-input-wrap > button:last-of-type { + border-bottom-left-radius: 4px; } /* Field - Access, Cycleway, Structure ------------------------------------------------------- */ .structure-extras-wrap li, -.form-field-cycleway .form-field-input-wrap li, -.form-field-access .form-field-input-wrap li { +.form-field-input-cycleway .form-field-input-wrap li, +.form-field-input-access .form-field-input-wrap li { border-bottom: 1px solid #ccc; display: flex; } .structure-extras-wrap li:last-child, -.form-field-cycleway .form-field-input-wrap li:last-child, -.form-field-access .form-field-input-wrap li:last-child { +.form-field-input-cycleway .form-field-input-wrap li:last-child, +.form-field-input-access .form-field-input-wrap li:last-child { border-bottom: 0; } .structure-extras-wrap li > *, -.form-field-cycleway .form-field-input-wrap li > *, -.form-field-access .form-field-input-wrap li > * { +.form-field-input-cycleway .form-field-input-wrap li > *, +.form-field-input-access .form-field-input-wrap li > * { flex: 1; } .structure-input-type-wrap input, @@ -1535,14 +1353,14 @@ a.hide-toggle { border-left-width: 0; border-right-width: 1px; } -.structure-extras-wrap .spin-control button { +.structure-extras-wrap button { border-bottom: 0; } -[dir='ltr'] .structure-extras-wrap .spin-control button { +[dir='ltr'] .structure-extras-wrap button { border-right: 0; border-left-width: 1px; } -[dir='rtl'] .structure-extras-wrap .spin-control button { +[dir='rtl'] .structure-extras-wrap button { border-left: 0; border-right-width: 1px; } @@ -1589,27 +1407,26 @@ a.hide-toggle { } +/* Field - Combo +------------------------------------------------------- */ +[dir='ltr'] .form-field-input-combo > input { + border-bottom-right-radius: 4px; +} +[dir='rtl'] .form-field-input-combo > input { + border-bottom-left-radius: 4px; +} + + /* Field - Multicombo ------------------------------------------------------- */ -.form-field-multicombo { - border: 1px solid #cfcfcf; - border-top: 0px; +.form-field-input-multicombo ul.chiplist { padding: 5px 0 5px 10px; background: #fff; display: block; border-radius: 0 0 4px 4px; - overflow: hidden; - flex: 1 1 auto; -} -.form-field-multicombo:focus { - border-bottom: 0px; -} -.form-field-multicombo.active { - border-bottom-left-radius: 0px; - border-bottom-right-radius: 0px; } -.form-field-multicombo li { +.form-field-input-multicombo li.chips { display: inline-flex; flex-flow: row nowrap; align-items: center; @@ -1621,7 +1438,7 @@ a.hide-toggle { margin: 3px; } -.form-field-multicombo a { +.form-field-input-multicombo a { font-family: Arial, Helvetica, sans-serif !important; font-size: 16px !important; line-height: 24px; @@ -1632,42 +1449,38 @@ a.hide-toggle { color: #a6b4ce; } -.form-field-multicombo input { +.form-field-input-multicombo input { border: 1px solid #ddd; width: 100px; margin: 3px; height: 31px; } -.form-field-multicombo .combobox-caret { +.form-field-input-multicombo .combobox-caret { margin: 3px 3px 3px -30px; } -.form-field-multicombo input:focus { +.form-field-input-multicombo input:focus { border-radius: 4px !important; } /* Field - Numeric ------------------------------------------------------- */ -.spin-control { - position: relative; - display: flex; -} -.spin-control button.decrement::after, -.spin-control button.increment::after { - content:""; +.form-field-input-number button.decrement::after, +.form-field-input-number button.increment::after { + content: ""; height: 0; width: 0; position: absolute; left: 0; right: 0; bottom: 0; top: 0; margin: auto; } -.spin-control button.decrement::after { +.form-field-input-number button.decrement::after { border-top: 5px solid #ccc; border-left: 5px solid transparent; border-right: 5px solid transparent; } -.spin-control button.increment::after { +.form-field-input-number button.increment::after { border-bottom: 5px solid #ccc; border-left: 5px solid transparent; border-right: 5px solid transparent; @@ -1676,22 +1489,25 @@ a.hide-toggle { /* Field - Checkbox ------------------------------------------------------- */ -.checkselect label:last-of-type { +.form-field-input-check { display: block; background: #fff; padding: 5px 10px; color: #7092ff; + border: 1px solid #ccc; + border-top: 0; + cursor: pointer; } -.checkselect label:hover { +.form-field-input-check:hover { background: #f1f1f1; } -.checkselect .set { +.form-field-input-check .set { color: inherit; } -.checkselect label:not(.set) input[type="checkbox"] { +.form-field-input-check label:not(.set) input[type="checkbox"] { opacity: .5; } -.checkselect .reverser.button { +.form-field-input-check .reverser.button { display: block; float: right; background-color: #eff2f7; @@ -1699,83 +1515,92 @@ a.hide-toggle { border-radius: 2px; padding: 0px 8px; } -[dir='rtl'] .checkselect .reverser.button { +[dir='rtl'] .form-field-input-check .reverser.button { float: left; } -.checkselect .reverser.button.hide { +.form-field-input-check .reverser.button.hide { display: none; } /* Field - Radio button ------------------------------------------------------- */ -.toggle-list button.remove { +.form-field-input-radio { + flex: 1 1 auto; + display: flex; + flex-flow: row wrap; + border: 0; + border-top: 0px; +} +.form-field-input-radio > label { + width: 100%; + position: relative; + padding: 5px 10px; + display: block; + height: 30px; + background-color: #fff; + color: #7092ff; + cursor: pointer; +} + +.form-field-input-radio > label:hover { + background-color: #ececec; +} +.form-field-input-radio > label:not(:last-child) { + border-bottom: 1px solid #ccc; +} +.form-field-input-radio > label:last-child { border-radius: 0 0 3px 3px; } -.toggle-list button.remove .icon { +.form-field-input-radio label > span { + display: block; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +.form-field-input-radio > label.active { + background: #e8ebff; +} + +.form-field-input-radio button.remove { + border-radius: 0 0 3px 3px; +} +.form-field-input-radio button.remove .icon { position: absolute; left: 5px; } -.toggle-list button.remove::before { +.form-field-input-radio button.remove::before { content: none; } +/* Hide placeholder for radio buttons if another is active, or not in hover state */ +.form-field-input-radio label.active ~ .placeholder, +.form-field-input-radio .placeholder { + padding: 0; + opacity: 0; + width: 0; + line-height: 0; + display: block; + overflow: hidden; +} + /* Field - Maxspeed ------------------------------------------------------- */ -#preset-input-maxspeed_advisory, -#preset-input-maxspeed { - border-right: none; - flex: 1; -} -[dir='rtl'] #preset-input-maxspeed_advisory, -[dir='rtl'] #preset-input-maxspeed { - border-right: 1px solid #ccc; -} - -.form-field .maxspeed-unit { +.form-field-input-maxspeed > .maxspeed-unit { + flex: 0 1 80px; + width: 80px; + border-left: 0; border-radius: 0 0 4px 0; - flex: 0 1 20%; - min-width: 70px; } -[dir='rtl'] .form-field .maxspeed-unit { +[dir='rtl'] .form-field-input-maxspeed > .maxspeed-unit { border-right: 0; border-radius: 0 0 0 4px; } -/* Field - Wikipedia -------------------------------------------------------- */ -.form-field .wiki-lang { - border-radius: 0; - flex-basis: 100%; -} - - /* Field - Localized Name ------------------------------------------------------- */ -.localized-input-wrap { - display: flex; - flex: 1 1 100%; -} - -.form-field .localized-add { - position: relative; - border: 1px solid #ccc; - border-top-width: 0; - border-left-width: 0; - border-radius: 0 0 4px 0; - height: 30px; - vertical-align: top; - width: 32px; - flex: 0 1 auto; -} -[dir='rtl'] .form-field .localized-add { - border-left-width: 1px; - border-right-width: 0; - border-radius: 0 0 0 4px; -} - .localized-multilingual { padding: 0 10px; flex-basis: 100%; @@ -1809,8 +1634,6 @@ a.hide-toggle { width: 100%; } -button.localized-add.disabled, -.localized-multilingual .form-field-label button.disabled, .localized-multilingual .localized-lang.disabled, .localized-multilingual .localized-value.disabled { color: #777; @@ -1819,50 +1642,75 @@ button.localized-add.disabled, } -/* Field - Address +/* Field - Table-like (Address, Wikipedia) ------------------------------------------------------- */ -.addr-row input { +.form-field-input-address, +.form-field-input-wikipedia { + flex: 1 1 auto; + display: flex; + flex-flow: row wrap; + border: 1px solid #ccc; + border-top: 0px; +} + +.form-row-container { + flex: 1 1 auto; + display: flex; + width: 100%; + min-height: 30px; +} + +.form-row-container > input { + flex: 1 1 auto; + border-radius: 0; border-right: 0; border-bottom: 0; } -[dir='rtl'] .addr-row input { +[dir='rtl'] .form-row-container input { border-right: 1px solid #ccc; border-left: 0; } -.addr-row:first-of-type input { +.form-row-container:first-of-type input { border-top: 0; } - -.addr-row input:first-of-type { +.form-row-container input:first-of-type { border-left: 0; } -[dir='rtl'] .addr-row input:first-of-type { +[dir='rtl'] .form-row-container input:first-of-type { border-right: 0; } - -.addr-row input { - border-radius: 0; -} - -.addr-row:last-of-type input:first-of-type { +.form-row-container:last-of-type input:first-of-type { border-radius: 0 0 0 4px; } -[dir='rtl'] .addr-row:last-of-type input:first-of-type { +[dir='rtl'] .form-row-container:last-of-type input:first-of-type { border-radius: 0 0 4px 0; } +.form-row-container:last-of-type input:last-of-type { + border-radius: 0 0 4px 0; +} +[dir='rtl'] .form-row-container:last-of-type input:last-of-type { + border-radius: 0 0 0 4px; +} -.addr-row:last-of-type input:last-of-type { +/* overrides for last row of wikipedia field */ +.wiki-title-container:last-of-type input.wiki-title { + border-radius: 0 0 0 4px; +} +[dir='rtl'] .wiki-title-container:last-of-type input.wiki-title { border-radius: 0 0 4px 0; } -[dir='rtl'] .addr-row:last-of-type input:last-of-type { +.wiki-title-container:last-of-type button.wiki-link { border-radius: 0 0 0 4px; } +[dir='rtl'] .wiki-title-container:last-of-type button.wiki-link { + border-radius: 0 0 4px 0; +} /* Field - Restriction Editor ------------------------------------------------------- */ -.form-field-restrictions .restriction-controls-container { +.form-field-input-restrictions .restriction-controls-container { background-color: #fff; border-top: 1px solid #ccc; width: 100%; @@ -1901,16 +1749,16 @@ button.localized-add.disabled, vertical-align: middle; } -.form-field-restrictions .restriction-container { +.form-field-input-restrictions .restriction-container { position: relative; height: 370px; } /* zero width space, so container takes up space */ -.form-field-restrictions .restriction-container:after { +.form-field-input-restrictions .restriction-container:after { content: '\200b'; } -.form-field-restrictions svg.surface { +.form-field-input-restrictions svg.surface { width: 100%; height: 100%; } @@ -2007,6 +1855,7 @@ div.combobox { width: 30px; margin-left: -30px; vertical-align: top; + cursor: pointer; } [dir='rtl'] .combobox-caret { margin-left: 0; @@ -2194,7 +2043,6 @@ div.combobox { .tag-row:first-child input.value { border-top: 1px solid #ccc; } - .tag-row button { height: 31px; width: 32px; @@ -2210,11 +2058,9 @@ div.combobox { .tag-row button:hover { background: #f1f1f1; } - .tag-row button .icon { opacity: .5; } - .tag-row:first-child button { border-top-width: 1px; } @@ -2252,20 +2098,17 @@ div.combobox { background: rgba(0,0,0,.5); border-radius: 0 0 4px 4px; } - .raw-tag-editor .add-tag:hover { background: rgba(0,0,0,.8); } - .raw-tag-editor .add-tag .label { display: none; } /* Tag reference */ -button.minor.tag-reference-loading { +.tag-reference-loading { background-color: #f5f5f5; } - .tag-reference-loading .icon { background-image: url(img/mini-loader.gif); background-position: 0 0; @@ -2275,15 +2118,12 @@ button.minor.tag-reference-loading { overflow: hidden; clear: both; } - .tag-reference-body .tag-reference-description { margin: 10px 5px 0 5px; } - .tag-reference-body a { display: block; } - .tag-reference-body .tag-reference-description:last-child, .tag-reference-body a:last-child { margin-bottom: 15px; @@ -2293,34 +2133,20 @@ button.minor.tag-reference-loading { position: relative; width: 100%; } - .raw-tag-editor .tag-reference-body { width: 100%; } - .raw-tag-editor .tag-row.readonly .tag-reference-body { background: #f6f6f6; color: #333; } - .raw-tag-editor .tag-row:not(:last-child) .tag-reference-body.expanded { border-bottom: 1px solid #ccc; } - .raw-tag-editor .tag-row.readonly .tag-reference-body.expanded { border-top: 1px solid #ccc; } -img.tag-reference-wiki-image { - float: right; - width: 33.3333%; - width: -webkit-calc(33.3333% - 10px); - width: calc(33.3333% - 10px); - border-radius: 4px; - max-height: 200px; - margin: 10px 5px 15px 20px; -} - /* Raw Member / Membership Editor ------------------------------------------------------- */ @@ -2328,12 +2154,10 @@ img.tag-reference-wiki-image { .raw-membership-editor .member-list li:first-child { padding-top: 10px; } - .raw-member-editor .member-row, .raw-membership-editor .member-row { position: relative; } - .raw-member-editor .member-row .member-entity-name, .raw-membership-editor .member-row .member-entity-name { font-weight: normal; @@ -2343,10 +2167,9 @@ img.tag-reference-wiki-image { .member-incomplete .member-delete { display: none; } - .member-row-new .member-entity-input { border-radius: 4px 4px 0 0; - border: 1px solid #cfcfcf; + border: 1px solid #ccc; flex-basis: 100%; } @@ -2357,7 +2180,6 @@ img.tag-reference-wiki-image { border-radius: 4px; margin-top: 10px; } - .add-relation:hover { background: rgba(0,0,0,.8); } @@ -2376,6 +2198,159 @@ input.key-trap { } +/* More Fields dropdown +------------------------------------------------------- */ +.more-fields { + padding: 0 20px 20px 20px; + font-weight: bold; +} +.changeset-editor .more-fields { + padding: 15px 20px 0 20px; +} + +.more-fields label { + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + align-items: center; +} + +.more-fields input { + margin-left: 10px; + flex: 1 1 50%; +} +[dir='rtl'] .more-fields input { + margin-left: auto; + margin-right: 10px; +} + +.form-field-input-wrap .label { + height: 30px; + background: #f6f6f6; + padding: 5px 10px; +} + + +/* Inspector (hover styles) +------------------------------------------------------- */ +.inspector-hover .form-field-input-wrap .label, +.inspector-hover .form-field-input-multicombo .chiplist, +.inspector-hover .form-field-button, +.inspector-hover .structure-extras-wrap, +.inspector-hover .comments-container .comment, +.inspector-hover input, +.inspector-hover textarea, +.inspector-hover label { + background: #ececec; +} + +.inspector-hover a, +.inspector-hover .form-field-input-multicombo .chips, +.inspector-hover .form-field-input-check span { + color: #666; +} + +.inspector-hover .form-field-input-multicombo .chips { + background: #eee; + border: 1px solid #ccc; +} + +/* no scrollbars */ +.inspector-hover div { + overflow-x: hidden; + overflow-y: hidden; +} + +/* hide and remove from layout */ +.inspector-hidden, +.inspector-hover label input[type="checkbox"], +.inspector-hover label input[type="radio"], +.inspector-hover .form-field-input-multicombo .combobox-input, +.inspector-hover .form-field-input-radio label, +.inspector-hover .form-field-input-radio label span, +.inspector-hover .form-field-input-radio label.remove .icon, +.inspector-hover .inspector-inner .add-tag, +.inspector-hover .inspector-inner .add-relation { + height: 0; + width: 0; + overflow: hidden; + opacity: 0 !important; + border-width: 0; + margin: 0; + padding: 0; +} + +/* hide but preserve in layout */ +.inspector-hover .combobox-caret, +.inspector-hover .header button, +.inspector-hover .form-field-input-multicombo .chips .remove, +.inspector-hover .hide-toggle:before, +.inspector-hover .more-fields, +.inspector-hover .form-field-label button, +.inspector-hover .tag-reference-button, +.inspector-hover .footer * { + opacity: 0; +} + +/* Styles for raw tag inspector on hover */ +.inspector-hover .tag-row .key-wrap, +.inspector-hover .tag-row .input-wrap-position { + height: 31px; +} + +.inspector-hover .tag-row:first-child input.value { + border-top-right-radius: 4px; +} +[dir='rtl'] .inspector-hover .tag-row:first-child input.value { + border-top-right-radius: 0; + border-top-left-radius: 4px; +} + +.inspector-hover .tag-row:last-child input.value { + border-bottom-right-radius: 4px; +} +[dir='rtl'] .inspector-hover .tag-row:last-child input.value { + border-bottom-right-radius: 0; + border-bottom-left-radius: 4px; +} + +.inspector-hover .tag-row:last-child input.key { + border-bottom-left-radius: 4px; +} +[dir='rtl'] .inspector-hover .tag-row:last-child input.key { + border-bottom-left-radius: 0; + border-bottom-right-radius: 4px; +} + +.inspector-hover .more-fields { + max-height: 0; + margin-bottom: -10px; +} + +/* Unstyle button fields */ +.inspector-hover .form-field-input-radio label.active, +.inspector-hover .entity-editor-pane a.hide-toggle { + opacity: 1; + background-color: transparent; + color: #666; + padding-left: 0; + border-width: 0; +} + +.inspector-hover .form-field-input-radio button.active { + padding-left: 10px; +} + +/* Add placeholder only on hover for radio buttons */ +.inspector-hover .form-field-input-radio .placeholder { + color: #a9a9a9; + padding: 5px 10px; + opacity: 1; + line-height: 20px; + width: 100%; +} + + /* OSM Note Editor ------------------------------------------------------- */ .note-header { diff --git a/modules/lib/d3.combobox.js b/modules/lib/d3.combobox.js index c82be677f..d991257bf 100644 --- a/modules/lib/d3.combobox.js +++ b/modules/lib/d3.combobox.js @@ -242,8 +242,8 @@ export function d3combobox() { function render() { if (_suggestions.length >= _minItems && - document.activeElement === input.node() && - input.attr('readonly') === null) { + document.activeElement === input.node()) { + // input.attr('readonly') === null) show(); } else { hide(); diff --git a/modules/ui/fields/access.js b/modules/ui/fields/access.js index fbcde7187..f0f4ac34b 100644 --- a/modules/ui/fields/access.js +++ b/modules/ui/fields/access.js @@ -19,8 +19,7 @@ export function uiFieldAccess(field, context) { wrap = wrap.enter() .append('div') - .attr('class', 'form-field-input-wrap') - .append('ul') + .attr('class', 'form-field-input-wrap form-field-input-' + field.type) .merge(wrap); var list = wrap.selectAll('ul') @@ -214,6 +213,8 @@ export function uiFieldAccess(field, context) { .attr('placeholder', 'yes'); var which = tags.highway; + if (!placeholders[which]) return; + var keys = Object.keys(placeholders[which]); keys.forEach(function(k) { var v = placeholders[which][k]; diff --git a/modules/ui/fields/address.js b/modules/ui/fields/address.js index a9faccfa9..813ba2599 100644 --- a/modules/ui/fields/address.js +++ b/modules/ui/fields/address.js @@ -148,11 +148,11 @@ export function uiFieldAddress(field, context) { }); } - wrap.selectAll('div.addr-row') + wrap.selectAll('div.form-row-container') .data(addressFormat.format) .enter() .append('div') - .attr('class', 'addr-row') + .attr('class', 'form-row-container') .selectAll('input') .data(row) .enter() @@ -212,7 +212,7 @@ export function uiFieldAddress(field, context) { wrap = wrap.enter() .append('div') - .attr('class', 'form-field-input-wrap') + .attr('class', 'form-field-input-wrap form-field-input-' + field.type) .merge(wrap); if (nominatim && _entity) { diff --git a/modules/ui/fields/check.js b/modules/ui/fields/check.js index 5b34e68e5..4c101fd19 100644 --- a/modules/ui/fields/check.js +++ b/modules/ui/fields/check.js @@ -90,14 +90,13 @@ export function uiFieldCheck(field, context) { var check = function(selection) { checkImpliedYes(); - selection.classed('checkselect', 'true'); label = selection.selectAll('.form-field-input-wrap') .data([0]); var enter = label.enter() .append('label') - .attr('class', 'form-field-input-wrap'); + .attr('class', 'form-field-input-wrap form-field-input-check'); enter .append('input') diff --git a/modules/ui/fields/combo.js b/modules/ui/fields/combo.js index 1df90468b..991f81f06 100644 --- a/modules/ui/fields/combo.js +++ b/modules/ui/fields/combo.js @@ -286,19 +286,26 @@ export function uiFieldCombo(field, context) { function combo(selection) { + container = selection.selectAll('.form-field-input-wrap') + .data([0]); + + var type = (isMulti || isSemi) ? 'multicombo': 'combo'; + container = container.enter() + .append('div') + .attr('class', 'form-field-input-wrap form-field-input-' + type) + .merge(container); + if (isMulti || isSemi) { - container = selection.selectAll('ul').data([0]); + container = container.selectAll('.chiplist') + .data([0]); container = container.enter() .append('ul') - .attr('class', 'form-field-multicombo') + .attr('class', 'chiplist') .on('click', function() { window.setTimeout(function() { input.node().focus(); }, 10); }) .merge(container); - - } else { - container = selection; } input = container.selectAll('input') diff --git a/modules/ui/fields/cycleway.js b/modules/ui/fields/cycleway.js index d36f04e6d..ee29c2ab2 100644 --- a/modules/ui/fields/cycleway.js +++ b/modules/ui/fields/cycleway.js @@ -26,7 +26,7 @@ export function uiFieldCycleway(field, context) { wrap = wrap.enter() .append('div') - .attr('class', 'form-field-input-wrap') + .attr('class', 'form-field-input-wrap form-field-input-' + field.type) .merge(wrap); diff --git a/modules/ui/fields/input.js b/modules/ui/fields/input.js index a667138e4..b6756dfa9 100644 --- a/modules/ui/fields/input.js +++ b/modules/ui/fields/input.js @@ -42,9 +42,17 @@ export function uiFieldText(field, context) { var preset = _entity && context.presets().match(_entity, context.graph()); var isSuggestion = preset && preset.suggestion && field.id === 'brand'; + var wrap = selection.selectAll('.form-field-input-wrap') + .data([0]); + + wrap = wrap.enter() + .append('div') + .attr('class', 'form-field-input-wrap form-field-input-' + field.type) + .merge(wrap); + var fieldID = 'preset-input-' + field.safeid; - input = selection.selectAll('input') + input = wrap.selectAll('input') .data([0]); input = input.enter() @@ -68,7 +76,7 @@ export function uiFieldText(field, context) { var center = _entity.extent(context.graph()).center(); nominatim.countryCode(center, function (err, countryCode) { if (err || !dataPhoneFormats[countryCode]) return; - selection.selectAll('#' + fieldID) + wrap.selectAll('#' + fieldID) .attr('placeholder', dataPhoneFormats[countryCode]); }); @@ -77,31 +85,17 @@ export function uiFieldText(field, context) { input.attr('type', 'text'); - var spinControl = selection.selectAll('.spin-control') - .data([0]); + var buttons = wrap.selectAll('.increment, .decrement') + .data(rtl ? [1, -1] : [-1, 1]); - var enter = spinControl.enter() - .append('div') - .attr('class', 'spin-control'); - - enter + buttons.enter() .append('button') - .datum(rtl ? 1 : -1) - .attr('class', 'button-input-action minor') - .classed(rtl ? 'increment' : 'decrement', true) - .attr('tabindex', -1); - - enter - .append('button') - .datum(rtl ? -1 : 1) - .attr('class', 'button-input-action minor') - .classed(rtl ? 'decrement' : 'increment', true) - .attr('tabindex', -1); - - spinControl = spinControl - .merge(enter); - - spinControl.selectAll('button') + .attr('tabindex', -1) + .attr('class', function(d) { + var which = (d === 1 ? 'increment' : 'decrement'); + return 'form-field-button ' + which; + }) + .merge(buttons) .on('click', function(d) { d3_event.preventDefault(); input.node().value = parsed(input.node().value) + d; @@ -118,7 +112,7 @@ export function uiFieldText(field, context) { .filter(function(k) { return k !== pKey && k !== 'name'; }); } - selection.call(isSuggestion ? _brandTip : _brandTip.destroy); + wrap.call(isSuggestion ? _brandTip : _brandTip.destroy); } } @@ -128,6 +122,7 @@ export function uiFieldText(field, context) { return parseFloat(val || 0, 10) || 0; } + // clamp number to min/max function clamped(num) { if (field.minValue !== undefined) { diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js index 69462d8c9..be9e460fc 100644 --- a/modules/ui/fields/lanes.js +++ b/modules/ui/fields/lanes.js @@ -24,7 +24,7 @@ export function uiFieldLanes(field, context) { wrap = wrap.enter() .append('div') - .attr('class', 'form-field-input-wrap') + .attr('class', 'form-field-input-wrap form-field-input-' + field.type) .merge(wrap); var surface = wrap.selectAll('.surface') diff --git a/modules/ui/fields/localized.js b/modules/ui/fields/localized.js index 033ef16fb..abd72f486 100644 --- a/modules/ui/fields/localized.js +++ b/modules/ui/fields/localized.js @@ -67,13 +67,13 @@ export function uiFieldLocalized(field, context) { calcLocked(); var preset = _entity && context.presets().match(_entity, context.graph()); - var wrap = selection.selectAll('.localized-input-wrap') + var wrap = selection.selectAll('.form-field-input-wrap') .data([0]); // enter/update wrap = wrap.enter() .append('div') - .attr('class', 'localized-input-wrap') + .attr('class', 'form-field-input-wrap form-field-input-' + field.type) .merge(wrap) .call(_isLocked ? _brandTip : _brandTip.destroy); @@ -157,7 +157,7 @@ export function uiFieldLocalized(field, context) { translateButton = translateButton.enter() .append('button') - .attr('class', 'localized-add button-input-action minor') + .attr('class', 'localized-add form-field-button') .attr('tabindex', -1) .call(svgIcon('#iD-icon-plus')) .merge(translateButton); @@ -344,7 +344,7 @@ export function uiFieldLocalized(field, context) { label .append('button') - .attr('class', 'minor remove-icon-multilingual') + .attr('class', 'remove-icon-multilingual') .on('click', function(d){ if (_isLocked) return; d3_event.preventDefault(); diff --git a/modules/ui/fields/maxspeed.js b/modules/ui/fields/maxspeed.js index 9fefc3bf2..250e96952 100644 --- a/modules/ui/fields/maxspeed.js +++ b/modules/ui/fields/maxspeed.js @@ -15,11 +15,11 @@ import { export function uiFieldMaxspeed(field, context) { var dispatch = d3_dispatch('change'); - var _entity; - var isImperial; var unitInput = d3_select(null); var input = d3_select(null); var combobox; + var _entity; + var _isImperial; var metricValues = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120]; var imperialValues = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80]; @@ -33,7 +33,16 @@ export function uiFieldMaxspeed(field, context) { .container(context.container()) .data(['km/h', 'mph'].map(comboValues)); - input = selection.selectAll('#preset-input-' + field.safeid) + var wrap = selection.selectAll('.form-field-input-wrap') + .data([0]); + + wrap = wrap.enter() + .append('div') + .attr('class', 'form-field-input-wrap form-field-input-' + field.type) + .merge(wrap); + + + input = wrap.selectAll('#preset-input-' + field.safeid) .data([0]); input = input.enter() @@ -52,19 +61,18 @@ export function uiFieldMaxspeed(field, context) { var loc; if (_entity.type === 'node') { loc = _entity.loc; - } - else { + } else { var childNodes = context.graph().childNodes(context.entity(_entity.id)); loc = childNodes[~~(childNodes.length/2)].loc; } - isImperial = _some(dataImperial.features, function(f) { + _isImperial = _some(dataImperial.features, function(f) { return _some(f.geometry.coordinates, function(d) { return geoPointInPolygon(loc, d); }); }); - unitInput = selection.selectAll('input.maxspeed-unit') + unitInput = wrap.selectAll('input.maxspeed-unit') .data([0]); unitInput = unitInput.enter() @@ -80,8 +88,8 @@ export function uiFieldMaxspeed(field, context) { function changeUnits() { - isImperial = utilGetSetValue(unitInput) === 'mph'; - utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h'); + _isImperial = utilGetSetValue(unitInput) === 'mph'; + utilGetSetValue(unitInput, _isImperial ? 'mph' : 'km/h'); setSuggestions(); change(); } @@ -89,8 +97,8 @@ export function uiFieldMaxspeed(field, context) { function setSuggestions() { - combobox.data((isImperial ? imperialValues : metricValues).map(comboValues)); - utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h'); + combobox.data((_isImperial ? imperialValues : metricValues).map(comboValues)); + utilGetSetValue(unitInput, _isImperial ? 'mph' : 'km/h'); } @@ -108,7 +116,7 @@ export function uiFieldMaxspeed(field, context) { if (!value) { tag[field.key] = undefined; - } else if (isNaN(value) || !isImperial) { + } else if (isNaN(value) || !_isImperial) { tag[field.key] = value; } else { tag[field.key] = value + ' mph'; @@ -123,9 +131,9 @@ export function uiFieldMaxspeed(field, context) { if (value && value.indexOf('mph') >= 0) { value = parseInt(value, 10); - isImperial = true; + _isImperial = true; } else if (value) { - isImperial = false; + _isImperial = false; } setSuggestions(); diff --git a/modules/ui/fields/radio.js b/modules/ui/fields/radio.js index d5872134f..d4d0e8247 100644 --- a/modules/ui/fields/radio.js +++ b/modules/ui/fields/radio.js @@ -27,7 +27,7 @@ export function uiFieldRadio(field, context) { function selectedKey() { - var node = wrap.selectAll('.toggle-list label.active input'); + var node = wrap.selectAll('.form-field-input-radio label.active input'); return !node.empty() && node.datum(); } @@ -40,7 +40,7 @@ export function uiFieldRadio(field, context) { var enter = wrap.enter() .append('div') - .attr('class', 'form-field-input-wrap toggle-list'); + .attr('class', 'form-field-input-wrap form-field-input-radio') enter .append('span') diff --git a/modules/ui/fields/restrictions.js b/modules/ui/fields/restrictions.js index a40738acd..df16c3f50 100644 --- a/modules/ui/fields/restrictions.js +++ b/modules/ui/fields/restrictions.js @@ -107,7 +107,7 @@ export function uiFieldRestrictions(field, context) { wrap = wrap.enter() .append('div') - .attr('class', 'form-field-input-wrap') + .attr('class', 'form-field-input-wrap form-field-input-' + field.type) .merge(wrap); var container = wrap.selectAll('.restriction-container') diff --git a/modules/ui/fields/textarea.js b/modules/ui/fields/textarea.js index 91b6c6d7e..d319f2b56 100644 --- a/modules/ui/fields/textarea.js +++ b/modules/ui/fields/textarea.js @@ -15,7 +15,15 @@ export function uiFieldTextarea(field) { function textarea(selection) { - input = selection.selectAll('textarea') + var wrap = selection.selectAll('.form-field-input-wrap') + .data([0]); + + wrap = wrap.enter() + .append('div') + .attr('class', 'form-field-input-wrap form-field-input-' + field.type) + .merge(wrap); + + input = wrap.selectAll('textarea') .data([0]); input = input.enter() diff --git a/modules/ui/fields/wikipedia.js b/modules/ui/fields/wikipedia.js index 0f30a19aa..5ae90843d 100644 --- a/modules/ui/fields/wikipedia.js +++ b/modules/ui/fields/wikipedia.js @@ -27,7 +27,6 @@ export function uiFieldWikipedia(field, context) { var dispatch = d3_dispatch('change'); var wikipedia = services.wikipedia; var wikidata = services.wikidata; - var link = d3_select(null); var lang = d3_select(null); var title = d3_select(null); var _wikiURL = ''; @@ -65,7 +64,25 @@ export function uiFieldWikipedia(field, context) { }); - lang = selection.selectAll('input.wiki-lang') + var wrap = selection.selectAll('.form-field-input-wrap') + .data([0]); + + wrap = wrap.enter() + .append('div') + .attr('class', 'form-field-input-wrap form-field-input-' + field.type) + .merge(wrap); + + + var langRow = wrap.selectAll('.wiki-lang-container') + .data([0]); + + langRow = langRow.enter() + .append('div') + .attr('class', 'form-row-container wiki-lang-container') + .merge(langRow) + + + lang = langRow.selectAll('input.wiki-lang') .data([0]); lang = lang.enter() @@ -84,7 +101,15 @@ export function uiFieldWikipedia(field, context) { .on('change', changeLang); - title = selection.selectAll('input.wiki-title') + var titleRow = wrap.selectAll('.wiki-title-container') + .data([0]); + + titleRow = titleRow.enter() + .append('div') + .attr('class', 'form-row-container wiki-title-container') + .merge(titleRow) + + title = titleRow.selectAll('input.wiki-title') .data([0]); title = title.enter() @@ -101,12 +126,12 @@ export function uiFieldWikipedia(field, context) { .on('change', change); - link = selection.selectAll('.wiki-link') + var link = titleRow.selectAll('.wiki-link') .data([0]); link = link.enter() .append('button') - .attr('class', 'button-input-action wiki-link minor') + .attr('class', 'form-field-button wiki-link') .attr('tabindex', -1) .call(svgIcon('#iD-icon-out-link')) .merge(link); diff --git a/modules/ui/raw_member_editor.js b/modules/ui/raw_member_editor.js index 336b363db..b12678b78 100644 --- a/modules/ui/raw_member_editor.js +++ b/modules/ui/raw_member_editor.js @@ -220,7 +220,7 @@ export function uiRawMemberEditor(context) { .append('button') .attr('tabindex', -1) .attr('title', t('icons.remove')) - .attr('class', 'remove button-input-action member-delete minor') + .attr('class', 'remove form-field-button member-delete') .on('click', deleteMember) .call(svgIcon('#iD-operation-delete')); diff --git a/modules/ui/raw_membership_editor.js b/modules/ui/raw_membership_editor.js index d37e64a49..e902317d7 100644 --- a/modules/ui/raw_membership_editor.js +++ b/modules/ui/raw_membership_editor.js @@ -222,7 +222,7 @@ export function uiRawMembershipEditor(context) { enter .append('button') .attr('tabindex', -1) - .attr('class', 'remove button-input-action member-delete minor') + .attr('class', 'remove form-field-button member-delete') .on('click', deleteMembership) .call(svgIcon('#iD-operation-delete')); @@ -259,7 +259,7 @@ export function uiRawMembershipEditor(context) { enter .append('button') .attr('tabindex', -1) - .attr('class', 'remove button-input-action member-delete minor') + .attr('class', 'remove form-field-button member-delete') .on('click', deleteMembership) .call(svgIcon('#iD-operation-delete')); diff --git a/modules/ui/raw_tag_editor.js b/modules/ui/raw_tag_editor.js index 63e3b4317..bc97d8248 100644 --- a/modules/ui/raw_tag_editor.js +++ b/modules/ui/raw_tag_editor.js @@ -135,7 +135,7 @@ export function uiRawTagEditor(context) { innerWrap .append('button') .attr('tabindex', -1) - .attr('class', 'remove minor') + .attr('class', 'form-field-button remove') .call(svgIcon('#iD-operation-delete')); From d0612ba51939a4b67ab747f2d6f375ffb6f0d1be Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 28 Nov 2018 23:20:52 -0500 Subject: [PATCH 2/5] Fix css for address and wikipedia fields, fix hover styles --- css/80_app.css | 91 ++++++++++++++++++++++++---------- modules/ui/fields/address.js | 4 +- modules/ui/fields/wikipedia.js | 4 +- 3 files changed, 69 insertions(+), 30 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index 6bc06047a..61146064d 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -1259,7 +1259,6 @@ img.tag-reference-wiki-image { flex: 1 1 100%; min-height: 30px; border-top: 0; - border-radius: 0 0 4px 4px; } .form-field-input-wrap > input, @@ -1305,13 +1304,13 @@ img.tag-reference-wiki-image { /* round corners of first/last child elements */ -[dir='ltr'] .form-field-input-wrap > input:first-of-type { +.form-field-input-wrap > input:first-of-type { border-bottom-left-radius: 4px; } [dir='rtl'] .form-field-input-wrap > input:first-of-type { border-bottom-right-radius: 4px; } -[dir='ltr'] .form-field-input-wrap > button:last-of-type { +.form-field-input-wrap > button:last-of-type { border-bottom-right-radius: 4px; } [dir='rtl'] .form-field-input-wrap > button:last-of-type { @@ -1369,9 +1368,14 @@ img.tag-reference-wiki-image { border-bottom-right-radius: 4px; } + .structure-extras-wrap { + width: 100%; padding: 10px 10px; background: #fff; + border: 1px solid #ccc; + border-top: 0px; + border-radius: 0 0 4px 4px; } .structure-extras-wrap ul { border: 1px solid #ccc; @@ -1381,12 +1385,14 @@ img.tag-reference-wiki-image { border-top-left-radius: 4px; } .structure-extras-wrap li:first-child input { + border-radius: 0; border-top-right-radius: 4px; } .structure-extras-wrap li:last-child span { border-bottom-left-radius: 4px; } .structure-extras-wrap li:last-child input { + border-radius: 0; border-bottom-right-radius: 4px; } [dir='rtl'] .structure-extras-wrap li:first-child span { @@ -1496,6 +1502,7 @@ img.tag-reference-wiki-image { color: #7092ff; border: 1px solid #ccc; border-top: 0; + border-radius: 0 0 4px 4px; cursor: pointer; } .form-field-input-check:hover { @@ -1546,7 +1553,7 @@ img.tag-reference-wiki-image { .form-field-input-radio > label:hover { background-color: #ececec; } -.form-field-input-radio > label:not(:last-child) { +.form-field-input-radio > label:not(:last-of-type) { border-bottom: 1px solid #ccc; } .form-field-input-radio > label:last-child { @@ -1642,10 +1649,9 @@ img.tag-reference-wiki-image { } -/* Field - Table-like (Address, Wikipedia) +/* Field - Address ------------------------------------------------------- */ -.form-field-input-address, -.form-field-input-wikipedia { +.form-field-input-address { flex: 1 1 auto; display: flex; flex-flow: row wrap; @@ -1653,59 +1659,81 @@ img.tag-reference-wiki-image { border-top: 0px; } -.form-row-container { +.addr-row { flex: 1 1 auto; display: flex; width: 100%; min-height: 30px; } -.form-row-container > input { +.addr-row > input { flex: 1 1 auto; border-radius: 0; border-right: 0; border-bottom: 0; } -[dir='rtl'] .form-row-container input { +[dir='rtl'] .addr-row input { border-right: 1px solid #ccc; border-left: 0; } -.form-row-container:first-of-type input { +.addr-row:first-of-type input { border-top: 0; } -.form-row-container input:first-of-type { +.addr-row input:first-of-type { border-left: 0; } -[dir='rtl'] .form-row-container input:first-of-type { +[dir='rtl'] .addr-row input:first-of-type { border-right: 0; } -.form-row-container:last-of-type input:first-of-type { +.addr-row:last-of-type input:first-of-type { border-radius: 0 0 0 4px; } -[dir='rtl'] .form-row-container:last-of-type input:first-of-type { +[dir='rtl'] .addr-row:last-of-type input:first-of-type { border-radius: 0 0 4px 0; } -.form-row-container:last-of-type input:last-of-type { +.addr-row:last-of-type input:last-of-type { border-radius: 0 0 4px 0; } -[dir='rtl'] .form-row-container:last-of-type input:last-of-type { +[dir='rtl'] .addr-row:last-of-type input:last-of-type { border-radius: 0 0 0 4px; } -/* overrides for last row of wikipedia field */ -.wiki-title-container:last-of-type input.wiki-title { + +/* Field - Wikipedia +------------------------------------------------------- */ +.form-field-input-wikipedia { + display: flex; + flex-flow: row wrap; + flex: 1 1 auto; +} + +.wiki-lang-container, +.wiki-title-container { + display: flex; + flex-flow: row nowrap; + flex: 1 1 auto; + width: 100%; +} + +.wiki-lang-container > .wiki-lang, +.wiki-title-container > .wiki-title { + flex: 1 1 auto; + border-top: 0; + border-radius: 0; +} +.wiki-title-container > .wiki-title { border-radius: 0 0 0 4px; } -[dir='rtl'] .wiki-title-container:last-of-type input.wiki-title { +[dir='rtl'] .wiki-title-container > .wiki-title { border-radius: 0 0 4px 0; } -.wiki-title-container:last-of-type button.wiki-link { +.wiki-title-container > .wiki-link { + border-radius: 0 0 4px 0; +} +[dir='rtl'] .wiki-title-container > .wiki-link { border-radius: 0 0 0 4px; } -[dir='rtl'] .wiki-title-container:last-of-type button.wiki-link { - border-radius: 0 0 4px 0; -} /* Field - Restriction Editor @@ -1873,6 +1901,13 @@ div.combobox { border-right: 5px solid transparent; } +/* remove bottom border radius when combobox is open */ +.combobox + * textarea:focus, +.combobox + * input:focus { + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} + /* Field Help ------------------------------------------------------- */ @@ -2238,6 +2273,7 @@ input.key-trap { .inspector-hover .form-field-button, .inspector-hover .structure-extras-wrap, .inspector-hover .comments-container .comment, +.inspector-hover button, .inspector-hover input, .inspector-hover textarea, .inspector-hover label { @@ -2343,11 +2379,14 @@ input.key-trap { /* Add placeholder only on hover for radio buttons */ .inspector-hover .form-field-input-radio .placeholder { - color: #a9a9a9; - padding: 5px 10px; opacity: 1; + color: #666; + padding: 5px 10px; line-height: 20px; width: 100%; + border: 1px solid #ccc; + border-top: 0; + border-bottom: 0; } diff --git a/modules/ui/fields/address.js b/modules/ui/fields/address.js index 813ba2599..8d1eb6db6 100644 --- a/modules/ui/fields/address.js +++ b/modules/ui/fields/address.js @@ -148,11 +148,11 @@ export function uiFieldAddress(field, context) { }); } - wrap.selectAll('div.form-row-container') + wrap.selectAll('.addr-row') .data(addressFormat.format) .enter() .append('div') - .attr('class', 'form-row-container') + .attr('class', 'addr-row') .selectAll('input') .data(row) .enter() diff --git a/modules/ui/fields/wikipedia.js b/modules/ui/fields/wikipedia.js index 5ae90843d..b102e1410 100644 --- a/modules/ui/fields/wikipedia.js +++ b/modules/ui/fields/wikipedia.js @@ -78,7 +78,7 @@ export function uiFieldWikipedia(field, context) { langRow = langRow.enter() .append('div') - .attr('class', 'form-row-container wiki-lang-container') + .attr('class', 'wiki-lang-container') .merge(langRow) @@ -106,7 +106,7 @@ export function uiFieldWikipedia(field, context) { titleRow = titleRow.enter() .append('div') - .attr('class', 'form-row-container wiki-title-container') + .attr('class', 'wiki-title-container') .merge(titleRow) title = titleRow.selectAll('input.wiki-title') From 838407b351f1ea0be468a7af73eeeaceb6214ec2 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Thu, 29 Nov 2018 13:50:23 -0500 Subject: [PATCH 3/5] Fix up the flex css for radio, access, structure, wiki --- css/80_app.css | 265 ++++++++++++++++++++++++++++++------------------- 1 file changed, 165 insertions(+), 100 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index 61146064d..4f615a928 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -1259,7 +1259,12 @@ img.tag-reference-wiki-image { flex: 1 1 100%; min-height: 30px; border-top: 0; + border-radius: 0 0 4px 4px; } +.nowrap .form-field-input-wrap { + border-radius: 0; +} + .form-field-input-wrap > input, .form-field-input-wrap > label, @@ -1304,12 +1309,6 @@ img.tag-reference-wiki-image { /* round corners of first/last child elements */ -.form-field-input-wrap > input:first-of-type { - border-bottom-left-radius: 4px; -} -[dir='rtl'] .form-field-input-wrap > input:first-of-type { - border-bottom-right-radius: 4px; -} .form-field-input-wrap > button:last-of-type { border-bottom-right-radius: 4px; } @@ -1320,28 +1319,46 @@ img.tag-reference-wiki-image { /* Field - Access, Cycleway, Structure ------------------------------------------------------- */ +.form-field-input-access, +.form-field-input-cycleway { + flex: 1 1 auto; + display: flex; + flex-flow: row wrap; +} +.form-field-input-access > ul, +.form-field-input-cycleway > ul { + flex: 1 1 auto; + border: 1px solid #ccc; + border-top: 0; + border-radius: 0 0 4px 4px; + width: 100%; +} + .structure-extras-wrap li, -.form-field-input-cycleway .form-field-input-wrap li, -.form-field-input-access .form-field-input-wrap li { +.form-field-input-cycleway li, +.form-field-input-access li { border-bottom: 1px solid #ccc; display: flex; + flex-flow: row nowrap; } .structure-extras-wrap li:last-child, -.form-field-input-cycleway .form-field-input-wrap li:last-child, -.form-field-input-access .form-field-input-wrap li:last-child { +.form-field-input-cycleway li:last-child, +.form-field-input-access li:last-child { border-bottom: 0; } .structure-extras-wrap li > *, -.form-field-input-cycleway .form-field-input-wrap li > *, -.form-field-input-access .form-field-input-wrap li > * { - flex: 1; +.form-field-input-cycleway li > *, +.form-field-input-access li > * { + flex: 1 1 auto; + width: 100%; + border-radius: 0; } .structure-input-type-wrap input, .structure-input-layer-wrap input, .preset-input-cycleway-wrap input, .preset-input-access-wrap input { - border-radius: 0; border-width: 0; + border-radius: 0; border-left-width: 1px; width: 100%; } @@ -1352,17 +1369,6 @@ img.tag-reference-wiki-image { border-left-width: 0; border-right-width: 1px; } -.structure-extras-wrap button { - border-bottom: 0; -} -[dir='ltr'] .structure-extras-wrap button { - border-right: 0; - border-left-width: 1px; -} -[dir='rtl'] .structure-extras-wrap button { - border-left: 0; - border-right-width: 1px; -} .form-field-input-wrap li:last-child input { border-bottom-right-radius: 4px; @@ -1377,54 +1383,79 @@ img.tag-reference-wiki-image { border-top: 0px; border-radius: 0 0 4px 4px; } -.structure-extras-wrap ul { +.structure-extras-wrap > ul { border: 1px solid #ccc; border-radius: 4px; } + +.structure-extras-wrap li button { + border-bottom: 0; + border-right: 0; + border-left-width: 1px; +} +[dir='rtl'] .structure-extras-wrap li button { + border-left: 0; + border-right-width: 1px; +} + .structure-extras-wrap li:first-child span { - border-top-left-radius: 4px; -} -.structure-extras-wrap li:first-child input { - border-radius: 0; - border-top-right-radius: 4px; -} -.structure-extras-wrap li:last-child span { - border-bottom-left-radius: 4px; -} -.structure-extras-wrap li:last-child input { - border-radius: 0; - border-bottom-right-radius: 4px; + border-radius: 4px 0 0 0; } [dir='rtl'] .structure-extras-wrap li:first-child span { - border-top-left-radius: 0; - border-top-right-radius: 4px; + border-radius: 0 4px 0 0; +} + +.structure-extras-wrap li:first-child input { + border-radius: 0 4px 0 0; } [dir='rtl'] .structure-extras-wrap li:first-child input { - border-top-right-radius: 0; - border-top-left-radius: 4px; + border-radius: 4px 0 0 0; } -[dir='rtl'] .structure-extras-wrap li:last-child span { - border-bottom-left-radius: 0; - border-bottom-right-radius: 4px; + +.structure-extras-wrap li:last-child span, +.form-field-input-cycleway li:last-child span, +.form-field-input-access li:last-child span { + border-radius: 0 0 0 4px; } -[dir='rtl'] .structure-extras-wrap li:last-child input { - border-bottom-right-radius: 0; - border-bottom-left-radius: 4px; +[dir='rtl'] .structure-extras-wrap li:last-child span, +[dir='rtl'] .form-field-input-cycleway li:last-child span, +[dir='rtl'] .form-field-input-access li:last-child span { + border-radius: 0 0 4px 0; +} + +.form-field-input-cycleway li:last-child input, +.form-field-input-access li:last-child input { + border-radius: 0 0 4px 0; +} +[dir='rtl'] .form-field-input-cycleway li:last-child input, +[dir='rtl'] .form-field-input-access li:last-child input { + border-radius: 0 0 0 4px; +} + +.structure-extras-wrap li:last-child input { + border-radius: 0 0 0 0; +} + +.structure-extras-wrap li:only-child span { + border-radius: 4px 0 0 4px; +} +[dir='rtl'] .structure-extras-wrap li:only-child span { + border-radius: 0 4px 4px 0; +} +.structure-extras-wrap li:only-child input { + border-radius: 0 4px 4px 0; +} +[dir='rtl'] .structure-extras-wrap li:only-child input { + border-radius: 4px 0 0 4px; } -/* Field - Combo +/* Field - Combo / Multicombo ------------------------------------------------------- */ -[dir='ltr'] .form-field-input-combo > input { - border-bottom-right-radius: 4px; -} -[dir='rtl'] .form-field-input-combo > input { - border-bottom-left-radius: 4px; +.form-field-input-combo > input:only-of-type { + border-radius: 0 0 4px 4px; } - -/* Field - Multicombo -------------------------------------------------------- */ .form-field-input-multicombo ul.chiplist { padding: 5px 0 5px 10px; background: #fff; @@ -1471,8 +1502,28 @@ img.tag-reference-wiki-image { } -/* Field - Numeric +/* Field - Text / Numeric ------------------------------------------------------- */ +.form-field-input-text > input:only-of-type, +.form-field-input-tel > input:only-of-type, +.form-field-input-email > input:only-of-type, +.form-field-input-url > input:only-of-type { + border-radius: 0 0 4px 4px; +} +.form-field-input-number > input:only-of-type { + border-radius: 0 0 0 4px; +} +[dir='rtl'] .form-field-input-number > input:only-of-type { + border-radius: 0 0 4px 0; +} +.form-field-input-number > button:last-of-type { + border-radius: 0 0 4px 0; +} +[dir='rtl'] .form-field-input-number > button:last-of-type { + border-radius: 0 0 0 4px; +} + +/* draw the up/down on the buttons */ .form-field-input-number button.decrement::after, .form-field-input-number button.increment::after { content: ""; @@ -1502,7 +1553,6 @@ img.tag-reference-wiki-image { color: #7092ff; border: 1px solid #ccc; border-top: 0; - border-radius: 0 0 4px 4px; cursor: pointer; } .form-field-input-check:hover { @@ -1536,8 +1586,6 @@ img.tag-reference-wiki-image { flex: 1 1 auto; display: flex; flex-flow: row wrap; - border: 0; - border-top: 0px; } .form-field-input-radio > label { width: 100%; @@ -1549,36 +1597,24 @@ img.tag-reference-wiki-image { color: #7092ff; cursor: pointer; } - +.form-field-input-radio > label:last-child { + border-radius: 0 0 4px 4px; +} .form-field-input-radio > label:hover { background-color: #ececec; } +.form-field-input-radio > label.active { + background-color: #e8ebff; +} .form-field-input-radio > label:not(:last-of-type) { border-bottom: 1px solid #ccc; } -.form-field-input-radio > label:last-child { - border-radius: 0 0 3px 3px; -} .form-field-input-radio label > span { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } -.form-field-input-radio > label.active { - background: #e8ebff; -} - -.form-field-input-radio button.remove { - border-radius: 0 0 3px 3px; -} -.form-field-input-radio button.remove .icon { - position: absolute; - left: 5px; -} -.form-field-input-radio button.remove::before { - content: none; -} /* Hide placeholder for radio buttons if another is active, or not in hover state */ .form-field-input-radio label.active ~ .placeholder, @@ -1594,13 +1630,19 @@ img.tag-reference-wiki-image { /* Field - Maxspeed ------------------------------------------------------- */ -.form-field-input-maxspeed > .maxspeed-unit { +.form-field-input-maxspeed > input:first-of-type { + border-radius: 0 0 0 4px; +} +[dir='rtl'] .form-field-input-maxspeed > input:first-of-type { + border-radius: 0 0 4px 0; +} +.form-field-input-maxspeed > input:last-of-type { /* unit field */ flex: 0 1 80px; width: 80px; border-left: 0; border-radius: 0 0 4px 0; } -[dir='rtl'] .form-field-input-maxspeed > .maxspeed-unit { +[dir='rtl'] .form-field-input-maxspeed > input:last-of-type { border-right: 0; border-radius: 0 0 0 4px; } @@ -1608,6 +1650,29 @@ img.tag-reference-wiki-image { /* Field - Localized Name ------------------------------------------------------- */ +.form-field-input-localized > input.localized-main { + border-radius: 0 0 0 4px; +} +[dir='rtl'] .form-field-input-localized > input.localized-main { + border-radius: 0 0 4px 0; +} +.form-field-input-localized > button.localized-add { + border-radius: 0 0 4px 0; +} +[dir='rtl'] .form-field-input-localized > button.localized-add { + border-radius: 0 0 0 4px; +} + +.form-field-input-localized button.localized-add.disabled, +.form-field-input-localized input.localized-main.disabled, +.form-field-input-localized input.localized-lang.disabled, +.form-field-input-localized input.localized-value.disabled { + color: #777; + background-color: #eee; + cursor: not-allowed; +} + +/* nested subfields for name in different languages */ .localized-multilingual { padding: 0 10px; flex-basis: 100%; @@ -1617,6 +1682,7 @@ img.tag-reference-wiki-image { overflow: hidden; } +/* draws a little line connecting the multilingual field up to the name field */ .localized-multilingual .entry::before { content: ""; display: block; @@ -1641,13 +1707,6 @@ img.tag-reference-wiki-image { width: 100%; } -.localized-multilingual .localized-lang.disabled, -.localized-multilingual .localized-value.disabled { - color: #777; - background-color: #eee; - cursor: not-allowed; -} - /* Field - Address ------------------------------------------------------- */ @@ -1716,22 +1775,22 @@ img.tag-reference-wiki-image { width: 100%; } -.wiki-lang-container > .wiki-lang, -.wiki-title-container > .wiki-title { +.wiki-lang-container > input.wiki-lang, +.wiki-title-container > input.wiki-title { flex: 1 1 auto; border-top: 0; border-radius: 0; } -.wiki-title-container > .wiki-title { +.wiki-title-container > input.wiki-title { border-radius: 0 0 0 4px; } -[dir='rtl'] .wiki-title-container > .wiki-title { +[dir='rtl'] .wiki-title-container > input.wiki-title { border-radius: 0 0 4px 0; } -.wiki-title-container > .wiki-link { +.wiki-title-container > button.wiki-link { border-radius: 0 0 4px 0; } -[dir='rtl'] .wiki-title-container > .wiki-link { +[dir='rtl'] .wiki-title-container > button.wiki-link { border-radius: 0 0 0 4px; } @@ -1901,7 +1960,8 @@ div.combobox { border-right: 5px solid transparent; } -/* remove bottom border radius when combobox is open */ +/* Remove the field's bottom border radius when combobox is open */ +/* For some reason this stops the combobox from overlapping the bottom of the field */ .combobox + * textarea:focus, .combobox + * input:focus { border-bottom-left-radius: 0 !important; @@ -2372,21 +2432,26 @@ input.key-trap { padding-left: 0; border-width: 0; } - .inspector-hover .form-field-input-radio button.active { padding-left: 10px; } -/* Add placeholder only on hover for radio buttons */ +/* Show placeholder on hover for radio buttons */ +.inspector-hover .form-field-input-radio { + border: 1px solid #ccc; + border-top: 0; + border-radius: 0 0 4px 4px; +} .inspector-hover .form-field-input-radio .placeholder { opacity: 1; color: #666; padding: 5px 10px; line-height: 20px; width: 100%; - border: 1px solid #ccc; - border-top: 0; - border-bottom: 0; + border: 0; +} +.inspector-hover .form-field-input-radio .structure-extras-wrap { + border: 0; } From a8f477f2568fe1e7331a6938c306802e9ba5c5e0 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Thu, 29 Nov 2018 14:43:00 -0500 Subject: [PATCH 4/5] Fix the restrictions editor to display as block, not flex --- css/80_app.css | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/css/80_app.css b/css/80_app.css index 4f615a928..126894880 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -1797,11 +1797,19 @@ img.tag-reference-wiki-image { /* Field - Restriction Editor ------------------------------------------------------- */ +.form-field-input-restrictions { + display: block; + border: 1px solid #ccc; + border-top: 0; + border-radius: 0 0 4px 4px; +} + .form-field-input-restrictions .restriction-controls-container { background-color: #fff; - border-top: 1px solid #ccc; width: 100%; padding: 5px; + border-top: 1px solid #ccc; + border-radius: 0 0 4px 4px; } .restriction-controls-container .restriction-controls { From 50d204866bde517716f65ff419a9a69199f79c58 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Thu, 29 Nov 2018 22:31:58 -0500 Subject: [PATCH 5/5] Flexbox the raw member, membership controls, finish tag editor --- css/80_app.css | 101 +++++++++++++++------------- modules/ui/fields/radio.js | 2 +- modules/ui/fields/wikipedia.js | 4 +- modules/ui/raw_member_editor.js | 31 +++++---- modules/ui/raw_membership_editor.js | 59 ++++++++-------- modules/ui/raw_tag_editor.js | 2 +- 6 files changed, 107 insertions(+), 92 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index 126894880..12fb9b707 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -2079,6 +2079,39 @@ div.combobox { } +/* More Fields dropdown +------------------------------------------------------- */ +.more-fields { + padding: 0 20px 20px 20px; + font-weight: bold; +} +.changeset-editor .more-fields { + padding: 15px 20px 0 20px; +} + +.more-fields label { + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + align-items: center; +} + +.more-fields input { + margin-left: 10px; + flex: 1 1 50%; +} +[dir='rtl'] .more-fields input { + margin-left: auto; + margin-right: 10px; +} + +.form-field-input-wrap .label { + height: 30px; + background: #f6f6f6; + padding: 5px 10px; +} + + /* Raw Tag Editor ------------------------------------------------------- */ .tag-list { @@ -2089,9 +2122,14 @@ div.combobox { position: relative; } .tag-row .inner-wrap { + display: flex; + flex-flow: row nowrap; width: 100%; position: relative; - display: flex; +} +.tag-row .key-wrap, +.tag-row .value-wrap { + flex: 1 1 auto; } .tag-row.readonly, @@ -2116,11 +2154,6 @@ div.combobox { border-right: 1px solid #ccc; } -.tag-row .key-wrap, -.tag-row .input-wrap-position { - flex: 1; - height: 30px; -} .tag-row input.key { font-weight: bold; @@ -2147,6 +2180,7 @@ div.combobox { border-top: 1px solid #ccc; } .tag-row button { + flex: 0 0 32px; height: 31px; width: 32px; border: 1px solid #ccc; @@ -2186,7 +2220,6 @@ div.combobox { .tag-row .tag-reference-button { border-radius: 0; - background: #fafafa; } [dir='rtl'] .tag-row .tag-reference-button { border-left-width: 1px; @@ -2257,19 +2290,28 @@ div.combobox { .raw-membership-editor .member-list li:first-child { padding-top: 10px; } -.raw-member-editor .member-row, -.raw-membership-editor .member-row { - position: relative; -} .raw-member-editor .member-row .member-entity-name, .raw-membership-editor .member-row .member-entity-name { font-weight: normal; padding-left: 10px; } +.form-field-input-member > input.member-role { + border-radius: 0 0 0 4px; +} +[dir='rtl'] .form-field-input-member > input.member-role { + border-radius: 0 0 4px 0; +} + +.member-incomplete .form-field-input-member > input.member-role, +[dir='rtl'] .member-incomplete .form-field-input-member > input.member-role { + border-radius: 0 0 4px 4px; +} + .member-incomplete .member-delete { display: none; } + .member-row-new .member-entity-input { border-radius: 4px 4px 0 0; border: 1px solid #ccc; @@ -2301,39 +2343,6 @@ input.key-trap { } -/* More Fields dropdown -------------------------------------------------------- */ -.more-fields { - padding: 0 20px 20px 20px; - font-weight: bold; -} -.changeset-editor .more-fields { - padding: 15px 20px 0 20px; -} - -.more-fields label { - display: flex; - flex-flow: row nowrap; - justify-content: space-between; - align-items: center; -} - -.more-fields input { - margin-left: 10px; - flex: 1 1 50%; -} -[dir='rtl'] .more-fields input { - margin-left: auto; - margin-right: 10px; -} - -.form-field-input-wrap .label { - height: 30px; - background: #f6f6f6; - padding: 5px 10px; -} - - /* Inspector (hover styles) ------------------------------------------------------- */ .inspector-hover .form-field-input-wrap .label, @@ -2398,7 +2407,7 @@ input.key-trap { /* Styles for raw tag inspector on hover */ .inspector-hover .tag-row .key-wrap, -.inspector-hover .tag-row .input-wrap-position { +.inspector-hover .tag-row .value-wrap { height: 31px; } @@ -2638,7 +2647,7 @@ input.key-trap { display: none; } .data-editor.raw-tag-editor .tag-row .key-wrap, -.data-editor.raw-tag-editor .tag-row .input-wrap-position { +.data-editor.raw-tag-editor .tag-row .value-wrap { width: 50%; } diff --git a/modules/ui/fields/radio.js b/modules/ui/fields/radio.js index d4d0e8247..04d1197be 100644 --- a/modules/ui/fields/radio.js +++ b/modules/ui/fields/radio.js @@ -40,7 +40,7 @@ export function uiFieldRadio(field, context) { var enter = wrap.enter() .append('div') - .attr('class', 'form-field-input-wrap form-field-input-radio') + .attr('class', 'form-field-input-wrap form-field-input-radio'); enter .append('span') diff --git a/modules/ui/fields/wikipedia.js b/modules/ui/fields/wikipedia.js index b102e1410..589776e81 100644 --- a/modules/ui/fields/wikipedia.js +++ b/modules/ui/fields/wikipedia.js @@ -79,7 +79,7 @@ export function uiFieldWikipedia(field, context) { langRow = langRow.enter() .append('div') .attr('class', 'wiki-lang-container') - .merge(langRow) + .merge(langRow); lang = langRow.selectAll('input.wiki-lang') @@ -107,7 +107,7 @@ export function uiFieldWikipedia(field, context) { titleRow = titleRow.enter() .append('div') .attr('class', 'wiki-title-container') - .merge(titleRow) + .merge(titleRow); title = titleRow.selectAll('input.wiki-title') .data([0]); diff --git a/modules/ui/raw_member_editor.js b/modules/ui/raw_member_editor.js index b12678b78..98f5c4111 100644 --- a/modules/ui/raw_member_editor.js +++ b/modules/ui/raw_member_editor.js @@ -21,11 +21,12 @@ import { export function uiRawMemberEditor(context) { - var taginfo = services.taginfo, - _entityID; + var taginfo = services.taginfo; + var _entityID; function downloadMember(d) { d3_event.preventDefault(); + // display the loading indicator d3_select(this.parentNode).classed('tag-reference-loading', true); context.loadEntity(d.id); @@ -82,8 +83,8 @@ export function uiRawMemberEditor(context) { function rawMemberEditor(selection) { - var entity = context.entity(_entityID), - memberships = []; + var entity = context.entity(_entityID); + var memberships = []; entity.members.slice(0, 1000).forEach(function(member, index) { memberships.push({ @@ -108,8 +109,8 @@ export function uiRawMemberEditor(context) { ); - function content(wrap) { - var list = wrap.selectAll('.member-list') + function content(selection) { + var list = selection.selectAll('.member-list') .data([0]); list = list.enter() @@ -206,7 +207,11 @@ export function uiRawMemberEditor(context) { } }); - enter + var wrapEnter = enter + .append('div') + .attr('class', 'form-field-input-wrap form-field-input-member'); + + wrapEnter .append('input') .attr('class', 'member-role') .property('type', 'text') @@ -216,7 +221,7 @@ export function uiRawMemberEditor(context) { .property('value', function(d) { return d.role; }) .on('change', changeRole); - enter + wrapEnter .append('button') .attr('tabindex', -1) .attr('title', t('icons.remove')) @@ -225,17 +230,17 @@ export function uiRawMemberEditor(context) { .call(svgIcon('#iD-operation-delete')); if (taginfo) { - enter.each(bindTypeahead); + wrapEnter.each(bindTypeahead); } function bindTypeahead(d) { - var row = d3_select(this), - role = row.selectAll('input.member-role'); + var row = d3_select(this); + var role = row.selectAll('input.member-role'); function sort(value, data) { - var sameletter = [], - other = []; + var sameletter = []; + var other = []; for (var i = 0; i < data.length; i++) { if (data[i].value.substring(0, value.length) === value) { sameletter.push(data[i]); diff --git a/modules/ui/raw_membership_editor.js b/modules/ui/raw_membership_editor.js index e902317d7..be2b8b3a2 100644 --- a/modules/ui/raw_membership_editor.js +++ b/modules/ui/raw_membership_editor.js @@ -1,6 +1,5 @@ import _extend from 'lodash-es/extend'; import _filter from 'lodash-es/filter'; -import _forEach from 'lodash-es/forEach'; import _groupBy from 'lodash-es/groupBy'; import { @@ -28,9 +27,9 @@ import { utilDisplayName, utilNoAuto, utilHighlightEntity } from '../util'; export function uiRawMembershipEditor(context) { - var taginfo = services.taginfo, - _entityID, - _showBlank; + var taginfo = services.taginfo; + var _entityID; + var _showBlank; function selectRelation(d) { @@ -90,16 +89,14 @@ export function uiRawMembershipEditor(context) { var graph = context.graph(); context.intersects(context.extent()).forEach(function(entity) { - if (entity.type !== 'relation' || entity.id === _entityID) - return; + if (entity.type !== 'relation' || entity.id === _entityID) return; - var matched = context.presets().match(entity, graph), - presetName = (matched && matched.name()) || t('inspector.relation'), - entityName = utilDisplayName(entity) || ''; + var matched = context.presets().match(entity, graph); + var presetName = (matched && matched.name()) || t('inspector.relation'); + var entityName = utilDisplayName(entity) || ''; var value = presetName + ' ' + entityName; - if (q && value.toLowerCase().indexOf(q.toLowerCase()) === -1) - return; + if (q && value.toLowerCase().indexOf(q.toLowerCase()) === -1) return; result.push({ relation: entity, value: value }); }); @@ -120,7 +117,7 @@ export function uiRawMembershipEditor(context) { }); }); - _forEach(result, function(obj) { + result.forEach(function(obj) { obj.title = obj.value; }); @@ -130,9 +127,9 @@ export function uiRawMembershipEditor(context) { function rawMembershipEditor(selection) { - var entity = context.entity(_entityID), - parents = context.graph().parentRelations(entity), - memberships = []; + var entity = context.entity(_entityID); + var parents = context.graph().parentRelations(entity); + var memberships = []; parents.slice(0, 1000).forEach(function(relation) { relation.members.forEach(function(member, index) { @@ -154,8 +151,8 @@ export function uiRawMembershipEditor(context) { ); - function content(wrap) { - var list = wrap.selectAll('.member-list') + function content(selection) { + var list = selection.selectAll('.member-list') .data([0]); list = list.enter() @@ -187,7 +184,7 @@ export function uiRawMembershipEditor(context) { }); }); - var label = enter + var labelEnter = enter .append('label') .attr('class', 'form-field-label') .append('span') @@ -196,7 +193,7 @@ export function uiRawMembershipEditor(context) { .attr('href', '#') .on('click', selectRelation); - label + labelEnter .append('span') .attr('class', 'member-entity-type') .text(function(d) { @@ -204,12 +201,16 @@ export function uiRawMembershipEditor(context) { return (matched && matched.name()) || t('inspector.relation'); }); - label + labelEnter .append('span') .attr('class', 'member-entity-name') .text(function(d) { return utilDisplayName(d.relation); }); - enter + var wrapEnter = enter + .append('div') + .attr('class', 'form-field-input-wrap form-field-input-member'); + + wrapEnter .append('input') .attr('class', 'member-role') .property('type', 'text') @@ -219,7 +220,7 @@ export function uiRawMembershipEditor(context) { .property('value', function(d) { return d.member.role; }) .on('change', changeRole); - enter + wrapEnter .append('button') .attr('tabindex', -1) .attr('class', 'remove form-field-button member-delete') @@ -227,7 +228,7 @@ export function uiRawMembershipEditor(context) { .call(svgIcon('#iD-operation-delete')); if (taginfo) { - enter.each(bindTypeahead); + wrapEnter.each(bindTypeahead); } @@ -275,7 +276,7 @@ export function uiRawMembershipEditor(context) { ); - var addrel = wrap.selectAll('.add-relation') + var addrel = selection.selectAll('.add-relation') .data([0]); addrel = addrel.enter() @@ -287,7 +288,7 @@ export function uiRawMembershipEditor(context) { .call(svgIcon('#iD-icon-plus', 'light')) .on('click', function() { _showBlank = true; - content(wrap); + content(selection); list.selectAll('.member-entity-input').node().focus(); }); @@ -299,12 +300,12 @@ export function uiRawMembershipEditor(context) { function bindTypeahead(d) { - var row = d3_select(this), - role = row.selectAll('input.member-role'); + var row = d3_select(this); + var role = row.selectAll('input.member-role'); function sort(value, data) { - var sameletter = [], - other = []; + var sameletter = []; + var other = []; for (var i = 0; i < data.length; i++) { if (data[i].value.substring(0, value.length) === value) { sameletter.push(data[i]); diff --git a/modules/ui/raw_tag_editor.js b/modules/ui/raw_tag_editor.js index bc97d8248..3fedd01c6 100644 --- a/modules/ui/raw_tag_editor.js +++ b/modules/ui/raw_tag_editor.js @@ -122,7 +122,7 @@ export function uiRawTagEditor(context) { innerWrap .append('div') - .attr('class', 'input-wrap-position') + .attr('class', 'value-wrap') .append('input') .property('type', 'text') .attr('class', 'value')