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