1/*! Icinga Web 2 | (c) 2019 Icinga Development Team | GPLv2+ */
2
3/**
4 Rules found in here are structured with two layers:
5
6  1) form.icinga-form, that's what defines the general structure of our single/individual forms. It's not
7     supposed to be used for any other forms that are not the only content on the page (e.g. inline-forms)
8  2) .icinga-controls, this defines the design of our controls. Any input that's part of a container with
9     this class gets our design applied
10 */
11
12// General form layout
13
14form.icinga-form {
15  max-width: 70em;
16  width: 80%;
17
18  .control-group {
19    display: flex;
20    flex-wrap: wrap;
21    align-items: flex-start;
22
23    // Negative margin-right because every child gets 1em right but we can't exclude
24    // the last element as it's impossible to identify the last *visible* element
25    margin: 1em -1em 1em 0;
26  }
27
28  .control-group > :not(.control-label-group) {
29    margin-right: 1em;
30  }
31
32  .form-controls {
33    display: flex;
34    justify-content: flex-end;
35  }
36
37  &.inline {
38    width: auto;
39
40    .control-group {
41      margin: 0;
42
43      &:last-child {
44        margin-right: -1em;
45      }
46    }
47  }
48}
49
50form.inline {
51  display: inline-block;
52}
53
54// Minimal form layout
55
56#layout.minimal-layout,
57#layout.twocols:not(.wide-layout) {
58  form.icinga-form {
59    &:not(.inline) {
60      width: 100%;
61    }
62
63    .control-label-group {
64      text-align: left;
65      padding-bottom: 0;
66      padding-left: 0;
67      margin-bottom: 0;
68    }
69
70    .toggle-switch ~ .control-info:before {
71      margin-left: 0;
72    }
73
74    .control-info {
75      opacity: .5;
76    }
77
78    .errors {
79      margin: 0;
80    }
81  }
82}
83
84// Label styles
85
86form.icinga-form .control-label-group {
87  display: flex;
88  flex-direction: column;
89  justify-content: center;
90  line-height: 1.1em;
91  padding: .5625em .5625em .5625em 0;
92  max-height: 2.5em;
93  text-align: right;
94  width: 14em;
95}
96
97form.icinga-form.inline .control-label-group {
98  width: auto;
99  line-height: 0.857em;
100}
101
102.icinga-controls fieldset {
103  margin: 0;
104  padding: 0;
105  border: none;
106  border-top: 1px solid @gray-light;
107
108  legend, .description {
109    margin-left: .7em;
110  }
111}
112
113.icinga-controls .control-info {
114  line-height: 2.25em;
115  opacity: .6;
116
117  &:before {
118    margin-right: 0;
119  }
120
121  &:hover:before {
122    color: black;
123  }
124}
125
126form.icinga-form .control-group .control-info {
127  margin-left: -.5em;
128}
129form.icinga-form .control-group .toggle-switch ~ .control-info {
130  margin-left: 0;
131}
132
133// General input styles
134
135.icinga-controls {
136  input[type="text"],
137  input[type="password"],
138  input[type="number"],
139  input[type="datetime-local"],
140  input[type="date"],
141  input[type="time"],
142  textarea,
143  select {
144    background-color: @low-sat-blue;
145  }
146}
147
148form.icinga-form {
149  input[type="text"],
150  input[type="password"],
151  input[type="number"],
152  input[type="datetime-local"],
153  input[type="date"],
154  input[type="time"],
155  textarea,
156  select {
157    flex: 1 1 auto;
158    width: 0;
159  }
160}
161
162.icinga-controls {
163  input:not([type="radio"]),
164  .toggle-switch,
165  button,
166  select,
167  textarea {
168    border: none;
169    .rounded-corners(.25em);
170    .appearance(none);
171  }
172}
173
174.icinga-controls {
175  input:not([type="checkbox"]),
176  .toggle-switch,
177  select,
178  textarea,
179  button,
180  .toggle-switch {
181    font-size: inherit;
182    padding: @vertical-padding;
183  }
184
185  input[type="radio"] {
186    margin-right: .25em;
187  }
188}
189
190form.icinga-form {
191  .control-group .toggle-switch,
192  .form-controls .toggle-switch {
193    margin-top: 0.5em*0.666666667;
194    margin-bottom: 0.5em*0.666666667;
195  }
196}
197
198form.icinga-form select:not([multiple]) {
199  // Compensate inconsistent select height calculations
200  line-height: 1em;
201  height: 2.25em;
202}
203
204// Remove native dropdown arrow in IE10+
205.icinga-controls select::-ms-expand {
206  display: none;
207  opacity: 0;
208}
209
210.icinga-controls select:not([multiple]) {
211  padding-right: 1.5625em;
212  background-image: url(../img/select-icon.svg);
213  background-repeat: no-repeat;
214  background-position: right center;
215  background-size: contain;
216}
217
218form.icinga-form select {
219  width: 0; // Prevent selects with long option values from exceeding the container
220}
221
222form.inline select {
223  width: auto;
224}
225
226
227// Specific input styles
228
229.link-button {
230  .action-link();
231  // Reset defaults
232  background: none;
233  border: none;
234  display: inline-block;
235  padding: 0;
236
237  text-align: left;
238}
239
240.icinga-controls {
241  input ~ .spinner,
242  button ~ .spinner,
243  select ~ .spinner,
244  textarea ~ .spinner {
245    line-height: normal;
246    padding: .5em 0;
247
248    &:before {
249      vertical-align: middle;
250      margin-left: .5em;
251      opacity: 0.4;
252    }
253  }
254}
255
256/* selects get their spinner specifically placed */
257.icinga-controls select:not([multiple]) + .spinner {
258  height: 2.25em;
259  margin: 0;
260
261  &:before {
262    margin-left: -3.75em;
263  }
264}
265
266form.icinga-form .form-controls {
267  .spinner {
268    order: -1;
269  }
270
271  .btn-primary {
272    order: 99;
273  }
274}
275
276// Button styles
277
278.icinga-controls {
279  button:not([type]),
280  button[type="submit"],
281  input[type="submit"],
282  input[type="submit"].btn-confirm {
283    .button();
284  }
285
286  input[type="submit"].btn-remove {
287    .button(@body-bg-color, @color-critical, darken(@color-critical, 10%));
288  }
289
290  input[type="submit"].btn-cancel {
291    .button(@body-bg-color, @gray, @black);
292  }
293
294  button.noscript-apply {
295    color: @gray;
296    background-color: @gray-lightest;
297    border-color: @gray;
298    border-width: 1px;
299  }
300}
301
302form.inline {
303  button.noscript-apply {
304    margin-left: .5em;
305    padding: .1em;
306  }
307}
308
309// Toggle styles
310
311.icinga-controls .toggle-switch {
312  cursor: pointer;
313  position: relative;
314  display: inline-block;
315  height: 1.5em;
316  width: 2.625em;
317}
318
319.icinga-controls .toggle-switch .toggle-slider {
320  position: absolute;
321  left: 0;
322  top: 0;
323
324  display: inline-block;
325  background:  @low-sat-blue;
326  border: 1px solid @low-sat-blue;
327  box-sizing: content-box;
328  border-radius: 1em;
329  height: 4/3em;
330  width: 8/3em;
331  vertical-align: middle;
332}
333
334.icinga-controls .toggle-switch .toggle-slider:before {
335  position: absolute;
336  top: 0;
337  left: 0;
338
339  background: @text-color-inverted;
340  border-radius: 1em;
341  border: 1px solid @low-sat-blue;
342  box-sizing: border-box;
343  content: "";
344  display: block;
345  height: 4/3em;
346  margin-left: 0;
347  width: 4/3em;
348
349  @transition: left .2s ease, margin .2s ease;
350  -webkit-transition: @transition;
351  -moz-transition: @transition;
352  -o-transition: @transition;
353  transition: @transition;
354}
355
356.icinga-controls input[type="checkbox"]:checked + .toggle-switch .toggle-slider {
357  background-color: @icinga-blue;
358  border: 1px solid @icinga-blue;
359}
360
361.icinga-controls input[type="checkbox"]:focus + .toggle-switch .toggle-slider {
362  box-shadow: 0 0 0 2px @body-bg-color, 0 0 0 4px fade(@icinga-blue, 40);
363}
364
365.icinga-controls input[type="checkbox"]:checked + .toggle-switch .toggle-slider:before {
366  border: 1px solid @icinga-blue;
367  left: 100%;
368  margin-left: -4/3em;
369}
370
371// Disabled inputs
372
373.icinga-controls .toggle-switch.disabled {
374  cursor: default;
375
376  & > .toggle-slider {
377    background-color: @gray-light;
378    border-color: @gray-light;
379
380    &:before {
381      background-color: @gray-lighter;
382      border-color: @gray-light;
383    }
384  }
385}
386
387form.icinga-form .control-group.disabled .control-label-group {
388  color: @disabled-gray;
389}
390
391.icinga-controls {
392  input[disabled],
393  select[disabled] {
394    background: @gray-lighter;
395    border-color: transparent;
396  }
397}
398
399// Errors and additional information
400
401form.icinga-form {
402  .form-notifications,
403  .form-description {
404    border-radius: .25em;
405    display: flex;
406    list-style: none;
407    align-items: center;
408    margin: 0 0 1em 0;
409    padding: .25em .5em;
410
411    ul {
412      list-style: none;
413      margin: 0;
414      padding: 0 .5em;
415    }
416
417    li {
418      list-style: none;
419    }
420
421    & .form-notification-icon,
422    & .form-description-icon {
423      font-size: 2em;
424      margin-left: .25em;
425      opacity: .4;
426      align-self: flex-start;
427    }
428  }
429
430  .form-notifications {
431    &.info {
432      background-color: fade(@color-ok, 20%);
433    }
434
435    &.error {
436      background-color: fade(@color-critical, 30%);
437    }
438
439    &.warning {
440      background-color: fade(@color-warning, 40%);
441    }
442  }
443
444  .form-description {
445    background-color: fade(@gray, 5%);
446  }
447
448  .errors {
449    list-style: none;
450    display: block;
451    width: 100%;
452    margin: 0 0 0 15em;
453    padding: 0;
454
455    & > li {
456      margin: 0.5em;
457      color: #f56;
458    }
459  }
460}
461
462form.icinga-form .form-info {
463  color: @text-color-light;
464  font-size: @font-size-small;
465  list-style: none;
466  padding-left: 0;
467}
468
469// Placeholder styles
470
471.icinga-controls {
472  input::placeholder {
473    color: @disabled-gray;
474    font-style: italic;
475    opacity: 1;
476  }
477
478  input:-ms-input-placeholder {
479    color: @disabled-gray;
480    font-style: italic;
481    opacity: 1;
482  }
483}
484
485// Specific form styles
486
487.search.inline {
488  display: inline-block;
489}
490
491/* Flyover form styles */
492
493.flyover-content form:not(.inline):not([role="search"]) {
494  width: auto;
495}
496
497.flyover-content .control-label-group {
498  text-align: left;
499}
500