@fastkit/vui 0.7.56 → 0.7.61
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/dist/vui.cjs.js +387 -25
- package/dist/vui.cjs.prod.js +387 -25
- package/dist/vui.css +67 -0
- package/dist/vui.d.ts +89 -1
- package/dist/vui.min.css +1 -1
- package/dist/vui.min.css.map +1 -1
- package/dist/vui.mjs +382 -27
- package/package.json +6 -6
- package/src/components/VWysiwygEditor/.DS_Store +0 -0
- package/src/components/VWysiwygEditor/VWysiwygEditor.scss +2 -0
- package/src/components/VWysiwygEditor/VWysiwygEditor.tsx +80 -49
- package/src/components/VWysiwygEditor/extensions/.DS_Store +0 -0
- package/src/components/VWysiwygEditor/extensions/index.ts +1 -0
- package/src/components/VWysiwygEditor/extensions/linter/.DS_Store +0 -0
- package/src/components/VWysiwygEditor/extensions/linter/Linter.scss +75 -0
- package/src/components/VWysiwygEditor/extensions/linter/Linter.ts +262 -0
- package/src/components/VWysiwygEditor/extensions/linter/LinterPlugin.ts +44 -0
- package/src/components/VWysiwygEditor/extensions/linter/index.ts +5 -0
- package/src/components/VWysiwygEditor/extensions/linter/plugins/BadWords.ts +34 -0
- package/src/components/VWysiwygEditor/extensions/linter/plugins/HeadingLevel.ts +33 -0
- package/src/components/VWysiwygEditor/extensions/linter/plugins/Punctuation.ts +43 -0
- package/src/components/VWysiwygEditor/extensions/linter/plugins/index.ts +3 -0
- package/src/components/VWysiwygEditor/index.ts +1 -0
- package/src/components/VWysiwygEditor/schemes.ts +107 -3
package/dist/vui.mjs
CHANGED
|
@@ -8,12 +8,15 @@ import { getDocumentScroller as getDocumentScroller$1 } from '@fastkit/vue-scrol
|
|
|
8
8
|
import { VProgressCircular } from '@fastkit/vue-loading';
|
|
9
9
|
export * from '@fastkit/vue-loading';
|
|
10
10
|
import { useScopeColorClass, colorSchemeProps, useColorClasses, toScopeColorClass } from '@fastkit/vue-color-scheme';
|
|
11
|
-
import { loadImage, IN_WINDOW, isPromise } from '@fastkit/helpers';
|
|
11
|
+
import { loadImage, IN_WINDOW, isPromise, debounce } from '@fastkit/helpers';
|
|
12
12
|
export { ICON_NAMES } from '@fastkit/icon-font';
|
|
13
13
|
import { VAppContainer, VAppLayoutControl } from '@fastkit/vue-app-layout';
|
|
14
14
|
import { createTextableProps, createTextableEmits, TextableControl } from '@fastkit/vue-form-control';
|
|
15
15
|
import { useEditor, EditorContent, BubbleMenu } from '@tiptap/vue-3';
|
|
16
16
|
import StarterKit from '@tiptap/starter-kit';
|
|
17
|
+
import { Extension } from '@tiptap/core';
|
|
18
|
+
import { DecorationSet, Decoration } from 'prosemirror-view';
|
|
19
|
+
import { Plugin, PluginKey, TextSelection } from 'prosemirror-state';
|
|
17
20
|
import { BulletList } from '@tiptap/extension-bullet-list';
|
|
18
21
|
import { Bold } from '@tiptap/extension-bold';
|
|
19
22
|
import { Italic } from '@tiptap/extension-italic';
|
|
@@ -2869,13 +2872,63 @@ const VTextarea = defineComponent({
|
|
|
2869
2872
|
|
|
2870
2873
|
});
|
|
2871
2874
|
|
|
2875
|
+
const EDITOR_EVENTS = [
|
|
2876
|
+
'beforeCreate',
|
|
2877
|
+
'create',
|
|
2878
|
+
'update',
|
|
2879
|
+
'selectionUpdate',
|
|
2880
|
+
'transaction',
|
|
2881
|
+
'focus',
|
|
2882
|
+
'blur',
|
|
2883
|
+
'destroy',
|
|
2884
|
+
];
|
|
2885
|
+
const prefixedEventName = (source) => {
|
|
2886
|
+
return `on${source.charAt(0).toUpperCase()}${source.slice(1)}`;
|
|
2887
|
+
};
|
|
2888
|
+
class WysiwygEditorInitializeContext {
|
|
2889
|
+
listeners = {};
|
|
2890
|
+
constructor(opts = {}) {
|
|
2891
|
+
EDITOR_EVENTS.forEach((event) => {
|
|
2892
|
+
this.listeners[event] = [];
|
|
2893
|
+
const prefixed = prefixedEventName(event);
|
|
2894
|
+
const fn = opts[prefixed];
|
|
2895
|
+
fn && this.listeners[event].push(fn);
|
|
2896
|
+
});
|
|
2897
|
+
}
|
|
2898
|
+
on(ev, handler) {
|
|
2899
|
+
this.listeners[ev].push(handler);
|
|
2900
|
+
return () => this.off(ev, handler);
|
|
2901
|
+
}
|
|
2902
|
+
off(ev, handler) {
|
|
2903
|
+
this.listeners[ev] = this.listeners[ev].filter((_handler) => _handler !== handler);
|
|
2904
|
+
}
|
|
2905
|
+
editorOptions() {
|
|
2906
|
+
const opts = {};
|
|
2907
|
+
EDITOR_EVENTS.forEach((event) => {
|
|
2908
|
+
const prefixed = prefixedEventName(event);
|
|
2909
|
+
opts[prefixed] = (props) => {
|
|
2910
|
+
const handlers = this.listeners[event];
|
|
2911
|
+
handlers.forEach((handler) => {
|
|
2912
|
+
handler(props);
|
|
2913
|
+
});
|
|
2914
|
+
};
|
|
2915
|
+
});
|
|
2916
|
+
return opts;
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
function resolveRawWysiwygExtension(raw, ctx) {
|
|
2920
|
+
return typeof raw === 'function' ? raw(ctx) : raw;
|
|
2921
|
+
}
|
|
2922
|
+
function resolveRawWysiwygExtensions(raws, ctx) {
|
|
2923
|
+
return raws.map((raw) => resolveRawWysiwygExtension(raw, ctx));
|
|
2924
|
+
}
|
|
2872
2925
|
function resolveRawWysiwygEditorTool(raw, vui) {
|
|
2873
2926
|
return typeof raw === 'function' ? raw(vui) : raw;
|
|
2874
2927
|
}
|
|
2875
|
-
function resolveRawWysiwygEditorTools(
|
|
2928
|
+
function resolveRawWysiwygEditorTools(rawTools, vui) {
|
|
2876
2929
|
const tools = [];
|
|
2877
2930
|
const extensions = [];
|
|
2878
|
-
|
|
2931
|
+
rawTools.forEach((raw) => {
|
|
2879
2932
|
let resolved = resolveRawWysiwygEditorTool(raw, vui);
|
|
2880
2933
|
if (!Array.isArray(resolved)) {
|
|
2881
2934
|
resolved = [resolved];
|
|
@@ -2906,6 +2959,10 @@ const VWysiwygEditor = defineComponent({
|
|
|
2906
2959
|
...createControlFieldProviderProps(),
|
|
2907
2960
|
...createControlProps(),
|
|
2908
2961
|
...defineSlotsProps(),
|
|
2962
|
+
extensions: {
|
|
2963
|
+
type: Array,
|
|
2964
|
+
default: () => []
|
|
2965
|
+
},
|
|
2909
2966
|
tools: {
|
|
2910
2967
|
type: Array,
|
|
2911
2968
|
default: () => []
|
|
@@ -2928,13 +2985,40 @@ const VWysiwygEditor = defineComponent({
|
|
|
2928
2985
|
nodeType: VUI_WYSIWYG_EDITOR_SYMBOL,
|
|
2929
2986
|
validationValue: () => textRef.value
|
|
2930
2987
|
});
|
|
2988
|
+
const initializeCtx = new WysiwygEditorInitializeContext({
|
|
2989
|
+
onCreate: ({
|
|
2990
|
+
editor
|
|
2991
|
+
}) => {
|
|
2992
|
+
textRef.value = editor.getText();
|
|
2993
|
+
updateEditable();
|
|
2994
|
+
},
|
|
2995
|
+
onFocus: ({
|
|
2996
|
+
event
|
|
2997
|
+
}) => {
|
|
2998
|
+
inputControl.focusHandler(event);
|
|
2999
|
+
},
|
|
3000
|
+
onBlur: ({
|
|
3001
|
+
event
|
|
3002
|
+
}) => {
|
|
3003
|
+
inputControl.blurHandler(event);
|
|
3004
|
+
},
|
|
3005
|
+
onUpdate: ({
|
|
3006
|
+
editor
|
|
3007
|
+
}) => {
|
|
3008
|
+
inputControl.value = editor.getHTML();
|
|
3009
|
+
textRef.value = editor.getText();
|
|
3010
|
+
}
|
|
3011
|
+
});
|
|
2931
3012
|
const extensions = [StarterKit.configure({
|
|
2932
3013
|
bold: false,
|
|
2933
3014
|
bulletList: false,
|
|
2934
3015
|
orderedList: false,
|
|
2935
3016
|
history: false,
|
|
2936
3017
|
italic: false
|
|
2937
|
-
}),
|
|
3018
|
+
}), // Linter.configure({
|
|
3019
|
+
// plugins: [BadWords(['abc', 'evidently']), Punctuation, HeadingLevel],
|
|
3020
|
+
// }),
|
|
3021
|
+
...resolveRawWysiwygExtensions(props.extensions, initializeCtx), ...wysiwygSettings.value.extensions];
|
|
2938
3022
|
|
|
2939
3023
|
const updateEditable = () => {
|
|
2940
3024
|
if (!editor.value) return;
|
|
@@ -2948,23 +3032,13 @@ const VWysiwygEditor = defineComponent({
|
|
|
2948
3032
|
$editor.commands.setContent(modelValue == null ? '' : modelValue, false);
|
|
2949
3033
|
textRef.value = $editor.getText();
|
|
2950
3034
|
});
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
onFocus: ctx => {
|
|
2959
|
-
inputControl.focusHandler(ctx.event);
|
|
2960
|
-
},
|
|
2961
|
-
onBlur: ctx => {
|
|
2962
|
-
inputControl.blurHandler(ctx.event);
|
|
2963
|
-
},
|
|
2964
|
-
onUpdate: ev => {
|
|
2965
|
-
inputControl.value = ev.editor.getHTML();
|
|
2966
|
-
textRef.value = ev.editor.getText();
|
|
2967
|
-
},
|
|
3035
|
+
initializeCtx.on('create', ({
|
|
3036
|
+
editor
|
|
3037
|
+
}) => {
|
|
3038
|
+
textRef.value = editor.getText();
|
|
3039
|
+
updateEditable();
|
|
3040
|
+
});
|
|
3041
|
+
const editor = useEditor({ ...initializeCtx.editorOptions(),
|
|
2968
3042
|
autofocus: props.autofocus,
|
|
2969
3043
|
content: props.modelValue,
|
|
2970
3044
|
extensions,
|
|
@@ -3047,6 +3121,9 @@ const VWysiwygEditor = defineComponent({
|
|
|
3047
3121
|
});
|
|
3048
3122
|
};
|
|
3049
3123
|
|
|
3124
|
+
onBeforeUnmount(() => {
|
|
3125
|
+
editor.value && editor.value.destroy();
|
|
3126
|
+
});
|
|
3050
3127
|
return {
|
|
3051
3128
|
editor,
|
|
3052
3129
|
...inputControl.expose(),
|
|
@@ -3082,9 +3159,7 @@ const VWysiwygEditor = defineComponent({
|
|
|
3082
3159
|
} = this;
|
|
3083
3160
|
return createVNode("div", {
|
|
3084
3161
|
"class": "v-wysiwyg-editor__wrapper"
|
|
3085
|
-
}, [!this.isReadonly && this.createTools(), createVNode(
|
|
3086
|
-
"class": "v-wysiwyg-editor__body"
|
|
3087
|
-
}, [createVNode(VControlField, {
|
|
3162
|
+
}, [!this.isReadonly && this.createTools(), createVNode(VControlField, {
|
|
3088
3163
|
"class": "v-wysiwyg-editor__input",
|
|
3089
3164
|
"autoHeight": true,
|
|
3090
3165
|
"startAdornment": this.startAdornment,
|
|
@@ -3094,7 +3169,9 @@ const VWysiwygEditor = defineComponent({
|
|
|
3094
3169
|
default: () => {
|
|
3095
3170
|
let _slot2;
|
|
3096
3171
|
|
|
3097
|
-
return createVNode(
|
|
3172
|
+
return createVNode("div", {
|
|
3173
|
+
"class": "v-wysiwyg-editor__body"
|
|
3174
|
+
}, [createVNode(EditorContent, {
|
|
3098
3175
|
"class": "v-wysiwyg-editor__input__element wysiwyg",
|
|
3099
3176
|
"editor": editor
|
|
3100
3177
|
}, null), !this.floatingToolbar && !!editor && !this.isReadonly && createVNode(BubbleMenu, {
|
|
@@ -3104,7 +3181,7 @@ const VWysiwygEditor = defineComponent({
|
|
|
3104
3181
|
default: () => [_slot2]
|
|
3105
3182
|
})]);
|
|
3106
3183
|
}
|
|
3107
|
-
})])
|
|
3184
|
+
})]);
|
|
3108
3185
|
},
|
|
3109
3186
|
infoAppends: () => {
|
|
3110
3187
|
const {
|
|
@@ -3122,6 +3199,284 @@ function resolveContextableValue(ctx, source) {
|
|
|
3122
3199
|
return typeof source === 'function' ? source(ctx) : source;
|
|
3123
3200
|
}
|
|
3124
3201
|
|
|
3202
|
+
const PROBLEM_CLASS_NAME = 'v-linter__problem';
|
|
3203
|
+
const ISSUE_ICON_CLASS_NAME = 'v-linter__issue-icon';
|
|
3204
|
+
const ISSUE_MENU_CLASS_NAME = 'v-linter__issue-menu';
|
|
3205
|
+
function renderIcon(view, issue) {
|
|
3206
|
+
const { level = 'warning' } = issue;
|
|
3207
|
+
const icon = document.createElement('div');
|
|
3208
|
+
icon.className = `${ISSUE_ICON_CLASS_NAME} ${level}-scope`;
|
|
3209
|
+
icon.title = issue.message;
|
|
3210
|
+
icon.issue = issue;
|
|
3211
|
+
return icon;
|
|
3212
|
+
}
|
|
3213
|
+
function renderMenu(view, issue) {
|
|
3214
|
+
const menuWrapper = document.createElement('div');
|
|
3215
|
+
menuWrapper.className = 'v-linter__issue-menu-wrapper';
|
|
3216
|
+
const menu = document.createElement('div');
|
|
3217
|
+
menu.className = `${ISSUE_MENU_CLASS_NAME} elevation-3`;
|
|
3218
|
+
menu.innerText = issue.message;
|
|
3219
|
+
const { fix, fixMessage } = issue;
|
|
3220
|
+
if (fix && fixMessage) {
|
|
3221
|
+
const $fix = document.createElement('button');
|
|
3222
|
+
$fix.type = 'button';
|
|
3223
|
+
$fix.innerHTML = fixMessage;
|
|
3224
|
+
$fix.addEventListener('click', () => {
|
|
3225
|
+
fix(view, issue);
|
|
3226
|
+
});
|
|
3227
|
+
$fix.className = `v-linter__issue-menu__fix`;
|
|
3228
|
+
menu.appendChild($fix);
|
|
3229
|
+
}
|
|
3230
|
+
menu.issue = issue;
|
|
3231
|
+
menuWrapper.appendChild(menu);
|
|
3232
|
+
return menuWrapper;
|
|
3233
|
+
}
|
|
3234
|
+
function getIssueElement(source, className) {
|
|
3235
|
+
if (!source || !(source instanceof HTMLElement)) {
|
|
3236
|
+
return;
|
|
3237
|
+
}
|
|
3238
|
+
if (source.classList.contains(className)) {
|
|
3239
|
+
return source;
|
|
3240
|
+
}
|
|
3241
|
+
const el = source.closest(`.${className}`);
|
|
3242
|
+
if (el) {
|
|
3243
|
+
return el;
|
|
3244
|
+
}
|
|
3245
|
+
}
|
|
3246
|
+
function getIconElement(source) {
|
|
3247
|
+
return getIssueElement(source, ISSUE_ICON_CLASS_NAME);
|
|
3248
|
+
}
|
|
3249
|
+
function getMenuElement(source) {
|
|
3250
|
+
return getIssueElement(source, ISSUE_MENU_CLASS_NAME);
|
|
3251
|
+
}
|
|
3252
|
+
function getProblemElement(source) {
|
|
3253
|
+
return getIssueElement(source, PROBLEM_CLASS_NAME);
|
|
3254
|
+
}
|
|
3255
|
+
function runAllLinterPlugins(doc, plugins) {
|
|
3256
|
+
const decorations = [];
|
|
3257
|
+
const results = plugins
|
|
3258
|
+
.map((RegisteredLinterPlugin) => {
|
|
3259
|
+
return new RegisteredLinterPlugin(doc).scan().getResults();
|
|
3260
|
+
})
|
|
3261
|
+
.flat();
|
|
3262
|
+
results.forEach((issue) => {
|
|
3263
|
+
const { level = 'warning' } = issue;
|
|
3264
|
+
decorations.push(Decoration.inline(issue.from, issue.to, {
|
|
3265
|
+
class: `${PROBLEM_CLASS_NAME} ${level}-scope`,
|
|
3266
|
+
'data-issue': JSON.stringify(issue),
|
|
3267
|
+
title: issue.message,
|
|
3268
|
+
}), Decoration.widget(issue.from, (view) => renderIcon(view, issue)), Decoration.widget(issue.from, (view) => renderMenu(view, issue)));
|
|
3269
|
+
});
|
|
3270
|
+
return DecorationSet.create(doc, decorations);
|
|
3271
|
+
}
|
|
3272
|
+
function updateMenusPosition(editorElement) {
|
|
3273
|
+
const { left, right } = editorElement.getBoundingClientRect();
|
|
3274
|
+
const menus = Array.from(editorElement.querySelectorAll(`.${ISSUE_MENU_CLASS_NAME}`));
|
|
3275
|
+
menus.forEach((menu) => {
|
|
3276
|
+
const { left: menuLeft, right: menuRight } = menu.getBoundingClientRect();
|
|
3277
|
+
const overflow = menuRight - right;
|
|
3278
|
+
let offset = 0;
|
|
3279
|
+
if (overflow > 0) {
|
|
3280
|
+
offset = -overflow;
|
|
3281
|
+
if (menuLeft + offset < left) {
|
|
3282
|
+
offset = 0;
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
menu.style.transform = `translateX(${offset}px)`;
|
|
3286
|
+
});
|
|
3287
|
+
}
|
|
3288
|
+
const debouncedUpdateMenusPosition = debounce(updateMenusPosition, 250);
|
|
3289
|
+
const Linter = Extension.create({
|
|
3290
|
+
name: 'linter',
|
|
3291
|
+
addOptions() {
|
|
3292
|
+
return {
|
|
3293
|
+
plugins: [],
|
|
3294
|
+
};
|
|
3295
|
+
},
|
|
3296
|
+
onCreate() {
|
|
3297
|
+
const { dom } = this.editor.view;
|
|
3298
|
+
debouncedUpdateMenusPosition(dom);
|
|
3299
|
+
},
|
|
3300
|
+
onUpdate() {
|
|
3301
|
+
const { dom } = this.editor.view;
|
|
3302
|
+
debouncedUpdateMenusPosition(dom);
|
|
3303
|
+
},
|
|
3304
|
+
addProseMirrorPlugins() {
|
|
3305
|
+
const { plugins } = this.options;
|
|
3306
|
+
return [
|
|
3307
|
+
new Plugin({
|
|
3308
|
+
key: new PluginKey('linter'),
|
|
3309
|
+
state: {
|
|
3310
|
+
init(_, { doc }) {
|
|
3311
|
+
return runAllLinterPlugins(doc, plugins);
|
|
3312
|
+
},
|
|
3313
|
+
apply(transaction, oldState) {
|
|
3314
|
+
return transaction.docChanged
|
|
3315
|
+
? runAllLinterPlugins(transaction.doc, plugins)
|
|
3316
|
+
: oldState;
|
|
3317
|
+
},
|
|
3318
|
+
},
|
|
3319
|
+
props: {
|
|
3320
|
+
decorations(state) {
|
|
3321
|
+
return this.getState(state);
|
|
3322
|
+
},
|
|
3323
|
+
handleClick(view, _, event) {
|
|
3324
|
+
const activeMenus = Array.from(view.dom.querySelectorAll(`.${ISSUE_MENU_CLASS_NAME}--active`));
|
|
3325
|
+
activeMenus.forEach((menu) => menu.classList.remove(`${ISSUE_MENU_CLASS_NAME}--active`));
|
|
3326
|
+
const problem = getProblemElement(event.target);
|
|
3327
|
+
const issueString = problem && problem.dataset['issue'];
|
|
3328
|
+
const issue = issueString && JSON.parse(issueString);
|
|
3329
|
+
if (issue) {
|
|
3330
|
+
const menuWrapper = problem.previousElementSibling;
|
|
3331
|
+
const menu = menuWrapper &&
|
|
3332
|
+
menuWrapper.querySelector(`.${ISSUE_MENU_CLASS_NAME}`);
|
|
3333
|
+
menu && menu.classList.add(`${ISSUE_MENU_CLASS_NAME}--active`);
|
|
3334
|
+
const { from, to } = issue;
|
|
3335
|
+
view.dispatch(view.state.tr
|
|
3336
|
+
.setSelection(TextSelection.create(view.state.doc, from, to))
|
|
3337
|
+
.scrollIntoView());
|
|
3338
|
+
return true;
|
|
3339
|
+
}
|
|
3340
|
+
const menu = getMenuElement(event.target);
|
|
3341
|
+
if (menu) {
|
|
3342
|
+
menu.classList.add(`${ISSUE_MENU_CLASS_NAME}--active`);
|
|
3343
|
+
}
|
|
3344
|
+
const target = getIconElement(event.target);
|
|
3345
|
+
if (target && target.issue) {
|
|
3346
|
+
const menuWrapper = target.nextElementSibling;
|
|
3347
|
+
const menu = menuWrapper &&
|
|
3348
|
+
menuWrapper.querySelector(`.${ISSUE_MENU_CLASS_NAME}`);
|
|
3349
|
+
menu && menu.classList.add(`${ISSUE_MENU_CLASS_NAME}--active`);
|
|
3350
|
+
const { from, to } = target.issue;
|
|
3351
|
+
view.dispatch(view.state.tr
|
|
3352
|
+
.setSelection(TextSelection.create(view.state.doc, from, to))
|
|
3353
|
+
.scrollIntoView());
|
|
3354
|
+
return true;
|
|
3355
|
+
}
|
|
3356
|
+
return false;
|
|
3357
|
+
},
|
|
3358
|
+
handleDoubleClick(view, _, event) {
|
|
3359
|
+
const target = getIconElement(event.target);
|
|
3360
|
+
if (target && target.issue) {
|
|
3361
|
+
const prob = target.issue;
|
|
3362
|
+
if (prob.fix) {
|
|
3363
|
+
prob.fix(view, prob);
|
|
3364
|
+
view.focus();
|
|
3365
|
+
return true;
|
|
3366
|
+
}
|
|
3367
|
+
}
|
|
3368
|
+
return false;
|
|
3369
|
+
},
|
|
3370
|
+
},
|
|
3371
|
+
}),
|
|
3372
|
+
];
|
|
3373
|
+
},
|
|
3374
|
+
});
|
|
3375
|
+
|
|
3376
|
+
class LinterPlugin {
|
|
3377
|
+
doc;
|
|
3378
|
+
results = [];
|
|
3379
|
+
constructor(doc) {
|
|
3380
|
+
this.doc = doc;
|
|
3381
|
+
}
|
|
3382
|
+
record(result) {
|
|
3383
|
+
this.results.push({
|
|
3384
|
+
level: 'error',
|
|
3385
|
+
...result,
|
|
3386
|
+
});
|
|
3387
|
+
}
|
|
3388
|
+
scan() {
|
|
3389
|
+
return this;
|
|
3390
|
+
}
|
|
3391
|
+
getResults() {
|
|
3392
|
+
return this.results;
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
|
|
3396
|
+
function BadWords(words) {
|
|
3397
|
+
const regex = new RegExp(`\\b(${words.join('|')})\\b`);
|
|
3398
|
+
return class BadWords extends LinterPlugin {
|
|
3399
|
+
scan() {
|
|
3400
|
+
this.doc.descendants((node, position) => {
|
|
3401
|
+
if (!node.isText) {
|
|
3402
|
+
return;
|
|
3403
|
+
}
|
|
3404
|
+
const matches = regex.exec(node.text);
|
|
3405
|
+
if (matches) {
|
|
3406
|
+
const fixValue = matches[0] + '!!!!!';
|
|
3407
|
+
this.record({
|
|
3408
|
+
level: 'warning',
|
|
3409
|
+
message: `Try not to say '${matches[0]}'`,
|
|
3410
|
+
from: position + matches.index,
|
|
3411
|
+
to: position + matches.index + matches[0].length,
|
|
3412
|
+
fix: () => {
|
|
3413
|
+
console.log('hoge');
|
|
3414
|
+
},
|
|
3415
|
+
fixMessage: `「${fixValue}」に修正する。`,
|
|
3416
|
+
});
|
|
3417
|
+
}
|
|
3418
|
+
});
|
|
3419
|
+
return this;
|
|
3420
|
+
}
|
|
3421
|
+
};
|
|
3422
|
+
}
|
|
3423
|
+
|
|
3424
|
+
class HeadingLevel extends LinterPlugin {
|
|
3425
|
+
fixHeader(level) {
|
|
3426
|
+
return function ({ state, dispatch }, issue) {
|
|
3427
|
+
dispatch(state.tr.setNodeMarkup(issue.from - 1, undefined, { level }));
|
|
3428
|
+
};
|
|
3429
|
+
}
|
|
3430
|
+
scan() {
|
|
3431
|
+
let lastHeadLevel = null;
|
|
3432
|
+
this.doc.descendants((node, position) => {
|
|
3433
|
+
if (node.type.name === 'heading') {
|
|
3434
|
+
// Check whether heading levels fit under the current level
|
|
3435
|
+
const { level } = node.attrs;
|
|
3436
|
+
if (lastHeadLevel != null && level > lastHeadLevel + 1) {
|
|
3437
|
+
this.record({
|
|
3438
|
+
message: `Heading too small (${level} under ${lastHeadLevel})`,
|
|
3439
|
+
from: position + 1,
|
|
3440
|
+
to: position + 1 + node.content.size,
|
|
3441
|
+
fix: this.fixHeader(lastHeadLevel + 1),
|
|
3442
|
+
});
|
|
3443
|
+
}
|
|
3444
|
+
lastHeadLevel = level;
|
|
3445
|
+
}
|
|
3446
|
+
});
|
|
3447
|
+
return this;
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
|
|
3451
|
+
class Punctuation extends LinterPlugin {
|
|
3452
|
+
regex = / ([,.!?:]) ?/g;
|
|
3453
|
+
fix(replacement) {
|
|
3454
|
+
return function ({ state, dispatch }, issue) {
|
|
3455
|
+
dispatch(state.tr.replaceWith(issue.from, issue.to, state.schema.text(replacement)));
|
|
3456
|
+
};
|
|
3457
|
+
}
|
|
3458
|
+
scan() {
|
|
3459
|
+
this.doc.descendants((node, position) => {
|
|
3460
|
+
if (!node.isText) {
|
|
3461
|
+
return;
|
|
3462
|
+
}
|
|
3463
|
+
if (!node.text) {
|
|
3464
|
+
return;
|
|
3465
|
+
}
|
|
3466
|
+
const matches = this.regex.exec(node.text);
|
|
3467
|
+
if (matches) {
|
|
3468
|
+
this.record({
|
|
3469
|
+
message: 'Suspicious spacing around punctuation',
|
|
3470
|
+
from: position + matches.index,
|
|
3471
|
+
to: position + matches.index + matches[0].length,
|
|
3472
|
+
fix: this.fix(`${matches[1]} `),
|
|
3473
|
+
});
|
|
3474
|
+
}
|
|
3475
|
+
});
|
|
3476
|
+
return this;
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3479
|
+
|
|
3125
3480
|
const WysiwygBulletListTool = (vui, options) => {
|
|
3126
3481
|
const tool = {
|
|
3127
3482
|
key: 'bulletList',
|
|
@@ -5041,4 +5396,4 @@ function installVuiPlugin(app, opts) {
|
|
|
5041
5396
|
return app.use(VuiPlugin, opts);
|
|
5042
5397
|
}
|
|
5043
5398
|
|
|
5044
|
-
export { AVATAR_SIZES, CHIP_SIZES, CONTROL_FIELD_VARIANTS, CONTROL_LOADING_SPINNER_SIZES, CONTROL_SIZES, PAGINATION_ALIGNS, VApp, VAvatar, VBreadcrumbs, VBusyImage, VButton, VButtonGroup, VCard, VCardActions, VCardContent, VCheckbox, VCheckboxGroup, VChip, VContentSwitcher, VDataTable, VDrawerLayout, VForm, VFormControl, VGridContainer, VGridItem, VHero, VIcon, VListTile, VNavigation, VNavigationItem, VNumberField, VOption, VOptionGroup, VPagination, VPaper, VRadio, VRadioGroup, VSelect, VSkeltonLoaderBone, VSwitch, VSwitchGroup, VTabs, VTextField, VTextarea, VToolbar, VToolbarEdge, VToolbarMenu, VToolbarTitle, VUI_CHECKBOX_GROUP_SYMBOL, VUI_CHECKBOX_SYMBOL, VUI_FORM_SYMBOL, VUI_OPTION_SYMBOL, VUI_RADIO_GROUP_SYMBOL, VUI_RADIO_SYMBOL, VUI_SELECT_SYMBOL, VUI_SWITCH_GROUP_SYMBOL, VUI_SWITCH_SYMBOL, VUI_TEXTAREA_SYMBOL, VUI_TEXT_FIELD_SYMBOL, VUI_WYSIWYG_EDITOR_SYMBOL, VWysiwygEditor, VuiColorProviderInjectionKey, VuiControlFieldInjectionKey, VuiControlInjectionKey, VuiInjectionKey, VuiPlugin, VuiService, WysiwygBulletListTool, WysiwygFormatBoldTool, WysiwygFormatItalicTool, WysiwygFormatUnderlineTool, WysiwygHistoryTool, WysiwygLinkTool, WysiwygOrderedListTool, WysiwygTextColorTool, configureDataTableDefaults, createAvatarProps, createCardProps, createChipProps, createControlFieldProviderProps, createControlProps, createElevationProps, createListTileProps, createNavigationItemProps, createPaperBaseProps, createPaperProps, createRequiredChipRenderer, createVFormProps, defineFormSelectorComponent, iconProps, installVuiPlugin, listTileEmits, mergeVuiPluginOptions, mergeVuiServiceIconSettings, mergeVuiServiceOptions, mergeVuiServiceUISettings, paginationProps, rawIconProp, renderNavigationItemInput, resolveNavigationItemInput, resolveRawIconProp, resolveRawWysiwygEditorTools, splitAttrs, useControl, useControlField, useElevation, useVui, useVuiColorProvider, vueButtonProps };
|
|
5399
|
+
export { AVATAR_SIZES, BadWords, CHIP_SIZES, CONTROL_FIELD_VARIANTS, CONTROL_LOADING_SPINNER_SIZES, CONTROL_SIZES, HeadingLevel, Linter, LinterPlugin, PAGINATION_ALIGNS, Punctuation, VApp, VAvatar, VBreadcrumbs, VBusyImage, VButton, VButtonGroup, VCard, VCardActions, VCardContent, VCheckbox, VCheckboxGroup, VChip, VContentSwitcher, VDataTable, VDrawerLayout, VForm, VFormControl, VGridContainer, VGridItem, VHero, VIcon, VListTile, VNavigation, VNavigationItem, VNumberField, VOption, VOptionGroup, VPagination, VPaper, VRadio, VRadioGroup, VSelect, VSkeltonLoaderBone, VSwitch, VSwitchGroup, VTabs, VTextField, VTextarea, VToolbar, VToolbarEdge, VToolbarMenu, VToolbarTitle, VUI_CHECKBOX_GROUP_SYMBOL, VUI_CHECKBOX_SYMBOL, VUI_FORM_SYMBOL, VUI_OPTION_SYMBOL, VUI_RADIO_GROUP_SYMBOL, VUI_RADIO_SYMBOL, VUI_SELECT_SYMBOL, VUI_SWITCH_GROUP_SYMBOL, VUI_SWITCH_SYMBOL, VUI_TEXTAREA_SYMBOL, VUI_TEXT_FIELD_SYMBOL, VUI_WYSIWYG_EDITOR_SYMBOL, VWysiwygEditor, VuiColorProviderInjectionKey, VuiControlFieldInjectionKey, VuiControlInjectionKey, VuiInjectionKey, VuiPlugin, VuiService, WysiwygBulletListTool, WysiwygEditorInitializeContext, WysiwygFormatBoldTool, WysiwygFormatItalicTool, WysiwygFormatUnderlineTool, WysiwygHistoryTool, WysiwygLinkTool, WysiwygOrderedListTool, WysiwygTextColorTool, configureDataTableDefaults, createAvatarProps, createCardProps, createChipProps, createControlFieldProviderProps, createControlProps, createElevationProps, createListTileProps, createNavigationItemProps, createPaperBaseProps, createPaperProps, createRequiredChipRenderer, createVFormProps, defineFormSelectorComponent, iconProps, installVuiPlugin, listTileEmits, mergeVuiPluginOptions, mergeVuiServiceIconSettings, mergeVuiServiceOptions, mergeVuiServiceUISettings, paginationProps, rawIconProp, renderNavigationItemInput, resolveNavigationItemInput, resolveRawIconProp, resolveRawWysiwygEditorTools, resolveRawWysiwygExtensions, splitAttrs, useControl, useControlField, useElevation, useVui, useVuiColorProvider, vueButtonProps };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastkit/vui",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.61",
|
|
4
4
|
"description": "@fastkit/vui",
|
|
5
5
|
"buildOptions": {
|
|
6
6
|
"name": "Vui",
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
"vue": "^3.2.26"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@fastkit/color-scheme": "0.7.
|
|
36
|
-
"@fastkit/icon-font": "0.7.
|
|
37
|
-
"@fastkit/tiny-logger": "0.7.
|
|
38
|
-
"@fastkit/vite-kit": "0.7.
|
|
39
|
-
"@fastkit/vue-kit": "0.7.
|
|
35
|
+
"@fastkit/color-scheme": "0.7.61",
|
|
36
|
+
"@fastkit/icon-font": "0.7.61",
|
|
37
|
+
"@fastkit/tiny-logger": "0.7.61",
|
|
38
|
+
"@fastkit/vite-kit": "0.7.61",
|
|
39
|
+
"@fastkit/vue-kit": "0.7.61",
|
|
40
40
|
"@tiptap/extension-link": "^2.0.0-beta.36",
|
|
41
41
|
"@tiptap/extension-underline": "^2.0.0-beta.23",
|
|
42
42
|
"@tiptap/starter-kit": "^2.0.0-beta.183",
|
|
Binary file
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
&__body {
|
|
31
31
|
position: relative;
|
|
32
|
+
width: 100%;
|
|
32
33
|
max-height: var(--max-height);
|
|
33
34
|
// max-height: 200px;
|
|
34
35
|
overflow: auto;
|
|
@@ -45,6 +46,7 @@
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
&__prose {
|
|
49
|
+
width: 100%;
|
|
48
50
|
min-height: var(--min-height);
|
|
49
51
|
outline: none;
|
|
50
52
|
}
|