tiptap-extension-izzy-resizable-image 0.1.3 → 0.1.4

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.
Files changed (3) hide show
  1. package/README.md +27 -16
  2. package/npm/index.js +25 -6
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Resizable inline image node for TipTap v2 with eight resize handles, optional alignment menu, drag-and-drop, and sensible defaults via `.extend()`.
4
4
 
5
- Demo: https://bernanr.github.io/TipTap-Extension-Izzy-Resizable-Image
5
+ Demo: https://startinn.github.io/TipTap-Extension-Izzy-Resizable-Image/
6
6
 
7
7
  ## Features
8
8
 
@@ -44,14 +44,14 @@ editor.commands.setResizableImageAlignment('center');
44
44
 
45
45
  ### Using from npm (bundler)
46
46
 
47
- ```bash
48
- npm install tiptap-extension-izzy-resizable-image @tiptap/core@^3 prosemirror-state
49
- ```
47
+ ```bash
48
+ npm install tiptap-extension-izzy-resizable-image @tiptap/core@^3 prosemirror-state
49
+ ```
50
50
 
51
51
  ```js
52
52
  import { Editor } from '@tiptap/core';
53
53
  import StarterKit from '@tiptap/starter-kit';
54
- import { TiptapIzzyExtensionResizableImage } from 'tiptap-extension-izzy-resizable-image';
54
+ import { TiptapIzzyExtensionResizableImage } from 'tiptap-extension-izzy-resizable-image';
55
55
 
56
56
  const editor = new Editor({
57
57
  element: document.querySelector('#editor'),
@@ -74,13 +74,23 @@ const editor = new Editor({
74
74
  height: 200,
75
75
  showAlignMenu: true,
76
76
  alignMenuPosition: 'below',
77
- alignMenuIcons: {
78
- left: '⟸',
79
- center: '⇔',
80
- right: '⟹',
81
- clear: 'x',
82
- preview: '🔍',
83
- },
77
+ alignMenuIcons: {
78
+ left: '⟸',
79
+ center: '⇔',
80
+ right: '⟹',
81
+ clear: 'x',
82
+ preview: '🔍',
83
+ },
84
+ alignMenuButtonsHide: {
85
+ // hide specific buttons if true
86
+ // left: true,
87
+ // right: true,
88
+ // center: true,
89
+ // clear: true,
90
+ // preview: true,
91
+ // size50: true,
92
+ // size100: true,
93
+ },
84
94
  };
85
95
  },
86
96
  }),
@@ -96,7 +106,8 @@ editor.commands.insertResizableImage({ src: 'https://picsum.photos/300/200', wid
96
106
  - `height: number | null` — default height in pixels when node `height` attr is missing.
97
107
  - `showAlignMenu: boolean` — whether the inline alignment menu is shown by default.
98
108
  - `alignMenuPosition: 'above' | 'below'` — where the menu appears relative to the image.
99
- - `alignMenuIcons: { left: string, center: string, right: string, clear: string, preview: string }` — HTML strings for menu buttons.
109
+ - `alignMenuIcons: { left: string, center: string, right: string, clear: string, preview: string }` — HTML strings for menu buttons.
110
+ - `alignMenuButtonsHide: Record<string, boolean>` — hide specific buttons when `true` (supports `left`, `center`, `right`, `clear`, `preview`, `size50`, `size100`).
100
111
 
101
112
  Reference:
102
113
  - Defined in `resizable-image.js:387-394`
@@ -117,9 +128,9 @@ These can be set per-node, overriding options.
117
128
  - `alignMenuPosition: 'above' | 'below' | null`
118
129
  - `iconLeft: string | null` — HTML or text for the left button.
119
130
  - `iconCenter: string | null`
120
- - `iconRight: string | null`
121
- - `iconClear: string | null`
122
- - `iconView: string | null` — HTML or text for the preview (lightbox) button.
131
+ - `iconRight: string | null`
132
+ - `iconClear: string | null`
133
+ - `iconView: string | null` — HTML or text for the preview (lightbox) button.
123
134
 
124
135
  Reference: `resizable-image.js:358-372`
125
136
 
package/npm/index.js CHANGED
@@ -85,24 +85,33 @@ class ResizableImageView {
85
85
  this.btnRight = document.createElement('button')
86
86
  this.btnClear = document.createElement('button')
87
87
  this.btnView = document.createElement('button')
88
+ this.btnSize50 = document.createElement('button')
89
+ this.btnSize100 = document.createElement('button')
88
90
 
89
91
  this.btnLeft.innerHTML = (node.attrs.iconLeft != null ? node.attrs.iconLeft : (this.options.alignMenuIcons?.left ?? '⟸'))
90
92
  this.btnCenter.innerHTML = (node.attrs.iconCenter != null ? node.attrs.iconCenter : (this.options.alignMenuIcons?.center ?? '⇔'))
91
93
  this.btnRight.innerHTML = (node.attrs.iconRight != null ? node.attrs.iconRight : (this.options.alignMenuIcons?.right ?? '⟹'))
92
94
  this.btnClear.innerHTML = (node.attrs.iconClear != null ? node.attrs.iconClear : (this.options.alignMenuIcons?.clear ?? 'x'))
93
95
  this.btnView.innerHTML = (this.options.alignMenuIcons?.preview ?? '🔍')
96
+ this.btnSize50.textContent = '50%'
97
+ this.btnSize100.textContent = '100%'
94
98
 
95
99
  this.btnLeft.addEventListener('click', () => this.applyAlignAttr('left'))
96
100
  this.btnCenter.addEventListener('click', () => this.applyAlignAttr('center'))
97
101
  this.btnRight.addEventListener('click', () => this.applyAlignAttr('right'))
98
102
  this.btnClear.addEventListener('click', () => this.applyAlignAttr(null))
99
103
  this.btnView.addEventListener('click', () => this.openModal())
100
-
101
- this.menu.appendChild(this.btnLeft)
102
- this.menu.appendChild(this.btnCenter)
103
- this.menu.appendChild(this.btnRight)
104
- this.menu.appendChild(this.btnClear)
105
- this.menu.appendChild(this.btnView)
104
+ this.btnSize50.addEventListener('click', () => this.applyResizePercent(0.5))
105
+ this.btnSize100.addEventListener('click', () => this.applyResizePercent(1))
106
+
107
+ const hidden = this.options.alignMenuButtonsHide || {}
108
+ if (!hidden.left) this.menu.appendChild(this.btnLeft)
109
+ if (!hidden.center) this.menu.appendChild(this.btnCenter)
110
+ if (!hidden.right) this.menu.appendChild(this.btnRight)
111
+ if (!hidden.clear) this.menu.appendChild(this.btnClear)
112
+ if (!hidden.preview) this.menu.appendChild(this.btnView)
113
+ if (!hidden.size50) this.menu.appendChild(this.btnSize50)
114
+ if (!hidden.size100) this.menu.appendChild(this.btnSize100)
106
115
 
107
116
  this.updateMenuPosition(node.attrs.alignMenuPosition != null ? node.attrs.alignMenuPosition : (this.options && this.options.alignMenuPosition != null ? this.options.alignMenuPosition : 'below'))
108
117
 
@@ -187,6 +196,15 @@ class ResizableImageView {
187
196
  }
188
197
  }
189
198
 
199
+ applyResizePercent(percent) {
200
+ const naturalW = this.img.naturalWidth || Math.round(this.img.getBoundingClientRect().width)
201
+ const targetW = Math.max(20, Math.round(naturalW * percent))
202
+ const targetH = this.aspect ? Math.round(targetW / this.aspect) : Math.round(this.img.getBoundingClientRect().height)
203
+ const pos = this.getPos()
204
+ const tr = this.view.state.tr.setNodeMarkup(pos, null, { ...this.node.attrs, width: targetW, height: targetH })
205
+ this.view.dispatch(tr)
206
+ }
207
+
190
208
  onPointerDown(event) {
191
209
  event.preventDefault()
192
210
  const direction = event.currentTarget.dataset.direction
@@ -364,6 +382,7 @@ export const TiptapIzzyExtensionResizableImage = Node.create({
364
382
  showAlignMenu: true,
365
383
  alignMenuPosition: 'below',
366
384
  alignMenuIcons: { left: '⟸', center: '⇔', right: '⟹', clear: 'x', preview: '🔍' },
385
+ alignMenuButtonsHide: {},
367
386
  }
368
387
  },
369
388
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiptap-extension-izzy-resizable-image",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Resizable image NodeView for TipTap v2 with alignment menu and defaults",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,7 +15,7 @@
15
15
  ],
16
16
  "repository": {
17
17
  "type": "git",
18
- "url": "https://github.com/BernanR/TipTap-Extension-Izzy-Resizable-Image.git"
18
+ "url": "git+https://github.com/startinn/TipTap-Extension-Izzy-Resizable-Image.git"
19
19
  },
20
20
  "keywords": [
21
21
  "tiptap",