mirror of
https://github.com/zadam/trilium.git
synced 2025-12-29 19:49:58 +01:00
Compare commits
121 Commits
feat/rice-
...
static-cor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d96528dae4 | ||
|
|
f3cfa84d1d | ||
|
|
dc2ffa516b | ||
|
|
37c0f7ec75 | ||
|
|
a14eed81f6 | ||
|
|
54f51b365a | ||
|
|
c0e0a712ad | ||
|
|
3ab5bbae4d | ||
|
|
cafeb3920a | ||
|
|
fb465b442c | ||
|
|
d3a559a700 | ||
|
|
7768003735 | ||
|
|
f02b3b48e8 | ||
|
|
ba273bb9f4 | ||
|
|
490c539d63 | ||
|
|
ebd60519dd | ||
|
|
56304a4d71 | ||
|
|
32f0f98522 | ||
|
|
b18dd22341 | ||
|
|
8eebae0955 | ||
|
|
ed229e0578 | ||
|
|
dbfaad6c06 | ||
|
|
6e5176b088 | ||
|
|
becf4d7426 | ||
|
|
082040c6e1 | ||
|
|
1ae11ce3a5 | ||
|
|
cf968b3590 | ||
|
|
a3db1ab156 | ||
|
|
7440110a44 | ||
|
|
3638e6b12c | ||
|
|
621ed5b9de | ||
|
|
1e3135dea0 | ||
|
|
8f21c0b34a | ||
|
|
b3feb38369 | ||
|
|
2bf862d5b9 | ||
|
|
cbb7b4ffea | ||
|
|
b2f496048f | ||
|
|
e084bc4c07 | ||
|
|
d9b0660def | ||
|
|
b997452733 | ||
|
|
e699566e62 | ||
|
|
2bd83e6285 | ||
|
|
46e5090445 | ||
|
|
035a311e4d | ||
|
|
850528750c | ||
|
|
645720a725 | ||
|
|
a6c74449aa | ||
|
|
7f05d9cdff | ||
|
|
02d42dc5ff | ||
|
|
e730378b27 | ||
|
|
c14d95f561 | ||
|
|
13b700e0e5 | ||
|
|
f849c4b315 | ||
|
|
c2c19e8ecd | ||
|
|
12875ec308 | ||
|
|
5d12d57a22 | ||
|
|
5cc2296768 | ||
|
|
7c1175995f | ||
|
|
d834cd78a7 | ||
|
|
79d2010bfa | ||
|
|
3f86c809ce | ||
|
|
1570ea77d8 | ||
|
|
99bdd2e433 | ||
|
|
7646061215 | ||
|
|
505a985755 | ||
|
|
e895ea406a | ||
|
|
8b8a78e949 | ||
|
|
1c940ff8a2 | ||
|
|
841cb32835 | ||
|
|
61e96f91d0 | ||
|
|
9f6c07f5cc | ||
|
|
1efb21c627 | ||
|
|
d5b04864c8 | ||
|
|
da28f4505a | ||
|
|
e2a628fa2f | ||
|
|
290f488c78 | ||
|
|
b00cb52da5 | ||
|
|
c7bb5ff119 | ||
|
|
faa069b8a1 | ||
|
|
e57f1e6f23 | ||
|
|
73975ab521 | ||
|
|
761a67f238 | ||
|
|
736c69816d | ||
|
|
270339da11 | ||
|
|
aa93bc5492 | ||
|
|
0c9c36ea7e | ||
|
|
af67967502 | ||
|
|
78bec0c782 | ||
|
|
0c77563672 | ||
|
|
241a9e2e7f | ||
|
|
59b691d670 | ||
|
|
ecec661b72 | ||
|
|
fb629f7693 | ||
|
|
13fff33aa4 | ||
|
|
8053221b12 | ||
|
|
ba699f9842 | ||
|
|
eb5ebb53cb | ||
|
|
c26357be40 | ||
|
|
db4af96040 | ||
|
|
5cb3983fe0 | ||
|
|
92292de0ff | ||
|
|
a26923cc6d | ||
|
|
2c4ac4ba30 | ||
|
|
254511bfbf | ||
|
|
e2f6f8a4e4 | ||
|
|
e346963e76 | ||
|
|
5f1bdf7264 | ||
|
|
93a3b29677 | ||
|
|
b157cd909c | ||
|
|
2f24703690 | ||
|
|
27efa8844e | ||
|
|
98de4b6dc3 | ||
|
|
d121de5152 | ||
|
|
5ad7323d03 | ||
|
|
183020a4e3 | ||
|
|
a56a5fe1f5 | ||
|
|
7e7f3ba78f | ||
|
|
03eaebc71c | ||
|
|
afcd23cb99 | ||
|
|
94d1181fe8 | ||
|
|
7e45aaa1da |
@@ -61,6 +61,7 @@
|
||||
"panzoom": "9.4.3",
|
||||
"preact": "10.28.1",
|
||||
"react-i18next": "16.5.0",
|
||||
"react-window": "2.2.3",
|
||||
"reveal.js": "5.2.1",
|
||||
"svg-pan-zoom": "3.6.2",
|
||||
"tabulator-tables": "6.3.1",
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import appContext from "./components/app_context.js";
|
||||
import utils from "./services/utils.js";
|
||||
import noteTooltipService from "./services/note_tooltip.js";
|
||||
import bundleService from "./services/bundle.js";
|
||||
import toastService from "./services/toast.js";
|
||||
import noteAutocompleteService from "./services/note_autocomplete.js";
|
||||
import electronContextMenu from "./menus/electron_context_menu.js";
|
||||
import glob from "./services/glob.js";
|
||||
import { t } from "./services/i18n.js";
|
||||
import options from "./services/options.js";
|
||||
import "autocomplete.js/index_jquery.js";
|
||||
|
||||
import type ElectronRemote from "@electron/remote";
|
||||
import type Electron from "electron";
|
||||
import "boxicons/css/boxicons.min.css";
|
||||
import "autocomplete.js/index_jquery.js";
|
||||
|
||||
import appContext from "./components/app_context.js";
|
||||
import electronContextMenu from "./menus/electron_context_menu.js";
|
||||
import bundleService from "./services/bundle.js";
|
||||
import glob from "./services/glob.js";
|
||||
import { t } from "./services/i18n.js";
|
||||
import noteAutocompleteService from "./services/note_autocomplete.js";
|
||||
import noteTooltipService from "./services/note_tooltip.js";
|
||||
import options from "./services/options.js";
|
||||
import toastService from "./services/toast.js";
|
||||
import utils from "./services/utils.js";
|
||||
|
||||
await appContext.earlyInit();
|
||||
|
||||
|
||||
@@ -582,6 +582,10 @@ export default class FNote {
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
return `tn-icon ${this.#getIconInternal()}`;
|
||||
}
|
||||
|
||||
#getIconInternal() {
|
||||
const iconClassLabels = this.getLabels("iconClass");
|
||||
const workspaceIconClass = this.getWorkspaceIconClass();
|
||||
|
||||
|
||||
BIN
apps/client/src/fonts/boxicons.woff2
Normal file
BIN
apps/client/src/fonts/boxicons.woff2
Normal file
Binary file not shown.
@@ -1,9 +1,9 @@
|
||||
import appContext from "./components/app_context.js";
|
||||
import noteAutocompleteService from "./services/note_autocomplete.js";
|
||||
import glob from "./services/glob.js";
|
||||
import "boxicons/css/boxicons.min.css";
|
||||
import "autocomplete.js/index_jquery.js";
|
||||
|
||||
import appContext from "./components/app_context.js";
|
||||
import glob from "./services/glob.js";
|
||||
import noteAutocompleteService from "./services/note_autocomplete.js";
|
||||
|
||||
glob.setupGlobs();
|
||||
|
||||
await appContext.earlyInit();
|
||||
|
||||
498
apps/client/src/stylesheets/boxicons-compat.css
Normal file
498
apps/client/src/stylesheets/boxicons-compat.css
Normal file
@@ -0,0 +1,498 @@
|
||||
.bx-ul
|
||||
{
|
||||
margin-left: 2em;
|
||||
padding-left: 0;
|
||||
|
||||
list-style: none;
|
||||
}
|
||||
.bx-ul > li
|
||||
{
|
||||
position: relative;
|
||||
}
|
||||
.bx-ul .bx
|
||||
{
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
|
||||
position: absolute;
|
||||
left: -2em;
|
||||
|
||||
width: 2em;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
@-webkit-keyframes spin
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
100%
|
||||
{
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@keyframes spin
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
100%
|
||||
{
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes burst
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes burst
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes flashing
|
||||
{
|
||||
0%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
45%
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
90%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes flashing
|
||||
{
|
||||
0%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
45%
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
90%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(-20px);
|
||||
transform: translateX(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(-20px);
|
||||
transform: translateX(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-up
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-up
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-down
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(20px);
|
||||
transform: translateY(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-down
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(20px);
|
||||
transform: translateY(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes tada
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
10%,
|
||||
20%
|
||||
{
|
||||
-webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
60%,
|
||||
80%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes tada
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
10%,
|
||||
20%
|
||||
{
|
||||
-webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
60%,
|
||||
80%
|
||||
{
|
||||
-webkit-transform: rotate3d(0, 0, 1, -10deg);
|
||||
transform: rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
.bx-spin
|
||||
{
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
.bx-spin-hover:hover
|
||||
{
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
.bx-tada
|
||||
{
|
||||
-webkit-animation: tada 1.5s ease infinite;
|
||||
animation: tada 1.5s ease infinite;
|
||||
}
|
||||
.bx-tada-hover:hover
|
||||
{
|
||||
-webkit-animation: tada 1.5s ease infinite;
|
||||
animation: tada 1.5s ease infinite;
|
||||
}
|
||||
|
||||
.bx-flashing
|
||||
{
|
||||
-webkit-animation: flashing 1.5s infinite linear;
|
||||
animation: flashing 1.5s infinite linear;
|
||||
}
|
||||
.bx-flashing-hover:hover
|
||||
{
|
||||
-webkit-animation: flashing 1.5s infinite linear;
|
||||
animation: flashing 1.5s infinite linear;
|
||||
}
|
||||
|
||||
.bx-burst
|
||||
{
|
||||
-webkit-animation: burst 1.5s infinite linear;
|
||||
animation: burst 1.5s infinite linear;
|
||||
}
|
||||
.bx-burst-hover:hover
|
||||
{
|
||||
-webkit-animation: burst 1.5s infinite linear;
|
||||
animation: burst 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-up
|
||||
{
|
||||
-webkit-animation: fade-up 1.5s infinite linear;
|
||||
animation: fade-up 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-up-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-up 1.5s infinite linear;
|
||||
animation: fade-up 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-down
|
||||
{
|
||||
-webkit-animation: fade-down 1.5s infinite linear;
|
||||
animation: fade-down 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-down-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-down 1.5s infinite linear;
|
||||
animation: fade-down 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-left
|
||||
{
|
||||
-webkit-animation: fade-left 1.5s infinite linear;
|
||||
animation: fade-left 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-left-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-left 1.5s infinite linear;
|
||||
animation: fade-left 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-right
|
||||
{
|
||||
-webkit-animation: fade-right 1.5s infinite linear;
|
||||
animation: fade-right 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-right-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-right 1.5s infinite linear;
|
||||
animation: fade-right 1.5s infinite linear;
|
||||
}
|
||||
.bx-xs
|
||||
{
|
||||
font-size: 1rem!important;
|
||||
}
|
||||
.bx-sm
|
||||
{
|
||||
font-size: 1.55rem!important;
|
||||
}
|
||||
.bx-md
|
||||
{
|
||||
font-size: 2.25rem!important;
|
||||
}
|
||||
.bx-lg
|
||||
{
|
||||
font-size: 3.0rem!important;
|
||||
}
|
||||
.bx-fw
|
||||
{
|
||||
font-size: 1.2857142857em;
|
||||
line-height: .8em;
|
||||
|
||||
width: 1.2857142857em;
|
||||
height: .8em;
|
||||
margin-top: -.2em!important;
|
||||
|
||||
vertical-align: middle;
|
||||
}
|
||||
.bx-pull-left
|
||||
{
|
||||
float: left;
|
||||
|
||||
margin-right: .3em!important;
|
||||
}
|
||||
.bx-pull-right
|
||||
{
|
||||
float: right;
|
||||
|
||||
margin-left: .3em!important;
|
||||
}
|
||||
.bx-rotate-90
|
||||
{
|
||||
transform: rotate(90deg);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=1)';
|
||||
}
|
||||
.bx-rotate-180
|
||||
{
|
||||
transform: rotate(180deg);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)';
|
||||
}
|
||||
.bx-rotate-270
|
||||
{
|
||||
transform: rotate(270deg);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=3)';
|
||||
}
|
||||
.bx-flip-horizontal
|
||||
{
|
||||
transform: scaleX(-1);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)';
|
||||
}
|
||||
.bx-flip-vertical
|
||||
{
|
||||
transform: scaleY(-1);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)';
|
||||
}
|
||||
.bx-border
|
||||
{
|
||||
padding: .25em;
|
||||
|
||||
border: .07em solid rgba(0,0,0,.1);
|
||||
border-radius: .25em;
|
||||
}
|
||||
.bx-border-circle
|
||||
{
|
||||
padding: .25em;
|
||||
|
||||
border: .07em solid rgba(0,0,0,.1);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/** Custom icon **/
|
||||
.bx-empty {
|
||||
width: 1em;
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
@import "./boxicons-compat.css";
|
||||
|
||||
@font-face {
|
||||
font-family: Montserrat;
|
||||
src: url(../fonts/Montserrat-Light.ttf);
|
||||
@@ -1128,11 +1130,6 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
|
||||
border-color: var(--main-border-color) !important;
|
||||
}
|
||||
|
||||
.bx-empty {
|
||||
width: 1em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
padding: 0.5rem 1rem 0.5rem 1rem !important; /* make modal header padding slightly smaller */
|
||||
}
|
||||
@@ -1799,7 +1796,7 @@ button.close:hover {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.reference-link .bx {
|
||||
.reference-link .tn-icon {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
margin-inline-end: 3px;
|
||||
@@ -2418,7 +2415,7 @@ footer.webview-footer button {
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.right-pane-tab .tab-title .bx {
|
||||
.right-pane-tab .tab-title .tn-icon {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
@@ -2546,18 +2543,11 @@ footer.webview-footer button {
|
||||
inset-inline-end: 10px;
|
||||
}
|
||||
|
||||
.content-floating-buttons button.bx {
|
||||
.content-floating-buttons button.tn-icon {
|
||||
font-size: 130%;
|
||||
padding: 1px 10px 1px 10px;
|
||||
}
|
||||
|
||||
/* Customized icons */
|
||||
|
||||
.bx-tn-toc::before {
|
||||
content: "\ec24";
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* CK Editor */
|
||||
|
||||
/* Insert text snippet: limit the width of the listed items to avoid overly long names */
|
||||
|
||||
@@ -134,7 +134,7 @@ body.backdrop-effects-disabled {
|
||||
white-space-collapse: discard;
|
||||
}
|
||||
|
||||
.dropdown-menu.tn-dropdown-menu .bx {
|
||||
.dropdown-menu.tn-dropdown-menu .dropdown-item .tn-icon {
|
||||
margin-inline-end: 6px;
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ html body .dropdown-item[disabled] {
|
||||
}
|
||||
|
||||
/* Menu item icon */
|
||||
.dropdown-item .bx {
|
||||
.dropdown-item .tn-icon {
|
||||
translate: 0 var(--menu-item-icon-vert-offset);
|
||||
color: var(--menu-item-icon-color) !important;
|
||||
font-size: 1.1em;
|
||||
@@ -496,7 +496,7 @@ li.dropdown-item a.dropdown-item-button {
|
||||
border: unset;
|
||||
}
|
||||
|
||||
li.dropdown-item a.dropdown-item-button.bx {
|
||||
li.dropdown-item a.dropdown-item-button.tn-icon {
|
||||
color: var(--menu-text-color) !important;
|
||||
}
|
||||
|
||||
@@ -557,13 +557,13 @@ li.dropdown-item a.dropdown-item-button:focus-visible {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#toast-container .toast:not(.no-title) .bx {
|
||||
#toast-container .toast:not(.no-title) .tn-icon {
|
||||
margin-inline-end: 0.5em;
|
||||
font-size: 1.1em;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
#toast-container .toast.no-title .bx {
|
||||
#toast-container .toast.no-title .tn-icon {
|
||||
margin-inline-end: 0;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
@@ -754,7 +754,7 @@ li.dropdown-item a.dropdown-item-button:focus-visible {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.note-list-wrapper .note-book-card .bx {
|
||||
.note-list-wrapper .note-book-card .tn-icon {
|
||||
color: var(--left-pane-icon-color) !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -423,6 +423,6 @@ div.tn-tool-dialog {
|
||||
font-size: unset;
|
||||
}
|
||||
|
||||
.note-type-chooser-dialog div.note-type-dropdown .dropdown-item span.bx {
|
||||
.note-type-chooser-dialog div.note-type-dropdown .dropdown-item span.tn-icon {
|
||||
margin-inline-end: .25em;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,10 +62,10 @@ button.ck.ck-button:is(.ck-button-action, .ck-button-save, .ck-button-cancel, .c
|
||||
}
|
||||
|
||||
/* Button's icon */
|
||||
button.btn.btn-primary span.bx,
|
||||
button.btn.btn-secondary span.bx,
|
||||
button.btn.btn-sm span.bx,
|
||||
button.btn.btn-success span.bx {
|
||||
button.btn.btn-primary span.tn-icon,
|
||||
button.btn.btn-secondary span.tn-icon,
|
||||
button.btn.btn-sm span.tn-icon,
|
||||
button.btn.btn-success span.tn-icon {
|
||||
color: var(--cmd-button-icon-color);
|
||||
padding-inline-end: 0.35em;
|
||||
font-size: 1.2em;
|
||||
|
||||
@@ -151,6 +151,11 @@
|
||||
--options-title-font-size: .75rem;
|
||||
--options-title-offset: 13px;
|
||||
}
|
||||
|
||||
.note-split.options {
|
||||
--preferred-max-content-width: var(--options-card-max-width);
|
||||
}
|
||||
|
||||
/* Create a gap at the top of the option pages */
|
||||
.note-detail-content-widget-content.options>*:first-child {
|
||||
margin-top: var(--options-first-item-top-margin, 1em);
|
||||
@@ -185,10 +190,6 @@ body.experimental-feature-new-layout .note-detail-content-widget-content.options
|
||||
padding: var(--options-card-padding);
|
||||
}
|
||||
|
||||
body.prefers-centered-content .options-section:not(.tn-no-card) {
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
body.desktop .options-section:not(.tn-no-card) {
|
||||
min-width: var(--options-card-min-width);
|
||||
max-width: var(--options-card-max-width);
|
||||
|
||||
@@ -497,7 +497,7 @@ div.bookmark-folder-widget .note-link:hover a {
|
||||
}
|
||||
|
||||
/* The item's icon */
|
||||
div.bookmark-folder-widget .note-link .bx {
|
||||
div.bookmark-folder-widget .note-link .tn-icon {
|
||||
color: var(--menu-item-icon-color);
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
@@ -229,11 +229,11 @@ span.fancytree-node.archived {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.fancytree-node:hover .bx.tree-item-button {
|
||||
.fancytree-node:hover .tn-icon.tree-item-button {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.bx.tree-item-button {
|
||||
.tn-icon.tree-item-button {
|
||||
display: none;
|
||||
font-size: 120%;
|
||||
cursor: pointer;
|
||||
@@ -243,7 +243,7 @@ span.fancytree-node.archived {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.unhoist-button.bx.tree-item-button {
|
||||
.unhoist-button.tn-icon.tree-item-button {
|
||||
margin-inline-start: 0; /* unhoist button is on the left and doesn't need more margin */
|
||||
display: block; /* keep always visible */
|
||||
}
|
||||
|
||||
@@ -223,7 +223,6 @@
|
||||
"backlink_other": ""
|
||||
},
|
||||
"note_icon": {
|
||||
"category": "الفئة:",
|
||||
"search": "بحث:",
|
||||
"change_note_icon": "تغيير ايقونة الملاحظة",
|
||||
"reset-default": "اعادة تعيين الى الايقونة الافتراضية"
|
||||
|
||||
@@ -146,7 +146,6 @@
|
||||
"relation": "relació"
|
||||
},
|
||||
"note_icon": {
|
||||
"category": "Categoria:",
|
||||
"search": "Cerca:"
|
||||
},
|
||||
"basic_properties": {
|
||||
|
||||
@@ -764,7 +764,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "更改笔记图标",
|
||||
"category": "类别:",
|
||||
"search": "搜索:",
|
||||
"reset-default": "重置为默认图标"
|
||||
},
|
||||
|
||||
@@ -21,7 +21,10 @@
|
||||
},
|
||||
"bundle-error": {
|
||||
"title": "Benutzerdefiniertes Skript konnte nicht geladen werden",
|
||||
"message": "Skript aus der Notiz \"{{title}}\" mit der ID \"{{id}}\", konnte nicht ausgeführt werden wegen:\n\n{{message}}"
|
||||
"message": "Skript konnte nicht ausgeführt werden wegen:\n\n{{message}}"
|
||||
},
|
||||
"widget-list-error": {
|
||||
"title": "Abruf der Liste von Widgets vom Server ist fehlgeschlagen"
|
||||
}
|
||||
},
|
||||
"add_link": {
|
||||
@@ -746,7 +749,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Notiz-Icon ändern",
|
||||
"category": "Kategorie:",
|
||||
"search": "Suche:",
|
||||
"reset-default": "Standard wiederherstellen"
|
||||
},
|
||||
|
||||
@@ -765,9 +765,16 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Change note icon",
|
||||
"category": "Category:",
|
||||
"search": "Search:",
|
||||
"reset-default": "Reset to default icon"
|
||||
"search_placeholder_one": "Search {{number}} icons across {{count}} packs",
|
||||
"search_placeholder_other": "Search {{number}} icons across {{count}} packs",
|
||||
"search_placeholder_filtered": "Search {{number}} icons in {{name}}",
|
||||
"reset-default": "Reset to default icon",
|
||||
"filter": "Filter",
|
||||
"filter-none": "All icons",
|
||||
"filter-default": "Default icons",
|
||||
"icon_tooltip": "{{name}}\nIcon pack: {{iconPack}}",
|
||||
"no_results": "No icons found."
|
||||
},
|
||||
"basic_properties": {
|
||||
"note_type": "Note type",
|
||||
@@ -1613,7 +1620,7 @@
|
||||
"will_be_deleted_in": "This attachment will be automatically deleted in {{time}}",
|
||||
"will_be_deleted_soon": "This attachment will be automatically deleted soon",
|
||||
"deletion_reason": ", because the attachment is not linked in the note's content. To prevent deletion, add the attachment link back into the content or convert the attachment into note.",
|
||||
"role_and_size": "Role: {{role}}, Size: {{size}}",
|
||||
"role_and_size": "Role: {{role}}, size: {{size}}, MIME: {{- mimeType}}",
|
||||
"link_copied": "Attachment link copied to clipboard.",
|
||||
"unrecognized_role": "Unrecognized attachment role '{{role}}'."
|
||||
},
|
||||
|
||||
@@ -749,7 +749,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Cambiar icono de nota",
|
||||
"category": "Categoría:",
|
||||
"search": "Búsqueda:",
|
||||
"reset-default": "Restablecer a icono por defecto"
|
||||
},
|
||||
|
||||
@@ -756,7 +756,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Changer l'icône de note",
|
||||
"category": "Catégorie :",
|
||||
"search": "Recherche :",
|
||||
"reset-default": "Réinitialiser l'icône par défaut"
|
||||
},
|
||||
|
||||
@@ -1333,7 +1333,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Cambia icona nota",
|
||||
"category": "Categoria:",
|
||||
"search": "Ricerca:",
|
||||
"reset-default": "Ripristina l'icona predefinita"
|
||||
},
|
||||
|
||||
@@ -152,7 +152,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "ノートアイコンの変更",
|
||||
"category": "カテゴリー:",
|
||||
"search": "検索:",
|
||||
"reset-default": "アイコンをデフォルトに戻す"
|
||||
},
|
||||
@@ -161,7 +160,7 @@
|
||||
"editable": "編集可能",
|
||||
"basic_properties": "基本プロパティ",
|
||||
"language": "言語",
|
||||
"configure_code_notes": "コードノートを設定しています..."
|
||||
"configure_code_notes": "コードノートを設定..."
|
||||
},
|
||||
"i18n": {
|
||||
"title": "ローカライゼーション",
|
||||
|
||||
@@ -1286,7 +1286,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Zmień ikonę notatki",
|
||||
"category": "Kategoria:",
|
||||
"search": "Szukaj:",
|
||||
"reset-default": "Przywróć domyślną ikonę"
|
||||
},
|
||||
|
||||
@@ -724,7 +724,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Alterar ícone da nota",
|
||||
"category": "Categoria:",
|
||||
"search": "Pesquisa:",
|
||||
"reset-default": "Redefinir para o ícone padrão"
|
||||
},
|
||||
|
||||
@@ -1008,7 +1008,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Alterar ícone da nota",
|
||||
"category": "Categoria:",
|
||||
"search": "Busca:",
|
||||
"reset-default": "Redefinir para o ícone padrão"
|
||||
},
|
||||
|
||||
@@ -1483,7 +1483,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Schimbă iconița notiței",
|
||||
"category": "Categorie:",
|
||||
"reset-default": "Resetează la iconița implicită",
|
||||
"search": "Căutare:"
|
||||
},
|
||||
|
||||
@@ -1010,7 +1010,6 @@
|
||||
"backlink_many": "{{count}} обратных ссылок"
|
||||
},
|
||||
"note_icon": {
|
||||
"category": "Категория:",
|
||||
"search": "Поиск:",
|
||||
"change_note_icon": "Изменить иконку заметки",
|
||||
"reset-default": "Сбросить к значку по умолчанию"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
},
|
||||
"bundle-error": {
|
||||
"title": "載入自訂腳本失敗",
|
||||
"message": "來自 ID 為 \"{{id}}\"、標題為 \"{{title}}\" 的筆記的腳本因以下原因無法執行:\n\n{{message}}"
|
||||
"message": "腳本因以下原因無法執行:\n\n{{message}}"
|
||||
},
|
||||
"widget-list-error": {
|
||||
"title": "無法從伺服器取得元件清單"
|
||||
@@ -761,7 +761,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "更改筆記圖標",
|
||||
"category": "類別:",
|
||||
"search": "搜尋:",
|
||||
"reset-default": "重置為預設圖標"
|
||||
},
|
||||
|
||||
@@ -849,7 +849,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Змінити значок нотатки",
|
||||
"category": "Категорія:",
|
||||
"search": "Пошук:",
|
||||
"reset-default": "Скинути значок до стандартного значення"
|
||||
},
|
||||
|
||||
2
apps/client/src/types-assets.d.ts
vendored
2
apps/client/src/types-assets.d.ts
vendored
@@ -17,5 +17,3 @@ declare module "*?raw" {
|
||||
var content: string;
|
||||
export default content;
|
||||
}
|
||||
|
||||
declare module "boxicons/css/boxicons.min.css" { }
|
||||
|
||||
3
apps/client/src/types.d.ts
vendored
3
apps/client/src/types.d.ts
vendored
@@ -1,3 +1,5 @@
|
||||
import { IconRegistry } from "@triliumnext/commons";
|
||||
|
||||
import appContext, { AppContext } from "./components/app_context";
|
||||
import type FNote from "./entities/fnote";
|
||||
import type { PrintReport } from "./print";
|
||||
@@ -46,6 +48,7 @@ interface CustomGlobals {
|
||||
linter: typeof lint;
|
||||
hasNativeTitleBar: boolean;
|
||||
isRtl: boolean;
|
||||
iconRegistry: IconRegistry;
|
||||
}
|
||||
|
||||
type RequireMethod = (moduleName: string) => any;
|
||||
|
||||
@@ -142,7 +142,7 @@ function ShowTocWidgetButton({ note, noteContext, isDefaultViewMode }: FloatingB
|
||||
|
||||
return isEnabled && <FloatingButton
|
||||
text={t("show_toc_widget_button.show_toc")}
|
||||
icon="bx bx-tn-toc"
|
||||
icon="bx bx-spreadsheet bx-rotate-180"
|
||||
onClick={() => {
|
||||
if (noteContext?.viewScope && noteContext.noteId) {
|
||||
noteContext.viewScope.tocTemporarilyHidden = false;
|
||||
|
||||
@@ -12,7 +12,7 @@ body.prefers-centered-content .note-list-widget:not(.full-height) {
|
||||
}
|
||||
|
||||
.note-list-widget .note-list {
|
||||
padding: 10px;
|
||||
padding-block: 10px;
|
||||
}
|
||||
|
||||
.note-list-widget.full-height,
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.geo-map-container .leaflet-div-icon .bx {
|
||||
.geo-map-container .leaflet-div-icon .tn-icon {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
inset-inline-start: 2px;
|
||||
|
||||
@@ -74,11 +74,11 @@ describe("Presentation model", () => {
|
||||
});
|
||||
|
||||
it("rewrites links to other slides", () => {
|
||||
expect(data.slides[1].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to <a class="reference-link" href="#/slide-slide1"><span><span class="bx bx-folder"></span>First slide</span></a>.</p></div>`);
|
||||
expect(data.slides[1].verticalSlides![0].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to <a class="reference-link" href="#/slide-slide2"><span><span class="bx bx-note"></span>First-sub</span></a>.</p></div>`);
|
||||
expect(data.slides[1].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to <a class="reference-link" href="#/slide-slide1"><span><span class="tn-icon bx bx-folder"></span>First slide</span></a>.</p></div>`);
|
||||
expect(data.slides[1].verticalSlides![0].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to <a class="reference-link" href="#/slide-slide2"><span><span class="tn-icon bx bx-note"></span>First-sub</span></a>.</p></div>`);
|
||||
});
|
||||
|
||||
it("rewrites links even if they are not part of the slideshow", () => {
|
||||
expect(data.slides[0].verticalSlides![0].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to <a class="reference-link" href="#/slide-other"><span><span class="bx bx-note"></span>Other note</span></a>.</p></div>`);
|
||||
expect(data.slides[0].verticalSlides![0].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to <a class="reference-link" href="#/slide-other"><span><span class="tn-icon bx bx-note"></span>Other note</span></a>.</p></div>`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
overflow: auto;
|
||||
scroll-behavior: smooth;
|
||||
position: relative;
|
||||
|
||||
> .inline-title,
|
||||
> .note-detail > .note-detail-editable-text,
|
||||
> .note-list-widget:not(.full-height) {
|
||||
padding-inline: 24px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.note-split.type-code:not(.mime-text-x-sqlite) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,7 +35,7 @@
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
|
||||
.bx {
|
||||
.tn-icon {
|
||||
margin-inline: 6px;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
.icon-action {
|
||||
font-size: .9rem !important;
|
||||
|
||||
.bxs-chevron-right {
|
||||
&.breadcrumb-separator {
|
||||
transform: translateY(8%);
|
||||
|
||||
&::before {
|
||||
|
||||
@@ -191,7 +191,7 @@ function BreadcrumbSeparator(props: BreadcrumbSeparatorProps) {
|
||||
<Dropdown
|
||||
text={<Icon icon="bx bxs-chevron-right" />}
|
||||
noSelectButtonStyle
|
||||
buttonClassName="icon-action"
|
||||
buttonClassName="icon-action breadcrumb-separator"
|
||||
hideToggleArrow
|
||||
dropdownContainerClassName="tn-dropdown-menu-scrollable breadcrumb-child-list"
|
||||
dropdownOptions={{ popperConfig: { strategy: "fixed", placement: "top" } }}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
max-width: var(--max-content-width);
|
||||
container-type: inline-size;
|
||||
padding-top: 20px;
|
||||
padding-inline-start: 24px;
|
||||
|
||||
& > .inline-title-row {
|
||||
--icon-size: 35px;
|
||||
|
||||
@@ -4,12 +4,21 @@ body.experimental-feature-new-layout {
|
||||
}
|
||||
|
||||
.title-actions {
|
||||
--title-actions-padding-start: 12px;
|
||||
--title-actions-padding-end: 8px;
|
||||
|
||||
display: flex;
|
||||
max-width: var(--max-content-width);
|
||||
flex-direction: column;
|
||||
gap: 0.5em;
|
||||
padding-inline: var(--title-actions-padding-start) var(--title-actions-padding-end);
|
||||
|
||||
body.prefers-centered-content .note-split:not(.full-content-width) & {
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
&:not(:empty) {
|
||||
padding: 0.75em 15px;
|
||||
padding-block: 0.75em;
|
||||
}
|
||||
|
||||
.edited-notes {
|
||||
@@ -40,5 +49,11 @@ body.experimental-feature-new-layout {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .collapsible,
|
||||
> .note-type-switcher {
|
||||
padding-inline-start: calc(24px - var(--title-actions-padding-start));
|
||||
padding-inline-end: calc(24px - var(--title-actions-padding-end));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
background-color: var(--left-pane-background-color);
|
||||
padding-inline: 0.25em;
|
||||
font-size: 0.85em;
|
||||
|
||||
|
||||
> .breadcrumb {
|
||||
flex-grow: 1;
|
||||
--icon-button-size: 23px;
|
||||
@@ -104,7 +104,7 @@
|
||||
/* Note path card */
|
||||
li {
|
||||
--border-radius: 6px;
|
||||
|
||||
|
||||
position: relative;
|
||||
background: var(--card-background-color);
|
||||
padding: 8px 20px 8px 25px;
|
||||
@@ -120,7 +120,7 @@
|
||||
& + li {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
|
||||
/* Current path arrow */
|
||||
&.path-current::before {
|
||||
position: absolute;
|
||||
@@ -180,7 +180,7 @@
|
||||
&:last-child {
|
||||
border-radius: 0 0 var(--border-radius) var(--border-radius);
|
||||
}
|
||||
|
||||
|
||||
/* Card header */
|
||||
& > span:first-child {
|
||||
display: block;
|
||||
@@ -202,7 +202,7 @@
|
||||
}
|
||||
|
||||
/* Note icon */
|
||||
> .bx {
|
||||
> .tn-icon {
|
||||
color: var(--menu-item-icon-color);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,17 +32,14 @@ div.note-icon-widget {
|
||||
}
|
||||
|
||||
.note-icon-widget .filter-row {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-inline-end: 20px;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
align-items: center;
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
.note-icon-widget .filter-row span {
|
||||
display: block;
|
||||
padding-inline-start: 15px;
|
||||
padding-inline-end: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@@ -75,6 +72,14 @@ div.note-icon-widget {
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.note-icon-widget {
|
||||
.no-results {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
color: var(--muted-text-color);
|
||||
}
|
||||
}
|
||||
|
||||
body.experimental-feature-new-layout {
|
||||
.note-icon-widget button.note-icon {
|
||||
--input-focus-outline-color: var(--note-icon-hover-background-color);
|
||||
@@ -111,4 +116,4 @@ body.experimental-feature-new-layout {
|
||||
transition: background 200ms ease-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,36 @@
|
||||
import Dropdown from "./react/Dropdown";
|
||||
import "./note_icon.css";
|
||||
|
||||
import { IconRegistry } from "@triliumnext/commons";
|
||||
import { Dropdown as BootstrapDropdown } from "bootstrap";
|
||||
import clsx from "clsx";
|
||||
import { t } from "i18next";
|
||||
import { useNoteContext, useNoteLabel } from "./react/hooks";
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import server from "../services/server";
|
||||
import type { Category, Icon } from "./icon_list";
|
||||
import FormTextBox from "./react/FormTextBox";
|
||||
import FormSelect from "./react/FormSelect";
|
||||
import { CSSProperties, RefObject } from "preact";
|
||||
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
|
||||
import { CellComponentProps, Grid } from "react-window";
|
||||
|
||||
import FNote from "../entities/fnote";
|
||||
import attributes from "../services/attributes";
|
||||
import Button from "./react/Button";
|
||||
import server from "../services/server";
|
||||
import ActionButton from "./react/ActionButton";
|
||||
import Dropdown from "./react/Dropdown";
|
||||
import { FormDropdownDivider, FormListItem } from "./react/FormList";
|
||||
import FormTextBox from "./react/FormTextBox";
|
||||
import { useNoteContext, useNoteLabel, useStaticTooltip } from "./react/hooks";
|
||||
|
||||
interface IconToCountCache {
|
||||
iconClassToCountMap: Record<string, number>;
|
||||
}
|
||||
|
||||
interface IconData {
|
||||
iconToCount: Record<string, number>;
|
||||
categories: Category[];
|
||||
icons: Icon[];
|
||||
}
|
||||
|
||||
let fullIconData: {
|
||||
categories: Category[];
|
||||
icons: Icon[];
|
||||
};
|
||||
let iconToCountCache!: Promise<IconToCountCache> | null;
|
||||
|
||||
type IconWithName = (IconRegistry["sources"][number]["icons"][number] & { iconPack: string });
|
||||
|
||||
export default function NoteIcon() {
|
||||
const { note, viewScope } = useNoteContext();
|
||||
const [ icon, setIcon ] = useState<string | null | undefined>();
|
||||
const [ iconClass ] = useNoteLabel(note, "iconClass");
|
||||
const [ workspaceIconClass ] = useNoteLabel(note, "workspaceIconClass");
|
||||
const dropdownRef = useRef<BootstrapDropdown>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setIcon(note?.getIcon());
|
||||
@@ -41,130 +40,219 @@ export default function NoteIcon() {
|
||||
<Dropdown
|
||||
className="note-icon-widget"
|
||||
title={t("note_icon.change_note_icon")}
|
||||
dropdownContainerStyle={{ width: "610px" }}
|
||||
dropdownRef={dropdownRef}
|
||||
dropdownContainerStyle={{ width: "620px" }}
|
||||
dropdownOptions={{ autoClose: "outside" }}
|
||||
buttonClassName={`note-icon tn-focusable-button ${icon ?? "bx bx-empty"}`}
|
||||
hideToggleArrow
|
||||
disabled={viewScope?.viewMode !== "default"}
|
||||
>
|
||||
{ note && <NoteIconList note={note} /> }
|
||||
{ note && <NoteIconList note={note} dropdownRef={dropdownRef} /> }
|
||||
</Dropdown>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function NoteIconList({ note }: { note: FNote }) {
|
||||
function NoteIconList({ note, dropdownRef }: {
|
||||
note: FNote,
|
||||
dropdownRef: RefObject<BootstrapDropdown>;
|
||||
}) {
|
||||
const searchBoxRef = useRef<HTMLInputElement>(null);
|
||||
const iconListRef = useRef<HTMLDivElement>(null);
|
||||
const [ search, setSearch ] = useState<string>();
|
||||
const [ categoryId, setCategoryId ] = useState<string>("0");
|
||||
const [ iconData, setIconData ] = useState<IconData>();
|
||||
const [ filterByPrefix, setFilterByPrefix ] = useState<string | null>(null);
|
||||
useStaticTooltip(iconListRef, {
|
||||
selector: "span",
|
||||
customClass: "pre-wrap-text",
|
||||
animation: false,
|
||||
title() { return this.getAttribute("title") || ""; },
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
async function loadIcons() {
|
||||
if (!fullIconData) {
|
||||
fullIconData = (await import("./icon_list.js")).default;
|
||||
}
|
||||
|
||||
// Filter by text and/or category.
|
||||
let icons: Icon[] = fullIconData.icons;
|
||||
const processedSearch = search?.trim()?.toLowerCase();
|
||||
if (processedSearch || categoryId) {
|
||||
icons = icons.filter((icon) => {
|
||||
if (categoryId !== "0" && String(icon.category_id) !== categoryId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (processedSearch) {
|
||||
if (!icon.name.includes(processedSearch) &&
|
||||
!icon.term?.find((t) => t.includes(processedSearch))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// Sort by count.
|
||||
const iconToCount = await getIconToCountMap();
|
||||
if (iconToCount) {
|
||||
icons.sort((a, b) => {
|
||||
const countA = iconToCount[a.className ?? ""] || 0;
|
||||
const countB = iconToCount[b.className ?? ""] || 0;
|
||||
|
||||
return countB - countA;
|
||||
});
|
||||
}
|
||||
|
||||
setIconData({
|
||||
iconToCount,
|
||||
icons,
|
||||
categories: fullIconData.categories
|
||||
})
|
||||
}
|
||||
|
||||
loadIcons();
|
||||
}, [ search, categoryId ]);
|
||||
const allIcons = useAllIcons();
|
||||
const filteredIcons = useFilteredIcons(allIcons, search, filterByPrefix);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class="filter-row">
|
||||
<span>{t("note_icon.category")}</span>
|
||||
<FormSelect
|
||||
name="icon-category"
|
||||
values={fullIconData?.categories ?? []}
|
||||
currentValue={categoryId} onChange={setCategoryId}
|
||||
keyProperty="id" titleProperty="name"
|
||||
/>
|
||||
|
||||
<span>{t("note_icon.search")}</span>
|
||||
<FormTextBox
|
||||
inputRef={searchBoxRef}
|
||||
type="text"
|
||||
name="icon-search"
|
||||
placeholder={ filterByPrefix
|
||||
? t("note_icon.search_placeholder_filtered", {
|
||||
number: filteredIcons.length ?? 0,
|
||||
name: glob.iconRegistry.sources.find(s => s.prefix === filterByPrefix)?.name ?? ""
|
||||
})
|
||||
: t("note_icon.search_placeholder", { number: filteredIcons.length ?? 0, count: glob.iconRegistry.sources.length })}
|
||||
currentValue={search} onChange={setSearch}
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="icon-list"
|
||||
onClick={(e) => {
|
||||
const clickedTarget = e.target as HTMLElement;
|
||||
|
||||
if (!clickedTarget.classList.contains("bx")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const iconClass = Array.from(clickedTarget.classList.values()).join(" ");
|
||||
if (note) {
|
||||
const attributeToSet = note.hasOwnedLabel("workspace") ? "workspaceIconClass" : "iconClass";
|
||||
attributes.setLabel(note.noteId, attributeToSet, iconClass);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{getIconLabels(note).length > 0 && (
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<Button
|
||||
<ActionButton
|
||||
icon="bx bx-reset"
|
||||
text={t("note_icon.reset-default")}
|
||||
onClick={() => {
|
||||
if (!note) {
|
||||
return;
|
||||
}
|
||||
if (!note) return;
|
||||
for (const label of getIconLabels(note)) {
|
||||
attributes.removeAttributeById(note.noteId, label.attributeId);
|
||||
}
|
||||
dropdownRef?.current?.hide();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{(iconData?.icons ?? []).map(({className, name}) => (
|
||||
<span class={`bx ${className}`} title={name} />
|
||||
))}
|
||||
{glob.iconRegistry.sources.length > 0 && <Dropdown
|
||||
buttonClassName="bx bx-filter-alt"
|
||||
hideToggleArrow
|
||||
noSelectButtonStyle
|
||||
noDropdownListStyle
|
||||
iconAction
|
||||
title={t("note_icon.filter")}
|
||||
>
|
||||
<IconFilterContent filterByPrefix={filterByPrefix} setFilterByPrefix={setFilterByPrefix} />
|
||||
</Dropdown>}
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="icon-list"
|
||||
ref={iconListRef}
|
||||
onClick={(e) => {
|
||||
// Make sure we are not clicking on something else than a button.
|
||||
const clickedTarget = e.target as HTMLElement;
|
||||
if (!clickedTarget.classList.contains("tn-icon")) return;
|
||||
|
||||
const iconClass = Array.from(clickedTarget.classList.values()).filter(c => c !== "tn-icon").join(" ");
|
||||
if (note) {
|
||||
const attributeToSet = note.hasOwnedLabel("workspace") ? "workspaceIconClass" : "iconClass";
|
||||
attributes.setLabel(note.noteId, attributeToSet, iconClass);
|
||||
}
|
||||
dropdownRef?.current?.hide();
|
||||
}}
|
||||
>
|
||||
{filteredIcons.length ? (
|
||||
<Grid
|
||||
columnCount={12}
|
||||
columnWidth={48}
|
||||
rowCount={Math.ceil(filteredIcons.length / 12)}
|
||||
rowHeight={48}
|
||||
cellComponent={IconItemCell}
|
||||
cellProps={{
|
||||
filteredIcons
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div class="no-results">{t("note_icon.no_results")}</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function IconItemCell({ rowIndex, columnIndex, style, filteredIcons }: CellComponentProps<{
|
||||
filteredIcons: IconWithName[];
|
||||
}>): React.JSX.Element {
|
||||
const iconIndex = rowIndex * 12 + columnIndex;
|
||||
const iconData = filteredIcons[iconIndex] as IconWithName | undefined;
|
||||
if (!iconData) return <></>;
|
||||
|
||||
const { id, terms, iconPack } = iconData;
|
||||
return (
|
||||
<span
|
||||
key={id}
|
||||
class={clsx(id, "tn-icon")}
|
||||
title={t("note_icon.icon_tooltip", { name: terms?.[0] ?? id, iconPack })}
|
||||
style={style as CSSProperties}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function IconFilterContent({ filterByPrefix, setFilterByPrefix }: {
|
||||
filterByPrefix: string | null;
|
||||
setFilterByPrefix: (value: string | null) => void;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<FormListItem
|
||||
checked={filterByPrefix === null}
|
||||
onClick={() => setFilterByPrefix(null)}
|
||||
>{t("note_icon.filter-none")}</FormListItem>
|
||||
<FormListItem
|
||||
checked={filterByPrefix === "bx"}
|
||||
onClick={() => setFilterByPrefix("bx")}
|
||||
>{t("note_icon.filter-default")}</FormListItem>
|
||||
<FormDropdownDivider />
|
||||
|
||||
{glob.iconRegistry.sources.map(({ prefix, name, icon }) => (
|
||||
prefix !== "bx" && <FormListItem
|
||||
key={prefix}
|
||||
onClick={() => setFilterByPrefix(prefix)}
|
||||
icon={icon}
|
||||
checked={filterByPrefix === prefix}
|
||||
>{name}</FormListItem>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function useAllIcons() {
|
||||
const [ allIcons, setAllIcons ] = useState<IconWithName[]>();
|
||||
|
||||
useEffect(() => {
|
||||
getIconToCountMap().then((iconsToCount) => {
|
||||
const allIcons = [
|
||||
...glob.iconRegistry.sources.flatMap(s => s.icons.map((i) => ({
|
||||
...i,
|
||||
iconPack: s.name,
|
||||
})))
|
||||
];
|
||||
|
||||
// Sort by count.
|
||||
if (iconsToCount) {
|
||||
allIcons.sort((a, b) => {
|
||||
const countA = iconsToCount[a.id ?? ""] || 0;
|
||||
const countB = iconsToCount[b.id ?? ""] || 0;
|
||||
|
||||
return countB - countA;
|
||||
});
|
||||
}
|
||||
|
||||
setAllIcons(allIcons);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return allIcons;
|
||||
}
|
||||
|
||||
function useFilteredIcons(allIcons: IconWithName[] | undefined, search: string | undefined, filterByPrefix: string | null) {
|
||||
// Filter by text and/or icon pack.
|
||||
const filteredIcons = useMemo(() => {
|
||||
let icons: IconWithName[] = allIcons ?? [];
|
||||
const processedSearch = search?.trim()?.toLowerCase();
|
||||
if (processedSearch || filterByPrefix !== null) {
|
||||
icons = icons.filter((icon) => {
|
||||
if (filterByPrefix) {
|
||||
if (!icon.id?.startsWith(`${filterByPrefix} `)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (processedSearch) {
|
||||
if (!icon.terms?.some((t) => t.includes(processedSearch))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
return icons;
|
||||
}, [ allIcons, search, filterByPrefix ]);
|
||||
return filteredIcons;
|
||||
}
|
||||
|
||||
async function getIconToCountMap() {
|
||||
if (!iconToCountCache) {
|
||||
iconToCountCache = server.get<IconToCountCache>("other/icon-usage");
|
||||
@@ -180,5 +268,5 @@ function getIconLabels(note: FNote) {
|
||||
}
|
||||
return note.getOwnedLabels()
|
||||
.filter((label) => ["workspaceIconClass", "iconClass"]
|
||||
.includes(label.name));
|
||||
.includes(label.name));
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ body.experimental-feature-new-layout {
|
||||
height: var(--size);
|
||||
padding: 0;
|
||||
|
||||
.bx {
|
||||
.tn-icon {
|
||||
opacity: 1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -1,38 +1,39 @@
|
||||
import hoistedNoteService from "../services/hoisted_note.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import utils from "../services/utils.js";
|
||||
import contextMenu from "../menus/context_menu.js";
|
||||
import froca from "../services/froca.js";
|
||||
import branchService from "../services/branches.js";
|
||||
import ws from "../services/ws.js";
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
import server from "../services/server.js";
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
import toastService from "../services/toast.js";
|
||||
import appContext, { type CommandListenerData, type EventData } from "../components/app_context.js";
|
||||
import keyboardActionsService from "../services/keyboard_actions.js";
|
||||
import clipboard from "../services/clipboard.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
import linkService from "../services/link.js";
|
||||
import options from "../services/options.js";
|
||||
import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import dialogService from "../services/dialog.js";
|
||||
import shortcutService from "../services/shortcuts.js";
|
||||
import { t } from "../services/i18n.js";
|
||||
import type FBranch from "../entities/fbranch.js";
|
||||
import type LoadResults from "../services/load_results.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
import type { NoteType } from "../entities/fnote.js";
|
||||
import type { AttributeRow, BranchRow } from "../services/load_results.js";
|
||||
import type { SetNoteOpts } from "../components/note_context.js";
|
||||
import type { TouchBarItem } from "../components/touch_bar.js";
|
||||
import type { TreeCommandNames } from "../menus/tree_context_menu.js";
|
||||
import "jquery.fancytree";
|
||||
import "jquery.fancytree/dist/modules/jquery.fancytree.dnd5.js";
|
||||
import "jquery.fancytree/dist/modules/jquery.fancytree.clones.js";
|
||||
import "jquery.fancytree/dist/modules/jquery.fancytree.filter.js";
|
||||
import "../stylesheets/tree.css";
|
||||
|
||||
import appContext, { type CommandListenerData, type EventData } from "../components/app_context.js";
|
||||
import type { SetNoteOpts } from "../components/note_context.js";
|
||||
import type { TouchBarItem } from "../components/touch_bar.js";
|
||||
import type FBranch from "../entities/fbranch.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
import type { NoteType } from "../entities/fnote.js";
|
||||
import contextMenu from "../menus/context_menu.js";
|
||||
import type { TreeCommandNames } from "../menus/tree_context_menu.js";
|
||||
import branchService from "../services/branches.js";
|
||||
import clipboard from "../services/clipboard.js";
|
||||
import dialogService from "../services/dialog.js";
|
||||
import froca from "../services/froca.js";
|
||||
import hoistedNoteService from "../services/hoisted_note.js";
|
||||
import { t } from "../services/i18n.js";
|
||||
import keyboardActionsService from "../services/keyboard_actions.js";
|
||||
import linkService from "../services/link.js";
|
||||
import type LoadResults from "../services/load_results.js";
|
||||
import type { AttributeRow, BranchRow } from "../services/load_results.js";
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
import options from "../services/options.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import server from "../services/server.js";
|
||||
import shortcutService from "../services/shortcuts.js";
|
||||
import toastService from "../services/toast.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import utils from "../services/utils.js";
|
||||
import ws from "../services/ws.js";
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
|
||||
const TPL = /*html*/`
|
||||
<div class="tree-wrapper">
|
||||
<style>
|
||||
@@ -242,7 +243,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
e.preventDefault();
|
||||
|
||||
appContext.tabManager.openTabWithNoteWithHoisting(notePath, {
|
||||
activate: e.shiftKey ? true : false
|
||||
activate: !!e.shiftKey
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -402,7 +403,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
} else if (ctrlKey) {
|
||||
const notePath = treeService.getNotePath(node);
|
||||
appContext.tabManager.openTabWithNoteWithHoisting(notePath, {
|
||||
activate: event.shiftKey ? true : false
|
||||
activate: !!event.shiftKey
|
||||
});
|
||||
} else if (event.altKey) {
|
||||
node.setSelected(!node.isSelected());
|
||||
@@ -499,9 +500,9 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
return ["before", "after"];
|
||||
} else if (["_lbAvailableLaunchers", "_lbVisibleLaunchers"].includes(node.data.noteId)) {
|
||||
return ["over"];
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
||||
},
|
||||
dragDrop: async (node, data) => {
|
||||
if (
|
||||
@@ -597,7 +598,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
clones: {
|
||||
highlightActiveClones: true
|
||||
},
|
||||
enhanceTitle: async function (
|
||||
async enhanceTitle (
|
||||
event: Event,
|
||||
data: {
|
||||
node: Fancytree.FancytreeNode;
|
||||
@@ -627,7 +628,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
const isHoistedNote = activeNoteContext && activeNoteContext.hoistedNoteId === note.noteId && note.noteId !== "root";
|
||||
|
||||
if (note.hasLabel("workspace") && !isHoistedNote) {
|
||||
const $enterWorkspaceButton = $(`<span class="tree-item-button enter-workspace-button bx bx-door-open" title="${t("note_tree.hoist-this-note-workspace")}"></span>`).on(
|
||||
const $enterWorkspaceButton = $(`<span class="tree-item-button tn-icon enter-workspace-button bx bx-door-open" title="${t("note_tree.hoist-this-note-workspace")}"></span>`).on(
|
||||
"click",
|
||||
cancelClickPropagation
|
||||
);
|
||||
@@ -636,7 +637,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
}
|
||||
|
||||
if (note.type === "search") {
|
||||
const $refreshSearchButton = $(`<span class="tree-item-button refresh-search-button bx bx-refresh" title="${t("note_tree.refresh-saved-search-results")}"></span>`).on(
|
||||
const $refreshSearchButton = $(`<span class="tree-item-button tn-icon refresh-search-button bx bx-refresh" title="${t("note_tree.refresh-saved-search-results")}"></span>`).on(
|
||||
"click",
|
||||
cancelClickPropagation
|
||||
);
|
||||
@@ -650,7 +651,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
&& !note.isLaunchBarConfig()
|
||||
&& !note.noteId.startsWith("_help")
|
||||
) {
|
||||
const $createChildNoteButton = $(`<span class="tree-item-button add-note-button bx bx-plus" title="${t("note_tree.create-child-note")}"></span>`).on(
|
||||
const $createChildNoteButton = $(`<span class="tree-item-button tn-icon add-note-button bx bx-plus" title="${t("note_tree.create-child-note")}"></span>`).on(
|
||||
"click",
|
||||
cancelClickPropagation
|
||||
);
|
||||
@@ -659,7 +660,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
}
|
||||
|
||||
if (isHoistedNote) {
|
||||
const $unhoistButton = $(`<span class="tree-item-button unhoist-button bx bx-door-open" title="${t("note_tree.unhoist")}"></span>`).on("click", cancelClickPropagation);
|
||||
const $unhoistButton = $(`<span class="tree-item-button tn-icon unhoist-button bx bx-door-open" title="${t("note_tree.unhoist")}"></span>`).on("click", cancelClickPropagation);
|
||||
|
||||
$span.append($unhoistButton);
|
||||
}
|
||||
@@ -1281,7 +1282,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
|
||||
// activeNode is supposed to be moved when we find out activeNode is deleted but not all branches are deleted. save it for fixing activeNodePath after all nodes loaded.
|
||||
let movedActiveNode: Fancytree.FancytreeNode | null = null;
|
||||
let parentsOfAddedNodes: Fancytree.FancytreeNode[] = [];
|
||||
const parentsOfAddedNodes: Fancytree.FancytreeNode[] = [];
|
||||
|
||||
for (const branchRow of branchRows) {
|
||||
if (branchRow.noteId) {
|
||||
@@ -1452,10 +1453,10 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
if (branchId && branchId.startsWith("virt")) {
|
||||
// in case of virtual branches there's nothing to update
|
||||
return;
|
||||
} else {
|
||||
logError(`Cannot find branch=${branchId}`);
|
||||
return;
|
||||
}
|
||||
logError(`Cannot find branch=${branchId}`);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
branch.isExpanded = isExpanded;
|
||||
@@ -1594,7 +1595,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
// Trigger the event with the selected branch IDs
|
||||
appContext.triggerEvent("editBranchPrefix", {
|
||||
selectedOrActiveBranchIds: branchIds,
|
||||
node: node
|
||||
node
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1779,12 +1780,12 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
#moveLaunchers(selectedOrActiveBranchIds: string[], desktopParent: string, mobileParent: string) {
|
||||
const desktopLaunchersToMove = selectedOrActiveBranchIds.filter((branchId) => !branchId.startsWith("_lbMobile"));
|
||||
if (desktopLaunchersToMove) {
|
||||
branchService.moveToParentNote(desktopLaunchersToMove, "_lbRoot_" + desktopParent);
|
||||
branchService.moveToParentNote(desktopLaunchersToMove, `_lbRoot_${ desktopParent}`);
|
||||
}
|
||||
|
||||
const mobileLaunchersToMove = selectedOrActiveBranchIds.filter((branchId) => branchId.startsWith("_lbMobile"));
|
||||
if (mobileLaunchersToMove) {
|
||||
branchService.moveToParentNote(mobileLaunchersToMove, "_lbMobileRoot_" + mobileParent);
|
||||
branchService.moveToParentNote(mobileLaunchersToMove, `_lbMobileRoot_${ mobileParent}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1829,7 +1830,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
selectedOrActiveBranchIds: this.getSelectedOrActiveBranchIds(node),
|
||||
selectedOrActiveNoteIds: this.getSelectedOrActiveNoteIds(node)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const items: TouchBarItem[] = [
|
||||
new TouchBar.TouchBarButton({
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.bx {
|
||||
.tn-icon {
|
||||
font-size: 1.2em;
|
||||
margin-inline-end: 4px;
|
||||
opacity: .6;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
span.bx {
|
||||
span.tn-icon {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ interface IconProps extends Pick<HTMLAttributes<HTMLSpanElement>, "className" |
|
||||
export default function Icon({ icon, className, ...restProps }: IconProps) {
|
||||
return (
|
||||
<span
|
||||
class={clsx(icon ?? "bx bx-empty", className)}
|
||||
class={clsx(icon ?? "bx bx-empty", className, "tn-icon")}
|
||||
{...restProps}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -135,7 +135,7 @@ function RibbonTab({ icon, title, active, onClick, toggleCommand }: { icon: stri
|
||||
>
|
||||
<span
|
||||
ref={iconRef}
|
||||
className={`ribbon-tab-title-icon ${icon}`}
|
||||
className={`ribbon-tab-title-icon tn-icon ${icon}`}
|
||||
/>
|
||||
|
||||
{ active && <span class="ribbon-tab-title-label">{title}</span> }
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.ribbon-tab-title .bx {
|
||||
.ribbon-tab-title .tn-icon {
|
||||
font-size: 150%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ body.experimental-feature-new-layout #right-pane {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
&.collapsed .card-header > .bx {
|
||||
&.collapsed .card-header > .tn-icon {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ body.experimental-feature-new-layout #right-pane {
|
||||
padding: 0.75em;
|
||||
color: var(--muted-text-color);
|
||||
|
||||
.bx {
|
||||
.tn-icon {
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
.attachment-actions .dropdown-item .bx {
|
||||
.attachment-actions .dropdown-item .tn-icon {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
font-size: 120%;
|
||||
|
||||
@@ -195,7 +195,11 @@ function AttachmentInfo({ attachment, isFullDetail }: { attachment: FAttachment,
|
||||
) : (attachment.title)}
|
||||
</h4>
|
||||
<div className="attachment-details">
|
||||
{t("attachment_detail_2.role_and_size", { role: attachment.role, size: utils.formatSize(attachment.contentLength) })}
|
||||
{t("attachment_detail_2.role_and_size", {
|
||||
role: attachment.role,
|
||||
size: utils.formatSize(attachment.contentLength),
|
||||
mimeType: attachment.mime
|
||||
})}
|
||||
</div>
|
||||
<div style="flex: 1 1;" />
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.bx {
|
||||
.tn-icon {
|
||||
margin: 4px 0;
|
||||
font-size: 12px;
|
||||
opacity: 0.5;
|
||||
@@ -78,7 +78,7 @@
|
||||
.ribbon {
|
||||
padding: 0 5px;
|
||||
|
||||
.bx {
|
||||
.tn-icon {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
.note-detail-editable-text {
|
||||
font-family: var(--detail-font-family);
|
||||
padding-inline-start: 14px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -49,4 +48,8 @@ body.heading-style-underline .note-detail-editable-text h6 { border-bottom: 1px
|
||||
box-shadow: none !important;
|
||||
min-height: 50px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.note-detail-editable-text .ck.ck-editor__editable_inline {
|
||||
padding: 0;
|
||||
}
|
||||
@@ -35,5 +35,5 @@ describe("CK config", () => {
|
||||
expect(config.translations, locale.id).toHaveLength(2);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 10_000);
|
||||
});
|
||||
|
||||
1
apps/icon-pack-builder/.gitignore
vendored
Normal file
1
apps/icon-pack-builder/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.zip
|
||||
112
apps/icon-pack-builder/boxicons-free/LICENSE.txt
Normal file
112
apps/icon-pack-builder/boxicons-free/LICENSE.txt
Normal file
@@ -0,0 +1,112 @@
|
||||
Boxicons Free License
|
||||
|
||||
Free Icons offered by Boxicons is open source. You can use them for your personal and commercial projects.
|
||||
Icons
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
# Icons are free under — CC 4.0 License
|
||||
|
||||
You are free to:
|
||||
|
||||
- Share — copy and redistribute the material in any medium or format for any purpose, even commercially.
|
||||
- Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
- The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
- Attribution — You must give appropriate credit , provide a link to the license, and indicate if changes were made . You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
|
||||
- No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation .
|
||||
|
||||
No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material.
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Fonts
|
||||
|
||||
Fonts are free under - SIL OFL 1.1 License:
|
||||
|
||||
PREAMBLE
|
||||
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
|
||||
DEFINITIONS
|
||||
|
||||
“Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
|
||||
|
||||
“Reserved Font Name” refers to any names specified as such after the copyright statement(s).
|
||||
|
||||
“Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s).
|
||||
|
||||
“Modified Version” refers to any derivative made by adding to, deleting, or substituting – in part or in whole – any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
|
||||
|
||||
“Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
|
||||
PERMISSION & CONDITIONS
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
|
||||
|
||||
1 - Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2 - Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3 - No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
|
||||
|
||||
4 - The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
|
||||
|
||||
5 - The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
# Code is free under - MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
# Attribution
|
||||
|
||||
Attribution is required according to MIT,SIL OFL 1.1 and CC 4.0 License.
|
||||
They are already included in the Free icons , you are not required to take any actions
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
# Brand Icons License
|
||||
|
||||
The brand icons offered in Boxicons are trademarks of their respective brands. Their usage here is solely intended to represent the respective brands and does not imply any affiliation or endorsement.
|
||||
|
||||
|
||||
Copyright 2025 Boxicons.
|
||||
|
||||
515
apps/icon-pack-builder/boxicons-free/fonts/animations.css
Normal file
515
apps/icon-pack-builder/boxicons-free/fonts/animations.css
Normal file
@@ -0,0 +1,515 @@
|
||||
@-webkit-keyframes spin
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
100%
|
||||
{
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@keyframes spin
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
100%
|
||||
{
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes burst
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes burst
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes flashing
|
||||
{
|
||||
0%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
45%
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
90%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes flashing
|
||||
{
|
||||
0%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
45%
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
90%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(-20px);
|
||||
transform: translateX(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(-20px);
|
||||
transform: translateX(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-up
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-up
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-down
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(20px);
|
||||
transform: translateY(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-down
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(20px);
|
||||
transform: translateY(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes tada
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
10%,
|
||||
20%
|
||||
{
|
||||
-webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
60%,
|
||||
80%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes tada
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
10%,
|
||||
20%
|
||||
{
|
||||
-webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
60%,
|
||||
80%
|
||||
{
|
||||
-webkit-transform: rotate3d(0, 0, 1, -10deg);
|
||||
transform: rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
@keyframes beat {
|
||||
to {
|
||||
-webkit-transform: scale(1.4);
|
||||
transform: scale(1.4);
|
||||
}
|
||||
|
||||
}
|
||||
@keyframes bounce
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale(1.1,1);
|
||||
transform: scale(1.1,1);
|
||||
}
|
||||
|
||||
25%
|
||||
{
|
||||
-webkit-transform: scale(0.9,1) translateY(-.25em);
|
||||
transform: scale(0.9,1) translateY(-.25em);
|
||||
}
|
||||
|
||||
50%
|
||||
{
|
||||
-webkit-transform: scale(1.1,0.9);
|
||||
transform: scale(1.1,0.9);
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: scale(1, 1);
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
87.5%
|
||||
{
|
||||
-webkit-transform: scale(1, 1) translateY(-.1em);
|
||||
transform: scale(1, 1) translateY(-.1em);
|
||||
}
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale(1, 1);
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
}
|
||||
@keyframes breathe {
|
||||
from{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
50%{
|
||||
-webkit-transform: scale(1.4);
|
||||
transform: scale(1.4);
|
||||
opacity: 0.4;
|
||||
}
|
||||
to {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
}
|
||||
@keyframes wiggle {
|
||||
from{
|
||||
-webkit-transform: translateX(0);
|
||||
transform:translateX(0);
|
||||
}
|
||||
30%{
|
||||
-webkit-transform: translateX(0.075em);
|
||||
transform: translateX(0.075em);
|
||||
}
|
||||
60%{
|
||||
-webkit-transform: translateX(-0.075em);
|
||||
transform: translateX(-0.075em);
|
||||
}
|
||||
75%{
|
||||
-webkit-transform: translateX(0.025em);
|
||||
transform: translateX(0.025em);
|
||||
}
|
||||
90%{
|
||||
-webkit-transform: translateX(-0.025em);
|
||||
transform: translateX(-0.025em);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translateX(0);
|
||||
transform:translateX(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.bx-wiggle{
|
||||
-webkit-animation: wiggle 1s infinite;
|
||||
animation: wiggle 1s infinite;
|
||||
animation-timing-function:cubic-bezier(.23,.57,.79,.58);
|
||||
}
|
||||
.bx-wiggle-hover:hover{
|
||||
-webkit-animation: wiggle 1s infinite;
|
||||
animation: wiggle 1s infinite;
|
||||
animation-timing-function:cubic-bezier(.23,.57,.79,.58);
|
||||
}
|
||||
.bx-breathe{
|
||||
-webkit-animation: breathe 3s infinite;
|
||||
animation: breathe 3s infinite ease-in-out;
|
||||
|
||||
}
|
||||
.bx-breathe-hover:hover
|
||||
{
|
||||
-webkit-animation: breathe 3s infinite;
|
||||
animation: breathe 3s infinite ease-in-out;
|
||||
}
|
||||
.bx-bounce{
|
||||
-webkit-animation: bounce 1s infinite;
|
||||
animation: bounce 1s infinite;
|
||||
animation-timing-function: cubic-bezier(.98,.97,.64,1.62);
|
||||
}
|
||||
.bx-bounce-hover:hover
|
||||
{
|
||||
-webkit-animation: bounce 1s infinite;
|
||||
animation: bounce 1s infinite;
|
||||
animation-timing-function: cubic-bezier(.98,.97,.64,1.62);
|
||||
}
|
||||
|
||||
.bx-beat
|
||||
{
|
||||
-webkit-animation: beat .5s infinite alternate;
|
||||
animation: beat .5s infinite alternate;
|
||||
animation-timing-function: cubic-bezier(.19,.96,.65,1);
|
||||
transform-origin: center;
|
||||
}
|
||||
.bx-spin
|
||||
{
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
.bx-spin-hover:hover
|
||||
{
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.bx-tada
|
||||
{
|
||||
-webkit-animation: tada 1.5s ease infinite;
|
||||
animation: tada 1.5s ease infinite;
|
||||
}
|
||||
.bx-tada-hover:hover
|
||||
{
|
||||
-webkit-animation: tada 1.5s ease infinite;
|
||||
animation: tada 1.5s ease infinite;
|
||||
}
|
||||
|
||||
.bx-flashing
|
||||
{
|
||||
-webkit-animation: flashing 1.5s infinite linear;
|
||||
animation: flashing 1.5s infinite linear;
|
||||
}
|
||||
.bx-flashing-hover:hover
|
||||
{
|
||||
-webkit-animation: flashing 1.5s infinite linear;
|
||||
animation: flashing 1.5s infinite linear;
|
||||
}
|
||||
|
||||
.bx-burst
|
||||
{
|
||||
-webkit-animation: burst 1.5s infinite linear;
|
||||
animation: burst 1.5s infinite linear;
|
||||
}
|
||||
.bx-burst-hover:hover
|
||||
{
|
||||
-webkit-animation: burst 1.5s infinite linear;
|
||||
animation: burst 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-up
|
||||
{
|
||||
-webkit-animation: fade-up 1.5s infinite linear;
|
||||
animation: fade-up 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-up-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-up 1.5s infinite linear;
|
||||
animation: fade-up 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-down
|
||||
{
|
||||
-webkit-animation: fade-down 1.5s infinite linear;
|
||||
animation: fade-down 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-down-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-down 1.5s infinite linear;
|
||||
animation: fade-down 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-left
|
||||
{
|
||||
-webkit-animation: fade-left 1.5s infinite linear;
|
||||
animation: fade-left 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-left-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-left 1.5s infinite linear;
|
||||
animation: fade-left 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-right
|
||||
{
|
||||
-webkit-animation: fade-right 1.5s infinite linear;
|
||||
animation: fade-right 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-right-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-right 1.5s infinite linear;
|
||||
animation: fade-right 1.5s infinite linear;
|
||||
}
|
||||
1
apps/icon-pack-builder/boxicons-free/fonts/animations.min.css
vendored
Normal file
1
apps/icon-pack-builder/boxicons-free/fonts/animations.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
11124
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.css
Normal file
11124
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.css
Normal file
File diff suppressed because it is too large
Load Diff
25720
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.html
Normal file
25720
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.html
Normal file
File diff suppressed because it is too large
Load Diff
3702
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.json
Normal file
3702
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.json
Normal file
File diff suppressed because it is too large
Load Diff
1
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.min.css
vendored
Normal file
1
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.ttf
Normal file
BIN
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.ttf
Normal file
Binary file not shown.
BIN
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.woff
Normal file
BIN
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.woff
Normal file
Binary file not shown.
BIN
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.woff2
Normal file
BIN
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.woff2
Normal file
Binary file not shown.
515
apps/icon-pack-builder/boxicons-free/fonts/brands/animations.css
Normal file
515
apps/icon-pack-builder/boxicons-free/fonts/brands/animations.css
Normal file
@@ -0,0 +1,515 @@
|
||||
@-webkit-keyframes spin
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
100%
|
||||
{
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@keyframes spin
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
100%
|
||||
{
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes burst
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes burst
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes flashing
|
||||
{
|
||||
0%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
45%
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
90%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes flashing
|
||||
{
|
||||
0%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
45%
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
90%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(-20px);
|
||||
transform: translateX(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(-20px);
|
||||
transform: translateX(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-up
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-up
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-down
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(20px);
|
||||
transform: translateY(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-down
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(20px);
|
||||
transform: translateY(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes tada
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
10%,
|
||||
20%
|
||||
{
|
||||
-webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
60%,
|
||||
80%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes tada
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
10%,
|
||||
20%
|
||||
{
|
||||
-webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
60%,
|
||||
80%
|
||||
{
|
||||
-webkit-transform: rotate3d(0, 0, 1, -10deg);
|
||||
transform: rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
@keyframes beat {
|
||||
to {
|
||||
-webkit-transform: scale(1.4);
|
||||
transform: scale(1.4);
|
||||
}
|
||||
|
||||
}
|
||||
@keyframes bounce
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale(1.1,1);
|
||||
transform: scale(1.1,1);
|
||||
}
|
||||
|
||||
25%
|
||||
{
|
||||
-webkit-transform: scale(0.9,1) translateY(-.25em);
|
||||
transform: scale(0.9,1) translateY(-.25em);
|
||||
}
|
||||
|
||||
50%
|
||||
{
|
||||
-webkit-transform: scale(1.1,0.9);
|
||||
transform: scale(1.1,0.9);
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: scale(1, 1);
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
87.5%
|
||||
{
|
||||
-webkit-transform: scale(1, 1) translateY(-.1em);
|
||||
transform: scale(1, 1) translateY(-.1em);
|
||||
}
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale(1, 1);
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
}
|
||||
@keyframes breathe {
|
||||
from{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
50%{
|
||||
-webkit-transform: scale(1.4);
|
||||
transform: scale(1.4);
|
||||
opacity: 0.4;
|
||||
}
|
||||
to {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
}
|
||||
@keyframes wiggle {
|
||||
from{
|
||||
-webkit-transform: translateX(0);
|
||||
transform:translateX(0);
|
||||
}
|
||||
30%{
|
||||
-webkit-transform: translateX(0.075em);
|
||||
transform: translateX(0.075em);
|
||||
}
|
||||
60%{
|
||||
-webkit-transform: translateX(-0.075em);
|
||||
transform: translateX(-0.075em);
|
||||
}
|
||||
75%{
|
||||
-webkit-transform: translateX(0.025em);
|
||||
transform: translateX(0.025em);
|
||||
}
|
||||
90%{
|
||||
-webkit-transform: translateX(-0.025em);
|
||||
transform: translateX(-0.025em);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translateX(0);
|
||||
transform:translateX(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.bx-wiggle{
|
||||
-webkit-animation: wiggle 1s infinite;
|
||||
animation: wiggle 1s infinite;
|
||||
animation-timing-function:cubic-bezier(.23,.57,.79,.58);
|
||||
}
|
||||
.bx-wiggle-hover:hover{
|
||||
-webkit-animation: wiggle 1s infinite;
|
||||
animation: wiggle 1s infinite;
|
||||
animation-timing-function:cubic-bezier(.23,.57,.79,.58);
|
||||
}
|
||||
.bx-breathe{
|
||||
-webkit-animation: breathe 3s infinite;
|
||||
animation: breathe 3s infinite ease-in-out;
|
||||
|
||||
}
|
||||
.bx-breathe-hover:hover
|
||||
{
|
||||
-webkit-animation: breathe 3s infinite;
|
||||
animation: breathe 3s infinite ease-in-out;
|
||||
}
|
||||
.bx-bounce{
|
||||
-webkit-animation: bounce 1s infinite;
|
||||
animation: bounce 1s infinite;
|
||||
animation-timing-function: cubic-bezier(.98,.97,.64,1.62);
|
||||
}
|
||||
.bx-bounce-hover:hover
|
||||
{
|
||||
-webkit-animation: bounce 1s infinite;
|
||||
animation: bounce 1s infinite;
|
||||
animation-timing-function: cubic-bezier(.98,.97,.64,1.62);
|
||||
}
|
||||
|
||||
.bx-beat
|
||||
{
|
||||
-webkit-animation: beat .5s infinite alternate;
|
||||
animation: beat .5s infinite alternate;
|
||||
animation-timing-function: cubic-bezier(.19,.96,.65,1);
|
||||
transform-origin: center;
|
||||
}
|
||||
.bx-spin
|
||||
{
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
.bx-spin-hover:hover
|
||||
{
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.bx-tada
|
||||
{
|
||||
-webkit-animation: tada 1.5s ease infinite;
|
||||
animation: tada 1.5s ease infinite;
|
||||
}
|
||||
.bx-tada-hover:hover
|
||||
{
|
||||
-webkit-animation: tada 1.5s ease infinite;
|
||||
animation: tada 1.5s ease infinite;
|
||||
}
|
||||
|
||||
.bx-flashing
|
||||
{
|
||||
-webkit-animation: flashing 1.5s infinite linear;
|
||||
animation: flashing 1.5s infinite linear;
|
||||
}
|
||||
.bx-flashing-hover:hover
|
||||
{
|
||||
-webkit-animation: flashing 1.5s infinite linear;
|
||||
animation: flashing 1.5s infinite linear;
|
||||
}
|
||||
|
||||
.bx-burst
|
||||
{
|
||||
-webkit-animation: burst 1.5s infinite linear;
|
||||
animation: burst 1.5s infinite linear;
|
||||
}
|
||||
.bx-burst-hover:hover
|
||||
{
|
||||
-webkit-animation: burst 1.5s infinite linear;
|
||||
animation: burst 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-up
|
||||
{
|
||||
-webkit-animation: fade-up 1.5s infinite linear;
|
||||
animation: fade-up 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-up-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-up 1.5s infinite linear;
|
||||
animation: fade-up 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-down
|
||||
{
|
||||
-webkit-animation: fade-down 1.5s infinite linear;
|
||||
animation: fade-down 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-down-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-down 1.5s infinite linear;
|
||||
animation: fade-down 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-left
|
||||
{
|
||||
-webkit-animation: fade-left 1.5s infinite linear;
|
||||
animation: fade-left 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-left-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-left 1.5s infinite linear;
|
||||
animation: fade-left 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-right
|
||||
{
|
||||
-webkit-animation: fade-right 1.5s infinite linear;
|
||||
animation: fade-right 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-right-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-right 1.5s infinite linear;
|
||||
animation: fade-right 1.5s infinite linear;
|
||||
}
|
||||
@@ -0,0 +1,906 @@
|
||||
@font-face {
|
||||
font-family: "boxicons-brands";
|
||||
src: url("./boxicons-brands.ttf?945bfe89057cc7627be1ecdc648441aa") format("truetype"),
|
||||
url("./boxicons-brands.woff?945bfe89057cc7627be1ecdc648441aa") format("woff"),
|
||||
url("./boxicons-brands.woff2?945bfe89057cc7627be1ecdc648441aa") format("woff2");
|
||||
}
|
||||
|
||||
|
||||
.bxl {
|
||||
font-family: boxicons-brands !important;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
display:inline-block;
|
||||
speak:none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.bxl.variable-selector-00:before {
|
||||
content: "\fb1e";
|
||||
}
|
||||
.bxl.bx-500px:before {
|
||||
content: "\f101";
|
||||
}
|
||||
.bxl.bx-99designs:before {
|
||||
content: "\f102";
|
||||
}
|
||||
.bxl.bx-adobe:before {
|
||||
content: "\f103";
|
||||
}
|
||||
.bxl.bx-airbnb:before {
|
||||
content: "\f104";
|
||||
}
|
||||
.bxl.bx-algolia:before {
|
||||
content: "\f105";
|
||||
}
|
||||
.bxl.bx-amazon:before {
|
||||
content: "\f106";
|
||||
}
|
||||
.bxl.bx-amex:before {
|
||||
content: "\f107";
|
||||
}
|
||||
.bxl.bx-android:before {
|
||||
content: "\f108";
|
||||
}
|
||||
.bxl.bx-angular:before {
|
||||
content: "\f109";
|
||||
}
|
||||
.bxl.bx-anthropic:before {
|
||||
content: "\f10a";
|
||||
}
|
||||
.bxl.bx-apple-music:before {
|
||||
content: "\f10b";
|
||||
}
|
||||
.bxl.bx-apple:before {
|
||||
content: "\f10c";
|
||||
}
|
||||
.bxl.bx-arc-browser:before {
|
||||
content: "\f10d";
|
||||
}
|
||||
.bxl.bx-artstation:before {
|
||||
content: "\f10e";
|
||||
}
|
||||
.bxl.bx-asana:before {
|
||||
content: "\f10f";
|
||||
}
|
||||
.bxl.bx-atlassian:before {
|
||||
content: "\f110";
|
||||
}
|
||||
.bxl.bx-atom-editor:before {
|
||||
content: "\f111";
|
||||
}
|
||||
.bxl.bx-audible:before {
|
||||
content: "\f112";
|
||||
}
|
||||
.bxl.bx-auth0:before {
|
||||
content: "\f113";
|
||||
}
|
||||
.bxl.bx-autodesk:before {
|
||||
content: "\f114";
|
||||
}
|
||||
.bxl.bx-aws:before {
|
||||
content: "\f115";
|
||||
}
|
||||
.bxl.bx-baidu:before {
|
||||
content: "\f116";
|
||||
}
|
||||
.bxl.bx-bash:before {
|
||||
content: "\f117";
|
||||
}
|
||||
.bxl.bx-behance:before {
|
||||
content: "\f118";
|
||||
}
|
||||
.bxl.bx-better-auth:before {
|
||||
content: "\f119";
|
||||
}
|
||||
.bxl.bx-bing:before {
|
||||
content: "\f11a";
|
||||
}
|
||||
.bxl.bx-bitcoin-logo:before {
|
||||
content: "\f11b";
|
||||
}
|
||||
.bxl.bx-blender:before {
|
||||
content: "\f11c";
|
||||
}
|
||||
.bxl.bx-blogger:before {
|
||||
content: "\f11d";
|
||||
}
|
||||
.bxl.bx-bluesky:before {
|
||||
content: "\f11e";
|
||||
}
|
||||
.bxl.bx-bolt-b:before {
|
||||
content: "\f11f";
|
||||
}
|
||||
.bxl.bx-bootstrap:before {
|
||||
content: "\f120";
|
||||
}
|
||||
.bxl.bx-boxicons:before {
|
||||
content: "\f121";
|
||||
}
|
||||
.bxl.bx-brave-browser:before {
|
||||
content: "\f122";
|
||||
}
|
||||
.bxl.bx-bun:before {
|
||||
content: "\f123";
|
||||
}
|
||||
.bxl.bx-buy-me-a-coffee:before {
|
||||
content: "\f124";
|
||||
}
|
||||
.bxl.bx-c-plus-plus:before {
|
||||
content: "\f125";
|
||||
}
|
||||
.bxl.bx-c-sharp:before {
|
||||
content: "\f126";
|
||||
}
|
||||
.bxl.bx-c:before {
|
||||
content: "\f127";
|
||||
}
|
||||
.bxl.bx-canva:before {
|
||||
content: "\f128";
|
||||
}
|
||||
.bxl.bx-chess-com:before {
|
||||
content: "\f129";
|
||||
}
|
||||
.bxl.bx-chrome:before {
|
||||
content: "\f12a";
|
||||
}
|
||||
.bxl.bx-claude-ai:before {
|
||||
content: "\f12b";
|
||||
}
|
||||
.bxl.bx-clerk:before {
|
||||
content: "\f12c";
|
||||
}
|
||||
.bxl.bx-cloudflare:before {
|
||||
content: "\f12d";
|
||||
}
|
||||
.bxl.bx-codepen:before {
|
||||
content: "\f12e";
|
||||
}
|
||||
.bxl.bx-convex:before {
|
||||
content: "\f12f";
|
||||
}
|
||||
.bxl.bx-creative-commons:before {
|
||||
content: "\f130";
|
||||
}
|
||||
.bxl.bx-crunchyroll:before {
|
||||
content: "\f131";
|
||||
}
|
||||
.bxl.bx-css3:before {
|
||||
content: "\f132";
|
||||
}
|
||||
.bxl.bx-cursor-ai:before {
|
||||
content: "\f133";
|
||||
}
|
||||
.bxl.bx-dailymotion:before {
|
||||
content: "\f134";
|
||||
}
|
||||
.bxl.bx-deepmind:before {
|
||||
content: "\f135";
|
||||
}
|
||||
.bxl.bx-deepseek:before {
|
||||
content: "\f136";
|
||||
}
|
||||
.bxl.bx-deezer:before {
|
||||
content: "\f137";
|
||||
}
|
||||
.bxl.bx-deno:before {
|
||||
content: "\f138";
|
||||
}
|
||||
.bxl.bx-dev-to:before {
|
||||
content: "\f139";
|
||||
}
|
||||
.bxl.bx-deviantart:before {
|
||||
content: "\f13a";
|
||||
}
|
||||
.bxl.bx-devpost:before {
|
||||
content: "\f13b";
|
||||
}
|
||||
.bxl.bx-digg:before {
|
||||
content: "\f13c";
|
||||
}
|
||||
.bxl.bx-digitalocean:before {
|
||||
content: "\f13d";
|
||||
}
|
||||
.bxl.bx-discord-alt:before {
|
||||
content: "\f13e";
|
||||
}
|
||||
.bxl.bx-discord:before {
|
||||
content: "\f13f";
|
||||
}
|
||||
.bxl.bx-discourse:before {
|
||||
content: "\f140";
|
||||
}
|
||||
.bxl.bx-discover:before {
|
||||
content: "\f141";
|
||||
}
|
||||
.bxl.bx-django:before {
|
||||
content: "\f142";
|
||||
}
|
||||
.bxl.bx-docker:before {
|
||||
content: "\f143";
|
||||
}
|
||||
.bxl.bx-dot-env:before {
|
||||
content: "\f144";
|
||||
}
|
||||
.bxl.bx-dribbble:before {
|
||||
content: "\f145";
|
||||
}
|
||||
.bxl.bx-drizzle-orm:before {
|
||||
content: "\f146";
|
||||
}
|
||||
.bxl.bx-dropbox:before {
|
||||
content: "\f147";
|
||||
}
|
||||
.bxl.bx-ebay:before {
|
||||
content: "\f148";
|
||||
}
|
||||
.bxl.bx-edge:before {
|
||||
content: "\f149";
|
||||
}
|
||||
.bxl.bx-ember-js:before {
|
||||
content: "\f14a";
|
||||
}
|
||||
.bxl.bx-etsy:before {
|
||||
content: "\f14b";
|
||||
}
|
||||
.bxl.bx-expo:before {
|
||||
content: "\f14c";
|
||||
}
|
||||
.bxl.bx-express-js:before {
|
||||
content: "\f14d";
|
||||
}
|
||||
.bxl.bx-facebook-circle:before {
|
||||
content: "\f14e";
|
||||
}
|
||||
.bxl.bx-facebook-square:before {
|
||||
content: "\f14f";
|
||||
}
|
||||
.bxl.bx-facebook:before {
|
||||
content: "\f150";
|
||||
}
|
||||
.bxl.bx-fastapi:before {
|
||||
content: "\f151";
|
||||
}
|
||||
.bxl.bx-fastify:before {
|
||||
content: "\f152";
|
||||
}
|
||||
.bxl.bx-figma-alt:before {
|
||||
content: "\f153";
|
||||
}
|
||||
.bxl.bx-figma:before {
|
||||
content: "\f154";
|
||||
}
|
||||
.bxl.bx-firebase:before {
|
||||
content: "\f155";
|
||||
}
|
||||
.bxl.bx-firefox:before {
|
||||
content: "\f156";
|
||||
}
|
||||
.bxl.bx-fiverr:before {
|
||||
content: "\f157";
|
||||
}
|
||||
.bxl.bx-flask-old:before {
|
||||
content: "\f158";
|
||||
}
|
||||
.bxl.bx-flask:before {
|
||||
content: "\f159";
|
||||
}
|
||||
.bxl.bx-flickr-square:before {
|
||||
content: "\f15a";
|
||||
}
|
||||
.bxl.bx-flickr:before {
|
||||
content: "\f15b";
|
||||
}
|
||||
.bxl.bx-flutter:before {
|
||||
content: "\f15c";
|
||||
}
|
||||
.bxl.bx-foursquare:before {
|
||||
content: "\f15d";
|
||||
}
|
||||
.bxl.bx-framer:before {
|
||||
content: "\f15e";
|
||||
}
|
||||
.bxl.bx-gatsby-js:before {
|
||||
content: "\f15f";
|
||||
}
|
||||
.bxl.bx-gemini:before {
|
||||
content: "\f160";
|
||||
}
|
||||
.bxl.bx-git:before {
|
||||
content: "\f161";
|
||||
}
|
||||
.bxl.bx-github-copilot:before {
|
||||
content: "\f162";
|
||||
}
|
||||
.bxl.bx-github:before {
|
||||
content: "\f163";
|
||||
}
|
||||
.bxl.bx-gitlab:before {
|
||||
content: "\f164";
|
||||
}
|
||||
.bxl.bx-gmail:before {
|
||||
content: "\f165";
|
||||
}
|
||||
.bxl.bx-go-lang:before {
|
||||
content: "\f166";
|
||||
}
|
||||
.bxl.bx-google-antigravity:before {
|
||||
content: "\f167";
|
||||
}
|
||||
.bxl.bx-google-cloud:before {
|
||||
content: "\f168";
|
||||
}
|
||||
.bxl.bx-google-pay:before {
|
||||
content: "\f169";
|
||||
}
|
||||
.bxl.bx-google:before {
|
||||
content: "\f16a";
|
||||
}
|
||||
.bxl.bx-graphql:before {
|
||||
content: "\f16b";
|
||||
}
|
||||
.bxl.bx-grok:before {
|
||||
content: "\f16c";
|
||||
}
|
||||
.bxl.bx-groq-ai:before {
|
||||
content: "\f16d";
|
||||
}
|
||||
.bxl.bx-gsap:before {
|
||||
content: "\f16e";
|
||||
}
|
||||
.bxl.bx-gumroad:before {
|
||||
content: "\f16f";
|
||||
}
|
||||
.bxl.bx-hashnode:before {
|
||||
content: "\f170";
|
||||
}
|
||||
.bxl.bx-hcaptcha:before {
|
||||
content: "\f171";
|
||||
}
|
||||
.bxl.bx-heroku:before {
|
||||
content: "\f172";
|
||||
}
|
||||
.bxl.bx-hono-js:before {
|
||||
content: "\f173";
|
||||
}
|
||||
.bxl.bx-html5:before {
|
||||
content: "\f174";
|
||||
}
|
||||
.bxl.bx-hugo:before {
|
||||
content: "\f175";
|
||||
}
|
||||
.bxl.bx-ibm:before {
|
||||
content: "\f176";
|
||||
}
|
||||
.bxl.bx-imdb:before {
|
||||
content: "\f177";
|
||||
}
|
||||
.bxl.bx-instagram-alt:before {
|
||||
content: "\f178";
|
||||
}
|
||||
.bxl.bx-instagram:before {
|
||||
content: "\f179";
|
||||
}
|
||||
.bxl.bx-internet-explorer:before {
|
||||
content: "\f17a";
|
||||
}
|
||||
.bxl.bx-invision:before {
|
||||
content: "\f17b";
|
||||
}
|
||||
.bxl.bx-java:before {
|
||||
content: "\f17c";
|
||||
}
|
||||
.bxl.bx-javascript:before {
|
||||
content: "\f17d";
|
||||
}
|
||||
.bxl.bx-joomla:before {
|
||||
content: "\f17e";
|
||||
}
|
||||
.bxl.bx-jquery:before {
|
||||
content: "\f17f";
|
||||
}
|
||||
.bxl.bx-jsfiddle:before {
|
||||
content: "\f180";
|
||||
}
|
||||
.bxl.bx-jwt:before {
|
||||
content: "\f181";
|
||||
}
|
||||
.bxl.bx-kick:before {
|
||||
content: "\f182";
|
||||
}
|
||||
.bxl.bx-kickstarter:before {
|
||||
content: "\f183";
|
||||
}
|
||||
.bxl.bx-kotlin:before {
|
||||
content: "\f184";
|
||||
}
|
||||
.bxl.bx-kubernetes:before {
|
||||
content: "\f185";
|
||||
}
|
||||
.bxl.bx-laravel:before {
|
||||
content: "\f186";
|
||||
}
|
||||
.bxl.bx-leetcode:before {
|
||||
content: "\f187";
|
||||
}
|
||||
.bxl.bx-lemon-squeezy:before {
|
||||
content: "\f188";
|
||||
}
|
||||
.bxl.bx-less:before {
|
||||
content: "\f189";
|
||||
}
|
||||
.bxl.bx-letterboxd:before {
|
||||
content: "\f18a";
|
||||
}
|
||||
.bxl.bx-lichess:before {
|
||||
content: "\f18b";
|
||||
}
|
||||
.bxl.bx-line-chat:before {
|
||||
content: "\f18c";
|
||||
}
|
||||
.bxl.bx-linear-app:before {
|
||||
content: "\f18d";
|
||||
}
|
||||
.bxl.bx-linkedin-square:before {
|
||||
content: "\f18e";
|
||||
}
|
||||
.bxl.bx-linkedin:before {
|
||||
content: "\f18f";
|
||||
}
|
||||
.bxl.bx-linktree:before {
|
||||
content: "\f190";
|
||||
}
|
||||
.bxl.bx-loom:before {
|
||||
content: "\f191";
|
||||
}
|
||||
.bxl.bx-lottie-files:before {
|
||||
content: "\f192";
|
||||
}
|
||||
.bxl.bx-lottie-lab:before {
|
||||
content: "\f193";
|
||||
}
|
||||
.bxl.bx-lovable:before {
|
||||
content: "\f194";
|
||||
}
|
||||
.bxl.bx-lyft:before {
|
||||
content: "\f195";
|
||||
}
|
||||
.bxl.bx-magento:before {
|
||||
content: "\f196";
|
||||
}
|
||||
.bxl.bx-mailchimp:before {
|
||||
content: "\f197";
|
||||
}
|
||||
.bxl.bx-markdown:before {
|
||||
content: "\f198";
|
||||
}
|
||||
.bxl.bx-mastercard:before {
|
||||
content: "\f199";
|
||||
}
|
||||
.bxl.bx-mastodon:before {
|
||||
content: "\f19a";
|
||||
}
|
||||
.bxl.bx-mcp:before {
|
||||
content: "\f19b";
|
||||
}
|
||||
.bxl.bx-medium-old:before {
|
||||
content: "\f19c";
|
||||
}
|
||||
.bxl.bx-medium-square:before {
|
||||
content: "\f19d";
|
||||
}
|
||||
.bxl.bx-medium:before {
|
||||
content: "\f19e";
|
||||
}
|
||||
.bxl.bx-messenger:before {
|
||||
content: "\f19f";
|
||||
}
|
||||
.bxl.bx-meta:before {
|
||||
content: "\f1a0";
|
||||
}
|
||||
.bxl.bx-microsoft-teams:before {
|
||||
content: "\f1a1";
|
||||
}
|
||||
.bxl.bx-microsoft-windows:before {
|
||||
content: "\f1a2";
|
||||
}
|
||||
.bxl.bx-microsoft:before {
|
||||
content: "\f1a3";
|
||||
}
|
||||
.bxl.bx-midjourney:before {
|
||||
content: "\f1a4";
|
||||
}
|
||||
.bxl.bx-mongodb:before {
|
||||
content: "\f1a5";
|
||||
}
|
||||
.bxl.bx-motion-js:before {
|
||||
content: "\f1a6";
|
||||
}
|
||||
.bxl.bx-mozilla:before {
|
||||
content: "\f1a7";
|
||||
}
|
||||
.bxl.bx-my-sql:before {
|
||||
content: "\f1a8";
|
||||
}
|
||||
.bxl.bx-neon-tech:before {
|
||||
content: "\f1a9";
|
||||
}
|
||||
.bxl.bx-neovim:before {
|
||||
content: "\f1aa";
|
||||
}
|
||||
.bxl.bx-nest-js:before {
|
||||
content: "\f1ab";
|
||||
}
|
||||
.bxl.bx-netlify:before {
|
||||
content: "\f1ac";
|
||||
}
|
||||
.bxl.bx-next-js:before {
|
||||
content: "\f1ad";
|
||||
}
|
||||
.bxl.bx-nodejs:before {
|
||||
content: "\f1ae";
|
||||
}
|
||||
.bxl.bx-notion:before {
|
||||
content: "\f1af";
|
||||
}
|
||||
.bxl.bx-npm:before {
|
||||
content: "\f1b0";
|
||||
}
|
||||
.bxl.bx-nuxt-js:before {
|
||||
content: "\f1b1";
|
||||
}
|
||||
.bxl.bx-ok-ru:before {
|
||||
content: "\f1b2";
|
||||
}
|
||||
.bxl.bx-ollama:before {
|
||||
content: "\f1b3";
|
||||
}
|
||||
.bxl.bx-openai:before {
|
||||
content: "\f1b4";
|
||||
}
|
||||
.bxl.bx-opensea:before {
|
||||
content: "\f1b5";
|
||||
}
|
||||
.bxl.bx-opera:before {
|
||||
content: "\f1b6";
|
||||
}
|
||||
.bxl.bx-paddle-p:before {
|
||||
content: "\f1b7";
|
||||
}
|
||||
.bxl.bx-paper-design:before {
|
||||
content: "\f1b8";
|
||||
}
|
||||
.bxl.bx-patreon:before {
|
||||
content: "\f1b9";
|
||||
}
|
||||
.bxl.bx-payload-cms:before {
|
||||
content: "\f1ba";
|
||||
}
|
||||
.bxl.bx-paypal:before {
|
||||
content: "\f1bb";
|
||||
}
|
||||
.bxl.bx-periscope:before {
|
||||
content: "\f1bc";
|
||||
}
|
||||
.bxl.bx-perplexity-ai:before {
|
||||
content: "\f1bd";
|
||||
}
|
||||
.bxl.bx-php:before {
|
||||
content: "\f1be";
|
||||
}
|
||||
.bxl.bx-pinterest-alt:before {
|
||||
content: "\f1bf";
|
||||
}
|
||||
.bxl.bx-pinterest:before {
|
||||
content: "\f1c0";
|
||||
}
|
||||
.bxl.bx-planetscale:before {
|
||||
content: "\f1c1";
|
||||
}
|
||||
.bxl.bx-play-store:before {
|
||||
content: "\f1c2";
|
||||
}
|
||||
.bxl.bx-playstation:before {
|
||||
content: "\f1c3";
|
||||
}
|
||||
.bxl.bx-pocket:before {
|
||||
content: "\f1c4";
|
||||
}
|
||||
.bxl.bx-polar:before {
|
||||
content: "\f1c5";
|
||||
}
|
||||
.bxl.bx-postgresql:before {
|
||||
content: "\f1c6";
|
||||
}
|
||||
.bxl.bx-prisma-orm:before {
|
||||
content: "\f1c7";
|
||||
}
|
||||
.bxl.bx-product-hunt:before {
|
||||
content: "\f1c8";
|
||||
}
|
||||
.bxl.bx-python:before {
|
||||
content: "\f1c9";
|
||||
}
|
||||
.bxl.bx-qdrant:before {
|
||||
content: "\f1ca";
|
||||
}
|
||||
.bxl.bx-qq:before {
|
||||
content: "\f1cb";
|
||||
}
|
||||
.bxl.bx-quora:before {
|
||||
content: "\f1cc";
|
||||
}
|
||||
.bxl.bx-radix-ui:before {
|
||||
content: "\f1cd";
|
||||
}
|
||||
.bxl.bx-railway:before {
|
||||
content: "\f1ce";
|
||||
}
|
||||
.bxl.bx-rasberry-pi:before {
|
||||
content: "\f1cf";
|
||||
}
|
||||
.bxl.bx-react-query:before {
|
||||
content: "\f1d0";
|
||||
}
|
||||
.bxl.bx-react-router:before {
|
||||
content: "\f1d1";
|
||||
}
|
||||
.bxl.bx-react:before {
|
||||
content: "\f1d2";
|
||||
}
|
||||
.bxl.bx-redbubble:before {
|
||||
content: "\f1d3";
|
||||
}
|
||||
.bxl.bx-reddit:before {
|
||||
content: "\f1d4";
|
||||
}
|
||||
.bxl.bx-redux:before {
|
||||
content: "\f1d5";
|
||||
}
|
||||
.bxl.bx-remix-js:before {
|
||||
content: "\f1d6";
|
||||
}
|
||||
.bxl.bx-replit:before {
|
||||
content: "\f1d7";
|
||||
}
|
||||
.bxl.bx-resend:before {
|
||||
content: "\f1d8";
|
||||
}
|
||||
.bxl.bx-roblox:before {
|
||||
content: "\f1d9";
|
||||
}
|
||||
.bxl.bx-sanity:before {
|
||||
content: "\f1da";
|
||||
}
|
||||
.bxl.bx-sass:before {
|
||||
content: "\f1db";
|
||||
}
|
||||
.bxl.bx-sentry:before {
|
||||
content: "\f1dc";
|
||||
}
|
||||
.bxl.bx-shadcn-ui:before {
|
||||
content: "\f1dd";
|
||||
}
|
||||
.bxl.bx-shopify:before {
|
||||
content: "\f1de";
|
||||
}
|
||||
.bxl.bx-sketch:before {
|
||||
content: "\f1df";
|
||||
}
|
||||
.bxl.bx-skype:before {
|
||||
content: "\f1e0";
|
||||
}
|
||||
.bxl.bx-slack-old:before {
|
||||
content: "\f1e1";
|
||||
}
|
||||
.bxl.bx-slack:before {
|
||||
content: "\f1e2";
|
||||
}
|
||||
.bxl.bx-snapchat:before {
|
||||
content: "\f1e3";
|
||||
}
|
||||
.bxl.bx-socket-io:before {
|
||||
content: "\f1e4";
|
||||
}
|
||||
.bxl.bx-soundcloud:before {
|
||||
content: "\f1e5";
|
||||
}
|
||||
.bxl.bx-spotify:before {
|
||||
content: "\f1e6";
|
||||
}
|
||||
.bxl.bx-spring-boot:before {
|
||||
content: "\f1e7";
|
||||
}
|
||||
.bxl.bx-squarespace:before {
|
||||
content: "\f1e8";
|
||||
}
|
||||
.bxl.bx-sst:before {
|
||||
content: "\f1e9";
|
||||
}
|
||||
.bxl.bx-stack-overflow:before {
|
||||
content: "\f1ea";
|
||||
}
|
||||
.bxl.bx-stackblitz:before {
|
||||
content: "\f1eb";
|
||||
}
|
||||
.bxl.bx-steam:before {
|
||||
content: "\f1ec";
|
||||
}
|
||||
.bxl.bx-stripe:before {
|
||||
content: "\f1ed";
|
||||
}
|
||||
.bxl.bx-supabase:before {
|
||||
content: "\f1ee";
|
||||
}
|
||||
.bxl.bx-svelte:before {
|
||||
content: "\f1ef";
|
||||
}
|
||||
.bxl.bx-tailwind-css:before {
|
||||
content: "\f1f0";
|
||||
}
|
||||
.bxl.bx-telegram:before {
|
||||
content: "\f1f1";
|
||||
}
|
||||
.bxl.bx-terraform:before {
|
||||
content: "\f1f2";
|
||||
}
|
||||
.bxl.bx-threads:before {
|
||||
content: "\f1f3";
|
||||
}
|
||||
.bxl.bx-three-js:before {
|
||||
content: "\f1f4";
|
||||
}
|
||||
.bxl.bx-tiktok:before {
|
||||
content: "\f1f5";
|
||||
}
|
||||
.bxl.bx-trello:before {
|
||||
content: "\f1f6";
|
||||
}
|
||||
.bxl.bx-trip-advisor:before {
|
||||
content: "\f1f7";
|
||||
}
|
||||
.bxl.bx-trpc:before {
|
||||
content: "\f1f8";
|
||||
}
|
||||
.bxl.bx-trustpilot:before {
|
||||
content: "\f1f9";
|
||||
}
|
||||
.bxl.bx-tumblr:before {
|
||||
content: "\f1fa";
|
||||
}
|
||||
.bxl.bx-tux:before {
|
||||
content: "\f1fb";
|
||||
}
|
||||
.bxl.bx-twitch:before {
|
||||
content: "\f1fc";
|
||||
}
|
||||
.bxl.bx-twitter-x:before {
|
||||
content: "\f1fd";
|
||||
}
|
||||
.bxl.bx-twitter:before {
|
||||
content: "\f1fe";
|
||||
}
|
||||
.bxl.bx-typescript:before {
|
||||
content: "\f1ff";
|
||||
}
|
||||
.bxl.bx-uber:before {
|
||||
content: "\f200";
|
||||
}
|
||||
.bxl.bx-ubuntu:before {
|
||||
content: "\f201";
|
||||
}
|
||||
.bxl.bx-udacity:before {
|
||||
content: "\f202";
|
||||
}
|
||||
.bxl.bx-union-pay:before {
|
||||
content: "\f203";
|
||||
}
|
||||
.bxl.bx-unity:before {
|
||||
content: "\f204";
|
||||
}
|
||||
.bxl.bx-unsplash:before {
|
||||
content: "\f205";
|
||||
}
|
||||
.bxl.bx-upi:before {
|
||||
content: "\f206";
|
||||
}
|
||||
.bxl.bx-upwork:before {
|
||||
content: "\f207";
|
||||
}
|
||||
.bxl.bx-v0:before {
|
||||
content: "\f208";
|
||||
}
|
||||
.bxl.bx-venmo:before {
|
||||
content: "\f209";
|
||||
}
|
||||
.bxl.bx-vercel:before {
|
||||
content: "\f20a";
|
||||
}
|
||||
.bxl.bx-vimeo:before {
|
||||
content: "\f20b";
|
||||
}
|
||||
.bxl.bx-visa:before {
|
||||
content: "\f20c";
|
||||
}
|
||||
.bxl.bx-visual-studio:before {
|
||||
content: "\f20d";
|
||||
}
|
||||
.bxl.bx-vite-js:before {
|
||||
content: "\f20e";
|
||||
}
|
||||
.bxl.bx-vk:before {
|
||||
content: "\f20f";
|
||||
}
|
||||
.bxl.bx-vuejs:before {
|
||||
content: "\f210";
|
||||
}
|
||||
.bxl.bx-waze:before {
|
||||
content: "\f211";
|
||||
}
|
||||
.bxl.bx-web-components:before {
|
||||
content: "\f212";
|
||||
}
|
||||
.bxl.bx-webflow:before {
|
||||
content: "\f213";
|
||||
}
|
||||
.bxl.bx-wechat:before {
|
||||
content: "\f214";
|
||||
}
|
||||
.bxl.bx-weibo:before {
|
||||
content: "\f215";
|
||||
}
|
||||
.bxl.bx-whatsapp-square:before {
|
||||
content: "\f216";
|
||||
}
|
||||
.bxl.bx-whatsapp:before {
|
||||
content: "\f217";
|
||||
}
|
||||
.bxl.bx-wikipedia:before {
|
||||
content: "\f218";
|
||||
}
|
||||
.bxl.bx-windsurf:before {
|
||||
content: "\f219";
|
||||
}
|
||||
.bxl.bx-wix:before {
|
||||
content: "\f21a";
|
||||
}
|
||||
.bxl.bx-wordpress:before {
|
||||
content: "\f21b";
|
||||
}
|
||||
.bxl.bx-work-os:before {
|
||||
content: "\f21c";
|
||||
}
|
||||
.bxl.bx-xai:before {
|
||||
content: "\f21d";
|
||||
}
|
||||
.bxl.bx-xbox:before {
|
||||
content: "\f21e";
|
||||
}
|
||||
.bxl.bx-xing:before {
|
||||
content: "\f21f";
|
||||
}
|
||||
.bxl.bx-yahoo:before {
|
||||
content: "\f220";
|
||||
}
|
||||
.bxl.bx-yarn:before {
|
||||
content: "\f221";
|
||||
}
|
||||
.bxl.bx-yelp:before {
|
||||
content: "\f222";
|
||||
}
|
||||
.bxl.bx-youtube-music:before {
|
||||
content: "\f223";
|
||||
}
|
||||
.bxl.bx-youtube:before {
|
||||
content: "\f224";
|
||||
}
|
||||
.bxl.bx-zen-browser:before {
|
||||
content: "\f225";
|
||||
}
|
||||
.bxl.bx-zoom-workplace:before {
|
||||
content: "\f226";
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,297 @@
|
||||
{
|
||||
"variable-selector-00": 64286,
|
||||
"bx-500px": 61697,
|
||||
"bx-99designs": 61698,
|
||||
"bx-adobe": 61699,
|
||||
"bx-airbnb": 61700,
|
||||
"bx-algolia": 61701,
|
||||
"bx-amazon": 61702,
|
||||
"bx-amex": 61703,
|
||||
"bx-android": 61704,
|
||||
"bx-angular": 61705,
|
||||
"bx-anthropic": 61706,
|
||||
"bx-apple-music": 61707,
|
||||
"bx-apple": 61708,
|
||||
"bx-arc-browser": 61709,
|
||||
"bx-artstation": 61710,
|
||||
"bx-asana": 61711,
|
||||
"bx-atlassian": 61712,
|
||||
"bx-atom-editor": 61713,
|
||||
"bx-audible": 61714,
|
||||
"bx-auth0": 61715,
|
||||
"bx-autodesk": 61716,
|
||||
"bx-aws": 61717,
|
||||
"bx-baidu": 61718,
|
||||
"bx-bash": 61719,
|
||||
"bx-behance": 61720,
|
||||
"bx-better-auth": 61721,
|
||||
"bx-bing": 61722,
|
||||
"bx-bitcoin-logo": 61723,
|
||||
"bx-blender": 61724,
|
||||
"bx-blogger": 61725,
|
||||
"bx-bluesky": 61726,
|
||||
"bx-bolt-b": 61727,
|
||||
"bx-bootstrap": 61728,
|
||||
"bx-boxicons": 61729,
|
||||
"bx-brave-browser": 61730,
|
||||
"bx-bun": 61731,
|
||||
"bx-buy-me-a-coffee": 61732,
|
||||
"bx-c-plus-plus": 61733,
|
||||
"bx-c-sharp": 61734,
|
||||
"bx-c": 61735,
|
||||
"bx-canva": 61736,
|
||||
"bx-chess-com": 61737,
|
||||
"bx-chrome": 61738,
|
||||
"bx-claude-ai": 61739,
|
||||
"bx-clerk": 61740,
|
||||
"bx-cloudflare": 61741,
|
||||
"bx-codepen": 61742,
|
||||
"bx-convex": 61743,
|
||||
"bx-creative-commons": 61744,
|
||||
"bx-crunchyroll": 61745,
|
||||
"bx-css3": 61746,
|
||||
"bx-cursor-ai": 61747,
|
||||
"bx-dailymotion": 61748,
|
||||
"bx-deepmind": 61749,
|
||||
"bx-deepseek": 61750,
|
||||
"bx-deezer": 61751,
|
||||
"bx-deno": 61752,
|
||||
"bx-dev-to": 61753,
|
||||
"bx-deviantart": 61754,
|
||||
"bx-devpost": 61755,
|
||||
"bx-digg": 61756,
|
||||
"bx-digitalocean": 61757,
|
||||
"bx-discord-alt": 61758,
|
||||
"bx-discord": 61759,
|
||||
"bx-discourse": 61760,
|
||||
"bx-discover": 61761,
|
||||
"bx-django": 61762,
|
||||
"bx-docker": 61763,
|
||||
"bx-dot-env": 61764,
|
||||
"bx-dribbble": 61765,
|
||||
"bx-drizzle-orm": 61766,
|
||||
"bx-dropbox": 61767,
|
||||
"bx-ebay": 61768,
|
||||
"bx-edge": 61769,
|
||||
"bx-ember-js": 61770,
|
||||
"bx-etsy": 61771,
|
||||
"bx-expo": 61772,
|
||||
"bx-express-js": 61773,
|
||||
"bx-facebook-circle": 61774,
|
||||
"bx-facebook-square": 61775,
|
||||
"bx-facebook": 61776,
|
||||
"bx-fastapi": 61777,
|
||||
"bx-fastify": 61778,
|
||||
"bx-figma-alt": 61779,
|
||||
"bx-figma": 61780,
|
||||
"bx-firebase": 61781,
|
||||
"bx-firefox": 61782,
|
||||
"bx-fiverr": 61783,
|
||||
"bx-flask-old": 61784,
|
||||
"bx-flask": 61785,
|
||||
"bx-flickr-square": 61786,
|
||||
"bx-flickr": 61787,
|
||||
"bx-flutter": 61788,
|
||||
"bx-foursquare": 61789,
|
||||
"bx-framer": 61790,
|
||||
"bx-gatsby-js": 61791,
|
||||
"bx-gemini": 61792,
|
||||
"bx-git": 61793,
|
||||
"bx-github-copilot": 61794,
|
||||
"bx-github": 61795,
|
||||
"bx-gitlab": 61796,
|
||||
"bx-gmail": 61797,
|
||||
"bx-go-lang": 61798,
|
||||
"bx-google-antigravity": 61799,
|
||||
"bx-google-cloud": 61800,
|
||||
"bx-google-pay": 61801,
|
||||
"bx-google": 61802,
|
||||
"bx-graphql": 61803,
|
||||
"bx-grok": 61804,
|
||||
"bx-groq-ai": 61805,
|
||||
"bx-gsap": 61806,
|
||||
"bx-gumroad": 61807,
|
||||
"bx-hashnode": 61808,
|
||||
"bx-hcaptcha": 61809,
|
||||
"bx-heroku": 61810,
|
||||
"bx-hono-js": 61811,
|
||||
"bx-html5": 61812,
|
||||
"bx-hugo": 61813,
|
||||
"bx-ibm": 61814,
|
||||
"bx-imdb": 61815,
|
||||
"bx-instagram-alt": 61816,
|
||||
"bx-instagram": 61817,
|
||||
"bx-internet-explorer": 61818,
|
||||
"bx-invision": 61819,
|
||||
"bx-java": 61820,
|
||||
"bx-javascript": 61821,
|
||||
"bx-joomla": 61822,
|
||||
"bx-jquery": 61823,
|
||||
"bx-jsfiddle": 61824,
|
||||
"bx-jwt": 61825,
|
||||
"bx-kick": 61826,
|
||||
"bx-kickstarter": 61827,
|
||||
"bx-kotlin": 61828,
|
||||
"bx-kubernetes": 61829,
|
||||
"bx-laravel": 61830,
|
||||
"bx-leetcode": 61831,
|
||||
"bx-lemon-squeezy": 61832,
|
||||
"bx-less": 61833,
|
||||
"bx-letterboxd": 61834,
|
||||
"bx-lichess": 61835,
|
||||
"bx-line-chat": 61836,
|
||||
"bx-linear-app": 61837,
|
||||
"bx-linkedin-square": 61838,
|
||||
"bx-linkedin": 61839,
|
||||
"bx-linktree": 61840,
|
||||
"bx-loom": 61841,
|
||||
"bx-lottie-files": 61842,
|
||||
"bx-lottie-lab": 61843,
|
||||
"bx-lovable": 61844,
|
||||
"bx-lyft": 61845,
|
||||
"bx-magento": 61846,
|
||||
"bx-mailchimp": 61847,
|
||||
"bx-markdown": 61848,
|
||||
"bx-mastercard": 61849,
|
||||
"bx-mastodon": 61850,
|
||||
"bx-mcp": 61851,
|
||||
"bx-medium-old": 61852,
|
||||
"bx-medium-square": 61853,
|
||||
"bx-medium": 61854,
|
||||
"bx-messenger": 61855,
|
||||
"bx-meta": 61856,
|
||||
"bx-microsoft-teams": 61857,
|
||||
"bx-microsoft-windows": 61858,
|
||||
"bx-microsoft": 61859,
|
||||
"bx-midjourney": 61860,
|
||||
"bx-mongodb": 61861,
|
||||
"bx-motion-js": 61862,
|
||||
"bx-mozilla": 61863,
|
||||
"bx-my-sql": 61864,
|
||||
"bx-neon-tech": 61865,
|
||||
"bx-neovim": 61866,
|
||||
"bx-nest-js": 61867,
|
||||
"bx-netlify": 61868,
|
||||
"bx-next-js": 61869,
|
||||
"bx-nodejs": 61870,
|
||||
"bx-notion": 61871,
|
||||
"bx-npm": 61872,
|
||||
"bx-nuxt-js": 61873,
|
||||
"bx-ok-ru": 61874,
|
||||
"bx-ollama": 61875,
|
||||
"bx-openai": 61876,
|
||||
"bx-opensea": 61877,
|
||||
"bx-opera": 61878,
|
||||
"bx-paddle-p": 61879,
|
||||
"bx-paper-design": 61880,
|
||||
"bx-patreon": 61881,
|
||||
"bx-payload-cms": 61882,
|
||||
"bx-paypal": 61883,
|
||||
"bx-periscope": 61884,
|
||||
"bx-perplexity-ai": 61885,
|
||||
"bx-php": 61886,
|
||||
"bx-pinterest-alt": 61887,
|
||||
"bx-pinterest": 61888,
|
||||
"bx-planetscale": 61889,
|
||||
"bx-play-store": 61890,
|
||||
"bx-playstation": 61891,
|
||||
"bx-pocket": 61892,
|
||||
"bx-polar": 61893,
|
||||
"bx-postgresql": 61894,
|
||||
"bx-prisma-orm": 61895,
|
||||
"bx-product-hunt": 61896,
|
||||
"bx-python": 61897,
|
||||
"bx-qdrant": 61898,
|
||||
"bx-qq": 61899,
|
||||
"bx-quora": 61900,
|
||||
"bx-radix-ui": 61901,
|
||||
"bx-railway": 61902,
|
||||
"bx-rasberry-pi": 61903,
|
||||
"bx-react-query": 61904,
|
||||
"bx-react-router": 61905,
|
||||
"bx-react": 61906,
|
||||
"bx-redbubble": 61907,
|
||||
"bx-reddit": 61908,
|
||||
"bx-redux": 61909,
|
||||
"bx-remix-js": 61910,
|
||||
"bx-replit": 61911,
|
||||
"bx-resend": 61912,
|
||||
"bx-roblox": 61913,
|
||||
"bx-sanity": 61914,
|
||||
"bx-sass": 61915,
|
||||
"bx-sentry": 61916,
|
||||
"bx-shadcn-ui": 61917,
|
||||
"bx-shopify": 61918,
|
||||
"bx-sketch": 61919,
|
||||
"bx-skype": 61920,
|
||||
"bx-slack-old": 61921,
|
||||
"bx-slack": 61922,
|
||||
"bx-snapchat": 61923,
|
||||
"bx-socket-io": 61924,
|
||||
"bx-soundcloud": 61925,
|
||||
"bx-spotify": 61926,
|
||||
"bx-spring-boot": 61927,
|
||||
"bx-squarespace": 61928,
|
||||
"bx-sst": 61929,
|
||||
"bx-stack-overflow": 61930,
|
||||
"bx-stackblitz": 61931,
|
||||
"bx-steam": 61932,
|
||||
"bx-stripe": 61933,
|
||||
"bx-supabase": 61934,
|
||||
"bx-svelte": 61935,
|
||||
"bx-tailwind-css": 61936,
|
||||
"bx-telegram": 61937,
|
||||
"bx-terraform": 61938,
|
||||
"bx-threads": 61939,
|
||||
"bx-three-js": 61940,
|
||||
"bx-tiktok": 61941,
|
||||
"bx-trello": 61942,
|
||||
"bx-trip-advisor": 61943,
|
||||
"bx-trpc": 61944,
|
||||
"bx-trustpilot": 61945,
|
||||
"bx-tumblr": 61946,
|
||||
"bx-tux": 61947,
|
||||
"bx-twitch": 61948,
|
||||
"bx-twitter-x": 61949,
|
||||
"bx-twitter": 61950,
|
||||
"bx-typescript": 61951,
|
||||
"bx-uber": 61952,
|
||||
"bx-ubuntu": 61953,
|
||||
"bx-udacity": 61954,
|
||||
"bx-union-pay": 61955,
|
||||
"bx-unity": 61956,
|
||||
"bx-unsplash": 61957,
|
||||
"bx-upi": 61958,
|
||||
"bx-upwork": 61959,
|
||||
"bx-v0": 61960,
|
||||
"bx-venmo": 61961,
|
||||
"bx-vercel": 61962,
|
||||
"bx-vimeo": 61963,
|
||||
"bx-visa": 61964,
|
||||
"bx-visual-studio": 61965,
|
||||
"bx-vite-js": 61966,
|
||||
"bx-vk": 61967,
|
||||
"bx-vuejs": 61968,
|
||||
"bx-waze": 61969,
|
||||
"bx-web-components": 61970,
|
||||
"bx-webflow": 61971,
|
||||
"bx-wechat": 61972,
|
||||
"bx-weibo": 61973,
|
||||
"bx-whatsapp-square": 61974,
|
||||
"bx-whatsapp": 61975,
|
||||
"bx-wikipedia": 61976,
|
||||
"bx-windsurf": 61977,
|
||||
"bx-wix": 61978,
|
||||
"bx-wordpress": 61979,
|
||||
"bx-work-os": 61980,
|
||||
"bx-xai": 61981,
|
||||
"bx-xbox": 61982,
|
||||
"bx-xing": 61983,
|
||||
"bx-yahoo": 61984,
|
||||
"bx-yarn": 61985,
|
||||
"bx-yelp": 61986,
|
||||
"bx-youtube-music": 61987,
|
||||
"bx-youtube": 61988,
|
||||
"bx-zen-browser": 61989,
|
||||
"bx-zoom-workplace": 61990
|
||||
}
|
||||
1
apps/icon-pack-builder/boxicons-free/fonts/brands/boxicons-brands.min.css
vendored
Normal file
1
apps/icon-pack-builder/boxicons-free/fonts/brands/boxicons-brands.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,108 @@
|
||||
.bx-rotate-90
|
||||
{
|
||||
transform: rotate(90deg);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=1)';
|
||||
}
|
||||
.bx-rotate-180
|
||||
{
|
||||
transform: rotate(180deg);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)';
|
||||
}
|
||||
.bx-rotate-270
|
||||
{
|
||||
transform: rotate(270deg);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=3)';
|
||||
}
|
||||
.bx-flip-horizontal
|
||||
{
|
||||
transform: scaleX(-1);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)';
|
||||
}
|
||||
.bx-flip-vertical
|
||||
{
|
||||
transform: scaleY(-1);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)';
|
||||
}
|
||||
.bx-xs
|
||||
{
|
||||
font-size: 1rem!important;
|
||||
}
|
||||
.bx-sm
|
||||
{
|
||||
font-size: 1.55rem!important;
|
||||
}
|
||||
.bx-md
|
||||
{
|
||||
font-size: 2.25rem!important;
|
||||
}
|
||||
.bx-lg
|
||||
{
|
||||
font-size: 3.0rem!important;
|
||||
}
|
||||
.bx-fw
|
||||
{
|
||||
font-size: 1.2857142857em;
|
||||
line-height: .8em;
|
||||
|
||||
width: 1.2857142857em;
|
||||
height: .8em;
|
||||
margin-top: -.2em!important;
|
||||
|
||||
vertical-align: middle;
|
||||
}
|
||||
.bx-pull-left
|
||||
{
|
||||
float: left;
|
||||
|
||||
margin-right: .3em!important;
|
||||
}
|
||||
.bx-pull-right
|
||||
{
|
||||
float: right;
|
||||
|
||||
margin-left: .3em!important;
|
||||
}
|
||||
|
||||
.bx-border
|
||||
{
|
||||
padding: .25em;
|
||||
|
||||
border: .07em solid rgba(0,0,0,.1);
|
||||
border-radius: .25em;
|
||||
}
|
||||
.bx-border-circle
|
||||
{
|
||||
padding: .25em;
|
||||
|
||||
border: .07em solid rgba(0,0,0,.1);
|
||||
border-radius: 50%;
|
||||
}
|
||||
.bx-ul
|
||||
{
|
||||
margin-left: 2em;
|
||||
padding-left: 0;
|
||||
|
||||
list-style: none;
|
||||
}
|
||||
.bx-ul > li
|
||||
{
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bx-ul .bx,.bx-ul .bxr,.bx-ul .bxs
|
||||
{
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
|
||||
position: absolute;
|
||||
left: -2em;
|
||||
|
||||
width: 2em;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
108
apps/icon-pack-builder/boxicons-free/fonts/transformations.css
Normal file
108
apps/icon-pack-builder/boxicons-free/fonts/transformations.css
Normal file
@@ -0,0 +1,108 @@
|
||||
.bx-rotate-90
|
||||
{
|
||||
transform: rotate(90deg);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=1)';
|
||||
}
|
||||
.bx-rotate-180
|
||||
{
|
||||
transform: rotate(180deg);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)';
|
||||
}
|
||||
.bx-rotate-270
|
||||
{
|
||||
transform: rotate(270deg);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=3)';
|
||||
}
|
||||
.bx-flip-horizontal
|
||||
{
|
||||
transform: scaleX(-1);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)';
|
||||
}
|
||||
.bx-flip-vertical
|
||||
{
|
||||
transform: scaleY(-1);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)';
|
||||
}
|
||||
.bx-xs
|
||||
{
|
||||
font-size: 1rem!important;
|
||||
}
|
||||
.bx-sm
|
||||
{
|
||||
font-size: 1.55rem!important;
|
||||
}
|
||||
.bx-md
|
||||
{
|
||||
font-size: 2.25rem!important;
|
||||
}
|
||||
.bx-lg
|
||||
{
|
||||
font-size: 3.0rem!important;
|
||||
}
|
||||
.bx-fw
|
||||
{
|
||||
font-size: 1.2857142857em;
|
||||
line-height: .8em;
|
||||
|
||||
width: 1.2857142857em;
|
||||
height: .8em;
|
||||
margin-top: -.2em!important;
|
||||
|
||||
vertical-align: middle;
|
||||
}
|
||||
.bx-pull-left
|
||||
{
|
||||
float: left;
|
||||
|
||||
margin-right: .3em!important;
|
||||
}
|
||||
.bx-pull-right
|
||||
{
|
||||
float: right;
|
||||
|
||||
margin-left: .3em!important;
|
||||
}
|
||||
|
||||
.bx-border
|
||||
{
|
||||
padding: .25em;
|
||||
|
||||
border: .07em solid rgba(0,0,0,.1);
|
||||
border-radius: .25em;
|
||||
}
|
||||
.bx-border-circle
|
||||
{
|
||||
padding: .25em;
|
||||
|
||||
border: .07em solid rgba(0,0,0,.1);
|
||||
border-radius: 50%;
|
||||
}
|
||||
.bx-ul
|
||||
{
|
||||
margin-left: 2em;
|
||||
padding-left: 0;
|
||||
|
||||
list-style: none;
|
||||
}
|
||||
.bx-ul > li
|
||||
{
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bx-ul .bx,.bx-ul .bxr,.bx-ul .bxs
|
||||
{
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
|
||||
position: absolute;
|
||||
left: -2em;
|
||||
|
||||
width: 2em;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
1
apps/icon-pack-builder/boxicons-free/fonts/transformations.min.css
vendored
Normal file
1
apps/icon-pack-builder/boxicons-free/fonts/transformations.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.bx-rotate-90{transform:rotate(90deg);-ms-filter:'progid:DXImageTransform.Microsoft.BasicImage(rotation=1)';}.bx-rotate-180{transform:rotate(180deg);-ms-filter:'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)';}.bx-rotate-270{transform:rotate(270deg);-ms-filter:'progid:DXImageTransform.Microsoft.BasicImage(rotation=3)';}.bx-flip-horizontal{transform:scaleX(-1);-ms-filter:'progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)';}.bx-flip-vertical{transform:scaleY(-1);-ms-filter:'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)';}.bx-xs{font-size:1rem!important;}.bx-sm{font-size:1.55rem!important;}.bx-md{font-size:2.25rem!important;}.bx-lg{font-size:3.0rem!important;}.bx-fw{font-size:1.2857142857em;line-height:.8em;width:1.2857142857em;height:.8em;margin-top:-.2em!important;vertical-align:middle;}.bx-pull-left{float:left;margin-right:.3em!important;}.bx-pull-right{float:right;margin-left:.3em!important;}.bx-border{padding:.25em;border:.07em solid rgba(0,0,0,.1);border-radius:.25em;}.bx-border-circle{padding:.25em;border:.07em solid rgba(0,0,0,.1);border-radius:50%;}.bx-ul{margin-left:2em;padding-left:0;list-style:none;}.bx-ul > li{position:relative;}.bx-ul .bx,.bx-ul .bxr,.bx-ul .bxs{font-size:inherit;line-height:inherit;position:absolute;left:-2em;width:2em;text-align:center;}
|
||||
14
apps/icon-pack-builder/package.json
Normal file
14
apps/icon-pack-builder/package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "@triliumnext/icon-pack-builder",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "src/index.ts",
|
||||
"scripts": {
|
||||
"start": "tsx ."
|
||||
},
|
||||
"keywords": [],
|
||||
"devDependencies": {
|
||||
"@mdi/font": "7.4.47",
|
||||
"@phosphor-icons/web": "2.1.2"
|
||||
}
|
||||
}
|
||||
76
apps/icon-pack-builder/src/index.ts
Normal file
76
apps/icon-pack-builder/src/index.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { createWriteStream, mkdirSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
|
||||
import cls from "@triliumnext/server/src/services/cls.js";
|
||||
|
||||
import type { IconPackData } from "./provider";
|
||||
import boxicons3 from "./providers/boxicons3";
|
||||
import mdi from "./providers/mdi";
|
||||
import phosphor from "./providers/phosphor";
|
||||
|
||||
process.env.TRILIUM_INTEGRATION_TEST = "memory-no-store";
|
||||
process.env.TRILIUM_RESOURCE_DIR = "../server/src";
|
||||
process.env.NODE_ENV = "development";
|
||||
|
||||
async function main() {
|
||||
const outputDir = join(__dirname, "output");
|
||||
mkdirSync(outputDir, { recursive: true });
|
||||
|
||||
const i18n = await import("@triliumnext/server/src/services/i18n.js");
|
||||
await i18n.initializeTranslations();
|
||||
|
||||
const sqlInit = (await import("../../server/src/services/sql_init.js")).default;
|
||||
await sqlInit.createInitialDatabase(true);
|
||||
|
||||
// Wait for becca to be loaded before importing data
|
||||
const beccaLoader = await import("../../server/src/becca/becca_loader.js");
|
||||
await beccaLoader.beccaLoaded;
|
||||
|
||||
const notesService = (await import("../../server/src/services/notes.js")).default;
|
||||
|
||||
async function buildIconPack(iconPack: IconPackData) {
|
||||
// Create the icon pack note.
|
||||
const { note, branch } = notesService.createNewNote({
|
||||
parentNoteId: "root",
|
||||
type: "file",
|
||||
title: iconPack.name,
|
||||
mime: "application/json",
|
||||
content: JSON.stringify(iconPack.manifest)
|
||||
});
|
||||
note.setLabel("iconPack", iconPack.prefix);
|
||||
note.setLabel("iconClass", iconPack.icon);
|
||||
|
||||
// Add the attachment.
|
||||
note.saveAttachment({
|
||||
role: "file",
|
||||
title: iconPack.fontFile.name,
|
||||
mime: iconPack.fontFile.mime,
|
||||
content: iconPack.fontFile.content
|
||||
});
|
||||
|
||||
// Export to zip.
|
||||
const zipFilePath = join(outputDir, `${iconPack.name}.zip`);
|
||||
const fileOutputStream = createWriteStream(zipFilePath);
|
||||
const { exportToZip } = (await import("@triliumnext/server/src/services/export/zip.js")).default;
|
||||
const taskContext = new (await import("@triliumnext/server/src/services/task_context.js")).default(
|
||||
"no-progress-reporting", "export", null
|
||||
);
|
||||
await exportToZip(taskContext, branch, "html", fileOutputStream, false, { skipExtraFiles: true });
|
||||
await new Promise<void>((resolve) => { fileOutputStream.on("finish", resolve); });
|
||||
|
||||
console.log(`Built icon pack: ${iconPack.name} (${zipFilePath})`);
|
||||
}
|
||||
|
||||
const builtIconPacks = [
|
||||
boxicons3("basic"),
|
||||
boxicons3("brands"),
|
||||
mdi(),
|
||||
phosphor("regular"),
|
||||
phosphor("fill")
|
||||
];
|
||||
await Promise.all(builtIconPacks.map(buildIconPack));
|
||||
}
|
||||
|
||||
cls.init(() => {
|
||||
main();
|
||||
});
|
||||
13
apps/icon-pack-builder/src/provider.ts
Normal file
13
apps/icon-pack-builder/src/provider.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { IconPackManifest } from "@triliumnext/server/src/services/icon_packs";
|
||||
|
||||
export interface IconPackData {
|
||||
name: string;
|
||||
prefix: string;
|
||||
manifest: IconPackManifest;
|
||||
icon: string;
|
||||
fontFile: {
|
||||
name: string;
|
||||
mime: string;
|
||||
content: Buffer;
|
||||
}
|
||||
}
|
||||
42
apps/icon-pack-builder/src/providers/boxicons3.ts
Normal file
42
apps/icon-pack-builder/src/providers/boxicons3.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { readFileSync } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
import { IconPackData } from "../provider";
|
||||
|
||||
export default function buildIcons(pack: "basic" | "brands"): IconPackData {
|
||||
const inputDir = join(__dirname, "../../boxicons-free/fonts");
|
||||
const fileName = pack === "basic" ? "boxicons" : `boxicons-${pack}`;
|
||||
const jsonPath = `${inputDir}/${pack}/${fileName}.json`;
|
||||
const inputData = JSON.parse(readFileSync(jsonPath, "utf-8"));
|
||||
const icons = {};
|
||||
|
||||
for (const [ key, value ] of Object.entries(inputData)) {
|
||||
if (key.startsWith("variable-selector")) continue;
|
||||
|
||||
let name = key;
|
||||
if (name.startsWith('bx-')) {
|
||||
name = name.slice(3);
|
||||
}
|
||||
if (name.startsWith('bxs-')) {
|
||||
name = name.slice(4);
|
||||
}
|
||||
icons[key] = {
|
||||
glyph: String.fromCodePoint(value as number),
|
||||
terms: [ name ]
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
name: pack === "basic" ? "Boxicons 3 (Basic)" : "Boxicons 3 (Brands)",
|
||||
prefix: pack === "basic" ? "bx3" : "bxl3",
|
||||
icon: pack === "basic" ? "bx3 bx-cube" : "bxl3 bxl-boxicons",
|
||||
fontFile: {
|
||||
name: `${fileName}.woff2`,
|
||||
mime: "font/woff2",
|
||||
content: readFileSync(join(inputDir, pack, `${fileName}.woff2`))
|
||||
},
|
||||
manifest: {
|
||||
icons
|
||||
}
|
||||
};
|
||||
}
|
||||
26
apps/icon-pack-builder/src/providers/mdi.ts
Normal file
26
apps/icon-pack-builder/src/providers/mdi.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { readFileSync } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
import type { IconPackData } from "../provider";
|
||||
import { extractClassNamesFromCss, getModulePath } from "../utils";
|
||||
|
||||
export default function buildIcons(): IconPackData {
|
||||
const baseDir = getModulePath("@mdi/font");
|
||||
|
||||
const cssFilePath = join(baseDir, "css", "materialdesignicons.min.css");
|
||||
const cssFileContent = readFileSync(cssFilePath, "utf-8");
|
||||
|
||||
return {
|
||||
name: "Material Design Icons",
|
||||
prefix: "mdi",
|
||||
icon: "mdi mdi-material-design",
|
||||
manifest: {
|
||||
icons: extractClassNamesFromCss(cssFileContent, "mdi"),
|
||||
},
|
||||
fontFile: {
|
||||
name: "materialdesignicons-webfont.woff2",
|
||||
mime: "font/woff2",
|
||||
content: readFileSync(join(baseDir, "fonts", "materialdesignicons-webfont.woff2"))
|
||||
}
|
||||
};
|
||||
}
|
||||
46
apps/icon-pack-builder/src/providers/phosphor.ts
Normal file
46
apps/icon-pack-builder/src/providers/phosphor.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { readdirSync, readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
|
||||
import { IconPackData } from "../provider";
|
||||
import { getModulePath } from "../utils";
|
||||
|
||||
export default function buildIcons(packName: "regular" | "fill"): IconPackData {
|
||||
const baseDir = join(getModulePath("@phosphor-icons/web"), "src", packName);
|
||||
const iconIndex = JSON.parse(readFileSync(join(baseDir, "selection.json"), "utf-8"));
|
||||
const icons: IconPackData["manifest"]["icons"] = {};
|
||||
|
||||
function removeSuffix(name: string) {
|
||||
if (name.endsWith(`-${packName}`)) {
|
||||
name = name.split("-").slice(0, -1).join("-");
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
for (const icon of iconIndex.icons) {
|
||||
const terms = icon.properties.name.split(", ").map((t: string) => removeSuffix(t));
|
||||
const name = removeSuffix(icon.icon.tags[0]);
|
||||
|
||||
const id = `ph-${name}`;
|
||||
icons[id] = {
|
||||
glyph: `${String.fromCharCode(icon.properties.code)}`,
|
||||
terms
|
||||
};
|
||||
}
|
||||
|
||||
const fontFile = readdirSync(baseDir).find(f => f.endsWith(".woff2"));
|
||||
const prefix = packName === "regular" ? "ph" : `ph-${packName}`;
|
||||
|
||||
return {
|
||||
name: `Phosphor Icons (${packName.charAt(0).toUpperCase() + packName.slice(1)})`,
|
||||
prefix,
|
||||
icon: `${prefix} ph-phosphor-logo`,
|
||||
manifest: {
|
||||
icons
|
||||
},
|
||||
fontFile: {
|
||||
name: fontFile!,
|
||||
mime: "font/woff2",
|
||||
content: readFileSync(join(baseDir, fontFile!))
|
||||
}
|
||||
};
|
||||
}
|
||||
26
apps/icon-pack-builder/src/utils.ts
Normal file
26
apps/icon-pack-builder/src/utils.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { join } from "path";
|
||||
|
||||
import { IconPackManifest } from "../../server/src/services/icon_packs";
|
||||
|
||||
export function extractClassNamesFromCss(css: string, prefix: string): IconPackManifest["icons"] {
|
||||
const regex = /\.([a-zA-Z0-9-]+)::before\s*\{\s*content:\s*"\\([A-Fa-f0-9]+)"\s*\}/g;
|
||||
const icons: IconPackManifest["icons"] = {};
|
||||
let match: string[];
|
||||
|
||||
while ((match = regex.exec(css)) !== null) {
|
||||
let name = match[1];
|
||||
if (prefix && name.startsWith(`${prefix}-`)) {
|
||||
name = name.substring(prefix.length + 1);
|
||||
}
|
||||
|
||||
icons[match[1]] = {
|
||||
glyph: String.fromCodePoint(parseInt(match[2], 16)),
|
||||
terms: [ name ]
|
||||
};
|
||||
}
|
||||
return icons;
|
||||
}
|
||||
|
||||
export function getModulePath(moduleName: string): string {
|
||||
return join(__dirname, "../../../node_modules", moduleName);
|
||||
}
|
||||
36
apps/icon-pack-builder/tsconfig.app.json
Normal file
36
apps/icon-pack-builder/tsconfig.app.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"target": "ES2020",
|
||||
"outDir": "dist",
|
||||
"strict": false,
|
||||
"types": [
|
||||
"node",
|
||||
"express"
|
||||
],
|
||||
"rootDir": "src",
|
||||
"tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"../server/src/*.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"eslint.config.js",
|
||||
"eslint.config.cjs",
|
||||
"eslint.config.mjs"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../server/tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "../desktop/tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "../client/tsconfig.app.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
15
apps/icon-pack-builder/tsconfig.json
Normal file
15
apps/icon-pack-builder/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "../server"
|
||||
},
|
||||
{
|
||||
"path": "../client"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -341,7 +341,7 @@ paths:
|
||||
post:
|
||||
description: >
|
||||
Create a branch (clone a note to a different location in the tree).
|
||||
In case there is a branch between parent note and child note already,
|
||||
In case there is a branch between parent note and child note already,
|
||||
then this will update the existing branch with prefix, notePosition and isExpanded.
|
||||
operationId: postBranch
|
||||
requestBody:
|
||||
@@ -416,7 +416,7 @@ paths:
|
||||
$ref: "#/components/schemas/Error"
|
||||
delete:
|
||||
description: >
|
||||
deletes a branch based on the branchId supplied. If this is the last branch of the (child) note,
|
||||
deletes a branch based on the branchId supplied. If this is the last branch of the (child) note,
|
||||
then the note is deleted as well.
|
||||
operationId: deleteBranchById
|
||||
responses:
|
||||
@@ -627,8 +627,8 @@ paths:
|
||||
$ref: "#/components/schemas/EntityId"
|
||||
post:
|
||||
description: >
|
||||
notePositions in branches are not automatically pushed to connected clients and need a specific instruction.
|
||||
If you want your changes to be in effect immediately, call this service after setting branches' notePosition.
|
||||
notePositions in branches are not automatically pushed to connected clients and need a specific instruction.
|
||||
If you want your changes to be in effect immediately, call this service after setting branches' notePosition.
|
||||
Note that you need to supply "parentNoteId" of branch(es) with changed positions.
|
||||
operationId: postRefreshNoteOrdering
|
||||
responses:
|
||||
@@ -692,18 +692,20 @@ paths:
|
||||
application/json; charset=utf-8:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
/calendar/weeks/{date}:
|
||||
/calendar/weeks/{week}:
|
||||
get:
|
||||
description: returns a week note for a given date. Gets created if doesn't exist.
|
||||
operationId: getWeekFirstDayNote
|
||||
summary: Get a week note
|
||||
description: Returns a week note for a given ISO week (format YYYY-Www, e.g., 2025-W01). The note is created if it doesn't exist.
|
||||
operationId: getWeekNote
|
||||
parameters:
|
||||
- name: date
|
||||
- name: week
|
||||
in: path
|
||||
required: true
|
||||
description: The ISO 8601 week identifier (YYYY-Www).
|
||||
schema:
|
||||
type: string
|
||||
format: date
|
||||
example: 2022-02-22
|
||||
pattern: "[0-9]{4}-W[0-9]{2}"
|
||||
example: "2025-W01"
|
||||
responses:
|
||||
"200":
|
||||
description: week note
|
||||
@@ -859,8 +861,8 @@ components:
|
||||
type: http
|
||||
scheme: basic
|
||||
description: >
|
||||
Basic Auth where username is arbitrary string (e.g. "trilium", not checked),
|
||||
username is the ETAPI token.
|
||||
Basic Auth where username is arbitrary string (e.g. "trilium", not checked),
|
||||
username is the ETAPI token.
|
||||
To emphasize, do not use Trilium password here (won't work), only the generated
|
||||
ETAPI token (from Options -> ETAPI)
|
||||
schemas:
|
||||
@@ -897,13 +899,13 @@ components:
|
||||
notePosition:
|
||||
type: integer
|
||||
description: >
|
||||
Position of the note in the parent. Normal ordering is 10, 20, 30 ...
|
||||
Position of the note in the parent. Normal ordering is 10, 20, 30 ...
|
||||
So if you want to create a note on the first position, use e.g. 5, for second position 15, for last e.g. 1000000
|
||||
prefix:
|
||||
type: string
|
||||
description: >
|
||||
Prefix is branch (placement) specific title prefix for the note.
|
||||
Let's say you have your note placed into two different places in the tree,
|
||||
Prefix is branch (placement) specific title prefix for the note.
|
||||
Let's say you have your note placed into two different places in the tree,
|
||||
but you want to change the title a bit in one of the placements. For this you can use prefix.
|
||||
isExpanded:
|
||||
type: boolean
|
||||
@@ -930,7 +932,24 @@ components:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
enum: [text, code, render, file, image, search, relationMap, book, noteMap, mermaid, webView, shortcut, doc, contentWidget, launcher]
|
||||
enum:
|
||||
[
|
||||
text,
|
||||
code,
|
||||
render,
|
||||
file,
|
||||
image,
|
||||
search,
|
||||
relationMap,
|
||||
book,
|
||||
noteMap,
|
||||
mermaid,
|
||||
webView,
|
||||
shortcut,
|
||||
doc,
|
||||
contentWidget,
|
||||
launcher,
|
||||
]
|
||||
mime:
|
||||
type: string
|
||||
isProtected:
|
||||
|
||||
2
apps/server/src/assets/doc_notes/en/User Guide/!!!meta.json
generated
vendored
2
apps/server/src/assets/doc_notes/en/User Guide/!!!meta.json
generated
vendored
File diff suppressed because one or more lines are too long
@@ -10,11 +10,13 @@
|
||||
<p>Trilium supports custom user themes, allowing you to personalize the application's
|
||||
appearance. To create a custom theme, follow these steps:</p>
|
||||
<ol>
|
||||
<li><strong>Create a CSS Code Note</strong>: Start by creating a new <a href="#root/_help_6f9hih2hXXZk">code note</a> with
|
||||
the <code>CSS</code> type.</li>
|
||||
<li><strong>Annotate with</strong> <code>#appTheme</code>: Add the <a href="#root/_help_zEY4DaJG4YT5">attribute</a> <code>#appTheme=my-theme-name</code> to
|
||||
your note, where <code>my-theme-name</code> is the name of your custom theme.</li>
|
||||
<li><strong>Define Your Styles</strong>: Write your custom CSS within the
|
||||
<li data-list-item-id="eca8bbfc636daa344eaabbbb94ea94c3f"><strong>Create a CSS Code Note</strong>: Start by creating a new <a href="#root/_help_6f9hih2hXXZk">code note</a> with
|
||||
the <code spellcheck="false">CSS</code> type.</li>
|
||||
<li data-list-item-id="e5ae35a0ee455e32c200fc095bf8415ac"><strong>Annotate with</strong> <code spellcheck="false">#appTheme</code>:
|
||||
Add the <a href="#root/_help_zEY4DaJG4YT5">attribute</a> <code spellcheck="false">#appTheme=my-theme-name</code> to
|
||||
your note, where <code spellcheck="false">my-theme-name</code> is the name
|
||||
of your custom theme.</li>
|
||||
<li data-list-item-id="e7cd8c79dcf2d9edc2d03c924b9d954e1"><strong>Define Your Styles</strong>: Write your custom CSS within the
|
||||
note. Below is an example of a custom theme:</li>
|
||||
</ol><pre><code class="language-text-x-trilium-auto">@font-face {
|
||||
font-family: 'Raleway';
|
||||
@@ -72,18 +74,20 @@ body .CodeMirror {
|
||||
<h3>Activating Your Custom Theme</h3>
|
||||
<p>Once you've created your custom theme:</p>
|
||||
<ol>
|
||||
<li>Go to "Menu" -> "Options" -> "Appearance."</li>
|
||||
<li>In the theme selection dropdown, you should see your custom theme listed
|
||||
under the name you provided with the <code>#appTheme</code> <a href="#root/_help_zEY4DaJG4YT5">label</a>.</li>
|
||||
<li>Select your custom theme to activate it.</li>
|
||||
<li data-list-item-id="ee141db479e6972f78a12a2ece4be4d8f">Go to "Menu" -> "Options" -> "Appearance."</li>
|
||||
<li data-list-item-id="e36a48638934829faceb5b68dececd6c7">In the theme selection dropdown, you should see your custom theme listed
|
||||
under the name you provided with the <code spellcheck="false">#appTheme</code>
|
||||
<a
|
||||
href="#root/_help_zEY4DaJG4YT5">label</a>.</li>
|
||||
<li data-list-item-id="eb7987a455a323d619c83e04a3f660cf9">Select your custom theme to activate it.</li>
|
||||
</ol>
|
||||
<p>If you make changes to your theme, press <kbd>Ctrl</kbd> + <kbd>R</kbd> to
|
||||
reload the frontend and apply your updates.</p>
|
||||
<h3>Sharing and Importing Themes</h3>
|
||||
<p>Custom themes can be exported as <code>.tar</code> archives, which can be
|
||||
shared with other users. However, be cautious when importing themes from
|
||||
untrusted sources, as they may contain executable scripts that could pose
|
||||
security risks.</p>
|
||||
<p>Custom themes can be exported as <code spellcheck="false">.tar</code> archives,
|
||||
which can be shared with other users. However, be cautious when importing
|
||||
themes from untrusted sources, as they may contain executable scripts that
|
||||
could pose security risks.</p>
|
||||
<p>An example user theme, <em>Steel Blue</em>, is available in the demo document.</p>
|
||||
<p>
|
||||
<img src="Themes_steel-blue.png" alt="Steel Blue Theme">
|
||||
@@ -96,17 +100,19 @@ body .CodeMirror {
|
||||
<h3>Applying Custom CSS</h3>
|
||||
<p>To use custom CSS:</p>
|
||||
<ol>
|
||||
<li><strong>Create a CSS Code Note</strong>: Create a new <a class="reference-link"
|
||||
href="#root/_help_6f9hih2hXXZk">Code</a> note with the <code>CSS</code> type.</li>
|
||||
<li><strong>Add the</strong> <code>appCss</code> <strong>Label</strong>: Annotate
|
||||
the note with the <code>#appCss</code> <a href="#root/_help_zEY4DaJG4YT5">label</a>.</li>
|
||||
<li><strong>Write Your CSS</strong>: Add your custom CSS rules to the note.</li>
|
||||
<li data-list-item-id="e34f8b4bcba7c20fb1b7653fe36ded3da"><strong>Create a CSS Code Note</strong>: Create a new <a class="reference-link"
|
||||
href="#root/_help_6f9hih2hXXZk">Code</a> note with the <code spellcheck="false">CSS</code> type.</li>
|
||||
<li
|
||||
data-list-item-id="ec697ca6baf249b374caa04b0817a54f0"><strong>Add the</strong> <code spellcheck="false">appCss</code> <strong>Label</strong>:
|
||||
Annotate the note with the <code spellcheck="false">#appCss</code> <a href="#root/_help_zEY4DaJG4YT5">label</a>.</li>
|
||||
<li
|
||||
data-list-item-id="e33d95fa67b19ef88f2561c3addecade8"><strong>Write Your CSS</strong>: Add your custom CSS rules to the note.</li>
|
||||
</ol>
|
||||
<p>For example:</p><pre><code class="language-text-x-trilium-auto">/* Custom CSS to style specific elements */
|
||||
.tree-item {
|
||||
color: #ff6347; /* Change tree item color */
|
||||
}</code></pre>
|
||||
<p>When Trilium's frontend starts, all notes labeled with <code>appCss</code> are
|
||||
<p>When Trilium's frontend starts, all notes labeled with <code spellcheck="false">appCss</code> are
|
||||
automatically included in the style element of the HTML page.</p>
|
||||
<p>After making changes, press <kbd>Ctrl</kbd> + <kbd>R</kbd> to reload the frontend
|
||||
and apply your new styles.</p>
|
||||
@@ -116,22 +122,24 @@ body .CodeMirror {
|
||||
<h3>Styling Specific Notes in the Tree</h3>
|
||||
<p>To apply specific styles to certain notes in the tree:</p>
|
||||
<ul>
|
||||
<li><strong>Use the</strong> <code>cssClass</code> <strong>Attribute</strong>:
|
||||
Add the <code>cssClass</code> <a href="#root/_help_zEY4DaJG4YT5">attribute</a> to
|
||||
<li data-list-item-id="e885cbe8b8c440d4bf71c95d5f8c73340"><strong>Use the</strong> <code spellcheck="false">cssClass</code> <strong>Attribute</strong>:
|
||||
Add the <code spellcheck="false">cssClass</code> <a href="#root/_help_zEY4DaJG4YT5">attribute</a> to
|
||||
a note, and assign it a value representing the desired CSS class.</li>
|
||||
<li><strong>Define an</strong> <code>iconClass</code>: You can also define
|
||||
a custom icon for a note using the <code>iconClass</code> attribute, selecting
|
||||
from <a href="https://boxicons.com">Box Icons</a> or your own custom classes.</li>
|
||||
<li
|
||||
data-list-item-id="e168c9c99d3bf9e7af0d0bd03ee6903f5"><strong>Define an</strong> <code spellcheck="false">iconClass</code>: You
|
||||
can also define a custom icon for a note using the <code spellcheck="false">iconClass</code> attribute,
|
||||
selecting from <a href="https://boxicons.com">Box Icons</a> or your own custom
|
||||
classes.</li>
|
||||
</ul>
|
||||
<p>For example, if you want to style notes of a specific type, such as notes
|
||||
containing PNG images, you can target them with classes like <code>type-image mime-image-png</code>.</p>
|
||||
containing PNG images, you can target them with classes like <code spellcheck="false">type-image mime-image-png</code>.</p>
|
||||
<h3>User-Provided Themes</h3>
|
||||
<p>A gallery of user-created themes is available, showcasing the variety
|
||||
of customizations that the Trilium community has developed. For more information,
|
||||
check the <a class="reference-link" href="#root/_help_VbjZvtUek0Ln">Theme Gallery</a>.</p>
|
||||
<h3>Asset Path Management</h3>
|
||||
<p>When referencing built-in assets like images in your custom themes or
|
||||
CSS, you can avoid hardcoding version numbers by using the <code>vX</code> alias.
|
||||
For example, instead of specifying <code>/assets/v0.57.0-beta/images/icon-grey.png</code>,
|
||||
you can use <code>/assets/vX/images/icon-grey.png</code> to keep your theme
|
||||
compatible with future versions of Trilium.</p>
|
||||
CSS, you can avoid hardcoding version numbers by using the <code spellcheck="false">vX</code> alias.
|
||||
For example, instead of specifying <code spellcheck="false">/assets/v0.57.0-beta/images/icon-grey.png</code>,
|
||||
you can use <code spellcheck="false">/assets/vX/images/icon-grey.png</code> to
|
||||
keep your theme compatible with future versions of Trilium.</p>
|
||||
76
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Themes/Icon Packs.html
generated
vendored
Normal file
76
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Themes/Icon Packs.html
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
<h2>Importing an existing icon pack</h2>
|
||||
<p>Icon packs are specific to Trilium, so they must either be created from
|
||||
scratch (see below) or imported from a ZIP file from a third-party developer.</p>
|
||||
<aside
|
||||
class="admonition note">
|
||||
<p><strong>Icon packs are third-party content</strong>
|
||||
<br>
|
||||
<br>The Trilium maintainers are not responsible for keeping these icon packs
|
||||
up to date. If you have an issue with a specific icon pack, then the issue
|
||||
must be reported to the third-party developer responsible for it, not the
|
||||
Trilium team.</p>
|
||||
</aside>
|
||||
<p>To import an icon pack:</p>
|
||||
<ol>
|
||||
<li data-list-item-id="e72cd89899a976ca5c54e089df2285d41">Ideally, create a dedicated spot in your note tree where to place the
|
||||
icon packs.</li>
|
||||
<li data-list-item-id="ed7f941fe865c5f14e1ae724831e49ba1">Right click the note where to put it and select <em>Import into note</em>.</li>
|
||||
<li
|
||||
data-list-item-id="e1b6980592dddab6a0235dd070b3b7067">Uncheck <em>Safe import</em>.</li>
|
||||
<li data-list-item-id="edd29376be6fbf3b9c59275145457de3b">Select <em>Import</em>.</li>
|
||||
<li data-list-item-id="ea9ae8004d6cd7b349ac648cde9141977"><a href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/_help_s8alTXmpFR61">Refresh the application</a>.</li>
|
||||
</ol>
|
||||
<aside class="admonition warning">
|
||||
<p>Since <em>Safe import</em> is disabled, make sure you trust the source as
|
||||
it could contain dangerous third-party scripts. One good way to check if
|
||||
the icon pack is safe is to manually extract the .zip and inspect the file
|
||||
contents. Icon packs should only contain a font file and a JSON file. Other
|
||||
files (especially scripts) are to be considered harmful.</p>
|
||||
</aside>
|
||||
<h2>Creating an icon pack</h2>
|
||||
<p>Creating an icon pack requires some scripting knowledge outside Trilium
|
||||
in order to generate the list of icons. For information, see <a class="reference-link"
|
||||
href="#root/pKK96zzmvBGf/_help_g1mlRoU8CsqC">Creating an icon pack</a>.</p>
|
||||
<h2>Using an icon from an icon pack</h2>
|
||||
<p>After <a href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/_help_s8alTXmpFR61">refreshing the application</a>,
|
||||
the icon pack should be enabled by default. To test this, simply select
|
||||
an existing note or create a new one and try to change the note icon.</p>
|
||||
<p>There should be a <em>Filter</em> button to the right of the search bar
|
||||
in the icon list. Clicking it allows filtering by icon pack and the newly
|
||||
imported icon pack should be displayed there.</p>
|
||||
<aside class="admonition note">
|
||||
<p>If the icon pack is missing from that list, then most likely there's something
|
||||
wrong with it.</p>
|
||||
<ul>
|
||||
<li data-list-item-id="e0a36a4a12c83b68ed1affd67e7ffa850">Try checking the <a class="reference-link" href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/qzNzp9LYQyPT/_help_bnyigUA2UK7s">Backend (server) logs</a> for
|
||||
clues and make sure that the icon pack has the <code spellcheck="false">#iconPack</code>
|
||||
<a
|
||||
href="#root/pOsGYCXsbNQG/tC7s2alapj8V/zEY4DaJG4YT5/_help_HI6GBBIduIgv">label</a>with a value assigned to it (a prefix).</li>
|
||||
<li data-list-item-id="e33510913f0656b1c14c5f0c7278093c7">Icon packs that are <a href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/BFs8mudNFgCS/_help_bwg0e8ewQMak">protected</a> are
|
||||
ignored.</li>
|
||||
</ul>
|
||||
</aside>
|
||||
<h2>Integration with the share and export functionality</h2>
|
||||
<p>Custom icon packs are also supported by the <a class="reference-link"
|
||||
href="#root/pOsGYCXsbNQG/tC7s2alapj8V/_help_R9pX4DGra2Vt">Sharing</a> feature,
|
||||
where they will be shown in the note tree. However, in order for an icon
|
||||
pack to be visible to the share function, the icon pack note must also
|
||||
be shared.</p>
|
||||
<p>If you are using a custom share theme, make sure it supports the
|
||||
<code
|
||||
spellcheck="false">iconPackCss</code>, otherwise icons will not show up. Check the original
|
||||
share template source code for reference.</p>
|
||||
<p>Custom icon packs will also be preserved when <a class="reference-link"
|
||||
href="#root/pOsGYCXsbNQG/tC7s2alapj8V/R9pX4DGra2Vt/_help_ycBFjKrrwE9p">Exporting static HTML for web publishing</a>.
|
||||
In this case, there's no requirement to make the icon pack shared.</p>
|
||||
<h2>What happens if I remove an icon pack</h2>
|
||||
<p>If an icon pack is removed or disabled (by removing or altering its
|
||||
<code
|
||||
spellcheck="false">#iconPack</code>label), all the notes that use this icon pack will show
|
||||
in the <a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/_help_oPVyFC7WL2Lp">Note Tree</a> with
|
||||
no icon. This won't cause any issues apart from looking strange.</p>
|
||||
<p>The solution is to replace the icons with some else, try using
|
||||
<a
|
||||
class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/wArbEsdSae6g/_help_eIg8jdvaoNNd">Search</a> which supports bulk actions, to identify the notes with
|
||||
the now deleted icon pack (by looking for the prefix) and changing or removing
|
||||
their <code spellcheck="false">iconClass</code>.</p>
|
||||
245
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Theme development/Creating an icon pack.html
generated
vendored
Normal file
245
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Theme development/Creating an icon pack.html
generated
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
<aside class="admonition note">
|
||||
<p>e This page describes how to create custom icon packs. For a general description
|
||||
of how to use already existing icon packs, see <a class="reference-link"
|
||||
href="#root/_help_gOKqSJgXLcIj">Icon Packs</a>.</p>
|
||||
</aside>
|
||||
<h2>Supported formats</h2>
|
||||
<p>The first step is to analyze if the icon set being packed can be integrated
|
||||
into Trilium.</p>
|
||||
<p>Trilium only supports <strong>font-based icon sets</strong>, with the following
|
||||
formats:</p>
|
||||
<figure class="table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Extension</th>
|
||||
<th>MIME type</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code spellcheck="false">.woff2</code>
|
||||
</td>
|
||||
<td><code spellcheck="false">font/woff2</code>
|
||||
</td>
|
||||
<td>Recommended due to great compression (low size).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code spellcheck="false">.woff</code>
|
||||
</td>
|
||||
<td><code spellcheck="false">font/woff</code>
|
||||
</td>
|
||||
<td>Higher compatibility, but the font file is bigger.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code spellcheck="false">.ttf</code>
|
||||
</td>
|
||||
<td><code spellcheck="false">font/ttf</code>
|
||||
</td>
|
||||
<td>Most common, but highest font size.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</figure>
|
||||
<h2>Unsupported formats</h2>
|
||||
<p>Trilium <strong>does not</strong> support the following formats:</p>
|
||||
<ul>
|
||||
<li data-list-item-id="e82a131514827c3594823b95a1e032e55">SVG-based fonts.</li>
|
||||
<li data-list-item-id="ea255621003bfddf0c27b138800b7461e">Individual SVGs.</li>
|
||||
<li data-list-item-id="eb75d3b9b71a147f48925903844e878a0"><code spellcheck="false">.eot</code> fonts (legacy and proprietary).</li>
|
||||
<li
|
||||
data-list-item-id="e67532d402708b0d266f438de7afc617b">Duotone icons, since it requires a special CSS format that Trilium doesn't
|
||||
support.</li>
|
||||
<li data-list-item-id="ee56cb0fb0ae77e969c44844a2b56ef94">Any other font format not specified in the <em>Supported formats</em> section.</li>
|
||||
</ul>
|
||||
<p>In this case, the font must be manually converted to one of the supported
|
||||
formats (ideally <code spellcheck="false">.woff2</code>).</p>
|
||||
<h2>Prerequisites</h2>
|
||||
<p>In order to create a new icon pack from a set of icons, it must meet the
|
||||
following criteria:</p>
|
||||
<ol>
|
||||
<li data-list-item-id="eba517372b7686baf9c5ffbec386e7853">It must have a web font of the supported format (see above).</li>
|
||||
<li data-list-item-id="e960457bf372dd1a2e3ec77140b38051c">It must have some kind of list, containing the name of each icon and the
|
||||
corresponding Unicode code point. If this is missing, icon fonts usually
|
||||
ship with a <code spellcheck="false">.css</code> file that can be used to
|
||||
extract the icon names from.</li>
|
||||
</ol>
|
||||
<h2>Step-by-step process</h2>
|
||||
<p>As an example throughout this page, we are going to go through the steps
|
||||
of integrating <a href="https://phosphoricons.com/">Phosphor Icons</a>.</p>
|
||||
<h3>Creating the manifest</h3>
|
||||
<p>This is the most difficult part of creating an icon pack, since it requires
|
||||
processing of the icon list to match Trilium's format.</p>
|
||||
<p>The icon pack manifest is a JSON file with the following structure:</p><pre><code class="language-text-x-trilium-auto">{
|
||||
"icons": {
|
||||
"bx-ball": {
|
||||
"glyph": "\ue9c2",
|
||||
"terms": [ "ball" ]
|
||||
},
|
||||
"bxs-party": {
|
||||
"glyph": "\uec92"
|
||||
"terms": [ "party" ]
|
||||
}
|
||||
}
|
||||
}</code></pre>
|
||||
<ul>
|
||||
<li data-list-item-id="e421d9a5fbad061cc4bb80123d2b3b383">The JSON example is a sample from the Boxicons font.</li>
|
||||
<li data-list-item-id="e61b71a1639566cc9ff760a99aca2279a">This is simply a mapping between the CSS classes (<code spellcheck="false">bx-ball</code>),
|
||||
to its corresponding code point in the font (<code spellcheck="false">\ue9c2</code>)
|
||||
and the terms/aliases used for search purposes.</li>
|
||||
<li data-list-item-id="e7f407f989ab48267d31975f75c89d007">Note that it's also possible to use the unescaped glyph inside the JSON.
|
||||
It will appear strange (e.g. ), but it will be rendered properly regardless.</li>
|
||||
<li
|
||||
data-list-item-id="ec4b9b5ac1609500d36d35e659d61b61f">The first term is also considered the “name” of the icon, which is displayed
|
||||
while hovering over it in the icon selector.</li>
|
||||
</ul>
|
||||
<p>In order to generate this manifest, generally a script is needed that
|
||||
processes an already existing list. In the case of Phosphor Icons, the
|
||||
icon list comes in a file called <code spellcheck="false">selection.json</code> with
|
||||
the following format:</p><pre><code class="language-application-json">{
|
||||
"icons": [
|
||||
{
|
||||
"icon": {
|
||||
"paths": [ /* [...] */ ],
|
||||
"grid": 0,
|
||||
"attrs": [{}],
|
||||
"isMulticolor": false,
|
||||
"isMulticolor2": false,
|
||||
"tags": ["acorn"]
|
||||
},
|
||||
"attrs": [{}],
|
||||
"properties": {
|
||||
"id": 0,
|
||||
"order": 1513,
|
||||
"name": "acorn",
|
||||
"code": 60314,
|
||||
"ligatures": "acorn",
|
||||
"prevSize": 16
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 0,
|
||||
"iconIdx": 0
|
||||
},
|
||||
/* [...] */
|
||||
]
|
||||
}</code></pre>
|
||||
<p>As such, we can write a Node.js script to automatically process the manifest
|
||||
file:</p><pre><code class="language-application-javascript-env-backend">import { join } from "node:path";
|
||||
import { readFileSync } from "node:fs";
|
||||
|
||||
function processIconPack(packName) {
|
||||
const path = join(packName);
|
||||
const selectionMeta = JSON.parse(readFileSync(join(path, "selection.json"), "utf-8"));
|
||||
const icons = {};
|
||||
|
||||
for (const icon of selectionMeta.icons) {
|
||||
let name = icon.properties.name;
|
||||
if (name.endsWith(`-${packName}`)) {
|
||||
name = name.split("-").slice(0, -1).join("-");
|
||||
}
|
||||
|
||||
const id = `ph-${name}`;
|
||||
icons[id] = {
|
||||
glyph: `${String.fromCharCode(icon.properties.code)}`,
|
||||
terms: [ name ]
|
||||
};
|
||||
}
|
||||
|
||||
return JSON.stringify({
|
||||
icons
|
||||
}, null, 2);
|
||||
}
|
||||
|
||||
console.log(processIconPack("light"));</code></pre>
|
||||
<aside class="admonition tip">
|
||||
<p><strong>Mind the escape format when processing CSS</strong>
|
||||
</p>
|
||||
<p>The Unicode escape syntax is different in CSS (<code spellcheck="false">"\ea3f"</code>)
|
||||
when compared to JSON (<code spellcheck="false">"\uea3f"</code>). Notice
|
||||
how the JSON escape is <code spellcheck="false">\u</code> and not <code spellcheck="false">\</code>.</p>
|
||||
<p>As a more compact alternative, provide the un-escaped character directly,
|
||||
as UTF-8 is supported.</p>
|
||||
</aside>
|
||||
<h3>Creating the icon pack</h3>
|
||||
<ol>
|
||||
<li data-list-item-id="e7d2cd4845de4760238012fc2ae8dc7a5">Create a note of type <em>Code</em>.</li>
|
||||
<li data-list-item-id="ef8c38938d0e7f8db06bc1e48654ba3d7">Set the language to <em>JSON</em>.</li>
|
||||
<li data-list-item-id="eb4d1eeb7b1af1474870e646096d5c71b">Copy and paste the manifest generated in the previous step as the content
|
||||
of this note.</li>
|
||||
<li data-list-item-id="e1e5a73c0ed4c207555912ccae863aa1c">Go to the <a href="#root/_help_0vhv7lsOLy82">note attachment</a> and upload the
|
||||
font file (in <code spellcheck="false">.woff2</code>, <code spellcheck="false">.woff</code>,
|
||||
<code
|
||||
spellcheck="false">.ttf</code>) format.
|
||||
<ol>
|
||||
<li data-list-item-id="e2aaef242576df43f2c9259ec743593c4">Trilium identifies the font to use from attachments via the MIME type,
|
||||
make sure the MIME type is displayed correctly after uploading the attachment
|
||||
(for example <code spellcheck="false">font/woff2</code>).</li>
|
||||
<li data-list-item-id="ed7e90b501e2503f559c3af48c3d1ae0c">Make sure the <code spellcheck="false">role</code> appears as <code spellcheck="false">file</code>,
|
||||
otherwise the font will not be identified.</li>
|
||||
<li data-list-item-id="e7fe120986469e80972cfff7e08095ce3">Multiple attachments are supported, but only one font will actually be
|
||||
used in Trilium's order of preference: <code spellcheck="false">.woff2</code>,
|
||||
<code
|
||||
spellcheck="false">.woff</code>, <code spellcheck="false">.ttf</code>. As such, there's not
|
||||
much reason to upload more than one font per icon pack.</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li data-list-item-id="e07ea13454ff47d3a80d140e435f6e31a">Go back to the note and rename it. The name of the note will also be the
|
||||
name of the icon pack as displayed in the list of icons.</li>
|
||||
</ol>
|
||||
<h3>Assigning the prefix</h3>
|
||||
<p>Before an icon pack can be used, it needs to have a prefix defined. This
|
||||
prefix uniquely identifies the icon pack so that it can be used throughout
|
||||
the application.</p>
|
||||
<p>To do so, Trilium makes use of the same format that was used for the internal
|
||||
icon pack (Boxicons). For example, when an icon from Boxicons is set, it
|
||||
looks like this: <code spellcheck="false">#iconClass="bx bxs-sushi"</code>.
|
||||
In this case, the icon pack prefix is <code spellcheck="false">bx</code> and
|
||||
the icon class name is <code spellcheck="false">bxs-sushi</code>.</p>
|
||||
<p>In order for an icon pack to be recognized, the prefix must be specified
|
||||
in the <code spellcheck="false">#iconPack</code> label. </p>
|
||||
<p>For our example with Phosphor Icons, we can use the <code spellcheck="false">ph</code> prefix
|
||||
since it also matches the prefix set in the original CSS. So in this case
|
||||
it would be <code spellcheck="false">#iconPack=ph</code>.</p>
|
||||
<aside class="admonition important">
|
||||
<p>The prefix must consist of only alphanumeric characters, hyphens and underscore.
|
||||
If the prefix doesn't match these constraints, the icon pack will be ignored
|
||||
and an error will be logged in <a class="reference-link" href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/qzNzp9LYQyPT/_help_bnyigUA2UK7s">Backend (server) logs</a>.</p>
|
||||
</aside>
|
||||
<h3>Final steps</h3>
|
||||
<ul>
|
||||
<li data-list-item-id="ea0a195d13028ebcfdd45cd27468bae7d"><a href="#root/_help_s8alTXmpFR61">Refresh the client</a>
|
||||
<ul>
|
||||
<li data-list-item-id="ecfbcbc9a17681cac7e86039dafa42280">Change the icon of the note and look for the <em>Filter</em> icon in the
|
||||
top-right side.</li>
|
||||
<li data-list-item-id="e37c446c42f22aa5fa6417a2521b4ea3f">Check if the new icon pack is displayed there and click on it to see the
|
||||
full list of icons.</li>
|
||||
<li data-list-item-id="e9546ed2a86e5debc1c3146972ce3ae5e">Go through most of the items to look for issues such as missing icon,
|
||||
wrong names (some icons have aliases/terms that can cause issues).</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="e6d48f2f0011e6dbbbf2aedce5a63ddd8">Optionally, assign an icon from the new icon pack to this note. This icon
|
||||
will be used in the icon pack filter for a visual distinction.</li>
|
||||
<li
|
||||
data-list-item-id="e9b5f41994bb6beae98a2d9a1e396fba0">The icon pack can then be <a href="#root/_help_mHbBMPDPkVV5">exported as ZIP</a> in
|
||||
order to be distributed to other users.
|
||||
<ul>
|
||||
<li data-list-item-id="e9a0f122846acf046541a084e505aba81">It's important to note that icon packs are considered “unsafe” by default,
|
||||
so “Safe mode” must be disabled when importing the ZIP.</li>
|
||||
<li data-list-item-id="e0e3990178843580147bb801c2c629a25">Consider linking new users to the <a class="reference-link" href="#root/_help_gOKqSJgXLcIj">Icon Packs</a> documentation
|
||||
in order to understand how to import and use an icon pack.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Troubleshooting</h3>
|
||||
<p>If the icon pack doesn't show up, look through the <a class="reference-link"
|
||||
href="#root/_help_bnyigUA2UK7s">Backend (server) logs</a> for clues.</p>
|
||||
<ul>
|
||||
<li data-list-item-id="ea20b69c8a700cef8919d3c74cb564d4d">One example is if the font could not be retrieved: <code spellcheck="false">ERROR: Icon pack is missing WOFF/WOFF2/TTF attachment: Boxicons v3 400 (dup) (XRzqDQ67fHEK)</code>.</li>
|
||||
<li
|
||||
data-list-item-id="ec83897ba2caaeb0d906b29e9e4f52a77">Make sure the prefix is unique and not already taken by some other icon
|
||||
pack. When there are two icon packs with the same prefix, only one is used.
|
||||
The server logs will indicate if this situation occurs.</li>
|
||||
<li data-list-item-id="ed42cfe9240d7ec8626e512f9322bf8b9">Make sure the prefix consists only of alphanumeric characters, hyphens
|
||||
and underscore.</li>
|
||||
</ul>
|
||||
@@ -8,6 +8,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover" />
|
||||
<link rel="manifest" crossorigin="use-credentials" href="manifest.webmanifest">
|
||||
<title>Trilium Notes</title>
|
||||
<style id="trilium-icon-packs">
|
||||
<%- iconPackCss %>
|
||||
</style>
|
||||
<script src="<%= appPath %>/runtime.js" crossorigin type="module"></script>
|
||||
</head>
|
||||
<body
|
||||
@@ -50,7 +53,6 @@
|
||||
<% } %>
|
||||
|
||||
<link href="<%= assetPath %>/stylesheets/style.css" rel="stylesheet">
|
||||
<link href="<%= assetPath %>/src/boxicons.css" rel="stylesheet">
|
||||
|
||||
<script src="<%= appPath %>/desktop.js" crossorigin type="module"></script>
|
||||
|
||||
|
||||
@@ -97,6 +97,9 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<style id="trilium-icon-packs">
|
||||
<%- iconPackCss %>
|
||||
</style>
|
||||
<script src="<%= appPath %>/runtime.js" crossorigin type="module"></script>
|
||||
</head>
|
||||
<body
|
||||
@@ -129,7 +132,6 @@
|
||||
<% } %>
|
||||
|
||||
<link href="<%= assetPath %>/stylesheets/style.css" rel="stylesheet">
|
||||
<link href="<%= assetPath %>/src/boxicons.css" rel="stylesheet">
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
platform: "<%= platform %>",
|
||||
hasNativeTitleBar: <%= hasNativeTitleBar %>,
|
||||
TRILIUM_SAFE_MODE: <%= !!process.env.TRILIUM_SAFE_MODE %>,
|
||||
isRtl: <%= !!currentLocale.rtl %>
|
||||
isRtl: <%= !!currentLocale.rtl %>,
|
||||
iconRegistry: <%- JSON.stringify(iconRegistry) %>
|
||||
};
|
||||
</script>
|
||||
@@ -1,15 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
import utils from "../../services/utils.js";
|
||||
import dateUtils from "../../services/date_utils.js";
|
||||
import AbstractBeccaEntity from "./abstract_becca_entity.js";
|
||||
import sql from "../../services/sql.js";
|
||||
import protectedSessionService from "../../services/protected_session.js";
|
||||
import log from "../../services/log.js";
|
||||
|
||||
import type { AttachmentRow } from "@triliumnext/commons";
|
||||
import type BNote from "./bnote.js";
|
||||
import type BBranch from "./bbranch.js";
|
||||
|
||||
import dateUtils from "../../services/date_utils.js";
|
||||
import log from "../../services/log.js";
|
||||
import noteService from "../../services/notes.js";
|
||||
import protectedSessionService from "../../services/protected_session.js";
|
||||
import sql from "../../services/sql.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import AbstractBeccaEntity from "./abstract_becca_entity.js";
|
||||
import type BBranch from "./bbranch.js";
|
||||
import type BNote from "./bnote.js";
|
||||
|
||||
const attachmentRoleToNoteTypeMapping = {
|
||||
image: "image",
|
||||
|
||||
@@ -1623,7 +1623,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
|
||||
* @param matchBy - choose by which property we detect if to update an existing attachment.
|
||||
* Supported values are either 'attachmentId' (default) or 'title'
|
||||
*/
|
||||
saveAttachment({ attachmentId, role, mime, title, content, position }: AttachmentRow, matchBy: "attachmentId" | "title" | undefined = "attachmentId") {
|
||||
saveAttachment({ attachmentId, role, mime, title, content, position }: Omit<AttachmentRow, "ownerId">, matchBy: "attachmentId" | "title" | undefined = "attachmentId") {
|
||||
if (!["attachmentId", "title"].includes(matchBy)) {
|
||||
throw new Error(`Unsupported value '${matchBy}' for matchBy param, has to be either 'attachmentId' or 'title'.`);
|
||||
}
|
||||
@@ -1697,8 +1697,12 @@ class BNote extends AbstractBeccaEntity<BNote> {
|
||||
return pojo;
|
||||
}
|
||||
|
||||
// TODO: Deduplicate with fnote
|
||||
getIcon() {
|
||||
return `tn-icon ${this.#getIconInternal()}`;
|
||||
}
|
||||
|
||||
// TODO: Deduplicate with fnote
|
||||
#getIconInternal() {
|
||||
const iconClassLabels = this.getLabels("iconClass");
|
||||
|
||||
if (iconClassLabels && iconClassLabels.length > 0) {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { assetUrlFragment } from "../services/asset_path.js";
|
||||
import path from "path";
|
||||
import express from "express";
|
||||
import { getResourceDir, isDev } from "../services/utils.js";
|
||||
import type serveStatic from "serve-static";
|
||||
import { existsSync } from "fs";
|
||||
import path from "path";
|
||||
import type serveStatic from "serve-static";
|
||||
|
||||
import { assetUrlFragment } from "../services/asset_path.js";
|
||||
import { getResourceDir, isDev } from "../services/utils.js";
|
||||
|
||||
const persistentCacheStatic = (root: string, options?: serveStatic.ServeStaticOptions<express.Response<unknown, Record<string, unknown>>>) => {
|
||||
if (!isDev) {
|
||||
@@ -31,14 +32,14 @@ async function register(app: express.Application) {
|
||||
css: { devSourcemap: true }
|
||||
});
|
||||
app.use(`/${assetUrlFragment}/`, (req, res, next) => {
|
||||
req.url = `/${assetUrlFragment}` + req.url;
|
||||
req.url = `/${assetUrlFragment}${req.url}`;
|
||||
vite.middlewares(req, res, next);
|
||||
});
|
||||
app.use(`/node_modules/@excalidraw/excalidraw/dist/prod`, persistentCacheStatic(path.join(srcRoot, "../../node_modules/@excalidraw/excalidraw/dist/prod")));
|
||||
} else {
|
||||
const publicDir = path.join(resourceDir, "public");
|
||||
if (!existsSync(publicDir)) {
|
||||
throw new Error("Public directory is missing at: " + path.resolve(publicDir));
|
||||
throw new Error(`Public directory is missing at: ${path.resolve(publicDir)}`);
|
||||
}
|
||||
|
||||
app.use(`/${assetUrlFragment}/src`, persistentCacheStatic(path.join(publicDir, "src")));
|
||||
@@ -47,6 +48,7 @@ async function register(app: express.Application) {
|
||||
app.use(`/${assetUrlFragment}/translations/`, persistentCacheStatic(path.join(publicDir, "translations")));
|
||||
app.use(`/node_modules/`, persistentCacheStatic(path.join(publicDir, "node_modules")));
|
||||
}
|
||||
app.use(`/share/assets/fonts/`, express.static(path.join(getClientDir(), "fonts")));
|
||||
app.use(`/share/assets/`, express.static(getShareThemeAssetDir()));
|
||||
app.use(`/${assetUrlFragment}/images`, persistentCacheStatic(path.join(resourceDir, "assets", "images")));
|
||||
app.use(`/${assetUrlFragment}/doc_notes`, persistentCacheStatic(path.join(resourceDir, "assets", "doc_notes")));
|
||||
@@ -59,10 +61,18 @@ export function getShareThemeAssetDir() {
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
const srcRoot = path.join(__dirname, "..", "..");
|
||||
return path.join(srcRoot, "../../packages/share-theme/dist");
|
||||
} else {
|
||||
const resourceDir = getResourceDir();
|
||||
return path.join(resourceDir, "share-theme/assets");
|
||||
}
|
||||
const resourceDir = getResourceDir();
|
||||
return path.join(resourceDir, "share-theme/assets");
|
||||
}
|
||||
|
||||
export function getClientDir() {
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
const srcRoot = path.join(__dirname, "..", "..");
|
||||
return path.join(srcRoot, "../client/src");
|
||||
}
|
||||
const resourceDir = getResourceDir();
|
||||
return path.join(resourceDir, "public");
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
"use strict";
|
||||
import type { Request, Response } from "express";
|
||||
|
||||
import sql from "../services/sql.js";
|
||||
import packageJson from "../../package.json" with { type: "json" };
|
||||
import type BNote from "../becca/entities/bnote.js";
|
||||
import appPath from "../services/app_path.js";
|
||||
import assetPath from "../services/asset_path.js";
|
||||
import attributeService from "../services/attributes.js";
|
||||
import config from "../services/config.js";
|
||||
import optionService from "../services/options.js";
|
||||
import log from "../services/log.js";
|
||||
import { isDev, isElectron, isWindows11 } from "../services/utils.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
import packageJson from "../../package.json" with { type: "json" };
|
||||
import assetPath from "../services/asset_path.js";
|
||||
import appPath from "../services/app_path.js";
|
||||
import { generateToken as generateCsrfToken } from "./csrf_protection.js";
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import type BNote from "../becca/entities/bnote.js";
|
||||
import { getCurrentLocale } from "../services/i18n.js";
|
||||
import { generateCss, generateIconRegistry, getIconPacks, MIME_TO_EXTENSION_MAPPINGS } from "../services/icon_packs.js";
|
||||
import log from "../services/log.js";
|
||||
import optionService from "../services/options.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
import sql from "../services/sql.js";
|
||||
import { isDev, isElectron, isWindows11 } from "../services/utils.js";
|
||||
import { generateToken as generateCsrfToken } from "./csrf_protection.js";
|
||||
|
||||
type View = "desktop" | "mobile" | "print";
|
||||
|
||||
@@ -35,10 +34,11 @@ function index(req: Request, res: Response) {
|
||||
const theme = options.theme;
|
||||
const themeNote = attributeService.getNoteWithLabel("appTheme", theme);
|
||||
const nativeTitleBarVisible = options.nativeTitleBarVisible === "true";
|
||||
const iconPacks = getIconPacks();
|
||||
|
||||
res.render(view, {
|
||||
device: view,
|
||||
csrfToken: csrfToken,
|
||||
csrfToken,
|
||||
themeCssUrl: getThemeCssUrl(theme, themeNote),
|
||||
themeUseNextAsBase: themeNote?.getAttributeValue("label", "appThemeBase"),
|
||||
headingStyle: options.headingStyle,
|
||||
@@ -61,7 +61,14 @@ function index(req: Request, res: Response) {
|
||||
assetPath,
|
||||
appPath,
|
||||
baseApiUrl: 'api/',
|
||||
currentLocale: getCurrentLocale()
|
||||
currentLocale: getCurrentLocale(),
|
||||
iconPackCss: iconPacks
|
||||
.map(p => generateCss(p, p.builtin
|
||||
? `${assetPath}/fonts/${p.fontAttachmentId}.${MIME_TO_EXTENSION_MAPPINGS[p.fontMime]}`
|
||||
: `api/attachments/download/${p.fontAttachmentId}`))
|
||||
.filter(Boolean)
|
||||
.join("\n\n"),
|
||||
iconRegistry: generateIconRegistry(iconPacks)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -118,10 +125,9 @@ function getThemeCssUrl(theme: string, themeNote: BNote | null) {
|
||||
return `${assetPath}/stylesheets/theme-next-dark.css`;
|
||||
} else if (!process.env.TRILIUM_SAFE_MODE && themeNote) {
|
||||
return `api/notes/download/${themeNote.noteId}`;
|
||||
} else {
|
||||
// baseline light theme
|
||||
return false;
|
||||
}
|
||||
// baseline light theme
|
||||
return false;
|
||||
}
|
||||
|
||||
function getAppCssNoteIds() {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user