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