From 8acc72975e95b80678a0422cdc97fb3510ce4286 Mon Sep 17 00:00:00 2001 From: Marco Morales Date: Wed, 20 May 2015 08:31:33 -0400 Subject: [PATCH] Iniital refactor of capa styling for basic checkbox and multiple choice problem types, including additional comments to sass styles --- .../lib/capa/capa/templates/choicegroup.html | 37 +- .../lib/capa/capa/templates/choicetext.html | 14 +- .../capa/templates/formulaequationinput.html | 8 +- .../lib/capa/capa/templates/optioninput.html | 13 +- common/lib/capa/capa/templates/textline.html | 22 +- .../capa/capa/tests/test_input_templates.py | 4 +- .../lib/xmodule/xmodule/css/capa/display.scss | 388 ++++++++++++++---- .../xmodule/js/src/capa/display.coffee | 4 +- common/static/sass/_mixins.scss | 9 + .../courseware/features/problems.feature | 8 +- lms/static/sass/base/_variables.scss | 22 + lms/static/sass/course/base/_extends.scss | 2 +- 12 files changed, 391 insertions(+), 140 deletions(-) diff --git a/common/lib/capa/capa/templates/choicegroup.html b/common/lib/capa/capa/templates/choicegroup.html index 814fae6594..6a27a3df4f 100644 --- a/common/lib/capa/capa/templates/choicegroup.html +++ b/common/lib/capa/capa/templates/choicegroup.html @@ -1,24 +1,5 @@
-
- % if input_type == 'checkbox' or not value: - - - %for choice_id, choice_description in choices: - % if choice_id in value: - ${choice_description}, - %endif - %endfor - - - ${status.display_name} - - - % endif -
-
- % for choice_id, choice_description in choices:
- +
+ % if input_type == 'checkbox' or not value: + + + %for choice_id, choice_description in choices: + % if choice_id in value: + ${choice_description}, + %endif + %endfor + - + ${status.display_name} + + + % endif +
% if show_correctness == "never" and (value or status not in ['unsubmitted']):
${submitted_message}
%endif diff --git a/common/lib/capa/capa/templates/choicetext.html b/common/lib/capa/capa/templates/choicetext.html index 91a894dd4f..e370f10594 100644 --- a/common/lib/capa/capa/templates/choicetext.html +++ b/common/lib/capa/capa/templates/choicetext.html @@ -9,12 +9,7 @@
-
- % if input_type == 'checkbox' or not element_checked: - - % endif -
- +
% for choice_id, choice_description in choices: <%choice_id= choice_id %> @@ -62,6 +57,13 @@
+ +
+ % if input_type == 'checkbox' or not element_checked: + + % endif +
+ % if show_correctness == "never" and (value or status not in ['unsubmitted']):
${_(submitted_message)}
%endif diff --git a/common/lib/capa/capa/templates/formulaequationinput.html b/common/lib/capa/capa/templates/formulaequationinput.html index de56fd5098..04b4f8e965 100644 --- a/common/lib/capa/capa/templates/formulaequationinput.html +++ b/common/lib/capa/capa/templates/formulaequationinput.html @@ -10,9 +10,11 @@ % endif /> -

- ${status.display_name} -

+ + + ${status.display_name} + +
\[\] diff --git a/common/lib/capa/capa/templates/optioninput.html b/common/lib/capa/capa/templates/optioninput.html index f804e771cc..65965597b7 100644 --- a/common/lib/capa/capa/templates/optioninput.html +++ b/common/lib/capa/capa/templates/optioninput.html @@ -13,12 +13,13 @@ - - ${value|h} - ${status.display_name} - - +
+ + ${value|h} - ${status.display_name} + +
% if msg: ${msg|n} % endif diff --git a/common/lib/capa/capa/templates/textline.html b/common/lib/capa/capa/templates/textline.html index 8a9826b0a5..ed006240ca 100644 --- a/common/lib/capa/capa/templates/textline.html +++ b/common/lib/capa/capa/templates/textline.html @@ -27,18 +27,20 @@ /> ${trailing_text | h} -

- %if value: - ${value|h} - % else: - ${label} - %endif - - - ${status.display_name} -

+ aria-describedby="input_${id}" data-tooltip="This is ${status.display_name}."> + + %if value: + ${value|h} + % else: + ${label} + %endif + - + ${status.display_name} + +

diff --git a/common/lib/capa/capa/tests/test_input_templates.py b/common/lib/capa/capa/tests/test_input_templates.py index 09ae25476d..4bed5e88c7 100644 --- a/common/lib/capa/capa/tests/test_input_templates.py +++ b/common/lib/capa/capa/tests/test_input_templates.py @@ -388,9 +388,9 @@ class TextlineTemplateTest(TemplateTestCase): xpath = "//div[@class='%s ']" % div_class self.assert_has_xpath(xml, xpath, self.context) - # Expect that we get a

with class="status" + # Expect that we get a with class="status" # (used to by CSS to draw the green check / red x) - self.assert_has_text(xml, "//p[@class='status']", + self.assert_has_text(xml, "//span[@class='status']", status_mark, exact=False) def test_label(self): diff --git a/common/lib/xmodule/xmodule/css/capa/display.scss b/common/lib/xmodule/xmodule/css/capa/display.scss index 727630b79b..c8d5f7787f 100644 --- a/common/lib/xmodule/xmodule/css/capa/display.scss +++ b/common/lib/xmodule/xmodule/css/capa/display.scss @@ -1,8 +1,54 @@ +// capa - styling +// ==================== + +// Table of Contents +// * +Variables - Capa +// * +Extends - Capa +// * +Mixins - Status Icon - Capa +// * +Resets - Deprecate Please +// * +Problem - Base +// * +Problem - Choice Group +// * +Problem - Misc, Unclassified Mess +// * +Problem - Text Input, Numerical Input +// * +Problem - Option Input (Dropdown) +// * +Problem - CodeMirror +// * +Problem - Misc, Unclassified Mess Part 2 +// * +Problem - Rubric +// * +Problem - Annotation +// * +Problem - Choice Text Group + +// +Variables - Capa +// ==================== $annotation-yellow: rgba(255,255,10,0.3); $color-copy-tip: rgb(100,100,100); -$color-success: rgb(0, 136, 1); -$color-fail: rgb(212, 64, 64); +$correct: $green-d1; +$incorrect: $red; +// +Extends - Capa +// ==================== +// Duplicated from _mixins.scss due to xmodule compilation, inheritance issues +%use-font-awesome { + font-family: FontAwesome; + -webkit-font-smoothing: antialiased; + display: inline-block; + speak: none; +} + +// +Mixins - Status Icon - Capa +// ==================== +@mixin status-icon($color: $gray, $fontAwesomeIcon: "\f00d"){ + + &:after { + @extend %use-font-awesome; + @include margin-left(17px); + color: $color; + font-size: 1.2em; + content: $fontAwesomeIcon; + } +} + +// +Resets - Deprecate Please +// ==================== h2 { margin-top: 0; margin-bottom: ($baseline*0.75); @@ -24,12 +70,12 @@ h2 { .feedback-hint-correct { margin-top: ($baseline/2); - color: $color-success; + color: $correct; } .feedback-hint-incorrect { margin-top: ($baseline/2); - color: $color-fail; + color: $incorrect; } .feedback-hint-text { @@ -55,10 +101,9 @@ h2 { display: block; } - iframe[seamless]{ overflow: hidden; - padding: 0px; + padding: 0; border: 0px none transparent; background-color: transparent; } @@ -68,13 +113,15 @@ iframe[seamless]{ } div.problem-progress { + @include padding-left($baseline/4); display: inline-block; - padding-left: ($baseline/4); - color: #666; + color: $gray-d1; font-weight: 100; font-size: em(16); } +// +Problem - Base +// ==================== div.problem { @media print { display: block; @@ -89,7 +136,11 @@ div.problem { .inline { display: inline; } +} +// +Problem - Choice Group +// ==================== +div.problem { .choicegroup { @include clearfix(); min-width: 100px; @@ -97,51 +148,100 @@ div.problem { width: 100px; label { - @include float(left); + @include box-sizing(border-box); + display: inline-block; clear: both; - margin-bottom: ($baseline/4); + width: 100%; + border: 2px solid $gray-l4; + border-radius: 3px; + margin-bottom: ($baseline/2); + padding: ($baseline/2); &.choicegroup_correct { - &:after { - margin-left: ($baseline*0.75); - content: url('../images/correct-icon.png'); + @include status-icon($correct, "\f00c"); + border: 2px solid $correct; + + // keep green for correct answers on hover. + &:hover { + border-color: $correct; } } &.choicegroup_incorrect { - &:after { - margin-left: ($baseline*0.75); - content: url('../images/incorrect-icon.png'); + @include status-icon($incorrect, "\f00d"); + border: 2px solid $incorrect; + + // keep red for incorrect answers on hover. + &:hover { + border-color: $incorrect; } } + + &:hover { + border: 2px solid $blue; + } } .indicator_container { - @include float(left); + display: inline-block; + min-height: 1px; width: 25px; - height: 1px; - @include margin-right(15px); } fieldset { @include box-sizing(border-box); - margin: 0px 0px $baseline; - @include padding-left($baseline); - @include border-left(1px solid #ddd); } input[type="radio"], input[type="checkbox"] { - @include float(left); - @include margin(4px, 8px, 0, 0); + @include margin(($baseline/4) ($baseline/2) ($baseline/4) ($baseline/4)); } text { + @include margin-left(25px); display: inline; - margin-left: 25px; } } +} +// +Problem - Status Indicators +// ==================== +// Summary status indicators shown after the input area +div.problem { + + .indicator_container { + + .status { + width: 20px; + height: 20px; + + // CASE: correct answer + &.correct { + @include status-icon($correct, "\f00c"); + } + + // CASE: incorrect answer + &.incorrect { + @include status-icon($incorrect, "\f00d"); + } + + // CASE: unanswered + &.unanswered { + @include status-icon($gray-l4, "\f128"); + } + + // CASE: processing + &.processing { + // add once spinner is rotated through animations + //@include status-icon($gray-d1, "\f110", 0); + } + } + } +} + +// +Problem - Misc, Unclassified Mess +// ==================== +div.problem { ol.enumerate { li { &:before { @@ -187,17 +287,22 @@ div.problem { } } + // known classes using this div: .indicator_container, moved to section above div { + + // TO-DO: Styling used by advanced capa problem types. Should be synced up to use .status class p { &.answer { margin-top: -2px; } + &.status { - margin: 8px 0 0 $baseline/2; + @include margin(8px, 0, 0, $baseline/2); text-indent: 100%; white-space: nowrap; overflow: hidden; } + span.clarification i { font-style: normal; &:hover { @@ -241,7 +346,21 @@ div.problem { } } - &.incorrect, &.incomplete, &.ui-icon-close { + &.ui-icon-close { + p.status { + display: inline-block; + width: 20px; + height: 20px; + background: url('../images/incorrect-icon.png') center center no-repeat; + } + + input { + border-color: red; + } + } + + &.incorrect, &.incomplete { + p.status { display: inline-block; width: 20px; @@ -260,9 +379,9 @@ div.problem { } p.answer { + @include margin-left($baseline/2); display: inline-block; margin-bottom: 0; - margin-left: $baseline/2; &:before { display: inline; @@ -287,8 +406,8 @@ div.problem { } img.loading { + @include padding-left($baseline/2); display: inline-block; - padding-left: ($baseline/2); } span { @@ -303,7 +422,7 @@ div.problem { background: #f1f1f1; } } - } + } // Hides equation previews in symbolic response problems when printing [id^='display'].equation { @@ -312,8 +431,9 @@ div.problem { } } + //TO-DO: review and deprecate all these styles within span {} span { - &.unanswered, &.ui-icon-bullet { + &.ui-icon-bullet { display: inline-block; position: relative; top: 4px; @@ -331,7 +451,7 @@ div.problem { background: url('../images/spinner.gif') center center no-repeat; } - &.correct, &.ui-icon-check { + &.ui-icon-check { display: inline-block; position: relative; top: 3px; @@ -349,7 +469,7 @@ div.problem { background: url('../images/partially-correct-icon.png') center center no-repeat; } - &.incorrect, &.incomplete, &.ui-icon-close { + &.incomplete, &.ui-icon-close { display: inline-block; position: relative; top: 3px; @@ -360,8 +480,8 @@ div.problem { } .reload { - float:right; - margin: $baseline/2; + @include float(right); + margin: ($baseline/2); } @@ -457,15 +577,6 @@ div.problem { } } - form.option-input { - margin: -$baseline/2 0 $baseline; - padding-bottom: $baseline; - - select { - margin-right: flex-gutter(); - } - } - ul { margin-bottom: lh(); margin-left: .75em; @@ -584,6 +695,93 @@ div.problem { white-space: pre; } } +} + +// +Problem - Text Input, Numerical Input +// ==================== +.problem { + .capa_inputtype.textline, .inputtype.formulaequationinput { + + input { + @include box-sizing(border-box); + border: 2px solid $gray-l4; + border-radius: 3px; + height: 46px; + min-width: 160px; + } + + > .incorrect, .correct, .unanswered { + + .status { + display: inline-block; + background: none; + margin-top: ($baseline/2); + } + } + + // CASE: incorrect answer + > .incorrect { + + input { + border: 2px solid $incorrect; + } + + .status { + @include status-icon($incorrect, "\f00d"); + } + } + + // CASE: correct answer + > .correct { + + input { + border: 2px solid $correct; + } + + .status { + @include status-icon($correct, "\f00c"); + } + } + + // CASE: unanswered + > .unanswered { + + input { + border: 2px solid $gray-l4; + } + + .status { + @include status-icon($gray-l4, "\f128"); + } + } + } +} + + +// +Problem - Option Input (Dropdown) +// ==================== +.problem { + .inputtype.option-input { + margin: (-$baseline/2) 0 $baseline; + padding-bottom: $baseline; + + select { + @include margin-right($baseline/2); + } + + .indicator_container { + display: inline-block; + + .status.correct:after, .status.incorrect:after { + @include margin-left(0); + } + } + } +} + +// +Problem - CodeMirror +// ==================== +div.problem { .CodeMirror { border: 1px solid black; @@ -634,7 +832,52 @@ div.problem { .CodeMirror-scroll { margin-right: 0px; } +} +// +Problem - Actions +// ==================== +div.problem .action { + margin-top: $baseline; + + .save, .check, .show, .reset, .hint-button { + @include margin-right($baseline/2); + margin-bottom: ($baseline/2); + height: ($baseline*2); + vertical-align: middle; + font-weight: 600; + text-transform: uppercase; + } + + .save { + @extend .blue-button !optional; + } + + .show { + + .show-label { + font-weight: 600; + font-size: 1.0em; + } + } + + .submission_feedback { + // background: #F3F3F3; + // border: 1px solid #ddd; + // border-radius: 3px; + // padding: 8px 12px; + // margin-top: ($baseline/2); + display: inline-block; + margin-top: 8px; + @include margin-left($baseline/2); + color: $gray-d1; + font-style: italic; + -webkit-font-smoothing: antialiased; + } +} + +// +Problem - Misc, Unclassified Mess Part 2 +// ==================== +div.problem { hr { float: none; clear: both; @@ -663,47 +906,7 @@ div.problem { padding: lh(); border: 1px solid $gray-l3; } - - div.action { - margin-top: $baseline; - - .save, .check, .show, .reset, .hint-button { - height: ($baseline*2); - vertical-align: middle; - font-weight: 600; - - @media print { - display: none; - } - } - - .save { - @extend .blue-button !optional; - } - - .show { - - .show-label { - font-weight: 600; - font-size: 1.0em; - } - } - - .submission_feedback { - // background: #F3F3F3; - // border: 1px solid #ddd; - // border-radius: 3px; - // padding: 8px 12px; - // margin-top: ($baseline/2); - display: inline-block; - margin-top: 8px; - @include margin-left($baseline/2); - color: #666; - font-style: italic; - -webkit-font-smoothing: antialiased; - } - } - + .detailed-solution { > p:first-child { color: #aaa; @@ -951,7 +1154,12 @@ div.problem { } } } +} + +// +Problem - Rubric +// ==================== +div.problem { .rubric { tr { margin: ($baseline/2) 0; @@ -1004,7 +1212,11 @@ div.problem { display: none; } } +} +// +Problem - Annotation +// ==================== +div.problem { .annotation-input { margin: 0 0 1em 0; border: 1px solid $gray-l3; @@ -1102,8 +1314,12 @@ div.problem { } } } +} - .choicetextgroup{ +// +Problem - Choice Text Group +// ==================== +div.problem { + .choicetextgroup { @extend .choicegroup; input[type="text"]{ diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 139654e5e5..f5e6c1baa0 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -468,7 +468,7 @@ class @Problem # They should set handlers on each to reset the whole. formulaequationinput: (element) -> $(element).find('input').on 'input', -> - $p = $(element).find('p.status') + $p = $(element).find('span.status') `// Translators: the word unanswered here is about answering a problem the student must solve.` $p.parent().removeClass().addClass "unanswered" @@ -496,7 +496,7 @@ class @Problem textline: (element) -> $(element).find('input').on 'input', -> - $p = $(element).find('p.status') + $p = $(element).find('span.status') `// Translators: the word unanswered here is about answering a problem the student must solve.` $p.parent().removeClass("correct incorrect").addClass "unanswered" diff --git a/common/static/sass/_mixins.scss b/common/static/sass/_mixins.scss index b86ac1e2bd..6e702fdff6 100644 --- a/common/static/sass/_mixins.scss +++ b/common/static/sass/_mixins.scss @@ -23,6 +23,7 @@ // * +Content - Screenreader Text - Extend // * +Content - Text Wrap - Extend // * +Content - Text Truncate - Extend +// * +Icon - Font-Awesome - Extend // +Font Sizing - Mixin // ==================== @@ -428,3 +429,11 @@ text-overflow: ellipsis; } +// * +Icon - Font-Awesome - Extend +// ==================== +%use-font-awesome { + font-family: FontAwesome; + -webkit-font-smoothing: antialiased; + display: inline-block; + speak: none; +} diff --git a/lms/djangoapps/courseware/features/problems.feature b/lms/djangoapps/courseware/features/problems.feature index b1e0359f62..58c0e90040 100644 --- a/lms/djangoapps/courseware/features/problems.feature +++ b/lms/djangoapps/courseware/features/problems.feature @@ -176,11 +176,11 @@ Feature: LMS.Answer problems Scenario: I can view and hide the answer if the problem has it: Given I am viewing a "numerical" that shows the answer "always" - When I press the button with the label "Show Answer" - Then the Show/Hide button label is "Hide Answer" + When I press the button with the label "SHOW ANSWER" + Then the Show/Hide button label is "HIDE ANSWER" And I should see "4.14159" somewhere in the page - When I press the button with the label "Hide Answer" - Then the Show/Hide button label is "Show Answer" + When I press the button with the label "HIDE ANSWER" + Then the Show/Hide button label is "SHOW ANSWER" And I should not see "4.14159" anywhere on the page Scenario: I can see my score on a problem when I answer it and after I reset it diff --git a/lms/static/sass/base/_variables.scss b/lms/static/sass/base/_variables.scss index a057789f27..5b1197c3ef 100644 --- a/lms/static/sass/base/_variables.scss +++ b/lms/static/sass/base/_variables.scss @@ -82,6 +82,28 @@ $gray-d2: shade($gray,40%); // #4c4c4c $gray-d3: shade($gray,60%); // #323232 $gray-d4: shade($gray,80%); // #191919 +// TO-DO: once existing lms $blue is removed, change $cms-blue to $blue. +$cms-blue: rgb(0, 159, 230); +$blue-l1: tint($cms-blue,20%); +$blue-l2: tint($cms-blue,40%); +$blue-l3: tint($cms-blue,60%); +$blue-l4: tint($cms-blue,80%); +$blue-l5: tint($cms-blue,90%); +$blue-d1: shade($cms-blue,20%); +$blue-d2: shade($cms-blue,40%); +$blue-d3: shade($cms-blue,60%); +$blue-d4: shade($cms-blue,80%); +$blue-s1: saturate($cms-blue,15%); +$blue-s2: saturate($cms-blue,30%); +$blue-s3: saturate($cms-blue,45%); +$blue-u1: desaturate($cms-blue,15%); +$blue-u2: desaturate($cms-blue,30%); +$blue-u3: desaturate($cms-blue,45%); +$blue-t0: rgba($cms-blue, 0.125); +$blue-t1: rgba($cms-blue, 0.25); +$blue-t2: rgba($cms-blue, 0.50); +$blue-t3: rgba($cms-blue, 0.75); + $pink: rgb(182,37,103); // #b72567; $pink-l1: tint($pink,20%); $pink-l2: tint($pink,40%); diff --git a/lms/static/sass/course/base/_extends.scss b/lms/static/sass/course/base/_extends.scss index cac78034be..19e065f31f 100644 --- a/lms/static/sass/course/base/_extends.scss +++ b/lms/static/sass/course/base/_extends.scss @@ -28,7 +28,7 @@ h1.top-header { .light-button, a.light-button, // only used in askbot as classes .gray-button { - @include button(simple, #eee); + @include button(simple, $gray-l5); @extend .button-reset; font-size: em(13); }