refactor space workout form controls

Group each movement and set-ending control set so desktop and mobile layouts use one typographic rhythm. Keep legends separate from their controls and retain visible gaps between stacked fields.

Commit
1831d1939465aa5de42831ab19c8fdb74d385a6a
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
lib/presenter/pages_workout.ml
index 6eb3786a..d71ed26a 100644..100644
@@ -24,7 +24,8 @@
24 24 reps stay together, so a responsive layout cannot mix two movements. *)
25 25 let movement_group ~name ~load_id ~load_field ~reps_id ~reps_field ?load_value
26 26 ?reps_value ?previous_load ?previous_reps ~reps_label () =
27 Removed: let number_field ~input_id ~field ~value ~step_ ~label ~previous ~unit =
27 Added: let number_field ~additional_class ~input_id ~field ~value ~step_ ~label
28 Added: ~previous ~unit =
28 29 let input =
29 30 void "input"
30 31 ([
@@ -56,7 +57,7 @@
56 57 @ [ input; tag "span" [ class_ "input-unit" ] [ txt "%s" unit ] ])
57 58 in
58 59 tag "div"
59 Removed: [ class_ "field field-number" ]
60 Added: [ class_ "field field-number%s" additional_class ]
60 61 [
61 62 tag "label"
62 63 [ Dream_html.string_attr "for" "%s" input_id; class_ "sr-only" ]
@@ -71,10 +72,16 @@
71 72 [ class_ "movement-fieldset" ]
72 73 [
73 74 tag "legend" [] [ txt "%s" name ];
74 Removed: number_field ~input_id:load_id ~field:load_field ~value:load_value
75 Removed: ~step_:"0.5" ~label:"Load (kg)" ~previous:previous_load ~unit:"kg";
76 Removed: number_field ~input_id:reps_id ~field:reps_field ~value:reps_value
77 Removed: ~step_:"1" ~label:reps_label ~previous:previous_reps ~unit:"reps";
75 Added: tag "div"
76 Added: [ class_ "movement-controls" ]
77 Added: [
78 Added: number_field ~additional_class:"" ~input_id:load_id
79 Added: ~field:load_field ~value:load_value ~step_:"0.5"
80 Added: ~label:"Load (kg)" ~previous:previous_load ~unit:"kg";
81 Added: number_field ~additional_class:" field-after-load"
82 Added: ~input_id:reps_id ~field:reps_field ~value:reps_value ~step_:"1"
83 Added: ~label:reps_label ~previous:previous_reps ~unit:"reps";
84 Added: ];
78 85 ];
79 86 ]
80 87
@@ -99,55 +106,60 @@
99 106 [
100 107 tag "legend" [] [ txt "Set ending" ];
101 108 tag "div"
102 Removed: [ class_ "field field-ending" ]
109 Added: [ class_ "set-ending-controls" ]
103 110 [
104 Removed: tag "label"
111 Added: tag "div"
112 Added: [ class_ "field field-ending" ]
105 113 [
106 Removed: Dream_html.string_attr "for" "%s" (field_id "extension");
107 Removed: class_ "sr-only";
108 Removed: ]
109 Removed: [ txt "Ending" ];
110 Removed: extension_select ~selected ~input_id:(field_id "extension") ();
111 Removed: ];
112 Removed: tag "div"
113 Removed: [ class_ "field field-extension-amount" ]
114 Removed: [
115 Removed: tag "label"
116 Removed: [
117 Removed: Dream_html.string_attr "for" "%s" (field_id "extension_amount");
118 Removed: class_ "sr-only";
119 Removed: ]
120 Removed: [
121 Removed: tag "span"
122 Removed: [ class_ "amount-label-reps" ]
123 Removed: [ txt "Extension reps" ];
124 Removed: tag "span" [ class_ "amount-label-sep" ] [ txt " / " ];
125 Removed: tag "span"
126 Removed: [ class_ "amount-label-seconds" ]
127 Removed: [ txt "Hold seconds" ];
114 Added: tag "label"
115 Added: [
116 Added: Dream_html.string_attr "for" "%s" (field_id "extension");
117 Added: class_ "sr-only";
118 Added: ]
119 Added: [ txt "Ending" ];
120 Added: extension_select ~selected ~input_id:(field_id "extension") ();
128 121 ];
129 122 tag "div"
130 Removed: [ class_ "input-group" ]
123 Added: [ class_ "field field-extension-amount field-after-ending" ]
131 124 [
132 Removed: void "input"
125 Added: tag "label"
133 126 [
134 Removed: type_ "number";
135 Removed: name "extension_amount";
136 Removed: Dream_html.string_attr "id" "%s"
127 Added: Dream_html.string_attr "for" "%s"
137 128 (field_id "extension_amount");
138 Removed: Dream_html.string_attr "min" "1";
139 Removed: step "1";
140 Removed: Dream_html.string_attr "value" "%s"
141 Removed: selected_extension_amount;
142 Removed: ];
143 Removed: tag "span"
144 Removed: [ class_ "input-unit" ]
129 Added: class_ "sr-only";
130 Added: ]
145 131 [
146 Removed: tag "span" [ class_ "amount-label-reps" ] [ txt "reps" ];
132 Added: tag "span"
133 Added: [ class_ "amount-label-reps" ]
134 Added: [ txt "Extension reps" ];
147 135 tag "span" [ class_ "amount-label-sep" ] [ txt " / " ];
148 136 tag "span"
149 137 [ class_ "amount-label-seconds" ]
150 Removed: [ txt "seconds" ];
138 Added: [ txt "Hold seconds" ];
139 Added: ];
140 Added: tag "div"
141 Added: [ class_ "input-group" ]
142 Added: [
143 Added: void "input"
144 Added: [
145 Added: type_ "number";
146 Added: name "extension_amount";
147 Added: Dream_html.string_attr "id" "%s"
148 Added: (field_id "extension_amount");
149 Added: Dream_html.string_attr "min" "1";
150 Added: step "1";
151 Added: Dream_html.string_attr "value" "%s"
152 Added: selected_extension_amount;
153 Added: ];
154 Added: tag "span"
155 Added: [ class_ "input-unit" ]
156 Added: [
157 Added: tag "span" [ class_ "amount-label-reps" ] [ txt "reps" ];
158 Added: tag "span" [ class_ "amount-label-sep" ] [ txt " / " ];
159 Added: tag "span"
160 Added: [ class_ "amount-label-seconds" ]
161 Added: [ txt "seconds" ];
162 Added: ];
151 163 ];
152 164 ];
153 165 ];
lib/web/assets/hito.css
index 8c61ff18..88bc6179 100644..100644
@@ -352,6 +352,7 @@
352 352
353 353 legend {
354 354 max-width: 100%;
355 Added: margin: 0 0 1rem;
355 356 padding: 0 0.35rem;
356 357 color: var(--ink);
357 358 font: 700 var(--font-size-small)/1.35 var(--sans);
@@ -930,7 +931,7 @@
930 931 .movement-list {
931 932 display: flex;
932 933 flex-direction: column;
933 Removed: gap: 0.7rem;
934 Added: gap: 1rem;
934 935 margin: 0;
935 936 padding: 0;
936 937 list-style: none;
@@ -938,36 +939,29 @@
938 939 .movement-group {
939 940 margin: 0;
940 941 }
941 Removed: .movement-fieldset {
942 Removed: display: flex;
943 Removed: flex-wrap: wrap;
944 Removed: align-items: center;
945 Removed: gap: 0.6rem;
942 Added: .movement-fieldset,
943 Added: .set-ending {
946 944 margin: 0;
947 945 padding: 0;
948 946 border: 0;
949 947 }
950 Removed: .movement-fieldset > legend {
951 Removed: flex: 1 0 100%;
952 Removed: }
953 Removed: .movement-fieldset > .field,
954 Removed: .set-ending > .field-ending {
955 Removed: flex: 1 1 15rem;
956 Removed: }
957 Removed: .set-ending > .field-extension-amount {
958 Removed: flex: 0 1 18rem;
959 Removed: }
960 948 .movement-fieldset > legend,
961 949 .set-ending > legend {
962 Removed: margin: 0 0 0.25rem;
963 Removed: padding: 0;
950 Added: margin: 0;
951 Added: padding: 0 0 0.75rem;
964 952 color: var(--ink);
965 953 font: 600 var(--font-size-lead)/1.2 var(--sans);
966 954 letter-spacing: -0.01em;
967 955 text-transform: none;
968 956 }
969 Removed: .movement-fieldset > .field,
970 Removed: .set-ending > .field {
957 Added: .movement-controls,
958 Added: .set-ending-controls {
959 Added: display: grid;
960 Added: grid-template-columns: repeat(2, minmax(0, 1fr));
961 Added: gap: 0.6rem;
962 Added: }
963 Added: .movement-controls > .field,
964 Added: .set-ending-controls > .field {
971 965 min-width: 0;
972 966 margin: 0;
973 967 }
@@ -1025,18 +1019,6 @@
1025 1019 }
1026 1020 /* The set ending is a property of the completed stimulus. Its spacing and
1027 1021 legend make that distinction clear without a second card. */
1028 Removed: .set-ending {
1029 Removed: display: flex;
1030 Removed: flex-wrap: wrap;
1031 Removed: align-items: center;
1032 Removed: gap: 0.6rem;
1033 Removed: margin: 0.1rem 0 0;
1034 Removed: padding: 0.9rem 0 0;
1035 Removed: border: 0;
1036 Removed: }
1037 Removed: .set-ending > legend {
1038 Removed: flex: 1 0 100%;
1039 Removed: }
1040 1022 .record-action { margin: 0 !important; }
1041 1023 .correction-actions {
1042 1024 display: grid;
@@ -1366,17 +1348,18 @@
1366 1348 }
1367 1349
1368 1350 /* One column: a movement and its ending each take the full width. */
1369 Removed: .movement-fieldset,
1370 Removed: .set-ending {
1371 Removed: flex-direction: column;
1372 Removed: align-items: stretch;
1351 Added: .movement-controls,
1352 Added: .set-ending-controls {
1353 Added: grid-template-columns: 1fr;
1354 Added: gap: 0;
1373 1355 }
1374 Removed: .movement-fieldset > legend,
1375 Removed: .movement-fieldset > .field,
1376 Removed: .set-ending > legend,
1377 Removed: .set-ending > .field {
1378 Removed: flex: 0 0 auto;
1379 Removed: width: 100%;
1356 Added: .movement-controls > .field,
1357 Added: .set-ending-controls > .field {
1358 Added: margin-bottom: 0.6rem;
1359 Added: }
1360 Added: .movement-controls > .field:last-child,
1361 Added: .set-ending-controls > .field:last-child {
1362 Added: margin-bottom: 0;
1380 1363 }
1381 1364 .correction-actions {
1382 1365 grid-template-columns: 1fr;