@zipify/wysiwyg 4.9.1 → 4.10.0-1
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/.github/actions/lint-js/action.yaml +8 -3
- package/.lintstagedrc.mjs +32 -0
- package/.oxlintrc.json +185 -0
- package/dist/assets/wysiwyg-B8cHOAcD.css +908 -0
- package/dist/cli.js +35 -35
- package/dist/node.js +22 -22
- package/dist/types/Wysiwyg.vue.d.ts +38 -176
- package/dist/types/components/base/Button.vue.d.ts +2 -2
- package/dist/types/components/base/Modal.vue.d.ts +2 -2
- package/dist/types/components/base/ModalFloating.vue.d.ts +2 -2
- package/dist/types/components/base/NumberField.vue.d.ts +2 -2
- package/dist/types/entryLib.d.ts +2 -0
- package/dist/types/enums/Devices.d.ts +15 -6
- package/dist/types/enums/index.d.ts +9 -9
- package/dist/types/models/PageBlock.d.ts +4 -0
- package/dist/types/models/StylePreset.d.ts +27 -0
- package/dist/types/models/index.d.ts +3 -2
- package/dist/types/types/StylePresetVariableFactory.d.ts +8 -0
- package/dist/types/types/index.d.ts +1 -0
- package/dist/wysiwyg.css +44 -76
- package/dist/wysiwyg.mjs +2077 -1331
- package/eslint.config.mjs +6 -0
- package/example/ExampleApp.vue +48 -78
- package/example/presets.ts +250 -0
- package/lib/Wysiwyg.vue +63 -118
- package/lib/cli/commands/Command.js +1 -2
- package/lib/components/base/Checkbox.vue +3 -0
- package/lib/components/base/Modal.vue +1 -1
- package/lib/components/base/colorPicker/ColorPicker.vue +11 -9
- package/lib/components/toolbar/Toolbar.vue +4 -4
- package/lib/components/toolbar/controls/__tests__/FontColorControl.test.js +2 -2
- package/lib/components/toolbar/controls/link/LinkControlHeader.vue +7 -2
- package/lib/components/toolbar/controls/link/__tests__/LinkControl.test.js +5 -5
- package/lib/components/toolbar/controls/link/__tests__/LinkControlHeader.test.js +4 -4
- package/lib/entryLib.ts +2 -0
- package/lib/enums/Devices.ts +17 -0
- package/lib/enums/index.ts +9 -0
- package/lib/extensions/FontStyle.js +3 -3
- package/lib/extensions/__tests__/StylePreset.test.js +5 -5
- package/lib/extensions/list/List.js +3 -3
- package/lib/extensions/list/__tests__/List.test.js +4 -4
- package/lib/models/PageBlock.ts +4 -0
- package/lib/models/StylePreset.ts +30 -0
- package/lib/models/index.ts +3 -2
- package/lib/services/JsonSerializer.js +0 -1
- package/lib/services/Storage.js +0 -1
- package/lib/services/__tests__/Storage.test.js +9 -4
- package/lib/services/normalizer/__tests__/HtmlNormalizer.test.js +25 -25
- package/lib/styles/variables.css +2 -33
- package/lib/types/StylePresetVariableFactory.ts +10 -0
- package/lib/types/index.ts +1 -0
- package/package.json +18 -28
- package/tsconfig.lint.json +7 -0
- package/.eslintignore +0 -2
- package/.eslintrc.js +0 -95
- package/.lintstagedrc +0 -12
- package/example/presets.js +0 -247
- package/lib/enums/Devices.js +0 -15
- package/lib/enums/index.js +0 -9
|
@@ -3,12 +3,10 @@
|
|
|
3
3
|
ref="pickerRef"
|
|
4
4
|
placement="bottom-end"
|
|
5
5
|
placement-strategy="fixed"
|
|
6
|
-
:favorite-colors="favoriteColors"
|
|
7
6
|
:window="ContextWindow.window"
|
|
8
|
-
:model-value="api.editingColor"
|
|
9
7
|
:has-gradient="false"
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
v-model="api.editingColor"
|
|
9
|
+
v-model:favorite-colors="favoriteColors"
|
|
12
10
|
v-out-click="{ onOutClick: api.close, isDisabled: !api.isOpened }"
|
|
13
11
|
>
|
|
14
12
|
<template #activator>
|
|
@@ -24,11 +22,11 @@
|
|
|
24
22
|
</template>
|
|
25
23
|
|
|
26
24
|
<script setup>
|
|
27
|
-
import { ColorPicker } from '@zipify/colorpicker';
|
|
28
25
|
import { computed, inject, ref, toRef, unref } from 'vue';
|
|
26
|
+
import { ColorPicker } from '@zipify/colorpicker';
|
|
27
|
+
import { InjectionTokens } from '@/injectionTokens';
|
|
28
|
+
import { ContextWindow } from '@/services';
|
|
29
29
|
import { outClick as vOutClick } from '../../../directives';
|
|
30
|
-
import { InjectionTokens } from '../../../injectionTokens';
|
|
31
|
-
import { ContextWindow } from '../../../services';
|
|
32
30
|
import { usePickerApi, usePickerHotkeys } from './composables';
|
|
33
31
|
|
|
34
32
|
const props = defineProps({
|
|
@@ -49,11 +47,13 @@ const api = usePickerApi({
|
|
|
49
47
|
emit('change', color);
|
|
50
48
|
editor.chain().focus().restoreSelection().run();
|
|
51
49
|
},
|
|
50
|
+
|
|
52
51
|
onClosed: () => editor.commands.restoreSelection(),
|
|
53
52
|
onBeforeOpened: () => editor.commands.storeSelection(),
|
|
54
53
|
colorRef: toRef(props, 'value'),
|
|
55
54
|
pickerRef
|
|
56
55
|
});
|
|
56
|
+
|
|
57
57
|
const isOpenedRef = toRef(api, 'isOpened');
|
|
58
58
|
|
|
59
59
|
usePickerHotkeys({
|
|
@@ -62,6 +62,8 @@ usePickerHotkeys({
|
|
|
62
62
|
onApply: api.close
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
const favoriteColors = computed(
|
|
66
|
-
|
|
65
|
+
const favoriteColors = computed({
|
|
66
|
+
get: () => unref(favoriteColorsService.listRef),
|
|
67
|
+
set: favoriteColorsService.triggerUpdate
|
|
68
|
+
});
|
|
67
69
|
</script>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
2
|
+
<KeepAlive>
|
|
3
|
+
<Transition name="zw-toolbar-" duration="150">
|
|
4
4
|
<ToolbarFloating
|
|
5
5
|
class="zw-toolbar"
|
|
6
6
|
:reference-ref="referenceRef"
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
>
|
|
10
10
|
<component :is="layoutComponent" :ai-component="aiComponent" />
|
|
11
11
|
</ToolbarFloating>
|
|
12
|
-
</
|
|
13
|
-
</
|
|
12
|
+
</Transition>
|
|
13
|
+
</KeepAlive>
|
|
14
14
|
</template>
|
|
15
15
|
|
|
16
16
|
<script setup>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { shallowMount } from '@vue/test-utils';
|
|
2
2
|
import { h, ref } from 'vue';
|
|
3
|
-
import { InjectionTokens } from '
|
|
3
|
+
import { InjectionTokens } from '@/injectionTokens';
|
|
4
4
|
import { ColorPicker } from '../../../base';
|
|
5
5
|
import FontColorControl from '../FontColorControl';
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ const SELECTORS = {
|
|
|
11
11
|
const createEditor = ({ fontColor, isSettingCustomized } = {}) => ({
|
|
12
12
|
commands: {
|
|
13
13
|
getFontColor: () => ref(fontColor),
|
|
14
|
-
isSettingCustomized: () => ref(
|
|
14
|
+
isSettingCustomized: () => ref(isSettingCustomized ?? false),
|
|
15
15
|
focus: jest.fn().mockReturnThis(),
|
|
16
16
|
applyFontColor: jest.fn().mockReturnThis(),
|
|
17
17
|
run: jest.fn()
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
Link
|
|
5
5
|
</span>
|
|
6
6
|
|
|
7
|
-
<Button
|
|
7
|
+
<Button
|
|
8
|
+
class="zw-link-modal-header__unlink-button"
|
|
9
|
+
:disabled="!isLink"
|
|
10
|
+
data-initial-focus="false"
|
|
11
|
+
@click="removeLink"
|
|
12
|
+
>
|
|
8
13
|
<Icon class="zw-link-modal-header__unlink-icon" name="unlink" size="14px" auto-color />
|
|
9
14
|
Remove
|
|
10
15
|
</Button>
|
|
@@ -14,7 +19,7 @@
|
|
|
14
19
|
<script setup>
|
|
15
20
|
import { inject } from 'vue';
|
|
16
21
|
import { Icon, Button } from '../../../base';
|
|
17
|
-
import { InjectionTokens } from '
|
|
22
|
+
import { InjectionTokens } from '@/injectionTokens';
|
|
18
23
|
|
|
19
24
|
const emit = defineEmits(['remove-link']);
|
|
20
25
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { shallowMount } from '@vue/test-utils';
|
|
2
2
|
import { ref, nextTick } from 'vue';
|
|
3
3
|
import LinkControl from '../LinkControl';
|
|
4
|
-
import { InjectionTokens } from '
|
|
4
|
+
import { InjectionTokens } from '@/injectionTokens';
|
|
5
5
|
import { Button, TextField } from '../../../../base';
|
|
6
6
|
import { LinkControlDestination } from '../destination';
|
|
7
7
|
|
|
@@ -26,7 +26,7 @@ const SELECTORS = {
|
|
|
26
26
|
|
|
27
27
|
describe('selection value', () => {
|
|
28
28
|
test('should render link status', () => {
|
|
29
|
-
const editor = createEditor(true
|
|
29
|
+
const editor = createEditor(true);
|
|
30
30
|
const wrapper = createComponent({ editor });
|
|
31
31
|
const buttonWrapper = wrapper.findComponent(Button);
|
|
32
32
|
|
|
@@ -36,7 +36,7 @@ describe('selection value', () => {
|
|
|
36
36
|
|
|
37
37
|
describe('validation', () => {
|
|
38
38
|
test('should show error on apply', async () => {
|
|
39
|
-
const editor = createEditor(true
|
|
39
|
+
const editor = createEditor(true);
|
|
40
40
|
const wrapper = createComponent({ editor });
|
|
41
41
|
const textFieldWrapper = wrapper.findComponent(TextField);
|
|
42
42
|
const linkControlDestinationWrapper = wrapper.findComponent(LinkControlDestination);
|
|
@@ -49,7 +49,7 @@ describe('validation', () => {
|
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
test('should reset errors on input', async () => {
|
|
52
|
-
const editor = createEditor(true
|
|
52
|
+
const editor = createEditor(true);
|
|
53
53
|
const wrapper = createComponent({ editor });
|
|
54
54
|
const textFieldWrapper = wrapper.findComponent(TextField);
|
|
55
55
|
const linkControlDestinationWrapper = wrapper.findComponent(LinkControlDestination);
|
|
@@ -64,7 +64,7 @@ describe('validation', () => {
|
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
test('should reset errors on change destination', async () => {
|
|
67
|
-
const editor = createEditor(true
|
|
67
|
+
const editor = createEditor(true);
|
|
68
68
|
const wrapper = createComponent({ editor });
|
|
69
69
|
const textFieldWrapper = wrapper.findComponent(TextField);
|
|
70
70
|
const linkControlDestinationWrapper = wrapper.findComponent(LinkControlDestination);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { shallowMount } from '@vue/test-utils';
|
|
2
|
-
import { InjectionTokens } from '
|
|
2
|
+
import { InjectionTokens } from '@/injectionTokens';
|
|
3
3
|
import { Button } from '../../../../base';
|
|
4
4
|
import LinkControlHeader from '../LinkControlHeader';
|
|
5
5
|
|
|
@@ -17,7 +17,7 @@ function createComponent({ editor }) {
|
|
|
17
17
|
|
|
18
18
|
describe('rendering unlink button', () => {
|
|
19
19
|
test('should button be disabled when no link', () => {
|
|
20
|
-
const editor = createEditor(true
|
|
20
|
+
const editor = createEditor(true);
|
|
21
21
|
const wrapper = createComponent({ editor });
|
|
22
22
|
const buttonWrapper = wrapper.findComponent(Button);
|
|
23
23
|
|
|
@@ -25,7 +25,7 @@ describe('rendering unlink button', () => {
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
test('should button be enabled when link selected', () => {
|
|
28
|
-
const editor = createEditor(false
|
|
28
|
+
const editor = createEditor(false);
|
|
29
29
|
const wrapper = createComponent({ editor });
|
|
30
30
|
const buttonWrapper = wrapper.findComponent(Button);
|
|
31
31
|
|
|
@@ -33,7 +33,7 @@ describe('rendering unlink button', () => {
|
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
test('should send unlink event', () => {
|
|
36
|
-
const editor = createEditor(true
|
|
36
|
+
const editor = createEditor(true);
|
|
37
37
|
const wrapper = createComponent({ editor });
|
|
38
38
|
const buttonWrapper = wrapper.findComponent(Button);
|
|
39
39
|
|
package/lib/entryLib.ts
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export enum Device {
|
|
2
|
+
COMMON = 'common',
|
|
3
|
+
MOBILE = 'mobile',
|
|
4
|
+
TABLET = 'tablet',
|
|
5
|
+
DESKTOP = 'desktop'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated use TS enum
|
|
10
|
+
*/
|
|
11
|
+
export const Devices = Object.freeze({
|
|
12
|
+
...Device,
|
|
13
|
+
|
|
14
|
+
get values() {
|
|
15
|
+
return Object.values(Device);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './Devices';
|
|
2
|
+
export * from './CaseStyles';
|
|
3
|
+
export * from './Alignments';
|
|
4
|
+
export * from './NodeTypes';
|
|
5
|
+
export * from './ListTypes';
|
|
6
|
+
export * from './TextSettings';
|
|
7
|
+
export * from './MarkGroups';
|
|
8
|
+
export * from './LinkTargets';
|
|
9
|
+
export * from './LinkDestinations';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Mark } from '@tiptap/vue-3';
|
|
2
2
|
import { computed, unref } from 'vue';
|
|
3
|
-
import { createCommand, createKeyboardShortcut, renderMark } from '
|
|
4
|
-
import { MarkGroups, TextSettings } from '
|
|
3
|
+
import { createCommand, createKeyboardShortcut, renderMark } from '@/utils';
|
|
4
|
+
import { MarkGroups, TextSettings } from '@/enums';
|
|
5
5
|
|
|
6
6
|
export const FontStyle = Mark.create({
|
|
7
7
|
name: TextSettings.FONT_STYLE,
|
|
@@ -64,7 +64,7 @@ export const FontStyle = Mark.create({
|
|
|
64
64
|
}),
|
|
65
65
|
|
|
66
66
|
parseHTML() {
|
|
67
|
-
const getAttrs = (value) => ({ italic: value.includes('italic')
|
|
67
|
+
const getAttrs = (value) => ({ italic: value.includes('italic') });
|
|
68
68
|
|
|
69
69
|
return [
|
|
70
70
|
{
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Editor, Extension, Mark } from '@tiptap/vue-3';
|
|
2
|
-
import { buildTestExtensions } from '
|
|
2
|
+
import { buildTestExtensions } from '@/__tests__/utils';
|
|
3
3
|
import { StylePreset } from '../StylePreset';
|
|
4
4
|
import { List } from '../list';
|
|
5
|
-
import { ListTypes, NodeTypes, TextSettings } from '
|
|
6
|
-
import { ContentNormalizer, NodeFactory } from '
|
|
7
|
-
import { createCommand } from '
|
|
5
|
+
import { ListTypes, NodeTypes, TextSettings } from '@/enums';
|
|
6
|
+
import { ContentNormalizer, NodeFactory } from '@/services';
|
|
7
|
+
import { createCommand } from '@/utils';
|
|
8
8
|
|
|
9
9
|
const MockFontSize = Mark.create({
|
|
10
10
|
name: TextSettings.FONT_SIZE,
|
|
@@ -129,7 +129,7 @@ function createEditor({ content, presets, defaultId, link }) {
|
|
|
129
129
|
defaultId,
|
|
130
130
|
|
|
131
131
|
styleRenderer: {
|
|
132
|
-
makePresetHtmlClass: (preset) =>
|
|
132
|
+
makePresetHtmlClass: (preset) => `zw ts-${preset.id}`,
|
|
133
133
|
makePresetCssClass: (preset) => `.zw.ts-${preset.id}`,
|
|
134
134
|
inject: jest.fn()
|
|
135
135
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Node, wrappingInputRule } from '@tiptap/vue-3';
|
|
2
2
|
import { computed, unref } from 'vue';
|
|
3
|
-
import { copyMark, createCommand } from '
|
|
4
|
-
import { ListTypes, MarkGroups, NodeTypes, TextSettings } from '
|
|
3
|
+
import { copyMark, createCommand } from '@/utils';
|
|
4
|
+
import { ListTypes, MarkGroups, NodeTypes, TextSettings } from '@/enums';
|
|
5
5
|
import { ListItem } from './ListItem';
|
|
6
6
|
|
|
7
7
|
export const List = Node.create({
|
|
@@ -29,7 +29,7 @@ export const List = Node.create({
|
|
|
29
29
|
const HTML_TYPES = {
|
|
30
30
|
a: ListTypes.ROMAN,
|
|
31
31
|
i: ListTypes.LATIN,
|
|
32
|
-
|
|
32
|
+
1: ListTypes.DECIMAL
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
const getBulletType = (element) => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Editor, Mark } from '@tiptap/vue-3';
|
|
2
|
-
import { buildTestExtensions } from '
|
|
3
|
-
import { ListTypes, TextSettings } from '
|
|
2
|
+
import { buildTestExtensions } from '@/__tests__/utils';
|
|
3
|
+
import { ListTypes, TextSettings } from '@/enums';
|
|
4
4
|
import { StylePreset } from '../../StylePreset';
|
|
5
|
-
import { ContentNormalizer, NodeFactory } from '
|
|
5
|
+
import { ContentNormalizer, NodeFactory } from '@/services';
|
|
6
6
|
import { List } from '../List';
|
|
7
7
|
|
|
8
8
|
const MockFontWeight = Mark.create({
|
|
@@ -31,7 +31,7 @@ function createEditor({ content }) {
|
|
|
31
31
|
defaultId: 'regular-1',
|
|
32
32
|
|
|
33
33
|
styleRenderer: {
|
|
34
|
-
makePresetHtmlClass: (preset) =>
|
|
34
|
+
makePresetHtmlClass: (preset) => `zw ts-${preset.id}`,
|
|
35
35
|
makePresetCssClass: (preset) => `.zw.ts-${preset.id}`,
|
|
36
36
|
render: () => ''
|
|
37
37
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface IPresetNode {
|
|
2
|
+
type: string;
|
|
3
|
+
level?: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface IPresetDeviceStyles {
|
|
7
|
+
alignment: string | null;
|
|
8
|
+
line_height: string;
|
|
9
|
+
font_size: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface IPresetCommonStyles {
|
|
13
|
+
font_family: string;
|
|
14
|
+
font_weight: string;
|
|
15
|
+
color: string;
|
|
16
|
+
font_style: string;
|
|
17
|
+
text_decoration: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface IStylePreset {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
node?: IPresetNode;
|
|
24
|
+
hidden?: boolean;
|
|
25
|
+
fallbackClass?: string;
|
|
26
|
+
common: IPresetCommonStyles;
|
|
27
|
+
desktop: IPresetDeviceStyles;
|
|
28
|
+
tablet: IPresetDeviceStyles;
|
|
29
|
+
mobile: IPresetDeviceStyles;
|
|
30
|
+
}
|
package/lib/models/index.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
export type
|
|
1
|
+
export * from './Font';
|
|
2
|
+
export type * from './StylePreset';
|
|
3
|
+
export type * from './PageBlock';
|
package/lib/services/Storage.js
CHANGED
|
@@ -38,10 +38,12 @@ describe('get item', () => {
|
|
|
38
38
|
const storage = createStorage({ storage: nativeStorage });
|
|
39
39
|
const error = new Error('private mode');
|
|
40
40
|
|
|
41
|
-
nativeStorage.getItem.mockImplementation(() => {
|
|
41
|
+
nativeStorage.getItem.mockImplementation(() => {
|
|
42
|
+
throw error;
|
|
43
|
+
});
|
|
44
|
+
|
|
42
45
|
storage.getItem('test');
|
|
43
46
|
|
|
44
|
-
// eslint-disable-next-line no-console
|
|
45
47
|
expect(console.error).toHaveBeenCalledWith(error);
|
|
46
48
|
});
|
|
47
49
|
});
|
|
@@ -70,10 +72,13 @@ describe('set item', () => {
|
|
|
70
72
|
const storage = createStorage({ storage: nativeStorage });
|
|
71
73
|
const error = new Error('private mode');
|
|
72
74
|
|
|
73
|
-
nativeStorage.getItem.mockImplementation(() => {
|
|
75
|
+
nativeStorage.getItem.mockImplementation(() => {
|
|
76
|
+
throw error;
|
|
77
|
+
});
|
|
78
|
+
|
|
74
79
|
storage.setItem('test', 'test');
|
|
75
80
|
|
|
76
|
-
|
|
81
|
+
|
|
77
82
|
expect(console.error).toHaveBeenCalledWith(error);
|
|
78
83
|
});
|
|
79
84
|
});
|
|
@@ -24,28 +24,28 @@ describe('normalize text content', () => {
|
|
|
24
24
|
|
|
25
25
|
test('should keep order in list nodes', () => {
|
|
26
26
|
const input = '<ul><li style="line-height: 2;"><span style="font-weight: 700">lorem</span> impsum</li></ul>';
|
|
27
|
-
const output = '<ul>'
|
|
28
|
-
'<li>'
|
|
29
|
-
|
|
30
|
-
'</li>'
|
|
31
|
-
|
|
27
|
+
const output = '<ul>'
|
|
28
|
+
+ '<li>'
|
|
29
|
+
+ '<p style="line-height: 2;"><span style="font-weight: 700">lorem</span> impsum</p>'
|
|
30
|
+
+ '</li>'
|
|
31
|
+
+ '</ul>';
|
|
32
32
|
|
|
33
33
|
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
test('should wrap non paragraph list content', () => {
|
|
37
|
-
const input = '<ul>'
|
|
38
|
-
'<li style="line-height: 2;">'
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
'</li>'
|
|
42
|
-
|
|
43
|
-
const output = '<ul>'
|
|
44
|
-
'<li>'
|
|
45
|
-
'<p style="line-height: 2;"><span style="font-weight: 700">lorem</span> impsum</p>'
|
|
46
|
-
'<p style="line-height: 2;">paragraph text</p>'
|
|
47
|
-
'</li>'
|
|
48
|
-
|
|
37
|
+
const input = '<ul>'
|
|
38
|
+
+ '<li style="line-height: 2;">'
|
|
39
|
+
+ '<span style="font-weight: 700">lorem</span> impsum'
|
|
40
|
+
+ '<p>paragraph text</p>'
|
|
41
|
+
+ '</li>'
|
|
42
|
+
+ '</ul>';
|
|
43
|
+
const output = '<ul>'
|
|
44
|
+
+ '<li>'
|
|
45
|
+
+ '<p style="line-height: 2;"><span style="font-weight: 700">lorem</span> impsum</p>'
|
|
46
|
+
+ '<p style="line-height: 2;">paragraph text</p>'
|
|
47
|
+
+ '</li>'
|
|
48
|
+
+ '</ul>';
|
|
49
49
|
|
|
50
50
|
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
51
51
|
});
|
|
@@ -114,10 +114,10 @@ describe('normalize text content', () => {
|
|
|
114
114
|
|
|
115
115
|
test('should normalize br in list items', () => {
|
|
116
116
|
const input = '<ul><li>lorem ipsum 1<br><br></li><li>lorem ipsum 2</li></ul>';
|
|
117
|
-
const output = '<ul>'
|
|
118
|
-
'<li><p>lorem ipsum 1</p><p><br></p></li>'
|
|
119
|
-
'<li><p>lorem ipsum 2</p></li>'
|
|
120
|
-
|
|
117
|
+
const output = '<ul>'
|
|
118
|
+
+ '<li><p>lorem ipsum 1</p><p><br></p></li>'
|
|
119
|
+
+ '<li><p>lorem ipsum 2</p></li>'
|
|
120
|
+
+ '</ul>';
|
|
121
121
|
|
|
122
122
|
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
123
123
|
});
|
|
@@ -145,10 +145,10 @@ describe('normalize text content', () => {
|
|
|
145
145
|
|
|
146
146
|
test('should move text decoration from block to mixed content', () => {
|
|
147
147
|
const input = '<p style="text-decoration: underline;"><span style="text-decoration: line-through;">lorem</span> ipsum</p>';
|
|
148
|
-
const output = '<p>'
|
|
149
|
-
'<span style="text-decoration: underline line-through;">lorem</span>'
|
|
150
|
-
'<span style="text-decoration: underline;"> ipsum</span>'
|
|
151
|
-
|
|
148
|
+
const output = '<p>'
|
|
149
|
+
+ '<span style="text-decoration: underline line-through;">lorem</span>'
|
|
150
|
+
+ '<span style="text-decoration: underline;"> ipsum</span>'
|
|
151
|
+
+ '</p>';
|
|
152
152
|
|
|
153
153
|
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
154
154
|
});
|
package/lib/styles/variables.css
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
.zw-wysiwyg
|
|
1
|
+
.zw-wysiwyg,
|
|
2
|
+
.zw-toolbar {
|
|
2
3
|
--zw-color-n5: 13, 13, 13; /* #0D0D0D */
|
|
3
4
|
--zw-color-n15: 38, 38, 38; /* #262626 */
|
|
4
5
|
--zw-color-n20: 59, 59, 59; /* #3B3B3B */
|
|
@@ -31,35 +32,3 @@
|
|
|
31
32
|
--zw-line-height-xxs: 1.21;
|
|
32
33
|
--zw-line-height-md: 1.72;
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
-
/*
|
|
36
|
-
$builder-N5: #0D0D0D;
|
|
37
|
-
$builder-N10: #1A1A1A;
|
|
38
|
-
$builder-N15: #262626;
|
|
39
|
-
$builder-N20: #3B3B3B;
|
|
40
|
-
$builder-N30: #4D4D4D;
|
|
41
|
-
$builder-N40: #666;
|
|
42
|
-
$builder-N50: #808080;
|
|
43
|
-
$builder-N60: #999;
|
|
44
|
-
$builder-N70: #B3B3B3;
|
|
45
|
-
$builder-N80: #C4C4C4;
|
|
46
|
-
$builder-N85: #D9D9D9;
|
|
47
|
-
$builder-N90: #E6E6E6;
|
|
48
|
-
$builder-N94: #F0F0F0;
|
|
49
|
-
$builder-N96: #F5F5F5;
|
|
50
|
-
$builder-N98: #FAFAFA;
|
|
51
|
-
$builder-N200: #C2C8D1;
|
|
52
|
-
$builder-R50: #EA3A3A;
|
|
53
|
-
|
|
54
|
-
$font-size-xxs: 12px;
|
|
55
|
-
$font-size-xs: 14px;
|
|
56
|
-
$font-size-sm: 16px;
|
|
57
|
-
$font-size-md: 18px;
|
|
58
|
-
$font-size-lmd: 20px;
|
|
59
|
-
$font-size-lg: 24px;
|
|
60
|
-
|
|
61
|
-
$font-height--xxs: 1.2;
|
|
62
|
-
$font-height--xs: 1.33;
|
|
63
|
-
$font-height--sm: 1.43;
|
|
64
|
-
$font-height--md: 1.72;
|
|
65
|
-
*/
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IStylePreset } from '@/models';
|
|
2
|
+
import { Device } from '@/enums';
|
|
3
|
+
|
|
4
|
+
export interface IStylePresetVariableArgs {
|
|
5
|
+
device: Device;
|
|
6
|
+
preset: IStylePreset;
|
|
7
|
+
property: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type StylePresetVariableFactory = (args: IStylePresetVariableArgs) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from './StylePresetVariableFactory';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zipify/wysiwyg",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.10.0-1",
|
|
4
4
|
"description": "Zipify modification of TipTap text editor",
|
|
5
5
|
"main": "dist/wysiwyg.mjs",
|
|
6
6
|
"types": "dist/wysiwyg.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"example:start": "NODE_ENV=development vite serve --config config/build/example.config.ts",
|
|
28
28
|
"example:build": "NODE_ENV=production vite build --config config/build/example.config.ts",
|
|
29
29
|
"test:unit": "jest .",
|
|
30
|
-
"lint:js": "
|
|
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
33
|
"prepare": "husky"
|
|
@@ -65,51 +65,41 @@
|
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@babel/core": "^7.
|
|
69
|
-
"@babel/
|
|
70
|
-
"@babel/
|
|
71
|
-
"@babel/
|
|
72
|
-
"@babel/runtime": "^7.25.7",
|
|
68
|
+
"@babel/core": "^7.26.0",
|
|
69
|
+
"@babel/plugin-transform-runtime": "^7.25.9",
|
|
70
|
+
"@babel/preset-env": "^7.26.0",
|
|
71
|
+
"@babel/runtime": "^7.26.0",
|
|
73
72
|
"@optimize-lodash/rollup-plugin": "^5.0.0",
|
|
74
73
|
"@rollup/plugin-alias": "^5.1.1",
|
|
75
74
|
"@rollup/plugin-commonjs": "^28.0.1",
|
|
76
75
|
"@rollup/plugin-json": "^6.1.0",
|
|
77
76
|
"@rollup/plugin-node-resolve": "^15.3.0",
|
|
78
77
|
"@rollup/plugin-replace": "^6.0.1",
|
|
79
|
-
"@rushstack/eslint-patch": "^1.10.4",
|
|
80
78
|
"@stylistic/stylelint-plugin": "^3.1.1",
|
|
81
79
|
"@types/jest": "^29.5.14",
|
|
82
|
-
"@types/node": "^22.
|
|
83
|
-
"@
|
|
84
|
-
"@typescript-eslint/parser": "^7.18.0",
|
|
85
|
-
"@vitejs/plugin-vue": "^5.2.0",
|
|
86
|
-
"@vue/eslint-config-typescript": "^13.0.0",
|
|
80
|
+
"@types/node": "^22.10.2",
|
|
81
|
+
"@vitejs/plugin-vue": "^5.2.1",
|
|
87
82
|
"@vue/test-utils": "^2.4.6",
|
|
88
|
-
"@vue/tsconfig": "^0.
|
|
83
|
+
"@vue/tsconfig": "^0.7.0",
|
|
89
84
|
"@vue/vue3-jest": "^29.2.6",
|
|
90
85
|
"@zipify/colorpicker": "^4.1.1",
|
|
91
|
-
"@zipify/eslint-config": "^
|
|
86
|
+
"@zipify/eslint-config": "^3.0.0",
|
|
92
87
|
"babel-jest": "^29.7.0",
|
|
93
88
|
"esbuild-jest": "^0.5.0",
|
|
94
|
-
"
|
|
95
|
-
"eslint-import-resolver-alias": "^1.1.2",
|
|
96
|
-
"eslint-plugin-import": "^2.31.0",
|
|
97
|
-
"eslint-plugin-jest": "^27.9.0",
|
|
98
|
-
"eslint-plugin-vue": "^9.29.0",
|
|
99
|
-
"husky": "^9.1.6",
|
|
89
|
+
"husky": "^9.1.7",
|
|
100
90
|
"jest": "^29.7.0",
|
|
101
91
|
"jest-environment-jsdom": "^29.7.0",
|
|
102
|
-
"lint-staged": "^15.2.
|
|
92
|
+
"lint-staged": "^15.2.11",
|
|
103
93
|
"postcss-html": "^1.7.0",
|
|
104
94
|
"release-it": "^17.10.0",
|
|
105
|
-
"rollup": "^4.
|
|
95
|
+
"rollup": "^4.28.1",
|
|
106
96
|
"rollup-plugin-esbuild": "^6.1.1",
|
|
107
|
-
"rollup-plugin-esbuild-minify": "^1.
|
|
108
|
-
"simplebar": "^6.
|
|
109
|
-
"stylelint": "^16.
|
|
97
|
+
"rollup-plugin-esbuild-minify": "^1.2.0",
|
|
98
|
+
"simplebar": "^6.3.0",
|
|
99
|
+
"stylelint": "^16.11.0",
|
|
110
100
|
"svgo": "^3.3.2",
|
|
111
|
-
"typescript": "
|
|
112
|
-
"vite": "^
|
|
101
|
+
"typescript": "5.6.3",
|
|
102
|
+
"vite": "^6.0.3",
|
|
113
103
|
"vue": "3.5.13",
|
|
114
104
|
"vue-tsc": "^2.1.10"
|
|
115
105
|
},
|
package/.eslintignore
DELETED