]> BookStack Code Mirror - bookstack/blob - resources/sass/_editor.scss
Lexical: Adjusted modals and content area for mobile sizes
[bookstack] / resources / sass / _editor.scss
1 @use "mixins";
2 @use "vars";
3
4 // Common variables
5 :root {
6   --editor-color-primary: #206ea7;
7 }
8
9 // Main UI elements
10 .editor-container {
11   @include mixins.lightDark(background-color, #FFF, #222);
12   position: relative;
13   &.fullscreen {
14     z-index: 500;
15   }
16 }
17
18 .editor-toolbar-main {
19   display: flex;
20   flex-wrap: wrap;
21   justify-content: center;
22   border-top: 1px solid #DDD;
23   border-bottom: 1px solid #DDD;
24   @include mixins.lightDark(border-color, #DDD, #000);
25 }
26
27 @include mixins.smaller-than(vars.$bp-xl) {
28   .editor-toolbar-main {
29     overflow-x: scroll;
30     flex-wrap: nowrap;
31     justify-content: start;
32   }
33 }
34
35 body.editor-is-fullscreen {
36   overflow: hidden;
37   .edit-area {
38     z-index: 20;
39   }
40 }
41 .editor-content-area {
42   min-height: 100%;
43   padding-block: 1rem;
44   &:focus {
45     outline: 0;
46   }
47 }
48 .editor-content-wrap {
49   position: relative;
50   overflow-y: scroll;
51   padding-inline: vars.$s;
52   flex: 1;
53 }
54
55 // Buttons
56 .editor-button {
57   font-size: 12px;
58   padding: 4px;
59   color: #444;
60   @include mixins.lightDark(color, #444, #999);
61   border-radius: 4px;
62   display: flex;
63   align-items: center;
64   justify-content: center;
65   margin: 2px;
66 }
67 .editor-button:hover {
68   background-color: #EEE;
69   @include mixins.lightDark(background-color, #EEE, #333);
70   cursor: pointer;
71   color: #000;
72 }
73 .editor-button[disabled] {
74   pointer-events: none;
75   cursor: not-allowed;
76   opacity: .6;
77 }
78 .editor-button-active, .editor-button-active:hover {
79   @include mixins.lightDark(background-color, #ceebff, #444);
80   color: #000;
81 }
82 .editor-button-long {
83   display: flex !important;
84   flex-direction: row;
85   align-items: center;
86   justify-content: start;
87   gap: .5rem;
88 }
89 .editor-button-text {
90   font-weight: 400;
91   @include mixins.lightDark(color, #000, #AAA);
92   font-size: 14px;
93   flex: 1;
94   padding-inline-end: 4px;
95 }
96 .editor-button-format-preview {
97   padding: 4px 6px;
98   display: block;
99 }
100 .editor-button-long .editor-button-icon {
101   width: 24px;
102   height: 24px;
103 }
104 .editor-button-icon svg {
105   width: 24px;
106   height: 24px;
107   color: inherit;
108   fill: currentColor;
109   display: block;
110 }
111 .editor-menu-button-icon {
112   width: 24px;
113   height: 24px;
114   svg {
115     fill: #888;
116   }
117 }
118 .editor-container[dir="rtl"] .editor-menu-button-icon {
119   rotate: 180deg;
120 }
121 .editor-button-with-menu-container {
122   display: flex;
123   flex-direction: row;
124   gap: 0;
125   align-items: stretch;
126   border-radius: 4px;
127   .editor-dropdown-menu-container {
128     display: flex;
129   }
130   .editor-dropdown-menu-container > .editor-dropdown-menu {
131     top: 100%;
132   }
133   .editor-dropdown-menu-container > .editor-button {
134     padding-inline: 4px;
135     margin-inline-start: -3px;
136     svg {
137       width: 12px;
138       height: 12px;
139     }
140   }
141   &:hover {
142     outline: 1px solid;
143     @include mixins.lightDark(outline-color, #DDD, #111);
144     outline-offset: -3px;
145   }
146 }
147
148 // Containers
149 .editor-dropdown-menu-container {
150     position: relative;
151 }
152 .editor-dropdown-menu {
153   position: absolute;
154   border: 1px solid;
155   @include mixins.lightDark(background-color, #FFF, #292929);
156   @include mixins.lightDark(border-color, #FFF, #333);
157   @include mixins.lightDark(box-shadow, 0 0 6px 0 rgba(0, 0, 0, 0.15), 0 1px 4px 0 rgba(0, 0, 0, 0.4));
158   z-index: 99;
159   display: flex;
160   flex-direction: row;
161   border-radius: 3px;
162 }
163 .editor-dropdown-menu-vertical {
164   display: flex;
165   flex-direction: column;
166   align-items: stretch;
167   min-width: 160px;
168 }
169 .editor-dropdown-menu-vertical .editor-button {
170   border-bottom: 0;
171   text-align: start;
172   display: block;
173   width: 100%;
174 }
175 .editor-dropdown-menu-vertical > .editor-dropdown-menu-container .editor-dropdown-menu {
176   inset-inline-start: 100%;
177   top: 0;
178 }
179
180 .editor-separator {
181   display: block;
182   height: 1px;
183   opacity: .8;
184   @include mixins.lightDark(background-color, #DDD, #000);
185 }
186
187 .editor-format-menu-toggle {
188   width: 130px;
189   height: 32px;
190   font-size: 13px;
191   overflow: hidden;
192   padding-inline: 12px;
193   justify-content: start;
194   background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23666" d="M7.41 8L12 12.58 16.59 8 18 9.41l-6 6-6-6z"/></svg>');
195   background-repeat: no-repeat;
196   background-position: 98% 50%;
197   background-size: 28px;
198 }
199 .editor-container[dir="rtl"] .editor-format-menu-toggle {
200   background-position: 2% 50%;
201 }
202 .editor-format-menu .editor-dropdown-menu {
203   min-width: 300px;
204   .editor-dropdown-menu {
205     min-width: 220px;
206   }
207   .editor-button-icon {
208     display: none;
209   }
210 }
211 .editor-format-menu .editor-dropdown-menu .editor-dropdown-menu-container > .editor-button {
212   padding: 8px 10px;
213 }
214
215 .editor-overflow-container {
216   display: flex;
217   border-inline: 1px solid #DDD;
218   padding-inline: 4px;
219   @include mixins.lightDark(border-color, #DDD, #000);
220   &:first-child {
221     border-inline-start: none;
222   }
223   &:last-child {
224     border-inline-end: none;
225   }
226   + .editor-overflow-container {
227     border-inline-start: none;
228   }
229 }
230
231 .editor-context-toolbar {
232   position: fixed;
233   border: 1px solid #DDD;
234   @include mixins.lightDark(background-color, #FFF, #222);
235   @include mixins.lightDark(border-color, #DDD, #333);
236   @include mixins.lightDark(box-shadow, 0 2px 4px 0 rgba(0, 0, 0, 0.12), 0 1px 4px 0 rgba(0, 0, 0, 0.4));
237   padding: .2rem;
238   border-radius: 4px;
239   display: flex;
240   flex-direction: row;
241   &:before {
242     content: '';
243     z-index: -1;
244     display: block;
245     width: 8px;
246     height: 8px;
247     position: absolute;
248     @include mixins.lightDark(background-color, #FFF, #222);
249     border-top: 1px solid #DDD;
250     border-left: 1px solid #DDD;
251     @include mixins.lightDark(border-color, #DDD, #333);
252     transform: rotate(45deg);
253     left: 50%;
254     margin-left: -4px;
255     top: -5px;
256   }
257   &.is-above:before {
258     top: calc(100% - 5px);
259     transform: rotate(225deg);
260   }
261 }
262
263 // Modals
264 .editor-modal-wrapper {
265   position: fixed;
266   display: flex;
267   align-items: center;
268   justify-content: center;
269   z-index: 999;
270   background-color: rgba(0, 0, 0, 0.5);
271   width: 100%;
272   height: 100%;
273 }
274 .editor-modal {
275   @include mixins.lightDark(background-color, #FFF, #222);
276   border-radius: 4px;
277   overflow: hidden;
278   box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.3);
279   margin: vars.$xs;
280   max-height: 100%;
281   overflow-y: auto;
282 }
283 .editor-modal-header {
284   display: flex;
285   justify-content: space-between;
286   align-items: stretch;
287   background-color: var(--color-primary);
288   color: #FFF;
289 }
290 .editor-modal-title {
291   padding: 8px vars.$m;
292 }
293 .editor-modal-close {
294   color: #FFF;
295   padding: 8px vars.$m;
296   align-items: center;
297   justify-content: center;
298   cursor: pointer;
299   &:hover {
300   background-color: rgba(255, 255, 255, 0.1);
301   }
302   svg {
303     width: 1rem;
304     height: 1rem;
305     fill: currentColor;
306     display: block;
307   }
308 }
309 .editor-modal-body {
310   padding: vars.$m;
311 }
312
313 // Specific UI elements
314 .editor-color-select-row {
315   display: flex;
316 }
317 .editor-color-select-option {
318   width: 28px;
319   height: 28px;
320   cursor: pointer;
321   display: flex;
322   align-items: center;
323   justify-content: center;
324 }
325 .editor-color-select-option:hover {
326   border-radius: 3px;
327   box-sizing: border-box;
328   z-index: 3;
329   box-shadow: 0 0 4px 1px rgba(0, 0, 0, 0.25);
330 }
331 .editor-color-select-option[data-color=""] svg {
332   width: 20px;
333   height: 20px;
334   fill: #888;
335 }
336 .editor-table-creator-row {
337   display: flex;
338 }
339 .editor-table-creator-cell {
340   border: 1px solid;
341   @include mixins.lightDark(border-color, #DDD, #000);
342   width: 15px;
343   height: 15px;
344   cursor: pointer;
345   &.active {
346     background-color: var(--editor-color-primary);
347   }
348 }
349 .editor-table-creator-display {
350   text-align: center;
351   padding: 0.2em;
352 }
353
354 // In-editor elements
355 .editor-image-wrap {
356   position: relative;
357   display: inline-flex;
358 }
359 .editor-node-resizer {
360   position: absolute;
361   left: 0;
362   right: auto;
363   display: inline-block;
364   outline: 2px dashed var(--editor-color-primary);
365   direction: ltr;
366 }
367 .editor-node-resizer-handle {
368   position: absolute;
369   display: block;
370   width: 10px;
371   height: 10px;
372   border: 2px solid var(--editor-color-primary);
373   z-index: 3;
374   @include mixins.lightDark(background-color, #FFF, #000);
375   user-select: none;
376   &.nw {
377     inset-inline-start: -5px;
378     inset-block-start: -5px;
379     cursor: nw-resize;
380   }
381   &.ne {
382     inset-inline-end: -5px;
383     inset-block-start: -5px;
384     cursor: ne-resize;
385   }
386   &.se {
387     inset-inline-end: -5px;
388     inset-block-end: -5px;
389     cursor: se-resize;
390   }
391   &.sw {
392     inset-inline-start: -5px;
393     inset-block-end: -5px;
394     cursor: sw-resize;
395   }
396 }
397 .editor-node-resizer-ghost {
398   opacity: 0.5;
399   display: none;
400   position: absolute;
401   left: 0;
402   top: 0;
403   width: 100%;
404   height: 100%;
405   z-index: 2;
406   pointer-events: none;
407   background-color: var(--editor-color-primary);
408 }
409 .editor-node-resizer.active .editor-node-resizer-ghost {
410   display: block;
411 }
412
413 .editor-table-marker {
414   position: fixed;
415   background-color: var(--editor-color-primary);
416   z-index: 99;
417   user-select: none;
418   opacity: 0;
419   &:hover, &.active {
420     opacity: 0.4;
421   }
422 }
423 .editor-table-marker-column {
424   width: 4px;
425   cursor: col-resize;
426 }
427 .editor-table-marker-row {
428   height: 4px;
429   cursor: row-resize;
430 }
431
432 .editor-code-block-wrap {
433   user-select: none;
434   > * {
435     pointer-events: none;
436   }
437   &.selected .cm-editor {
438     border: 1px dashed var(--editor-color-primary);
439   }
440 }
441 .editor-diagram.selected {
442   outline: 2px dashed var(--editor-color-primary);
443 }
444
445 .editor-media-wrap {
446   display: inline-block;
447   cursor: not-allowed;
448   iframe {
449     pointer-events: none;
450   }
451   &.align-left {
452     float: left;
453   }
454   &.align-right {
455     float: right;
456   }
457   &.align-center {
458     display: block;
459     margin-inline: auto;
460   }
461 }
462
463 /**
464  * Fake task list checkboxes
465  */
466 .editor-content-area .task-list-item {
467   margin-left: 0;
468   position: relative;
469 }
470 .editor-content-area .task-list-item > input[type="checkbox"] {
471   display: none;
472 }
473 .editor-content-area .task-list-item:before {
474   content: '';
475   display: inline-block;
476   border: 2px solid #CCC;
477   width: 12px;
478   height: 12px;
479   border-radius: 2px;
480   margin-right: 8px;
481   vertical-align: text-top;
482   cursor: pointer;
483   position: absolute;
484   left: -24px;
485   top: 4px;
486 }
487 .editor-content-area .task-list-item[checked]:before {
488   background-color: #CCC;
489   background-image: url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m8.4856 20.274-6.736-6.736 2.9287-2.7823 3.8073 3.8073 10.836-10.836 2.9287 2.9287z" stroke-width="1.4644"/></svg>');
490   background-position: 50% 50%;
491   background-size: 100% 100%;
492 }
493
494 /**
495  * Form elements
496  */
497 $inputWidth: 260px;
498
499 .editor-form-field-wrapper {
500   margin-bottom: .5rem;
501 }
502 .editor-form-field-input {
503   display: block;
504   width: $inputWidth;
505   min-width: 100px;
506   max-width: 100%;
507   border: 1px solid;
508   @include mixins.lightDark(border-color, #DDD, #000);
509   padding: .5rem;
510   border-radius: 4px;
511   @include mixins.lightDark(color, #444, #BBB);
512 }
513
514 @include mixins.smaller-than(vars.$bp-xs) {
515   .editor-form-field-input {
516     min-width: 160px;
517   }
518 }
519
520 textarea.editor-form-field-input {
521   font-family: var(--font-code);
522   width: 350px;
523   height: 250px;
524   font-size: 12px;
525 }
526 .editor-form-field-label {
527   color: #444;
528   font-weight: 700;
529   font-size: 12px;
530 }
531 .editor-form-actions {
532   display: flex;
533   justify-content: end;
534   gap: vars.$s;
535   margin-top: vars.$m;
536 }
537 .editor-form-actions > button {
538   display: block;
539   font-size: 0.85rem;
540   line-height: 1.4em;
541   padding: vars.$xs*1.3 vars.$m;
542   font-weight: 400;
543   border-radius: 4px;
544   cursor: pointer;
545   box-shadow: none;
546   &:focus {
547     outline: 1px dotted currentColor;
548     outline-offset: -(vars.$xs);
549     box-shadow: none;
550     filter: brightness(90%);
551   }
552 }
553 .editor-form-action-primary {
554   background-color: var(--color-primary);
555   color: #FFF;
556   border: 1px solid var(--color-primary);
557   &:hover {
558     @include mixins.lightDark(box-shadow, vars.$bs-light, vars.$bs-dark);
559     filter: brightness(110%);
560   }
561 }
562 .editor-form-action-secondary {
563   border: 1px solid;
564   @include mixins.lightDark(border-color, #CCC, #666);
565   @include mixins.lightDark(color, #666, #AAA);
566   &:hover, &:focus, &:active {
567     @include mixins.lightDark(color, #444, #BBB);
568     border: 1px solid #CCC;
569     box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.1);
570     background-color: #F2F2F2;
571     @include mixins.lightDark(background-color, #f8f8f8, #444);
572     filter: none;
573   }
574   &:active {
575     border-color: #BBB;
576     background-color: #DDD;
577     color: #666;
578     box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.1);
579   }
580 }
581 .editor-form-tab-container {
582   display: flex;
583   flex-direction: row;
584   gap: 2rem;
585 }
586 .editor-form-tab-controls {
587   display: flex;
588   flex-direction: column;
589   align-items: stretch;
590   gap: .25rem;
591 }
592
593 @include mixins.smaller-than(vars.$bp-m) {
594   .editor-form-tab-container {
595     flex-direction: column;
596     gap: .5rem;
597   }
598   .editor-form-tab-controls {
599     flex-direction: row;
600   }
601 }
602
603 .editor-form-tab-control {
604   font-weight: bold;
605   font-size: 14px;
606   @include mixins.lightDark(color, #444, #666);
607   border-bottom: 2px solid transparent;
608   position: relative;
609   cursor: pointer;
610   padding: .25rem .5rem;
611   text-align: start;
612   &[aria-selected="true"] {
613     border-color: var(--editor-color-primary);
614     color: var(--editor-color-primary) !important;
615   }
616   &[aria-selected="true"]:after, &:hover:after {
617     background-color: var(--editor-color-primary);
618     opacity: .15;
619     content: '';
620     display: block;
621     position: absolute;
622     left: 0;
623     top: 0;
624     width: 100%;
625     height: 100%;
626   }
627 }
628 .editor-form-tab-contents {
629   width: $inputWidth;
630   max-width: 100%;
631 }
632 .editor-action-input-container {
633   display: flex;
634   flex-direction: row;
635   align-items: end;
636   justify-content: space-between;
637   gap: .1rem;
638   .editor-button {
639     margin-bottom: 12px;
640   }
641   input {
642     width: $inputWidth - 40px;
643   }
644 }
645
646 // Editor theme styles
647 .editor-theme-bold {
648   font-weight: bold;
649 }
650 .editor-theme-italic {
651   font-style: italic;
652 }
653 .editor-theme-strikethrough {
654   text-decoration-line: line-through;
655 }
656 .editor-theme-underline {
657   text-decoration-line: underline;
658 }
659 .editor-theme-underline-strikethrough {
660   text-decoration: underline line-through;
661 }