noteloom 0.2.0 → 0.3.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 +193 -5
- package/dist/index.d.ts +232 -3
- package/dist/noteloom.cjs +402 -8
- package/dist/noteloom.cjs.map +1 -1
- package/dist/noteloom.es.js +6918 -5629
- package/dist/noteloom.es.js.map +1 -1
- package/dist/style.css +394 -0
- package/package.json +6 -1
package/dist/style.css
CHANGED
|
@@ -116,6 +116,20 @@
|
|
|
116
116
|
outline: none;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
/* A run with marks.commentIds set (see src/comments/commentMarks.js) --
|
|
120
|
+
presence/absence only, no per-comment value to vary the color by.
|
|
121
|
+
cursor: pointer hints that it opens CommentPopover on click. */
|
|
122
|
+
.be-comment-highlight {
|
|
123
|
+
background: rgba(234, 179, 8, 0.2);
|
|
124
|
+
border-bottom: 2px solid rgba(234, 179, 8, 0.6);
|
|
125
|
+
cursor: pointer;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* Echoes a hover from the panel/popover back onto the actual text -- see useHoveredComment. */
|
|
129
|
+
.be-comment-highlight-active {
|
|
130
|
+
background: rgba(234, 179, 8, 0.4);
|
|
131
|
+
}
|
|
132
|
+
|
|
119
133
|
/* --- basic leaf blocks --- */
|
|
120
134
|
|
|
121
135
|
.be-paragraph {
|
|
@@ -1703,6 +1717,67 @@ tr.be-table-row:hover .be-table-delete-row {
|
|
|
1703
1717
|
color: var(--noteloom-danger);
|
|
1704
1718
|
}
|
|
1705
1719
|
|
|
1720
|
+
/* --- template picker (see TemplatePicker.jsx) --- */
|
|
1721
|
+
|
|
1722
|
+
.be-template-picker {
|
|
1723
|
+
list-style: none;
|
|
1724
|
+
margin: 0;
|
|
1725
|
+
padding: 0;
|
|
1726
|
+
display: flex;
|
|
1727
|
+
flex-direction: column;
|
|
1728
|
+
gap: 6px;
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
.be-template-picker-empty {
|
|
1732
|
+
color: var(--noteloom-text-faint);
|
|
1733
|
+
font-size: 0.88rem;
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
.be-template-card {
|
|
1737
|
+
display: flex;
|
|
1738
|
+
align-items: center;
|
|
1739
|
+
justify-content: space-between;
|
|
1740
|
+
gap: 12px;
|
|
1741
|
+
padding: 10px 12px;
|
|
1742
|
+
border: 1px solid var(--noteloom-border);
|
|
1743
|
+
border-radius: var(--noteloom-radius-md);
|
|
1744
|
+
background: var(--noteloom-bg);
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
.be-template-card-body {
|
|
1748
|
+
display: flex;
|
|
1749
|
+
flex-direction: column;
|
|
1750
|
+
gap: 2px;
|
|
1751
|
+
min-width: 0;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
.be-template-card-name {
|
|
1755
|
+
font-weight: 600;
|
|
1756
|
+
font-size: 0.92rem;
|
|
1757
|
+
color: var(--noteloom-text);
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
.be-template-card-description {
|
|
1761
|
+
font-size: 0.82rem;
|
|
1762
|
+
color: var(--noteloom-text-muted);
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
.be-template-card-select {
|
|
1766
|
+
flex: none;
|
|
1767
|
+
border: 1px solid var(--noteloom-border);
|
|
1768
|
+
background: var(--noteloom-bg-subtle);
|
|
1769
|
+
color: var(--noteloom-text);
|
|
1770
|
+
border-radius: var(--noteloom-radius-sm);
|
|
1771
|
+
padding: 5px 12px;
|
|
1772
|
+
font-size: 0.85rem;
|
|
1773
|
+
font-weight: 500;
|
|
1774
|
+
cursor: pointer;
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
.be-template-card-select:hover {
|
|
1778
|
+
background: var(--noteloom-bg-hover);
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1706
1781
|
/* --- mobile action bar (pinned above the on-screen keyboard) --- */
|
|
1707
1782
|
|
|
1708
1783
|
.be-mobile-action-bar {
|
|
@@ -2375,6 +2450,323 @@ tr.be-table-row:hover .be-table-delete-row {
|
|
|
2375
2450
|
color: var(--noteloom-text);
|
|
2376
2451
|
}
|
|
2377
2452
|
|
|
2453
|
+
/* --- comments: avatar, header, composer, thread card, click/hover popover, right-side panel --- */
|
|
2454
|
+
|
|
2455
|
+
.be-comment-avatar {
|
|
2456
|
+
flex: none;
|
|
2457
|
+
display: flex;
|
|
2458
|
+
align-items: center;
|
|
2459
|
+
justify-content: center;
|
|
2460
|
+
border-radius: 50%;
|
|
2461
|
+
color: #fff;
|
|
2462
|
+
font-weight: 700;
|
|
2463
|
+
line-height: 1;
|
|
2464
|
+
}
|
|
2465
|
+
|
|
2466
|
+
/* Shared by CommentPopover and FloatingToolbar's standalone composer (see
|
|
2467
|
+
CommentPopoverHeader.jsx) -- title on the left, an explicit close button
|
|
2468
|
+
on the right so dismissing doesn't rely solely on Escape/outside-click. */
|
|
2469
|
+
.be-comment-popover-header {
|
|
2470
|
+
display: flex;
|
|
2471
|
+
align-items: center;
|
|
2472
|
+
justify-content: space-between;
|
|
2473
|
+
gap: 8px;
|
|
2474
|
+
margin-bottom: 10px;
|
|
2475
|
+
padding-bottom: 10px;
|
|
2476
|
+
border-bottom: 1px solid var(--noteloom-border);
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
.be-comment-popover-title {
|
|
2480
|
+
font-weight: 700;
|
|
2481
|
+
font-size: 0.9rem;
|
|
2482
|
+
}
|
|
2483
|
+
|
|
2484
|
+
.be-comment-popover-close {
|
|
2485
|
+
flex: none;
|
|
2486
|
+
border: none;
|
|
2487
|
+
background: transparent;
|
|
2488
|
+
color: var(--noteloom-text-muted);
|
|
2489
|
+
width: 22px;
|
|
2490
|
+
height: 22px;
|
|
2491
|
+
display: flex;
|
|
2492
|
+
align-items: center;
|
|
2493
|
+
justify-content: center;
|
|
2494
|
+
border-radius: var(--noteloom-radius-sm);
|
|
2495
|
+
cursor: pointer;
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2498
|
+
.be-comment-popover-close:hover {
|
|
2499
|
+
background: var(--noteloom-bg-hover);
|
|
2500
|
+
color: var(--noteloom-text);
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
/* Overrides the dark `.be-floating-toolbar` chrome it also carries (see
|
|
2504
|
+
FloatingToolbar.jsx's own comment on why that base class stays) -- a
|
|
2505
|
+
comment composer reads better as a light card than white text on the
|
|
2506
|
+
toolbar's own near-black background. */
|
|
2507
|
+
.be-floating-toolbar.be-floating-toolbar-comment-standalone {
|
|
2508
|
+
display: block;
|
|
2509
|
+
background: var(--noteloom-bg);
|
|
2510
|
+
border: 1px solid var(--noteloom-border);
|
|
2511
|
+
padding: 10px 12px 12px;
|
|
2512
|
+
width: 300px;
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
.be-comment-composer {
|
|
2516
|
+
display: flex;
|
|
2517
|
+
flex-direction: column;
|
|
2518
|
+
gap: 10px;
|
|
2519
|
+
margin-top: 10px;
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2522
|
+
.be-comment-composer-input-row {
|
|
2523
|
+
display: flex;
|
|
2524
|
+
align-items: flex-start;
|
|
2525
|
+
gap: 8px;
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
.be-comment-composer-textarea {
|
|
2529
|
+
flex: 1;
|
|
2530
|
+
min-width: 0;
|
|
2531
|
+
box-sizing: border-box;
|
|
2532
|
+
resize: none;
|
|
2533
|
+
/* ~2 lines to start, grows with content (see CommentComposer's own
|
|
2534
|
+
resizeToContent) up to ~5 lines, then scrolls. */
|
|
2535
|
+
min-height: 2.8em;
|
|
2536
|
+
max-height: 7.2em;
|
|
2537
|
+
overflow-y: auto;
|
|
2538
|
+
padding: 8px 10px;
|
|
2539
|
+
font: inherit;
|
|
2540
|
+
font-size: 0.85rem;
|
|
2541
|
+
line-height: 1.4;
|
|
2542
|
+
color: var(--noteloom-text);
|
|
2543
|
+
background: var(--noteloom-bg-subtle);
|
|
2544
|
+
border: 1px solid var(--noteloom-border);
|
|
2545
|
+
border-radius: var(--noteloom-radius-md);
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
.be-comment-composer-textarea:focus {
|
|
2549
|
+
outline: none;
|
|
2550
|
+
border-color: var(--noteloom-accent);
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2553
|
+
.be-comment-composer-actions {
|
|
2554
|
+
display: flex;
|
|
2555
|
+
justify-content: flex-end;
|
|
2556
|
+
gap: 8px;
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2559
|
+
.be-comment-composer-cancel,
|
|
2560
|
+
.be-comment-composer-submit {
|
|
2561
|
+
display: flex;
|
|
2562
|
+
align-items: center;
|
|
2563
|
+
gap: 6px;
|
|
2564
|
+
border: none;
|
|
2565
|
+
border-radius: var(--noteloom-radius-md);
|
|
2566
|
+
padding: 6px 12px;
|
|
2567
|
+
font-size: 0.8rem;
|
|
2568
|
+
font-weight: 600;
|
|
2569
|
+
cursor: pointer;
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
.be-comment-composer-cancel {
|
|
2573
|
+
background: var(--noteloom-bg-hover);
|
|
2574
|
+
color: var(--noteloom-text-muted);
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
.be-comment-composer-submit {
|
|
2578
|
+
background: var(--noteloom-accent);
|
|
2579
|
+
color: #fff;
|
|
2580
|
+
}
|
|
2581
|
+
|
|
2582
|
+
.be-comment-composer-submit:disabled {
|
|
2583
|
+
opacity: 0.4;
|
|
2584
|
+
cursor: not-allowed;
|
|
2585
|
+
}
|
|
2586
|
+
|
|
2587
|
+
.be-comment-thread {
|
|
2588
|
+
font-size: 0.85rem;
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
.be-comment-thread + .be-comment-thread {
|
|
2592
|
+
margin-top: 16px;
|
|
2593
|
+
padding-top: 16px;
|
|
2594
|
+
border-top: 1px solid var(--noteloom-border);
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2597
|
+
.be-comment-thread-resolved {
|
|
2598
|
+
opacity: 0.6;
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
/* Echoes a hover from the highlighted text back onto this card -- see useHoveredComment. */
|
|
2602
|
+
.be-comment-thread-hovered {
|
|
2603
|
+
background: var(--noteloom-bg-hover);
|
|
2604
|
+
border-radius: var(--noteloom-radius-md);
|
|
2605
|
+
margin: -6px;
|
|
2606
|
+
padding: 6px;
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2609
|
+
.be-comment-message {
|
|
2610
|
+
display: flex;
|
|
2611
|
+
align-items: flex-start;
|
|
2612
|
+
gap: 10px;
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2615
|
+
.be-comment-message + .be-comment-message {
|
|
2616
|
+
margin-top: 10px;
|
|
2617
|
+
}
|
|
2618
|
+
|
|
2619
|
+
.be-comment-message-body {
|
|
2620
|
+
flex: 1;
|
|
2621
|
+
min-width: 0;
|
|
2622
|
+
}
|
|
2623
|
+
|
|
2624
|
+
.be-comment-message-header {
|
|
2625
|
+
display: flex;
|
|
2626
|
+
align-items: baseline;
|
|
2627
|
+
gap: 6px;
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2630
|
+
.be-comment-message-author {
|
|
2631
|
+
font-weight: 600;
|
|
2632
|
+
font-size: 0.78rem;
|
|
2633
|
+
}
|
|
2634
|
+
|
|
2635
|
+
.be-comment-message-time {
|
|
2636
|
+
font-size: 0.72rem;
|
|
2637
|
+
color: var(--noteloom-text-muted);
|
|
2638
|
+
}
|
|
2639
|
+
|
|
2640
|
+
.be-comment-message-text {
|
|
2641
|
+
margin: 3px 0 0;
|
|
2642
|
+
line-height: 1.45;
|
|
2643
|
+
white-space: pre-wrap;
|
|
2644
|
+
word-break: break-word;
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2647
|
+
/* Replies (every message after the thread's first) get a connecting
|
|
2648
|
+
vertical line + indent, chat-thread style -- our data model has no
|
|
2649
|
+
deeper nesting than "root message + flat replies", so one indent level
|
|
2650
|
+
is all this needs. */
|
|
2651
|
+
.be-comment-thread-replies {
|
|
2652
|
+
margin: 10px 0 0 13px;
|
|
2653
|
+
padding-left: 14px;
|
|
2654
|
+
border-left: 2px solid var(--noteloom-border);
|
|
2655
|
+
}
|
|
2656
|
+
|
|
2657
|
+
.be-comment-thread-actions {
|
|
2658
|
+
display: flex;
|
|
2659
|
+
align-items: center;
|
|
2660
|
+
gap: 4px;
|
|
2661
|
+
margin-top: 10px;
|
|
2662
|
+
opacity: 0;
|
|
2663
|
+
transition: opacity 0.1s ease;
|
|
2664
|
+
}
|
|
2665
|
+
|
|
2666
|
+
.be-comment-thread:hover .be-comment-thread-actions,
|
|
2667
|
+
.be-comment-thread:focus-within .be-comment-thread-actions {
|
|
2668
|
+
opacity: 1;
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
.be-comment-thread-actions button {
|
|
2672
|
+
display: flex;
|
|
2673
|
+
align-items: center;
|
|
2674
|
+
gap: 4px;
|
|
2675
|
+
border: none;
|
|
2676
|
+
background: transparent;
|
|
2677
|
+
color: var(--noteloom-text-muted);
|
|
2678
|
+
font-size: 0.78rem;
|
|
2679
|
+
padding: 4px 8px;
|
|
2680
|
+
border-radius: var(--noteloom-radius-sm);
|
|
2681
|
+
cursor: pointer;
|
|
2682
|
+
}
|
|
2683
|
+
|
|
2684
|
+
.be-comment-thread-actions button:hover {
|
|
2685
|
+
background: var(--noteloom-bg-hover);
|
|
2686
|
+
color: var(--noteloom-text);
|
|
2687
|
+
}
|
|
2688
|
+
|
|
2689
|
+
.be-comment-thread-delete {
|
|
2690
|
+
margin-left: auto;
|
|
2691
|
+
}
|
|
2692
|
+
|
|
2693
|
+
/* --- comments: click/hover popover over existing highlighted text --- */
|
|
2694
|
+
|
|
2695
|
+
.be-comment-popover {
|
|
2696
|
+
z-index: 1000;
|
|
2697
|
+
width: 300px;
|
|
2698
|
+
max-width: calc(100vw - 24px);
|
|
2699
|
+
background: var(--noteloom-bg);
|
|
2700
|
+
border: 1px solid var(--noteloom-border);
|
|
2701
|
+
border-radius: var(--noteloom-radius-lg);
|
|
2702
|
+
padding: 12px 14px 14px;
|
|
2703
|
+
box-shadow: var(--noteloom-shadow);
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
/* --- comments: opt-in right-side panel (NoteloomEditor showCommentsPanel) --- */
|
|
2707
|
+
|
|
2708
|
+
/* Deliberately no border/shadow/box background here, or on
|
|
2709
|
+
.be-comments-panel-item below -- comments float directly on the page
|
|
2710
|
+
like margin notes, not a boxed widget, matching how most other editors'
|
|
2711
|
+
own comment sidebars read. */
|
|
2712
|
+
/* No overflow/scrolling of its own on purpose -- each card's position
|
|
2713
|
+
already tracks the PAGE's scroll (see CommentsPanel's recompute()), so
|
|
2714
|
+
the panel scrolling independently would fight that: a wheel gesture over
|
|
2715
|
+
it needs to fall through and scroll the page, not the panel's own box,
|
|
2716
|
+
or cards visually detach from the text they're anchored to. Cards whose
|
|
2717
|
+
anchor has scrolled off-screen just go negative/beyond the viewport and
|
|
2718
|
+
aren't painted -- no clipping box needed for that. */
|
|
2719
|
+
.be-comments-panel {
|
|
2720
|
+
position: fixed;
|
|
2721
|
+
top: 80px;
|
|
2722
|
+
right: 24px;
|
|
2723
|
+
width: 320px;
|
|
2724
|
+
overflow: visible;
|
|
2725
|
+
background: transparent;
|
|
2726
|
+
padding: 0 12px;
|
|
2727
|
+
font-size: 0.85rem;
|
|
2728
|
+
z-index: 500;
|
|
2729
|
+
pointer-events: none;
|
|
2730
|
+
}
|
|
2731
|
+
|
|
2732
|
+
.be-comments-panel-item,
|
|
2733
|
+
.be-comments-panel-empty {
|
|
2734
|
+
pointer-events: auto;
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2737
|
+
.be-comments-panel-empty {
|
|
2738
|
+
color: var(--noteloom-text-muted);
|
|
2739
|
+
font-size: 0.82rem;
|
|
2740
|
+
margin: 0;
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2743
|
+
/* Each .be-comments-panel-item is absolutely positioned (top set inline by
|
|
2744
|
+
CommentsPanel, aligned with its thread's own anchored text, margin-comment
|
|
2745
|
+
style) inside this relatively-positioned container -- height is also set
|
|
2746
|
+
inline, sized to fit the lowest card. */
|
|
2747
|
+
.be-comments-panel-list {
|
|
2748
|
+
position: relative;
|
|
2749
|
+
}
|
|
2750
|
+
|
|
2751
|
+
.be-comments-panel-item {
|
|
2752
|
+
position: absolute;
|
|
2753
|
+
left: 0;
|
|
2754
|
+
right: 0;
|
|
2755
|
+
padding: 8px 12px;
|
|
2756
|
+
border-radius: var(--noteloom-radius-md);
|
|
2757
|
+
transition: top 0.15s ease, background-color 0.1s ease;
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2760
|
+
.be-comments-panel-item:hover {
|
|
2761
|
+
background: var(--noteloom-bg-hover);
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
@media (max-width: 900px) {
|
|
2765
|
+
.be-comments-panel {
|
|
2766
|
+
display: none;
|
|
2767
|
+
}
|
|
2768
|
+
}
|
|
2769
|
+
|
|
2378
2770
|
/* --- voice typing: caret-anchored listening/processing indicator --- */
|
|
2379
2771
|
|
|
2380
2772
|
.be-voice-indicator {
|
|
@@ -2458,6 +2850,8 @@ tr.be-table-row:hover .be-table-delete-row {
|
|
|
2458
2850
|
#be-at-menu,
|
|
2459
2851
|
.be-floating-toolbar,
|
|
2460
2852
|
.be-link-hover-card,
|
|
2853
|
+
.be-comment-popover,
|
|
2854
|
+
.be-comments-panel,
|
|
2461
2855
|
.be-voice-indicator,
|
|
2462
2856
|
.be-table-header-menu-trigger,
|
|
2463
2857
|
.be-table-header-menu,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "noteloom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
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",
|
|
@@ -57,11 +57,15 @@
|
|
|
57
57
|
"dev:custom-block": "vite --config examples/02-custom-block/vite.config.js",
|
|
58
58
|
"dev:custom-field-type": "vite --config examples/03-custom-field-type/vite.config.js",
|
|
59
59
|
"dev:styling": "vite --config examples/04-styling/vite.config.js",
|
|
60
|
+
"dev:templates": "vite --config examples/05-templates/vite.config.js",
|
|
61
|
+
"dev:comments": "vite --config examples/06-comments/vite.config.js",
|
|
62
|
+
"dev:version-history": "vite --config examples/07-version-history/vite.config.js",
|
|
60
63
|
"dev:collab": "vite --config examples/collab/vite.config.js",
|
|
61
64
|
"dev:lan-collab": "vite --config examples/lan-collab/vite.config.js",
|
|
62
65
|
"dev:offline-persist": "vite --config examples/offline-persist/vite.config.js",
|
|
63
66
|
"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')\"",
|
|
64
67
|
"test": "vitest run",
|
|
68
|
+
"test:e2e": "playwright test",
|
|
65
69
|
"typecheck": "tsc",
|
|
66
70
|
"prepublishOnly": "npm test && npm run typecheck && npm run build"
|
|
67
71
|
},
|
|
@@ -70,6 +74,7 @@
|
|
|
70
74
|
"react-dom": "^18.2.0 || ^19.0.0"
|
|
71
75
|
},
|
|
72
76
|
"devDependencies": {
|
|
77
|
+
"@playwright/test": "^1.62.0",
|
|
73
78
|
"@testing-library/jest-dom": "^6.4.0",
|
|
74
79
|
"@testing-library/react": "^16.0.0",
|
|
75
80
|
"@types/react": "^18.3.0",
|