neiki-editor 2.7.0 → 2.8.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 CHANGED
@@ -11,7 +11,7 @@
11
11
  <img src="https://img.shields.io/badge/css-%23663399.svg?style=for-the-badge&logo=css&logoColor=white" alt="CSS">
12
12
  <br>
13
13
  <img src="https://img.shields.io/badge/License-MIT-2563EB?style=for-the-badge&logo=open-source-initiative&logoColor=white&labelColor=000F15&logoWidth=20" alt="License">
14
- <img src="https://img.shields.io/badge/Version-2.7.0-2563EB?style=for-the-badge&logo=semantic-release&logoColor=white&labelColor=000F15&logoWidth=20" alt="Version">
14
+ <img src="https://img.shields.io/badge/Version-2.8.0-2563EB?style=for-the-badge&logo=semantic-release&logoColor=white&labelColor=000F15&logoWidth=20" alt="Version">
15
15
  </p>
16
16
 
17
17
  <p align="center">
@@ -49,7 +49,7 @@ Add this single line — CSS is included automatically, always the **latest vers
49
49
  #### Pin a specific version
50
50
 
51
51
  ```html
52
- <script src="https://cdn.neiki.eu/neiki-editor/2.7.0/neiki-editor.min.js"></script>
52
+ <script src="https://cdn.neiki.eu/neiki-editor/2.8.0/neiki-editor.min.js"></script>
53
53
  ```
54
54
 
55
55
  #### Load CSS and JS separately
@@ -60,8 +60,8 @@ Add this single line — CSS is included automatically, always the **latest vers
60
60
  <script src="https://cdn.neiki.eu/neiki-editor/neiki-editor.js"></script>
61
61
 
62
62
  <!-- Or pinned -->
63
- <link rel="stylesheet" href="https://cdn.neiki.eu/neiki-editor/2.7.0/neiki-editor.css">
64
- <script src="https://cdn.neiki.eu/neiki-editor/2.7.0/neiki-editor.js"></script>
63
+ <link rel="stylesheet" href="https://cdn.neiki.eu/neiki-editor/2.8.0/neiki-editor.css">
64
+ <script src="https://cdn.neiki.eu/neiki-editor/2.8.0/neiki-editor.js"></script>
65
65
  ```
66
66
 
67
67
  #### Alternative CDN — jsDelivr
@@ -71,15 +71,15 @@ Add this single line — CSS is included automatically, always the **latest vers
71
71
  <script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@latest/dist/neiki-editor.min.js"></script>
72
72
 
73
73
  <!-- Pinned -->
74
- <script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.7.0/dist/neiki-editor.min.js"></script>
74
+ <script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.8.0/dist/neiki-editor.min.js"></script>
75
75
 
76
76
  <!-- Separate files (latest) -->
77
77
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@latest/dist/neiki-editor.css">
78
78
  <script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@latest/dist/neiki-editor.js"></script>
79
79
 
80
80
  <!-- Separate files (pinned) -->
81
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.7.0/dist/neiki-editor.css">
82
- <script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.7.0/dist/neiki-editor.js"></script>
81
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.8.0/dist/neiki-editor.css">
82
+ <script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.8.0/dist/neiki-editor.js"></script>
83
83
  ```
84
84
 
85
85
  #### Package Manager
@@ -466,6 +466,10 @@ Right-click on any table cell to access:
466
466
  - **Merge Cells** — merge selected cells horizontally
467
467
  - **Split Cell** — split a previously merged cell
468
468
 
469
+ ### Column Resize
470
+
471
+ Hover near any column border to reveal a **drag handle**. Drag to resize adjacent column widths. The table uses fixed layout during resize for precise control.
472
+
469
473
  ---
470
474
 
471
475
  ## 🖼️ Image Support
@@ -482,6 +486,10 @@ The Image dialog includes a file upload input. Selected images are converted to
482
486
 
483
487
  Drag image files directly into the editor content area. Images are automatically converted to base64 and inserted at the drop position.
484
488
 
489
+ ### Resize Images
490
+
491
+ Click any image in the editor to select it — **resize handles** appear on all four corners. Drag any handle to resize while maintaining aspect ratio. A live **size label** (width × height) is displayed below the image during resizing.
492
+
485
493
  ---
486
494
 
487
495
  ## 🔍 Find & Replace
@@ -501,13 +509,20 @@ Features:
501
509
 
502
510
  When you select text in the editor, a floating toolbar appears above the selection with quick access to:
503
511
 
504
- - Bold, Italic, Underline, Strikethrough
505
- - Insert Link
512
+ - **Move Block Up / Down** — reorder the current content block (left side)
513
+ - **Bold, Italic, Underline, Strikethrough** — quick formatting
514
+ - **Insert Link**
506
515
 
507
516
  The toolbar follows the selection and disappears when the selection is cleared.
508
517
 
509
518
  ---
510
519
 
520
+ ## 🔀 Block Drag & Drop
521
+
522
+ Hover over any content block (paragraph, heading, table, image, list, etc.) to reveal a **grip handle** (⠿) on the left side. Drag to reorder blocks within the editor. A ghost preview and drop placeholder guide the drop position.
523
+
524
+ ---
525
+
511
526
  ## 🖨️ Print
512
527
 
513
528
  Click the **Print** button to open the browser print dialog with the editor content formatted for printing.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * NeikiEditor - Production-Ready WYSIWYG Rich Text Editor
3
3
  * CSS Stylesheet
4
- * Version: 2.7.0
4
+ * Version: 2.8.0
5
5
  */
6
6
 
7
7
  /* ============================================
@@ -1533,6 +1533,18 @@
1533
1533
  height: 14px;
1534
1534
  }
1535
1535
 
1536
+ .neiki-floating-divider {
1537
+ width: 1px;
1538
+ height: 20px;
1539
+ background: var(--neiki-border-color);
1540
+ margin: 0 2px;
1541
+ }
1542
+
1543
+ .neiki-floating-move-btn svg {
1544
+ width: 16px;
1545
+ height: 16px;
1546
+ }
1547
+
1536
1548
  /* ============================================
1537
1549
  Tooltips
1538
1550
  ============================================ */
@@ -1598,28 +1610,146 @@
1598
1610
  /* ============================================
1599
1611
  Image Resize Handles
1600
1612
  ============================================ */
1601
- .neiki-image-wrapper {
1613
+ .neiki-img-resizable {
1602
1614
  display: inline-block;
1603
1615
  position: relative;
1616
+ outline: 2px solid var(--neiki-accent-color);
1617
+ outline-offset: 2px;
1618
+ border-radius: 4px;
1619
+ line-height: 0;
1604
1620
  }
1605
1621
 
1606
- .neiki-image-wrapper.selected {
1607
- outline: 2px solid var(--neiki-accent-color);
1622
+ .neiki-img-resizable img {
1623
+ display: block;
1624
+ max-width: 100%;
1608
1625
  }
1609
1626
 
1610
- .neiki-resize-handle {
1627
+ .neiki-img-resize-handle {
1611
1628
  position: absolute;
1612
- width: 10px;
1613
- height: 10px;
1629
+ width: 12px;
1630
+ height: 12px;
1614
1631
  background: var(--neiki-accent-color);
1615
1632
  border: 2px solid #fff;
1616
1633
  border-radius: 2px;
1634
+ z-index: 10;
1635
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
1636
+ }
1637
+
1638
+ .neiki-img-resize-handle.nw { top: -6px; left: -6px; cursor: nw-resize; }
1639
+ .neiki-img-resize-handle.ne { top: -6px; right: -6px; cursor: ne-resize; }
1640
+ .neiki-img-resize-handle.sw { bottom: -6px; left: -6px; cursor: sw-resize; }
1641
+ .neiki-img-resize-handle.se { bottom: -6px; right: -6px; cursor: se-resize; }
1642
+
1643
+ .neiki-img-size-label {
1644
+ position: absolute;
1645
+ bottom: -32px;
1646
+ left: 50%;
1647
+ transform: translateX(-50%);
1648
+ background: var(--neiki-text-primary);
1649
+ color: var(--neiki-bg-primary);
1650
+ font-size: 13px;
1651
+ line-height: 1.4;
1652
+ font-weight: 600;
1653
+ padding: 4px 12px;
1654
+ border-radius: 6px;
1655
+ white-space: nowrap;
1656
+ pointer-events: none;
1657
+ z-index: 10;
1658
+ opacity: 0.9;
1659
+ }
1660
+
1661
+ /* Touch-friendly resize handles */
1662
+ @media (pointer: coarse) {
1663
+ .neiki-img-resize-handle {
1664
+ width: 20px;
1665
+ height: 20px;
1666
+ }
1667
+ .neiki-img-resize-handle.nw { top: -10px; left: -10px; }
1668
+ .neiki-img-resize-handle.ne { top: -10px; right: -10px; }
1669
+ .neiki-img-resize-handle.sw { bottom: -10px; left: -10px; }
1670
+ .neiki-img-resize-handle.se { bottom: -10px; right: -10px; }
1671
+ }
1672
+
1673
+ /* ============================================
1674
+ Table Column Resize Handle
1675
+ ============================================ */
1676
+ .neiki-table-col-resize-handle {
1677
+ position: absolute;
1678
+ width: 6px;
1679
+ cursor: col-resize;
1680
+ z-index: 10;
1681
+ background: transparent;
1682
+ transition: background 0.1s;
1683
+ }
1684
+
1685
+ .neiki-table-col-resize-handle:hover,
1686
+ .neiki-table-col-resize-handle:active {
1687
+ background: var(--neiki-accent-color);
1688
+ opacity: 0.6;
1689
+ border-radius: 3px;
1690
+ }
1691
+
1692
+ /* ============================================
1693
+ Block Drag & Drop
1694
+ ============================================ */
1695
+ .neiki-block-grip {
1696
+ position: absolute;
1697
+ width: 22px;
1698
+ height: 22px;
1699
+ display: flex;
1700
+ align-items: center;
1701
+ justify-content: center;
1702
+ cursor: grab;
1703
+ color: var(--neiki-text-muted);
1704
+ opacity: 0;
1705
+ transition: opacity 0.15s, color 0.15s;
1706
+ border-radius: 4px;
1707
+ z-index: 5;
1708
+ user-select: none;
1709
+ }
1710
+
1711
+ .neiki-content:hover .neiki-block-grip {
1712
+ opacity: 0.5;
1713
+ }
1714
+
1715
+ .neiki-block-grip:hover {
1716
+ opacity: 1 !important;
1717
+ color: var(--neiki-text-primary);
1718
+ background: var(--neiki-bg-hover);
1719
+ }
1720
+
1721
+ .neiki-block-grip:active {
1722
+ cursor: grabbing;
1723
+ }
1724
+
1725
+ .neiki-block-grip svg {
1726
+ width: 14px;
1727
+ height: 14px;
1728
+ fill: currentColor;
1729
+ pointer-events: none;
1617
1730
  }
1618
1731
 
1619
- .neiki-resize-handle.nw { top: -5px; left: -5px; cursor: nw-resize; }
1620
- .neiki-resize-handle.ne { top: -5px; right: -5px; cursor: ne-resize; }
1621
- .neiki-resize-handle.sw { bottom: -5px; left: -5px; cursor: sw-resize; }
1622
- .neiki-resize-handle.se { bottom: -5px; right: -5px; cursor: se-resize; }
1732
+ .neiki-block-ghost {
1733
+ position: fixed;
1734
+ z-index: 100000;
1735
+ pointer-events: none;
1736
+ opacity: 0.7;
1737
+ background: var(--neiki-bg-primary);
1738
+ border: 2px solid var(--neiki-accent-color);
1739
+ border-radius: 6px;
1740
+ padding: 8px 12px;
1741
+ box-shadow: var(--neiki-shadow-lg);
1742
+ max-height: 120px;
1743
+ overflow: hidden;
1744
+ }
1745
+
1746
+ .neiki-block-placeholder {
1747
+ border: 2px dashed var(--neiki-accent-color);
1748
+ border-radius: 6px;
1749
+ background: rgba(13, 110, 253, 0.05);
1750
+ margin: 2px 0;
1751
+ transition: height 0.15s ease;
1752
+ }
1623
1753
 
1624
1754
  /* ============================================
1625
1755
  Print Styles
@@ -1634,7 +1764,11 @@
1634
1764
  .neiki-statusbar,
1635
1765
  .neiki-floating-toolbar,
1636
1766
  .neiki-find-replace,
1637
- .neiki-code-view-header {
1767
+ .neiki-code-view-header,
1768
+ .neiki-block-grip,
1769
+ .neiki-img-resize-handle,
1770
+ .neiki-img-size-label,
1771
+ .neiki-table-col-resize-handle {
1638
1772
  display: none !important;
1639
1773
  }
1640
1774