noteloom 0.1.6 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +639 -414
- package/dist/index.d.ts +620 -0
- package/dist/noteloom.cjs +330 -11
- package/dist/noteloom.cjs.map +1 -1
- package/dist/noteloom.es.js +8174 -5208
- package/dist/noteloom.es.js.map +1 -1
- package/dist/style.css +322 -3
- package/package.json +26 -6
package/dist/style.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* noteloom's default theme — minimal, clean,
|
|
2
|
+
* noteloom's default theme — minimal, clean, modern SaaS-adjacent.
|
|
3
3
|
*
|
|
4
4
|
* Ships as plain CSS custom properties on :root (not scoped to a wrapper
|
|
5
5
|
* element) deliberately: several of this package's own pieces — Select's
|
|
@@ -101,6 +101,18 @@
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
.be-editable {
|
|
104
|
+
/* Block-level and full-width so the whole line (including the blank
|
|
105
|
+
trailing space after short text, and an empty line's full height) is
|
|
106
|
+
part of the actual contentEditable hit-test box. Left inline/sized to
|
|
107
|
+
content, a click on that blank area lands on the non-editable wrapper
|
|
108
|
+
div instead of this element: the browser's native "nothing focused
|
|
109
|
+
yet" resolution still finds it on a first click, but re-clicking the
|
|
110
|
+
same dead-zone point while this element already holds the selection
|
|
111
|
+
collapses/clears it instead, since there's nothing here to re-anchor
|
|
112
|
+
the caret onto. */
|
|
113
|
+
display: block;
|
|
114
|
+
width: 100%;
|
|
115
|
+
min-height: 1em;
|
|
104
116
|
outline: none;
|
|
105
117
|
}
|
|
106
118
|
|
|
@@ -753,6 +765,311 @@
|
|
|
753
765
|
font-weight: 500;
|
|
754
766
|
}
|
|
755
767
|
|
|
768
|
+
/* --- canvas (freehand drawing) --- */
|
|
769
|
+
|
|
770
|
+
.be-canvas {
|
|
771
|
+
position: relative;
|
|
772
|
+
display: inline-block;
|
|
773
|
+
margin: 0.6em 0;
|
|
774
|
+
line-height: 0; /* avoids extra inline-block whitespace gap below the <svg> */
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
.be-canvas-surface {
|
|
778
|
+
display: block;
|
|
779
|
+
border: 1px solid var(--noteloom-border);
|
|
780
|
+
border-radius: var(--noteloom-radius-lg);
|
|
781
|
+
background: var(--noteloom-bg);
|
|
782
|
+
max-width: 100%;
|
|
783
|
+
touch-action: none; /* the surface owns its own pointer gestures (drawing/panning), not the browser's default scroll/zoom */
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
.be-canvas-toolbar {
|
|
787
|
+
position: absolute;
|
|
788
|
+
top: 8px;
|
|
789
|
+
right: 8px;
|
|
790
|
+
z-index: 2;
|
|
791
|
+
display: flex;
|
|
792
|
+
flex-wrap: wrap;
|
|
793
|
+
justify-content: flex-end;
|
|
794
|
+
max-width: calc(100% - 16px);
|
|
795
|
+
align-items: center;
|
|
796
|
+
gap: 2px;
|
|
797
|
+
padding: 3px;
|
|
798
|
+
background: rgba(15, 23, 42, 0.72);
|
|
799
|
+
border-radius: var(--noteloom-radius-md);
|
|
800
|
+
opacity: 0;
|
|
801
|
+
transition: opacity 0.12s ease;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
.be-canvas:hover .be-canvas-toolbar,
|
|
805
|
+
.be-canvas-toolbar:focus-within {
|
|
806
|
+
opacity: 1;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
.be-canvas-toolbar-btn {
|
|
810
|
+
border: none;
|
|
811
|
+
background: transparent;
|
|
812
|
+
width: 28px;
|
|
813
|
+
height: 24px;
|
|
814
|
+
display: flex;
|
|
815
|
+
align-items: center;
|
|
816
|
+
justify-content: center;
|
|
817
|
+
color: rgba(255, 255, 255, 0.8);
|
|
818
|
+
border-radius: var(--noteloom-radius-sm);
|
|
819
|
+
cursor: pointer;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
.be-canvas-toolbar-btn:hover {
|
|
823
|
+
background: rgba(255, 255, 255, 0.16);
|
|
824
|
+
color: #fff;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
.be-canvas-toolbar-btn-active {
|
|
828
|
+
background: var(--noteloom-accent);
|
|
829
|
+
color: #fff;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
.be-canvas-toolbar-btn:disabled {
|
|
833
|
+
opacity: 0.4;
|
|
834
|
+
cursor: default;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
.be-canvas-toolbar-btn:disabled:hover {
|
|
838
|
+
background: transparent;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
.be-canvas-zoom-label {
|
|
842
|
+
border: none;
|
|
843
|
+
background: transparent;
|
|
844
|
+
color: rgba(255, 255, 255, 0.8);
|
|
845
|
+
font-size: 0.75rem;
|
|
846
|
+
min-width: 2.8em;
|
|
847
|
+
padding: 0 2px;
|
|
848
|
+
cursor: pointer;
|
|
849
|
+
border-radius: var(--noteloom-radius-sm);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
.be-canvas-zoom-label:hover {
|
|
853
|
+
background: rgba(255, 255, 255, 0.16);
|
|
854
|
+
color: #fff;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
.be-canvas-toolbar-divider {
|
|
858
|
+
width: 1px;
|
|
859
|
+
height: 16px;
|
|
860
|
+
background: rgba(255, 255, 255, 0.24);
|
|
861
|
+
margin: 0 2px;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
.be-canvas-toolbar-swatch {
|
|
865
|
+
border: 2px solid transparent;
|
|
866
|
+
width: 18px;
|
|
867
|
+
height: 18px;
|
|
868
|
+
border-radius: 50%;
|
|
869
|
+
cursor: pointer;
|
|
870
|
+
padding: 0;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
.be-canvas-toolbar-swatch-active {
|
|
874
|
+
border-color: #fff;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
.be-canvas-picker-wrap {
|
|
878
|
+
position: relative;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
.be-canvas-picker {
|
|
882
|
+
position: absolute;
|
|
883
|
+
top: 100%;
|
|
884
|
+
right: 0;
|
|
885
|
+
margin-top: 8px;
|
|
886
|
+
display: flex;
|
|
887
|
+
align-items: center;
|
|
888
|
+
gap: 6px;
|
|
889
|
+
padding: 8px;
|
|
890
|
+
background: rgba(15, 23, 42, 0.92);
|
|
891
|
+
border-radius: var(--noteloom-radius-md);
|
|
892
|
+
z-index: 3;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
.be-canvas-shape-picker {
|
|
896
|
+
flex-wrap: wrap;
|
|
897
|
+
max-width: 132px;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
.be-canvas-color-trigger-dot {
|
|
901
|
+
display: block;
|
|
902
|
+
width: 14px;
|
|
903
|
+
height: 14px;
|
|
904
|
+
border-radius: 50%;
|
|
905
|
+
border: 1px solid rgba(255, 255, 255, 0.6);
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
.be-canvas-fill-trigger-dot {
|
|
909
|
+
display: block;
|
|
910
|
+
width: 14px;
|
|
911
|
+
height: 14px;
|
|
912
|
+
border-radius: 50%;
|
|
913
|
+
border: 1px solid rgba(255, 255, 255, 0.6);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
.be-canvas-fill-trigger-dot-none,
|
|
917
|
+
.be-canvas-fill-swatch-none {
|
|
918
|
+
background: repeating-conic-gradient(rgba(255, 255, 255, 0.5) 0% 25%, transparent 0% 50%) 50% / 8px 8px;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
.be-canvas-custom-swatch {
|
|
922
|
+
width: 18px;
|
|
923
|
+
height: 18px;
|
|
924
|
+
border-radius: 50%;
|
|
925
|
+
overflow: hidden;
|
|
926
|
+
border: 1px dashed rgba(255, 255, 255, 0.6);
|
|
927
|
+
display: inline-flex;
|
|
928
|
+
cursor: pointer;
|
|
929
|
+
flex-shrink: 0;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
.be-canvas-custom-swatch input[type='color'] {
|
|
933
|
+
width: 150%;
|
|
934
|
+
height: 150%;
|
|
935
|
+
margin: -25%;
|
|
936
|
+
border: none;
|
|
937
|
+
padding: 0;
|
|
938
|
+
cursor: pointer;
|
|
939
|
+
background: none;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/* Live size-preview popover: dot grows/shrinks together with the slider as it's dragged. */
|
|
943
|
+
.be-canvas-size-picker {
|
|
944
|
+
min-width: 160px;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
.be-canvas-size-trigger-dot {
|
|
948
|
+
display: block;
|
|
949
|
+
border-radius: 50%;
|
|
950
|
+
background: #fff;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
.be-canvas-size-preview {
|
|
954
|
+
flex-shrink: 0;
|
|
955
|
+
width: 44px;
|
|
956
|
+
height: 44px;
|
|
957
|
+
display: flex;
|
|
958
|
+
align-items: center;
|
|
959
|
+
justify-content: center;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
.be-canvas-size-preview-dot {
|
|
963
|
+
display: block;
|
|
964
|
+
border-radius: 50%;
|
|
965
|
+
background: #fff;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
.be-canvas-size-slider {
|
|
969
|
+
flex: 1;
|
|
970
|
+
min-width: 80px;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
.be-canvas-font-size-trigger {
|
|
974
|
+
display: block;
|
|
975
|
+
font-size: 13px;
|
|
976
|
+
font-weight: 600;
|
|
977
|
+
line-height: 1;
|
|
978
|
+
color: rgba(255, 255, 255, 0.85);
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
.be-canvas-font-size-preview-letter {
|
|
982
|
+
display: block;
|
|
983
|
+
line-height: 1;
|
|
984
|
+
color: #fff;
|
|
985
|
+
font-weight: 600;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
.be-canvas-size-value {
|
|
989
|
+
flex-shrink: 0;
|
|
990
|
+
min-width: 2.5em;
|
|
991
|
+
text-align: right;
|
|
992
|
+
font-size: 0.8rem;
|
|
993
|
+
color: rgba(255, 255, 255, 0.85);
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
.be-canvas[data-tool='eraser'] .be-canvas-surface {
|
|
997
|
+
cursor: cell;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
.be-canvas[data-tool='select'] .be-canvas-surface {
|
|
1001
|
+
cursor: default;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
.be-canvas-selection-box {
|
|
1005
|
+
stroke: var(--noteloom-accent);
|
|
1006
|
+
stroke-width: 1.5;
|
|
1007
|
+
stroke-dasharray: 6 4;
|
|
1008
|
+
vector-effect: non-scaling-stroke;
|
|
1009
|
+
pointer-events: none;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
.be-canvas-selection-handle {
|
|
1013
|
+
fill: #fff;
|
|
1014
|
+
stroke: var(--noteloom-accent);
|
|
1015
|
+
stroke-width: 1.5;
|
|
1016
|
+
vector-effect: non-scaling-stroke;
|
|
1017
|
+
pointer-events: none;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
.be-canvas-rotate-handle {
|
|
1021
|
+
fill: var(--noteloom-accent);
|
|
1022
|
+
stroke: #fff;
|
|
1023
|
+
stroke-width: 1.5;
|
|
1024
|
+
vector-effect: non-scaling-stroke;
|
|
1025
|
+
pointer-events: none;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
.be-canvas-marquee {
|
|
1029
|
+
fill: color-mix(in srgb, var(--noteloom-accent) 12%, transparent);
|
|
1030
|
+
stroke: var(--noteloom-accent);
|
|
1031
|
+
stroke-width: 1.5;
|
|
1032
|
+
stroke-dasharray: 6 4;
|
|
1033
|
+
vector-effect: non-scaling-stroke;
|
|
1034
|
+
pointer-events: none;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
.be-canvas-grid-background {
|
|
1038
|
+
pointer-events: none;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
.be-canvas-grid-dot {
|
|
1042
|
+
fill: rgba(255, 255, 255, 0.18);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
.be-canvas-text-editor {
|
|
1046
|
+
width: 100%;
|
|
1047
|
+
height: 100%;
|
|
1048
|
+
margin: 0;
|
|
1049
|
+
padding: 0;
|
|
1050
|
+
border: 1px dashed var(--noteloom-accent);
|
|
1051
|
+
outline: none;
|
|
1052
|
+
background: transparent;
|
|
1053
|
+
resize: none;
|
|
1054
|
+
overflow: hidden;
|
|
1055
|
+
line-height: 1.3;
|
|
1056
|
+
font-family: inherit;
|
|
1057
|
+
white-space: pre-wrap;
|
|
1058
|
+
word-break: break-word;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
.be-canvas-resize-handle {
|
|
1062
|
+
position: absolute;
|
|
1063
|
+
bottom: 4px;
|
|
1064
|
+
right: 4px;
|
|
1065
|
+
width: 12px;
|
|
1066
|
+
height: 12px;
|
|
1067
|
+
cursor: nwse-resize;
|
|
1068
|
+
border-radius: 2px;
|
|
1069
|
+
border: 1px solid #fff;
|
|
1070
|
+
background: var(--noteloom-accent);
|
|
1071
|
+
}
|
|
1072
|
+
|
|
756
1073
|
/* --- table --- */
|
|
757
1074
|
|
|
758
1075
|
.be-table-scroll {
|
|
@@ -1878,8 +2195,8 @@ tr.be-table-row:hover .be-table-delete-row {
|
|
|
1878
2195
|
}
|
|
1879
2196
|
|
|
1880
2197
|
/* A mention chip always uses this one fixed color, not each option's own
|
|
1881
|
-
tag color —
|
|
1882
|
-
|
|
2198
|
+
tag color — "@mentions are one consistent color" is the common
|
|
2199
|
+
convention rather than a per-person palette. */
|
|
1883
2200
|
.be-select-tag-mention {
|
|
1884
2201
|
background: var(--noteloom-accent-soft);
|
|
1885
2202
|
color: var(--noteloom-accent);
|
|
@@ -2153,6 +2470,8 @@ tr.be-table-row:hover .be-table-delete-row {
|
|
|
2153
2470
|
.be-embed-dropzone,
|
|
2154
2471
|
.be-embed-upload-btn,
|
|
2155
2472
|
.be-embed-url-row,
|
|
2473
|
+
.be-canvas-toolbar,
|
|
2474
|
+
.be-canvas-resize-handle,
|
|
2156
2475
|
.be-callout-color-wrap,
|
|
2157
2476
|
.be-modal-overlay,
|
|
2158
2477
|
.be-mobile-action-bar,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "noteloom",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Zero-runtime-dependency, React-first block/rich-text editor —
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Zero-runtime-dependency, React-first block/rich-text editor — nestable content blocks, inline widgets, slash commands, undo/redo, clipboard, real-time collaborative editing (a custom CRDT over WebRTC), offline-first persistence (IndexedDB + PWA-ready), and live presence, with an optional default theme (noteloom/style.css).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
7
7
|
"editor",
|
|
@@ -9,8 +9,13 @@
|
|
|
9
9
|
"block-editor",
|
|
10
10
|
"wysiwyg",
|
|
11
11
|
"contenteditable",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
12
|
+
"slash-commands",
|
|
13
|
+
"collaborative-editing",
|
|
14
|
+
"crdt",
|
|
15
|
+
"webrtc",
|
|
16
|
+
"offline-first",
|
|
17
|
+
"pwa",
|
|
18
|
+
"real-time"
|
|
14
19
|
],
|
|
15
20
|
"license": "MIT",
|
|
16
21
|
"author": "Nikhil Vishwakarma",
|
|
@@ -28,9 +33,11 @@
|
|
|
28
33
|
],
|
|
29
34
|
"main": "./dist/noteloom.cjs",
|
|
30
35
|
"module": "./dist/noteloom.es.js",
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
31
37
|
"style": "./dist/style.css",
|
|
32
38
|
"exports": {
|
|
33
39
|
".": {
|
|
40
|
+
"types": "./dist/index.d.ts",
|
|
34
41
|
"import": "./dist/noteloom.es.js",
|
|
35
42
|
"require": "./dist/noteloom.cjs",
|
|
36
43
|
"default": "./dist/noteloom.es.js"
|
|
@@ -46,9 +53,17 @@
|
|
|
46
53
|
},
|
|
47
54
|
"scripts": {
|
|
48
55
|
"dev": "vite --config examples/basic/vite.config.js",
|
|
49
|
-
"
|
|
56
|
+
"dev:quickstart": "vite --config examples/01-quickstart/vite.config.js",
|
|
57
|
+
"dev:custom-block": "vite --config examples/02-custom-block/vite.config.js",
|
|
58
|
+
"dev:custom-field-type": "vite --config examples/03-custom-field-type/vite.config.js",
|
|
59
|
+
"dev:styling": "vite --config examples/04-styling/vite.config.js",
|
|
60
|
+
"dev:collab": "vite --config examples/collab/vite.config.js",
|
|
61
|
+
"dev:lan-collab": "vite --config examples/lan-collab/vite.config.js",
|
|
62
|
+
"dev:offline-persist": "vite --config examples/offline-persist/vite.config.js",
|
|
63
|
+
"build": "vite build && node -e \"require('fs').copyFileSync('src/style.css','dist/style.css');require('fs').copyFileSync('src/index.d.ts','dist/index.d.ts')\"",
|
|
50
64
|
"test": "vitest run",
|
|
51
|
-
"
|
|
65
|
+
"typecheck": "tsc",
|
|
66
|
+
"prepublishOnly": "npm test && npm run typecheck && npm run build"
|
|
52
67
|
},
|
|
53
68
|
"peerDependencies": {
|
|
54
69
|
"react": "^18.2.0 || ^19.0.0",
|
|
@@ -57,11 +72,16 @@
|
|
|
57
72
|
"devDependencies": {
|
|
58
73
|
"@testing-library/jest-dom": "^6.4.0",
|
|
59
74
|
"@testing-library/react": "^16.0.0",
|
|
75
|
+
"@types/react": "^18.3.0",
|
|
76
|
+
"@types/react-dom": "^18.3.0",
|
|
60
77
|
"@vitejs/plugin-react": "^4.3.0",
|
|
78
|
+
"fake-indexeddb": "^6.2.5",
|
|
61
79
|
"jsdom": "^25.0.0",
|
|
62
80
|
"react": "^18.3.1",
|
|
63
81
|
"react-dom": "^18.3.1",
|
|
82
|
+
"typescript": "^5.6.0",
|
|
64
83
|
"vite": "^5.4.0",
|
|
84
|
+
"vite-plugin-pwa": "^1.3.0",
|
|
65
85
|
"vitest": "^2.1.0"
|
|
66
86
|
}
|
|
67
87
|
}
|