file-tree.scss 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. :root {
  2. --file-tree-item-hover-bg: var(--bg-dark-secondary);
  3. --file-tree-item-selected-bg: var(--bg-accent-01);
  4. --file-tree-item-color: var(--content-primary-dark);
  5. --file-tree-bg: var(--bg-dark-tertiary);
  6. --file-tree-item-selected-color: var(--content-primary-dark);
  7. --file-tree-item-dragging-bg: #{rgb($bg-dark-secondary, 0.9)};
  8. --file-tree-item-dragging-color: var(--content-primary-dark);
  9. --file-tree-item-icon-dragging-color: var(--content-disabled);
  10. --file-tree-item-dragging-preview-bg: #{rgb($bg-accent-01, 0.6)};
  11. --file-tree-item-dragging-preview-colour: var(--content-primary-dark);
  12. --file-tree-line-height: 2.05;
  13. --file-tree-icon-colour: var(--content-disabled);
  14. }
  15. @include theme('light') {
  16. --file-tree-item-hover-bg: var(--bg-light-tertiary);
  17. --file-tree-item-color: var(--content-secondary);
  18. --file-tree-bg: var(--bg-light-primary);
  19. --file-tree-item-selected-color: var(--bg-light-primary);
  20. --file-tree-item-dragging-bg: #{rgb($bg-light-tertiary, 0.9)};
  21. --file-tree-item-dragging-color: var(--content-secondary);
  22. --file-tree-item-dragging-preview-colour: var(--bg-light-primary);
  23. .ide-redesign-main {
  24. --file-tree-item-hover-bg: var(--bg-light-secondary);
  25. --file-tree-item-selected-bg: var(--bg-accent-03);
  26. --file-tree-item-selected-color: var(--green-70);
  27. --file-tree-item-color: var(--content-primary);
  28. --file-tree-bg: var(--white);
  29. --file-tree-icon-colour: var(--content-primary);
  30. --file-tree-item-dragging-bg: var(--green-60);
  31. --file-tree-item-dragging-color: var(--white);
  32. --file-tree-item-icon-dragging-color: var(--file-tree-item-dragging-color);
  33. --file-tree-item-dragging-preview-bg: #{rgb($bg-light-secondary, 0.6)};
  34. --file-tree-item-dragging-preview-colour: #{rgb($content-primary, 0.6)};
  35. --file-tree-expand-button-color: var(--content-primary);
  36. }
  37. }
  38. // TODO ide-redesign-cleanup: Replace the existing styling with these overrides.
  39. .ide-redesign-main {
  40. --file-tree-item-hover-bg: var(--bg-dark-secondary);
  41. --file-tree-item-selected-bg: var(--green-70);
  42. --file-tree-item-selected-color: var(--green-10);
  43. --file-tree-item-color: var(--content-primary-dark);
  44. --file-tree-bg: var(--bg-dark-primary);
  45. --file-tree-icon-colour: var(--content-primary-dark);
  46. --file-tree-item-dragging-bg: var(--green-40);
  47. --file-tree-item-dragging-color: var(--content-primary-dark);
  48. --file-tree-item-icon-dragging-color: var(--file-tree-item-dragging-color);
  49. --file-tree-item-dragging-preview-bg: #{rgb($bg-dark-secondary, 0.6)};
  50. --file-tree-item-dragging-preview-colour: #{rgb($content-primary-dark, 0.6)};
  51. --file-tree-expand-button-color: var(--content-primary-dark);
  52. .file-tree-outline-panel-group {
  53. background-color: var(--file-tree-bg);
  54. }
  55. .file-tree-toolbar {
  56. display: flex;
  57. justify-content: space-between;
  58. height: 28px;
  59. margin: var(--spacing-02);
  60. }
  61. .file-tree-panel {
  62. min-height: 36px;
  63. }
  64. .file-tree-panel-collapsed {
  65. max-height: 36px;
  66. }
  67. .file-tree-expand-collapse-button {
  68. border-radius: var(--border-radius-base);
  69. color: var(--file-tree-expand-button-color);
  70. display: flex;
  71. align-items: center;
  72. background-color: transparent;
  73. border: 0;
  74. padding: 0 var(--spacing-02);
  75. flex-grow: 1;
  76. overflow: hidden;
  77. &:hover {
  78. background-color: var(--file-tree-item-hover-bg);
  79. }
  80. h4 {
  81. color: var(--file-tree-expand-button-color);
  82. font-size: var(--font-size-02);
  83. line-height: var(--line-height-02);
  84. margin: 0;
  85. font-weight: bold;
  86. overflow: hidden;
  87. text-overflow: ellipsis;
  88. white-space: nowrap;
  89. }
  90. }
  91. .file-tree-toolbar-action-buttons {
  92. display: flex;
  93. }
  94. .file-tree-toolbar-action-button {
  95. color: var(--file-tree-expand-button-color);
  96. padding: var(--spacing-02);
  97. border-radius: var(--border-radius-full);
  98. &:hover {
  99. background-color: var(--file-tree-item-hover-bg);
  100. }
  101. &:active {
  102. color: var(--file-tree-expand-button-color);
  103. }
  104. }
  105. .file-tree {
  106. background-color: var(--file-tree-bg);
  107. }
  108. .file-tree ul.file-tree-list {
  109. margin: var(--spacing-02);
  110. }
  111. .file-tree-folder-list {
  112. border-left: 1px solid
  113. color-mix(in srgb, var(--border-primary) 24%, transparent);
  114. margin-left: 14px !important;
  115. margin-top: 0;
  116. &.file-tree-list {
  117. border-left: none;
  118. margin-left: var(--spacing-02) !important;
  119. > .file-tree-folder-list-inner {
  120. margin-left: 0;
  121. }
  122. }
  123. }
  124. .file-tree-folder-list-inner {
  125. margin-left: 10px;
  126. display: flex;
  127. flex-direction: column;
  128. gap: var(--spacing-02);
  129. }
  130. .item-name-button,
  131. .folder-expand-collapse-button {
  132. display: flex;
  133. align-items: center;
  134. height: 20px !important;
  135. }
  136. .file-tree ul.file-tree-list li .material-symbols.file-tree-expand-icon {
  137. margin-left: 0;
  138. }
  139. .file-tree ul.file-tree-list li .material-symbols.file-tree-icon {
  140. margin-left: 0;
  141. margin-right: 0;
  142. }
  143. // TODO ide-redesign-cleanup: Remove the !important overrides once
  144. // we have replaced the default styling
  145. .linked-file-highlight {
  146. background-color: var(--file-tree-bg) !important;
  147. color: var(--file-tree-icon-colour) !important;
  148. left: 14px !important;
  149. }
  150. .entity-name {
  151. color: var(--file-tree-item-color);
  152. border-radius: var(--border-radius-base);
  153. // TODO ide-redesign-cleanup: This is here to override the fake-full-width-bg
  154. // mixin. We can just remove that mixin when we clean this up.
  155. &::before {
  156. content: none !important;
  157. }
  158. }
  159. .item-name-button {
  160. margin-left: var(--spacing-02);
  161. overflow: hidden;
  162. span {
  163. overflow: hidden;
  164. text-overflow: ellipsis;
  165. }
  166. }
  167. .dnd-draggable-preview-item {
  168. border-radius: var(--border-radius-base);
  169. }
  170. }
  171. .ide-react-file-tree-panel {
  172. display: flex;
  173. flex-direction: column;
  174. // Prevent the file tree expanding beyond the boundary of the panel
  175. .file-tree {
  176. width: 100%;
  177. }
  178. }
  179. .context-menu {
  180. position: fixed;
  181. z-index: 100;
  182. }
  183. .context-menu-upwards {
  184. top: auto;
  185. bottom: 100%;
  186. }
  187. .editor-sidebar {
  188. background-color: var(--file-tree-bg);
  189. display: flex;
  190. flex-direction: column;
  191. }
  192. @mixin fake-full-width-bg($bg-color) {
  193. &::before {
  194. content: '\00a0';
  195. position: absolute;
  196. width: 9999px;
  197. left: -9999px;
  198. background-color: $bg-color;
  199. }
  200. }
  201. @include theme('default') {
  202. .file-tree {
  203. .toolbar {
  204. .toolbar-right,
  205. .toolbar-left {
  206. button {
  207. opacity: 0.8;
  208. &:hover,
  209. &:focus,
  210. &:active,
  211. &.active {
  212. background-color: rgba(125 125 125 / 20%);
  213. }
  214. &.active,
  215. &:active {
  216. background-color: rgba(125 125 125 / 40%);
  217. }
  218. }
  219. }
  220. }
  221. }
  222. }
  223. .file-tree {
  224. display: flex !important; // To work around jQuery layout's inline styles
  225. flex-direction: column;
  226. height: 100%;
  227. .file-tree-inner {
  228. position: relative;
  229. display: flex;
  230. flex-direction: column;
  231. flex-grow: 1;
  232. overflow-y: auto;
  233. width: inherit;
  234. height: inherit;
  235. font-size: var(--font-size-02);
  236. &.no-toolbar {
  237. top: 0;
  238. }
  239. }
  240. // TODO; Consolidate with "Project files" in Overleaf
  241. h3 {
  242. font-size: var(--font-size-03);
  243. border-bottom: 1px solid var(--border-primary);
  244. padding-bottom: var(--spacing-02);
  245. margin: var(--spacing-05);
  246. }
  247. .toolbar {
  248. .toolbar-right,
  249. .toolbar-left {
  250. button {
  251. display: inline-flex;
  252. align-items: center;
  253. justify-content: center;
  254. width: 24px;
  255. height: 24px;
  256. padding: 0;
  257. box-shadow: none;
  258. border-radius: var(--border-radius-base);
  259. border: none;
  260. &:hover,
  261. &:focus,
  262. &:active,
  263. &.active {
  264. background-color: rgb(125 125 125 / 10%);
  265. color: var(--toolbar-btn-color) !important;
  266. }
  267. &.active,
  268. &:active {
  269. background-color: rgb(125 125 125 / 20%);
  270. }
  271. }
  272. }
  273. }
  274. ul.file-tree-list {
  275. margin: 0;
  276. overflow: hidden auto;
  277. height: 100%;
  278. flex-grow: 1;
  279. position: relative;
  280. .entity > ul,
  281. ul[role='tree'] {
  282. margin-left: var(--spacing-08);
  283. }
  284. &::after {
  285. content: '';
  286. display: block;
  287. min-height: var(--spacing-08);
  288. }
  289. li {
  290. line-height: var(--file-tree-line-height);
  291. position: relative;
  292. .entity {
  293. user-select: none;
  294. }
  295. .entity > .entity-name {
  296. display: flex;
  297. align-items: center;
  298. & > button {
  299. background-color: transparent;
  300. border: 0;
  301. padding: 0;
  302. &.item-name-button {
  303. color: inherit;
  304. width: 100%;
  305. overflow: hidden;
  306. text-overflow: ellipsis;
  307. text-align: left;
  308. padding-right: var(--spacing-09);
  309. white-space: pre;
  310. }
  311. }
  312. }
  313. .entity-name {
  314. color: var(--file-tree-item-color);
  315. cursor: pointer;
  316. white-space: nowrap;
  317. overflow: hidden;
  318. text-overflow: ellipsis;
  319. &.entity-name-react {
  320. text-overflow: clip;
  321. }
  322. background-color: transparent;
  323. @include fake-full-width-bg(transparent);
  324. &:hover {
  325. background-color: var(--file-tree-item-hover-bg);
  326. // When the entity is a subfolder, the DOM element is "indented" via margin-left. This makes the
  327. // element not fill the entire file-tree width (as it's spaced from the left-hand side via margin)
  328. // and, in consequence, the background gets clipped. The ::before pseudo-selector is used to fill
  329. // the empty space.
  330. @include fake-full-width-bg(var(--file-tree-item-hover-bg));
  331. }
  332. input {
  333. line-height: 1.6;
  334. }
  335. .entity-menu-toggle > .material-symbols {
  336. color: var(--content-primary-dark);
  337. vertical-align: middle;
  338. }
  339. }
  340. .material-symbols {
  341. color: var(--file-tree-icon-colour);
  342. &.file-tree-icon {
  343. margin-right: var(--spacing-02);
  344. margin-left: var(--spacing-04);
  345. vertical-align: sub;
  346. &.linked-file-icon {
  347. position: relative;
  348. left: -2px;
  349. + .linked-file-highlight {
  350. color: var(--file-tree-bg);
  351. background-color: var(--content-disabled);
  352. position: absolute;
  353. top: 14px;
  354. left: 20px;
  355. font-size: var(--font-size-01);
  356. border-radius: var(--spacing-01);
  357. }
  358. }
  359. }
  360. &.file-tree-folder-icon {
  361. margin-right: var(--spacing-02);
  362. vertical-align: sub;
  363. }
  364. &.file-tree-expand-icon {
  365. margin-left: var(--spacing-04);
  366. vertical-align: sub;
  367. }
  368. }
  369. .material-symbols.toggle {
  370. width: 24px;
  371. padding: var(--spacing-03);
  372. font-size: var(--font-size-03);
  373. color: var(--file-tree-icon-colour);
  374. }
  375. .file-tree-dropdown-toggle {
  376. display: flex;
  377. align-items: center;
  378. color: var(--content-primary-dark);
  379. line-height: 1.6;
  380. font-size: var(--font-size-05);
  381. padding: 0 var(--font-size-02) 0 var(--font-size-04);
  382. &:hover,
  383. &:focus {
  384. text-decoration: none;
  385. }
  386. &::before {
  387. content: '\00B7\00B7\00B7';
  388. transform: rotate(90deg);
  389. letter-spacing: 0.5px;
  390. }
  391. }
  392. &.multi-selected {
  393. > .entity {
  394. > .entity-name {
  395. > div > .material-symbols,
  396. > button > .material-symbols,
  397. > .material-symbols,
  398. .entity-menu-toggle .material-symbols {
  399. color: var(--content-primary-dark);
  400. }
  401. > .material-symbols.linked-file-highlight {
  402. background-color: var(--bg-info-01);
  403. }
  404. @include fake-full-width-bg(var(--bg-info-01));
  405. color: var(--content-primary-dark);
  406. font-weight: bold;
  407. background-color: var(--bg-info-01);
  408. &:hover {
  409. background-color: var(--bg-info-02);
  410. @include fake-full-width-bg(var(--bg-info-02));
  411. }
  412. }
  413. }
  414. }
  415. .menu-button {
  416. position: absolute;
  417. right: 0;
  418. }
  419. .rename-input {
  420. display: block;
  421. position: absolute;
  422. top: 1px;
  423. left: 32px;
  424. right: 32px;
  425. color: var(--content-primary);
  426. input {
  427. width: 100%;
  428. }
  429. }
  430. > .entity > .entity-name {
  431. .entity-menu-toggle {
  432. display: none;
  433. }
  434. }
  435. .entity-limit-hit {
  436. line-height: var(--file-tree-line-height);
  437. color: var(--file-tree-item-color);
  438. margin-left: var(--spacing-05);
  439. white-space: nowrap;
  440. overflow: hidden;
  441. text-overflow: ellipsis;
  442. }
  443. .entity-limit-hit-message {
  444. font-style: italic;
  445. }
  446. .material-symbols .entity-limit-hit-tooltip-trigger {
  447. margin-left: var(spacing-03);
  448. cursor: pointer;
  449. }
  450. }
  451. }
  452. &:not(.multi-selected) {
  453. ul.file-tree-list li.selected {
  454. > .entity {
  455. > .entity-name {
  456. background-color: var(--file-tree-item-selected-bg);
  457. color: var(--file-tree-item-selected-color);
  458. > div > .material-symbols,
  459. > button > .material-symbols,
  460. > .material-symbols,
  461. .entity-menu-toggle .material-symbols {
  462. color: var(--file-tree-item-selected-color);
  463. }
  464. > .material-symbols.linked-file-highlight {
  465. background-color: var(--bg-info-01);
  466. }
  467. @include fake-full-width-bg(var(--file-tree-item-selected-bg));
  468. font-weight: bold;
  469. padding-right: var(--spacing-09);
  470. button {
  471. font-weight: inherit;
  472. }
  473. .entity-menu-toggle {
  474. display: inline-block;
  475. background-color: transparent;
  476. border: 0;
  477. padding-right: var(--spacing-02);
  478. padding-left: var(--spacing-02);
  479. }
  480. }
  481. }
  482. }
  483. }
  484. // while dragging, the previously selected item gets no highlight
  485. ul.file-tree-list.file-tree-dragging li.selected .entity .entity-name {
  486. @include fake-full-width-bg(transparent);
  487. font-weight: normal;
  488. background-color: transparent;
  489. color: var(--file-tree-item-color);
  490. .material-symbols {
  491. color: var(--content-disabled) !important;
  492. }
  493. }
  494. // the items being dragged get the full "hover" colour
  495. ul.file-tree-list.file-tree-dragging
  496. li
  497. .entity.file-tree-entity-dragging
  498. .entity-name {
  499. background-color: var(--file-tree-item-dragging-bg);
  500. @include fake-full-width-bg(var(--file-tree-item-dragging-bg));
  501. color: var(--file-tree-item-dragging-color);
  502. .material-symbols {
  503. color: var(--file-tree-item-icon-dragging-color) !important;
  504. }
  505. }
  506. // the drop target gets the "selected" colour
  507. ul.file-tree-list.file-tree-dragging
  508. li.dnd-droppable-hover
  509. .entity
  510. .entity-name {
  511. background-color: var(--file-tree-item-selected-bg);
  512. @include fake-full-width-bg(var(--file-tree-item-selected-bg));
  513. color: var(--file-tree-item-selected-color);
  514. .material-symbols {
  515. color: var(--file-tree-item-selected-color) !important;
  516. }
  517. }
  518. .dnd-draggable-preview-layer {
  519. position: absolute;
  520. pointer-events: none;
  521. z-index: 100;
  522. width: 100%;
  523. height: 100%;
  524. overflow: hidden;
  525. &.dnd-droppable-hover {
  526. border: 3px solid var(--file-tree-item-selected-bg);
  527. }
  528. }
  529. .dnd-draggable-preview-item {
  530. color: var(--file-tree-item-dragging-preview-colour);
  531. background-color: var(--file-tree-item-dragging-preview-bg);
  532. width: 75%;
  533. padding-left: var(--spacing-08);
  534. line-height: 2.05;
  535. overflow: hidden;
  536. text-overflow: ellipsis;
  537. white-space: nowrap;
  538. }
  539. .disconnected-overlay {
  540. background-color: var(--file-tree-bg);
  541. position: absolute;
  542. top: 0;
  543. left: 0;
  544. width: 100%;
  545. height: 100%;
  546. z-index: 10;
  547. opacity: 0.5;
  548. cursor: wait;
  549. }
  550. }
  551. .modal-new-file {
  552. padding: 0;
  553. table {
  554. width: 100%;
  555. table-layout: fixed;
  556. td {
  557. vertical-align: top;
  558. }
  559. }
  560. .toggle-file-type-button {
  561. font-size: var(--font-size-02);
  562. margin-top: calc(var(--spacing-05) * -1);
  563. .btn {
  564. display: inline-block;
  565. padding: 0;
  566. vertical-align: baseline;
  567. font-size: inherit;
  568. }
  569. .btn:focus-within {
  570. outline: none;
  571. text-decoration: none;
  572. }
  573. }
  574. }
  575. .modal-new-file-list {
  576. background-color: var(--bg-light-secondary);
  577. width: 220px;
  578. ul {
  579. li {
  580. /* old modal (a) */
  581. a {
  582. color: var(--content-secondary);
  583. padding: var(--spacing-03);
  584. display: block;
  585. text-decoration: none;
  586. }
  587. /* new modal (button) */
  588. .btn {
  589. color: var(--content-secondary);
  590. padding: var(--spacing-03);
  591. }
  592. .btn:hover {
  593. text-decoration: none;
  594. }
  595. .btn:focus {
  596. outline: none;
  597. text-decoration: none;
  598. background-color: white;
  599. }
  600. }
  601. li.active {
  602. background-color: white;
  603. /* old modal (a) */
  604. a {
  605. color: var(--link-ui);
  606. }
  607. /* new modal (button) */
  608. .btn {
  609. color: var(--link-ui);
  610. text-decoration: none;
  611. }
  612. }
  613. li:hover {
  614. background-color: white;
  615. }
  616. }
  617. }
  618. .file-tree-error {
  619. text-align: center;
  620. color: var(--content-secondary-dark);
  621. padding: 20px;
  622. }
  623. .file-tree-modal-alert {
  624. margin-top: var(--spacing-06);
  625. }
  626. .file-tree-entity-button,
  627. .file-tree-entity-details {
  628. display: flex;
  629. width: 100%;
  630. color: inherit;
  631. // TODO ide-redesign-cleanup: Remove !important when we clean up the old file tree
  632. padding: var(--spacing-02) !important;
  633. text-overflow: ellipsis;
  634. overflow: hidden;
  635. }
  636. .btn.modal-new-file-mode {
  637. justify-content: left;
  638. text-align: left;
  639. text-decoration: none;
  640. width: 100%;
  641. }
  642. .modal-new-file-body {
  643. padding: 20px;
  644. padding-top: var(--spacing-03);
  645. }
  646. .modal-new-file-body-upload {
  647. padding-top: 20px;
  648. }
  649. .modal-new-file-body-conflict {
  650. background-color: var(--bg-danger-03);
  651. border: 1px dashed var(--border-danger);
  652. min-height: 400px;
  653. border-radius: 3px;
  654. color: var(--content-primary);
  655. display: flex;
  656. flex-direction: column;
  657. justify-content: center;
  658. padding: var(--spacing-05);
  659. }
  660. /* stylelint-disable selector-class-pattern */
  661. .modal-new-file-body-upload .uppy-Root {
  662. font-family: inherit;
  663. }
  664. .modal-new-file-body-upload .uppy-Dashboard {
  665. .uppy-Dashboard-inner {
  666. border: none;
  667. }
  668. .uppy-Dashboard-dropFilesHereHint {
  669. inset: 0;
  670. }
  671. .uppy-Dashboard-AddFiles {
  672. margin: 0;
  673. border: 1px dashed var(--border-primary);
  674. height: 100%;
  675. .uppy-Dashboard-AddFiles-title {
  676. font-size: inherit;
  677. }
  678. }
  679. .uppy-Dashboard-AddFiles-title {
  680. width: 26em; // sized to create a wrap between the sentences
  681. max-width: 100%;
  682. }
  683. .uppy-Informer p {
  684. background-color: var(--bg-info-03);
  685. border: 1px solid var(--blue-20);
  686. border-radius: var(--border-radius-base);
  687. color: var(--content-primary);
  688. font-size: var(--font-size-03);
  689. }
  690. }