@zipify/wysiwyg 4.12.0-beta.2 → 4.12.0-beta.3
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 +1 -1
- package/dist/cli.js +27 -27
- package/dist/node.js +21 -21
- package/dist/types/enums/Device.d.ts +2 -1
- package/dist/types/enums/TextSetting.d.ts +0 -1
- package/dist/types/services/NodeFactory.d.ts +1 -1
- package/dist/types/utils/clone.d.ts +1 -0
- package/dist/types/utils/index.d.ts +1 -1
- package/dist/wysiwyg.css +28 -46
- package/dist/wysiwyg.mjs +184 -326
- package/example/ExampleApp.vue +6 -3
- package/example/presets.js +203 -227
- package/lib/components/base/NumberField.vue +2 -2
- package/lib/components/toolbar/controls/index.js +0 -1
- package/lib/components/toolbar/layouts/ToolbarDesktop.vue +0 -2
- package/lib/components/toolbar/layouts/ToolbarMobile.vue +0 -2
- package/lib/enums/Device.ts +2 -1
- package/lib/enums/TextSetting.ts +0 -2
- package/lib/extensions/Alignment.js +3 -2
- package/lib/extensions/DeviceManager.js +20 -3
- package/lib/extensions/FontSize.js +12 -6
- package/lib/extensions/LineHeight.js +3 -2
- package/lib/extensions/__tests__/Alignment.test.js +14 -2
- package/lib/extensions/__tests__/FontSize.test.js +14 -2
- package/lib/extensions/__tests__/LineHeight.test.js +14 -2
- package/lib/extensions/__tests__/__snapshots__/Alignment.test.js.snap +27 -0
- package/lib/extensions/__tests__/__snapshots__/FontSize.test.js.snap +30 -0
- package/lib/extensions/__tests__/__snapshots__/LineHeight.test.js.snap +27 -0
- package/lib/extensions/core/NodeProcessor.js +4 -2
- package/lib/extensions/core/__tests__/NodeProcessor.test.js +10 -1
- package/lib/extensions/index.js +0 -2
- package/lib/services/NodeFactory.ts +1 -1
- package/lib/styles/content.css +0 -3
- package/lib/utils/clone.ts +3 -0
- package/lib/utils/convertFontSize.js +7 -2
- package/lib/utils/index.ts +1 -1
- package/package.json +3 -2
- package/dist/types/components/toolbar/controls/LetterSpacingControl.vue.d.ts +0 -2
- package/dist/types/extensions/LetterSpacing.d.ts +0 -2
- package/dist/types/utils/convertEmToPx.d.ts +0 -1
- package/dist/types/utils/convertLetterSpacing.d.ts +0 -1
- package/lib/assets/icons/letter-spacing.svg +0 -3
- package/lib/components/toolbar/controls/LetterSpacingControl.vue +0 -96
- package/lib/extensions/LetterSpacing.js +0 -78
- package/lib/extensions/__tests__/LetterSpacing.test.js +0 -117
- package/lib/extensions/__tests__/__snapshots__/LetterSpacing.test.js.snap +0 -121
- package/lib/utils/convertEmToPx.ts +0 -8
- package/lib/utils/convertLetterSpacing.ts +0 -5
|
@@ -34,22 +34,28 @@ export const FontSize = Mark.create({
|
|
|
34
34
|
}),
|
|
35
35
|
|
|
36
36
|
applyFontSize: createCommand(({ commands }, value) => {
|
|
37
|
-
const
|
|
37
|
+
const targetDevices = commands.getTargetDevices();
|
|
38
|
+
const attrs = Object.fromEntries(targetDevices.map((device) => [device, value]));
|
|
38
39
|
|
|
39
|
-
commands.applyMark(this.name,
|
|
40
|
+
commands.applyMark(this.name, attrs, {
|
|
40
41
|
isAppliedToParent: (parentMark, mark) => {
|
|
41
42
|
if (parentMark.type.name !== mark.type.name) return false;
|
|
42
43
|
|
|
43
|
-
return parentMark.attrs[device] === mark.attrs[device];
|
|
44
|
+
return targetDevices.every((device) => parentMark.attrs[device] === mark.attrs[device]);
|
|
44
45
|
},
|
|
45
46
|
|
|
46
47
|
onAppliedToParent: ({ tr, node, position, mark }) => {
|
|
47
|
-
const
|
|
48
|
-
|
|
48
|
+
const updatedAttrs = { ...mark.attrs };
|
|
49
|
+
|
|
50
|
+
targetDevices.forEach((device) => {
|
|
51
|
+
updatedAttrs[device] = null;
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const canRemove = !Object.values(updatedAttrs).some((value) => !!value);
|
|
49
55
|
|
|
50
56
|
if (canRemove) return false;
|
|
51
57
|
|
|
52
|
-
const updated = mark.type.create(
|
|
58
|
+
const updated = mark.type.create(updatedAttrs);
|
|
53
59
|
|
|
54
60
|
if (node.isText) {
|
|
55
61
|
tr.addMark(position, position + node.nodeSize, updated);
|
|
@@ -72,9 +72,10 @@ export const LineHeight = Extension.create({
|
|
|
72
72
|
}),
|
|
73
73
|
|
|
74
74
|
applyLineHeight: createCommand(({ commands }, value) => {
|
|
75
|
-
const
|
|
75
|
+
const targetDevices = commands.getTargetDevices();
|
|
76
|
+
const attrs = Object.fromEntries(targetDevices.map((device) => [device, value]));
|
|
76
77
|
|
|
77
|
-
commands.setBlockAttributes(this.name,
|
|
78
|
+
commands.setBlockAttributes(this.name, attrs, DEFAULTS);
|
|
78
79
|
})
|
|
79
80
|
};
|
|
80
81
|
}
|
|
@@ -21,13 +21,13 @@ const MockStylePreset = Extension.create({
|
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
function createEditor({ content }) {
|
|
24
|
+
function createEditor({ content, device = 'desktop' }) {
|
|
25
25
|
return new Editor({
|
|
26
26
|
content: ContentNormalizer.normalize(content),
|
|
27
27
|
extensions: buildTestExtensions({
|
|
28
28
|
include: [
|
|
29
29
|
MockStylePreset,
|
|
30
|
-
DeviceManager.configure({ device: ref(
|
|
30
|
+
DeviceManager.configure({ device: ref(device) }),
|
|
31
31
|
AlignmentExtension
|
|
32
32
|
]
|
|
33
33
|
})
|
|
@@ -82,6 +82,18 @@ describe('change value', () => {
|
|
|
82
82
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
+
test('should apply value to all devices', () => {
|
|
86
|
+
const editor = createEditor({
|
|
87
|
+
content: createContent({ alignment: null }),
|
|
88
|
+
device: 'all'
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
editor.commands.selectAll();
|
|
92
|
+
editor.commands.applyAlignment(Alignment.RIGHT);
|
|
93
|
+
|
|
94
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
95
|
+
});
|
|
96
|
+
|
|
85
97
|
test('should remove value', () => {
|
|
86
98
|
const editor = createEditor({
|
|
87
99
|
content: createContent({
|
|
@@ -21,14 +21,14 @@ const MockStylePreset = Extension.create({
|
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
function createEditor({ content }) {
|
|
24
|
+
function createEditor({ content, device = 'desktop' }) {
|
|
25
25
|
return new Editor({
|
|
26
26
|
content: ContentNormalizer.normalize(content),
|
|
27
27
|
extensions: buildTestExtensions({
|
|
28
28
|
include: [
|
|
29
29
|
MockStylePreset,
|
|
30
30
|
DeviceManager.configure({
|
|
31
|
-
device: ref(
|
|
31
|
+
device: ref(device)
|
|
32
32
|
}),
|
|
33
33
|
FontSize.configure({
|
|
34
34
|
minSize: 5,
|
|
@@ -92,6 +92,18 @@ describe('apply font size', () => {
|
|
|
92
92
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
93
93
|
});
|
|
94
94
|
|
|
95
|
+
test('should change font size on all devices', () => {
|
|
96
|
+
const editor = createEditor({
|
|
97
|
+
content: createContent(NodeFactory.text('hello world')),
|
|
98
|
+
device: 'all'
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
editor.commands.selectAll();
|
|
102
|
+
editor.commands.applyFontSize('16');
|
|
103
|
+
|
|
104
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
105
|
+
});
|
|
106
|
+
|
|
95
107
|
test('should increase font size', () => {
|
|
96
108
|
const editor = createEditor({
|
|
97
109
|
content: createContent(NodeFactory.text('hello world', [
|
|
@@ -21,14 +21,14 @@ const MockStylePreset = Extension.create({
|
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
function createEditor({ content, wrapperEl }) {
|
|
24
|
+
function createEditor({ content, wrapperEl, device = 'desktop' }) {
|
|
25
25
|
return new Editor({
|
|
26
26
|
content: ContentNormalizer.normalize(content),
|
|
27
27
|
extensions: buildTestExtensions({
|
|
28
28
|
include: [
|
|
29
29
|
MockStylePreset,
|
|
30
30
|
DeviceManager.configure({
|
|
31
|
-
device: ref(
|
|
31
|
+
device: ref(device)
|
|
32
32
|
}),
|
|
33
33
|
LineHeight.configure({
|
|
34
34
|
wrapperRef: ref(wrapperEl ?? document.createElement('div'))
|
|
@@ -85,6 +85,18 @@ describe('apply value', () => {
|
|
|
85
85
|
|
|
86
86
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
87
87
|
});
|
|
88
|
+
|
|
89
|
+
test('should change value on all devices', () => {
|
|
90
|
+
const editor = createEditor({
|
|
91
|
+
content: createContent({ line_height: null }),
|
|
92
|
+
device: 'all'
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
editor.commands.selectAll();
|
|
96
|
+
editor.commands.applyLineHeight('1.41');
|
|
97
|
+
|
|
98
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
99
|
+
});
|
|
88
100
|
});
|
|
89
101
|
|
|
90
102
|
describe('rendering', () => {
|
|
@@ -27,6 +27,33 @@ Object {
|
|
|
27
27
|
}
|
|
28
28
|
`;
|
|
29
29
|
|
|
30
|
+
exports[`change value should apply value to all devices 1`] = `
|
|
31
|
+
Object {
|
|
32
|
+
"attrs": Object {
|
|
33
|
+
"meta": Object {},
|
|
34
|
+
},
|
|
35
|
+
"content": Array [
|
|
36
|
+
Object {
|
|
37
|
+
"attrs": Object {
|
|
38
|
+
"alignment": Object {
|
|
39
|
+
"desktop": "right",
|
|
40
|
+
"mobile": "right",
|
|
41
|
+
"tablet": "right",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
"content": Array [
|
|
45
|
+
Object {
|
|
46
|
+
"text": "hello world",
|
|
47
|
+
"type": "text",
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
"type": "paragraph",
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
"type": "doc",
|
|
54
|
+
}
|
|
55
|
+
`;
|
|
56
|
+
|
|
30
57
|
exports[`change value should remove value 1`] = `
|
|
31
58
|
Object {
|
|
32
59
|
"attrs": Object {
|
|
@@ -30,6 +30,36 @@ Object {
|
|
|
30
30
|
}
|
|
31
31
|
`;
|
|
32
32
|
|
|
33
|
+
exports[`apply font size should change font size on all devices 1`] = `
|
|
34
|
+
Object {
|
|
35
|
+
"attrs": Object {
|
|
36
|
+
"meta": Object {},
|
|
37
|
+
},
|
|
38
|
+
"content": Array [
|
|
39
|
+
Object {
|
|
40
|
+
"content": Array [
|
|
41
|
+
Object {
|
|
42
|
+
"text": "hello world",
|
|
43
|
+
"type": "text",
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
"marks": Array [
|
|
47
|
+
Object {
|
|
48
|
+
"attrs": Object {
|
|
49
|
+
"desktop": "16",
|
|
50
|
+
"mobile": "16",
|
|
51
|
+
"tablet": "16",
|
|
52
|
+
},
|
|
53
|
+
"type": "font_size",
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
"type": "paragraph",
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
"type": "doc",
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
62
|
+
|
|
33
63
|
exports[`apply font size should decrease font size 1`] = `
|
|
34
64
|
Object {
|
|
35
65
|
"attrs": Object {
|
|
@@ -27,6 +27,33 @@ Object {
|
|
|
27
27
|
}
|
|
28
28
|
`;
|
|
29
29
|
|
|
30
|
+
exports[`apply value should change value on all devices 1`] = `
|
|
31
|
+
Object {
|
|
32
|
+
"attrs": Object {
|
|
33
|
+
"meta": Object {},
|
|
34
|
+
},
|
|
35
|
+
"content": Array [
|
|
36
|
+
Object {
|
|
37
|
+
"attrs": Object {
|
|
38
|
+
"line_height": Object {
|
|
39
|
+
"desktop": "1.41",
|
|
40
|
+
"mobile": "1.41",
|
|
41
|
+
"tablet": "1.41",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
"content": Array [
|
|
45
|
+
Object {
|
|
46
|
+
"text": "hello world",
|
|
47
|
+
"type": "text",
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
"type": "paragraph",
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
"type": "doc",
|
|
54
|
+
}
|
|
55
|
+
`;
|
|
56
|
+
|
|
30
57
|
exports[`parsing html should get value from rendered view 1`] = `
|
|
31
58
|
Object {
|
|
32
59
|
"attrs": Object {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Extension, getMarkType } from '@tiptap/vue-3';
|
|
2
2
|
import { computed, toRef, unref } from 'vue';
|
|
3
3
|
import {
|
|
4
|
+
clone,
|
|
4
5
|
createCommand,
|
|
5
6
|
findMarkByType,
|
|
6
7
|
isMarkAppliedToParent,
|
|
@@ -21,6 +22,7 @@ export const NodeProcessor = Extension.create({
|
|
|
21
22
|
addCommands() {
|
|
22
23
|
return {
|
|
23
24
|
setBlockAttributes: createCommand(({ commands, state }, name, attrs, defaults = {}) => {
|
|
25
|
+
const safeAttrs = clone(attrs);
|
|
24
26
|
const current = unref(commands.getBlockAttributes(name)) ?? {};
|
|
25
27
|
const { doc, tr } = state;
|
|
26
28
|
const { from, to } = tr.selection;
|
|
@@ -28,7 +30,7 @@ export const NodeProcessor = Extension.create({
|
|
|
28
30
|
doc.nodesBetween(from, to, (node, position) => {
|
|
29
31
|
if (!NodeBlockTypeList.includes(node.type.name)) return;
|
|
30
32
|
|
|
31
|
-
tr.setNodeAttribute(position, name, { ...defaults, ...current, ...
|
|
33
|
+
tr.setNodeAttribute(position, name, { ...defaults, ...current, ...safeAttrs });
|
|
32
34
|
});
|
|
33
35
|
}),
|
|
34
36
|
|
|
@@ -139,7 +141,7 @@ export const NodeProcessor = Extension.create({
|
|
|
139
141
|
for (const attrs of unref(selectionRef)) {
|
|
140
142
|
const value = attrs[unref(deviceRef)];
|
|
141
143
|
|
|
142
|
-
if (value
|
|
144
|
+
if (value) return value;
|
|
143
145
|
}
|
|
144
146
|
|
|
145
147
|
return unref(defaultRef);
|
|
@@ -62,7 +62,16 @@ const DeviceManager = Extension.create({
|
|
|
62
62
|
}),
|
|
63
63
|
|
|
64
64
|
addCommands() {
|
|
65
|
-
return {
|
|
65
|
+
return {
|
|
66
|
+
getDevice: createCommand(() => ref(this.options.device)),
|
|
67
|
+
getTargetDevices: createCommand(() => {
|
|
68
|
+
const device = this.options.device;
|
|
69
|
+
|
|
70
|
+
return device === Device.ALL
|
|
71
|
+
? [Device.DESKTOP, Device.TABLET, Device.MOBILE]
|
|
72
|
+
: [device];
|
|
73
|
+
})
|
|
74
|
+
};
|
|
66
75
|
}
|
|
67
76
|
});
|
|
68
77
|
|
package/lib/extensions/index.js
CHANGED
|
@@ -13,7 +13,6 @@ import { TextDecoration } from './TextDecoration';
|
|
|
13
13
|
import { CaseStyle } from './CaseStyle';
|
|
14
14
|
import { Alignment } from './Alignment';
|
|
15
15
|
import { LineHeight } from './LineHeight';
|
|
16
|
-
import { LetterSpacing } from './LetterSpacing';
|
|
17
16
|
import { List } from './list';
|
|
18
17
|
import { Link } from './Link';
|
|
19
18
|
import { Superscript } from './Superscript';
|
|
@@ -67,7 +66,6 @@ export function buildExtensions(options) {
|
|
|
67
66
|
LineHeight.configure({
|
|
68
67
|
wrapperRef: options.wrapperRef
|
|
69
68
|
}),
|
|
70
|
-
LetterSpacing,
|
|
71
69
|
Link.configure({
|
|
72
70
|
preset: toRef(presetsMap, 'link'),
|
|
73
71
|
basePresetClass: options.basePresetClass,
|
|
@@ -136,7 +136,7 @@ export class NodeFactory {
|
|
|
136
136
|
return { type, attrs };
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
static populateAllDevices<V>(value: V): Record<Exclude<Device, Device.COMMON>, V> {
|
|
139
|
+
static populateAllDevices<V>(value: V): Record<Exclude<Device, Device.COMMON | Device.ALL>, V> {
|
|
140
140
|
return { mobile: value, tablet: value, desktop: value };
|
|
141
141
|
}
|
|
142
142
|
}
|
package/lib/styles/content.css
CHANGED
|
@@ -36,7 +36,6 @@ h4.zw-style.zw-style.zw-style {
|
|
|
36
36
|
font-size: var(--zw-font-size-desktop, var(--zw-preset-font-size-desktop));
|
|
37
37
|
text-align: var(--zw-alignment-desktop, var(--zw-preset-alignment-desktop));
|
|
38
38
|
line-height: var(--zw-line-height-desktop, var(--zw-preset-line-height-desktop));
|
|
39
|
-
letter-spacing: var(--zw-letter-spacing-desktop, var(--zw-preset-letter-spacing-desktop));
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
|
|
@@ -46,7 +45,6 @@ h4.zw-style.zw-style.zw-style {
|
|
|
46
45
|
font-size: var(--zw-font-size-tablet, var(--zw-preset-font-size-tablet));
|
|
47
46
|
text-align: var(--zw-alignment-tablet, var(--zw-preset-alignment-tablet));
|
|
48
47
|
line-height: var(--zw-line-height-tablet, var(--zw-preset-line-height-tablet));
|
|
49
|
-
letter-spacing: var(--zw-letter-spacing-tablet, var(--zw-preset-letter-spacing-tablet));
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
|
|
@@ -56,7 +54,6 @@ h4.zw-style.zw-style.zw-style {
|
|
|
56
54
|
font-size: var(--zw-font-size-mobile, var(--zw-preset-font-size-mobile));
|
|
57
55
|
text-align: var(--zw-alignment-mobile, var(--zw-preset-alignment-mobile));
|
|
58
56
|
line-height: var(--zw-line-height-mobile, var(--zw-preset-line-height-mobile));
|
|
59
|
-
letter-spacing: var(--zw-letter-spacing-mobile, var(--zw-preset-letter-spacing-mobile));
|
|
60
57
|
}
|
|
61
58
|
}
|
|
62
59
|
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ContextWindow } from '../services';
|
|
2
2
|
|
|
3
3
|
export function convertFontSize(value, wrapperEl) {
|
|
4
|
-
|
|
4
|
+
if (!value.includes('em')) return parseInt(value);
|
|
5
|
+
|
|
6
|
+
const containerValue = ContextWindow.getComputedStyle(wrapperEl).fontSize;
|
|
7
|
+
const size = parseFloat(value) * parseFloat(containerValue);
|
|
8
|
+
|
|
9
|
+
return Math.round(size);
|
|
5
10
|
}
|
package/lib/utils/index.ts
CHANGED
|
@@ -5,7 +5,6 @@ export { createKeyboardShortcut } from './createKeyboardShortcut';
|
|
|
5
5
|
export { convertColor } from './convertColor';
|
|
6
6
|
export { convertLineHeight } from './convertLineHeight';
|
|
7
7
|
export { convertFontSize } from './convertFontSize';
|
|
8
|
-
export { convertLetterSpacing } from './convertLetterSpacing';
|
|
9
8
|
export { convertAlignment } from './convertAlignment';
|
|
10
9
|
export { importIcon } from './importIcon';
|
|
11
10
|
export { isWysiwygContent } from './isWysiwygContent';
|
|
@@ -15,3 +14,4 @@ export { isNodeFullySelected } from './isNodeFullySelected';
|
|
|
15
14
|
export { isMarkAppliedToParent } from './isMarkAppliedToParent';
|
|
16
15
|
export { findMarkByType } from './findMarkByType';
|
|
17
16
|
export { copyMark } from './copyMark';
|
|
17
|
+
export { clone } from './clone';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zipify/wysiwyg",
|
|
3
|
-
"version": "4.12.0-beta.
|
|
3
|
+
"version": "4.12.0-beta.3",
|
|
4
4
|
"description": "Zipify modification of TipTap text editor",
|
|
5
5
|
"main": "dist/wysiwyg.mjs",
|
|
6
6
|
"types": "dist/wysiwyg.d.ts",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"lint:js": "zipify-lint-js --oxlint-tsconfig ./tsconfig.lint.json ./lib",
|
|
31
31
|
"lint:css": "stylelint ./lib/**/*.{css,vue}",
|
|
32
32
|
"optimize-svg": "svgo --config ./config/svgo.js",
|
|
33
|
-
"prepare": "husky"
|
|
33
|
+
"prepare": "husky",
|
|
34
|
+
"check-types": "vue-tsc -P ./tsconfig.types.json --noEmit"
|
|
34
35
|
},
|
|
35
36
|
"dependencies": {
|
|
36
37
|
"@floating-ui/vue": "^1.1.6",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
-
export default _default;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function convertEmToPx(value: string, wrapperEl: HTMLElement): number;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function convertLetterSpacing(value: string, wrapperEl: HTMLElement): number;
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" style="width:var(--zw-icon-width);height:var(--zw-icon-height)" viewBox="0 0 24 24">
|
|
2
|
-
<path fill="var(--zw-icon-foreground)" fill-rule="evenodd" d="M3 19V5h1.8v14zm16.2 0V5H21v14zM7.815 16.375l3.375-8.75h1.62l3.375 8.75h-1.552l-.81-2.231h-3.645l-.81 2.231zm2.835-3.5h2.7l-1.305-3.631h-.09z" clip-rule="evenodd"/>
|
|
3
|
-
</svg>
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="zw-position--relative" ref="wrapperRef">
|
|
3
|
-
<Button
|
|
4
|
-
class="zw-position--relative"
|
|
5
|
-
icon
|
|
6
|
-
skin="toolbar"
|
|
7
|
-
:active="toggler.isOpened"
|
|
8
|
-
@click="toggler.open"
|
|
9
|
-
v-tooltip="'Letter Spacing'"
|
|
10
|
-
>
|
|
11
|
-
<Icon name="letter-spacing" size="28px" auto-color />
|
|
12
|
-
|
|
13
|
-
<span
|
|
14
|
-
v-if="isCustomized"
|
|
15
|
-
class="zw-button__customized-indicator"
|
|
16
|
-
data-test-selector="customizedIndicator"
|
|
17
|
-
v-tooltip.lg="'Style differs from Page Styles'"
|
|
18
|
-
/>
|
|
19
|
-
</Button>
|
|
20
|
-
|
|
21
|
-
<Modal
|
|
22
|
-
class="zw-letter-spacing-control__modal"
|
|
23
|
-
:toggler="toggler"
|
|
24
|
-
:reference-ref="wrapperRef"
|
|
25
|
-
>
|
|
26
|
-
<FieldLabel class="zw-margin-bottom--xs" field-id="wswg-letter-spacing">
|
|
27
|
-
Letter Spacing
|
|
28
|
-
</FieldLabel>
|
|
29
|
-
|
|
30
|
-
<div class="zw-letter-spacing-control__row">
|
|
31
|
-
<Range
|
|
32
|
-
class="zw-letter-spacing-control__range"
|
|
33
|
-
:step="STEP"
|
|
34
|
-
:min="MIN_VALUE"
|
|
35
|
-
:max="MAX_VALUE"
|
|
36
|
-
:value="currentValue"
|
|
37
|
-
@input="apply"
|
|
38
|
-
/>
|
|
39
|
-
|
|
40
|
-
<NumberField
|
|
41
|
-
:step="STEP"
|
|
42
|
-
:min="MIN_VALUE"
|
|
43
|
-
:max="MAX_VALUE"
|
|
44
|
-
units="px"
|
|
45
|
-
class="zw-letter-spacing-control__field"
|
|
46
|
-
field-id="wswg-letter-spacing"
|
|
47
|
-
:value="currentValue"
|
|
48
|
-
@input="apply"
|
|
49
|
-
/>
|
|
50
|
-
</div>
|
|
51
|
-
</Modal>
|
|
52
|
-
</div>
|
|
53
|
-
</template>
|
|
54
|
-
|
|
55
|
-
<script setup>
|
|
56
|
-
import { inject, ref, computed } from 'vue';
|
|
57
|
-
import { Button, Icon, Modal, Range, NumberField, FieldLabel, useModalToggler } from '../../base';
|
|
58
|
-
import { InjectionTokens } from '../../../injectionTokens';
|
|
59
|
-
import { tooltip as vTooltip } from '../../../directives';
|
|
60
|
-
import { TextSetting } from '../../../enums';
|
|
61
|
-
|
|
62
|
-
const MIN_VALUE = -1.6;
|
|
63
|
-
const MAX_VALUE = 3.2;
|
|
64
|
-
const STEP = 0.1;
|
|
65
|
-
|
|
66
|
-
const editor = inject(InjectionTokens.EDITOR);
|
|
67
|
-
const wrapperRef = ref(null);
|
|
68
|
-
const toggler = useModalToggler();
|
|
69
|
-
|
|
70
|
-
const valueRef = editor.commands.getLetterSpacing();
|
|
71
|
-
|
|
72
|
-
const currentValue = computed(() => valueRef.value ?? 0);
|
|
73
|
-
const isCustomized = editor.commands.isSettingCustomized(TextSetting.LETTER_SPACING);
|
|
74
|
-
|
|
75
|
-
const apply = (value) => editor.commands.applyLetterSpacing(value);
|
|
76
|
-
</script>
|
|
77
|
-
|
|
78
|
-
<style scoped>
|
|
79
|
-
.zw-letter-spacing-control__modal {
|
|
80
|
-
padding: var(--zw-offset-sm);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.zw-letter-spacing-control__row {
|
|
84
|
-
display: flex;
|
|
85
|
-
align-items: center;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
.zw-letter-spacing-control__range {
|
|
89
|
-
width: 156px;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
.zw-letter-spacing-control__field {
|
|
93
|
-
width: 64px;
|
|
94
|
-
margin-left: var(--zw-offset-sm);
|
|
95
|
-
}
|
|
96
|
-
</style>
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { Mark } from '@tiptap/vue-3';
|
|
2
|
-
import { computed, unref } from 'vue';
|
|
3
|
-
import { createCommand, renderMark, convertLetterSpacing } from '../utils';
|
|
4
|
-
import { MarkGroup, TextSetting } from '../enums';
|
|
5
|
-
|
|
6
|
-
export const LetterSpacing = Mark.create({
|
|
7
|
-
name: TextSetting.LETTER_SPACING,
|
|
8
|
-
group: MarkGroup.SETTINGS,
|
|
9
|
-
|
|
10
|
-
addAttributes: () => ({
|
|
11
|
-
mobile: { default: null },
|
|
12
|
-
tablet: { default: null },
|
|
13
|
-
desktop: { default: null }
|
|
14
|
-
}),
|
|
15
|
-
|
|
16
|
-
addCommands() {
|
|
17
|
-
return {
|
|
18
|
-
getLetterSpacing: createCommand(({ commands }) => {
|
|
19
|
-
return commands.getDeviceSettingMark(this.name, commands.getDefaultLetterSpacing());
|
|
20
|
-
}),
|
|
21
|
-
|
|
22
|
-
getDefaultLetterSpacing: createCommand(({ commands }) => {
|
|
23
|
-
const device = commands.getDevice();
|
|
24
|
-
const preset = commands.getPreset();
|
|
25
|
-
|
|
26
|
-
return computed(() => unref(preset)[unref(device)].letter_spacing ?? null);
|
|
27
|
-
}),
|
|
28
|
-
|
|
29
|
-
applyLetterSpacing: createCommand(({ commands }, value) => {
|
|
30
|
-
const device = unref(commands.getDevice());
|
|
31
|
-
|
|
32
|
-
commands.applyMark(this.name, { [device]: value });
|
|
33
|
-
})
|
|
34
|
-
};
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
parseHTML() {
|
|
38
|
-
const parse = (value) => {
|
|
39
|
-
if (!value) return null;
|
|
40
|
-
|
|
41
|
-
const wrapperEl = unref(this.options.wrapperRef);
|
|
42
|
-
const converted = convertLetterSpacing(value, wrapperEl);
|
|
43
|
-
|
|
44
|
-
return `${converted}px`;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
return [
|
|
48
|
-
{
|
|
49
|
-
tag: '[style*="--zw-letter-spacing"]',
|
|
50
|
-
|
|
51
|
-
getAttrs: ({ style }) => ({
|
|
52
|
-
mobile: parse(style.getPropertyValue('--zw-letter-spacing-mobile')),
|
|
53
|
-
tablet: parse(style.getPropertyValue('--zw-letter-spacing-tablet')),
|
|
54
|
-
desktop: parse(style.getPropertyValue('--zw-letter-spacing-desktop'))
|
|
55
|
-
})
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
style: 'letter-spacing',
|
|
59
|
-
|
|
60
|
-
getAttrs: (input) => {
|
|
61
|
-
const value = parse(input);
|
|
62
|
-
|
|
63
|
-
return { desktop: value, tablet: value, mobile: value };
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
];
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
renderHTML({ HTMLAttributes: attrs }) {
|
|
70
|
-
const addUnits = (value) => value ? `${value}px` : null;
|
|
71
|
-
|
|
72
|
-
return renderMark({
|
|
73
|
-
letter_spacing_mobile: addUnits(attrs.mobile),
|
|
74
|
-
letter_spacing_tablet: addUnits(attrs.tablet),
|
|
75
|
-
letter_spacing_desktop: addUnits(attrs.desktop)
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
});
|