nuxt-codemirror 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Thimo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+
2
+
3
+ # Nuxt CodeMirror
4
+
5
+ [![npm version][npm-version-src]][npm-version-href]
6
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
7
+ [![License][license-src]][license-href]
8
+ [![Nuxt][nuxt-src]][nuxt-href]
9
+
10
+ Codemirror as a Nuxt module. Demo preview: Coming soon
11
+
12
+
13
+ - [โœจ  Release Notes](/CHANGELOG.md)
14
+ <!-- - [๐Ÿ€ Online playground](https://stackblitz.com/github/your-org/my-module?file=playground%2Fapp.vue) -->
15
+ <!-- - [๐Ÿ“– &nbsp;Documentation](https://example.com) -->
16
+
17
+ ## Features
18
+
19
+ <!-- Highlight some of the features your module provide here -->
20
+ - ๐Ÿš€ Easily configure codemirror to your own needs using almost every API
21
+ - ๐Ÿš  Built with Typescript
22
+ - ๐ŸŒฒ Custom useNuxtCodeMirror composable for creating your own editor
23
+ - Built for CodeMirror 6 and above
24
+
25
+ ## Quick Setup
26
+
27
+ Install the module to your Nuxt application with one command:
28
+
29
+ ```bash
30
+ npx nuxi module add thimodev/nuxt-codemirror
31
+ ```
32
+
33
+ That's it! You can now use Nuxt-codemirror in your Nuxt app โœจ
34
+
35
+ ## Contribution
36
+
37
+ <details>
38
+ <summary>Local development</summary>
39
+
40
+ ```bash
41
+ # Install dependencies
42
+ pnpm i
43
+
44
+ # Generate type stubs
45
+ pnpm dev:prepare
46
+
47
+ # Develop with the playground
48
+ pnpm dev
49
+
50
+ # Build the playground
51
+ pnpm dev:build
52
+
53
+ # Run ESLint
54
+ pnpm lint
55
+
56
+ # Run Vitest
57
+ pnpm test
58
+ pnpm test:watch
59
+
60
+ # Release new version
61
+ pnpm release
62
+ ```
63
+
64
+ </details>
65
+
66
+
67
+ <!-- Badges -->
68
+ [npm-version-src]: https://img.shields.io/npm/v/my-module/latest.svg?style=flat&colorA=020420&colorB=00DC82
69
+ [npm-version-href]: https://npmjs.com/package/my-module
70
+
71
+ [npm-downloads-src]: https://img.shields.io/npm/dm/my-module.svg?style=flat&colorA=020420&colorB=00DC82
72
+ [npm-downloads-href]: https://npmjs.com/package/my-module
73
+
74
+ [license-src]: https://img.shields.io/npm/l/my-module.svg?style=flat&colorA=020420&colorB=00DC82
75
+ [license-href]: https://npmjs.com/package/my-module
76
+
77
+ [nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js
78
+ [nuxt-href]: https://nuxt.com
79
+
80
+
81
+
82
+ ## FAQ
83
+
84
+ - I get an extension duplicate error: Fix Unrecognized extension value in extension set ([object Object]). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.
85
+
86
+ For now write shamefully-hoist=true in your .npmrc file to solve this. We are working on a better solution
@@ -0,0 +1,5 @@
1
+ module.exports = function(...args) {
2
+ return import('./module.mjs').then(m => m.default.call(this, ...args))
3
+ }
4
+ const _meta = module.exports.meta = require('./module.json')
5
+ module.exports.getMeta = () => Promise.resolve(_meta)
@@ -0,0 +1,7 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ }
5
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
6
+
7
+ export { type ModuleOptions, _default as default };
@@ -0,0 +1,7 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ }
5
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
6
+
7
+ export { type ModuleOptions, _default as default };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "nuxt-codemirror",
3
+ "configKey": "nuxtCodemirror",
4
+ "version": "0.0.1",
5
+ "builder": {
6
+ "@nuxt/module-builder": "0.8.1",
7
+ "unbuild": "2.0.0"
8
+ }
9
+ }
@@ -0,0 +1,28 @@
1
+ import { defineNuxtModule, createResolver, addComponent, addImports, addTypeTemplate } from '@nuxt/kit';
2
+
3
+ const module = defineNuxtModule({
4
+ meta: {
5
+ name: "nuxt-codemirror",
6
+ configKey: "nuxtCodemirror"
7
+ },
8
+ // Default configuration options of the Nuxt module
9
+ defaults: {},
10
+ setup(_options, _nuxt) {
11
+ const { resolve } = createResolver(import.meta.url);
12
+ addComponent({
13
+ name: "NuxtCodeMirror",
14
+ filePath: resolve("./runtime/components/NuxtCodeMirror.vue")
15
+ });
16
+ addImports({
17
+ name: "useNuxtCodeMirror",
18
+ as: "useNuxtCodeMirror",
19
+ from: resolve("./runtime/composables/useNuxtCodeMirror.ts")
20
+ });
21
+ addTypeTemplate({
22
+ filename: "../runtime/types/nuxt-codemirror.d.ts",
23
+ src: resolve("./runtime/types/nuxt-codemirror.d.ts")
24
+ });
25
+ }
26
+ });
27
+
28
+ export { module as default };
@@ -0,0 +1,77 @@
1
+ <script setup lang="ts">
2
+ import type { ViewUpdate, EditorView } from '@codemirror/view'
3
+ import type { EditorState } from '@codemirror/state'
4
+ import { useNuxtCodeMirror } from '../composables/useNuxtCodeMirror'
5
+ import type { NuxtCodeMirrorProps, Statistics } from '../types/nuxt-codemirror'
6
+ import { onMounted, ref, watch, nextTick, computed } from '#imports'
7
+
8
+ const editor = ref<HTMLDivElement | null>(null)
9
+ const container = ref<HTMLDivElement | null>(null)
10
+ const view = ref<EditorView>()
11
+ const state = ref<EditorState>()
12
+
13
+ const modelValue = defineModel<string>({ default: '' })
14
+
15
+ const props = withDefaults(defineProps<Omit<NuxtCodeMirrorProps, 'modelValue'>>(), {
16
+ extensions: () => [],
17
+ theme: 'light',
18
+ })
19
+
20
+ defineExpose({
21
+ container,
22
+ view,
23
+ state,
24
+ editor,
25
+ })
26
+
27
+ const emit = defineEmits<{
28
+ (event: 'onChange', value: string, viewUpdate: ViewUpdate): void
29
+ (event: 'onStatistics', data: Statistics): void
30
+ (event: 'onCreateEditor', editor: { view: EditorView, state: EditorState }): void
31
+ (event: 'onUpdate' | 'onFocus' | 'onBlur', update: ViewUpdate): void
32
+ }>()
33
+
34
+ onMounted(async () => {
35
+ await nextTick()
36
+
37
+ useNuxtCodeMirror({
38
+ ...props,
39
+ modelValue: modelValue.value,
40
+ onChange: (value, viewUpdate) => {
41
+ modelValue.value = value
42
+ emit('onChange', value, viewUpdate)
43
+ },
44
+ onStatistics: data => emit('onStatistics', data),
45
+ onCreateEditor: (view, state) => emit('onCreateEditor', { view, state }),
46
+ onUpdate: viewUpdate => emit('onUpdate', viewUpdate),
47
+ onFocus: viewUpdate => emit('onFocus', viewUpdate),
48
+ onBlur: viewUpdate => emit('onBlur', viewUpdate),
49
+ container: editor.value,
50
+ viewRef: view,
51
+ stateRef: state,
52
+ containerRef: container,
53
+ })
54
+
55
+ /** DEBUGGING the variables exposed by defineExpose */
56
+ // await nextTick()
57
+ // console.log('test: ', view.value)
58
+ })
59
+
60
+ watch(() => modelValue, (newValue) => {
61
+ if (typeof newValue !== 'string') {
62
+ console.error(`value must be typeof string but got ${typeof newValue}`)
63
+ }
64
+ })
65
+
66
+ const defaultClassNames = computed(() =>
67
+ typeof props.theme === 'string' ? `cm-theme-${props.theme}` : 'cm-theme',
68
+ )
69
+ </script>
70
+
71
+ <template>
72
+ <div
73
+ ref="editor"
74
+ :class="`${defaultClassNames}${$attrs.class ? ` ${$attrs.class}` : ''}`"
75
+ v-bind="$attrs"
76
+ />
77
+ </template>
@@ -0,0 +1,8 @@
1
+ import { EditorState } from '@codemirror/state';
2
+ import { EditorView } from '@codemirror/view';
3
+ import { type UseCodeMirrorProps } from '../types/nuxt-codemirror.js';
4
+ export declare function useNuxtCodeMirror(props: UseCodeMirrorProps): {
5
+ containerRef: import("#imports").Ref<HTMLDivElement | null>;
6
+ viewRef: import("#imports").Ref<EditorView | undefined>;
7
+ stateRef: import("#imports").Ref<EditorState | undefined>;
8
+ };
@@ -0,0 +1,160 @@
1
+ import { Annotation, EditorState, StateEffect } from "@codemirror/state";
2
+ import { EditorView } from "@codemirror/view";
3
+ import { getDefaultExtensions } from "../getDefaultExtensions.js";
4
+ import { getStatistics } from "../utils/utils.js";
5
+ import { onBeforeUnmount, watch, watchEffect } from "#imports";
6
+ const External = Annotation.define();
7
+ const emptyExtensions = [];
8
+ export function useNuxtCodeMirror(props) {
9
+ const {
10
+ // modelValue = '',
11
+ selection,
12
+ onChange,
13
+ onStatistics,
14
+ onCreateEditor,
15
+ onUpdate,
16
+ onFocus,
17
+ onBlur,
18
+ extensions = emptyExtensions,
19
+ autoFocus,
20
+ theme = "light",
21
+ height = null,
22
+ minHeight = null,
23
+ maxHeight = null,
24
+ width = null,
25
+ minWidth = null,
26
+ maxWidth = null,
27
+ placeholder: placeholderStr = "",
28
+ editable = true,
29
+ readOnly = false,
30
+ indentWithTab: defaultIndentWithTab = true,
31
+ basicSetup: defaultBasicSetup = true,
32
+ root,
33
+ initialState,
34
+ containerRef,
35
+ viewRef,
36
+ stateRef
37
+ } = props;
38
+ const defaultThemeOption = EditorView.theme({
39
+ "&": {
40
+ height,
41
+ minHeight,
42
+ maxHeight,
43
+ width,
44
+ minWidth,
45
+ maxWidth
46
+ },
47
+ "& .cm-scroller": {
48
+ height: "100% !important"
49
+ }
50
+ });
51
+ const updateListener = EditorView.updateListener.of((viewUpdate) => {
52
+ if (viewUpdate.docChanged && typeof onChange === "function" && !viewUpdate.transactions.some((tr) => tr.annotation(External))) {
53
+ const doc = viewUpdate.state.doc;
54
+ const value = doc.toString();
55
+ onChange(value, viewUpdate);
56
+ }
57
+ if (viewUpdate.focusChanged) {
58
+ viewUpdate.view.hasFocus ? onFocus && onFocus(viewUpdate) : onBlur && onBlur(viewUpdate);
59
+ }
60
+ onStatistics && onStatistics(getStatistics(viewUpdate));
61
+ });
62
+ const defaultExtensions = getDefaultExtensions({
63
+ theme,
64
+ editable,
65
+ readOnly,
66
+ placeholder: placeholderStr,
67
+ indentWithTab: defaultIndentWithTab,
68
+ basicSetup: defaultBasicSetup
69
+ });
70
+ let getExtensions = [updateListener, defaultThemeOption, ...defaultExtensions];
71
+ if (onUpdate && typeof onUpdate === "function") {
72
+ getExtensions.push(EditorView.updateListener.of(onUpdate));
73
+ }
74
+ getExtensions = getExtensions.concat(extensions);
75
+ watchEffect(() => {
76
+ if (containerRef.value && !stateRef?.value) {
77
+ const config = {
78
+ doc: props.modelValue,
79
+ selection,
80
+ extensions: getExtensions
81
+ };
82
+ const stateCurrent = initialState ? EditorState.fromJSON(initialState.json, config, initialState.fields) : EditorState.create(config);
83
+ stateRef.value = stateCurrent;
84
+ if (!viewRef.value) {
85
+ const viewCurrent = new EditorView({
86
+ state: stateCurrent,
87
+ parent: containerRef.value,
88
+ root
89
+ });
90
+ viewRef.value = viewCurrent;
91
+ onCreateEditor && onCreateEditor(viewCurrent, stateCurrent);
92
+ }
93
+ }
94
+ });
95
+ watch(
96
+ () => props.container,
97
+ (newContainer) => {
98
+ if (newContainer === void 0) return;
99
+ containerRef.value = newContainer;
100
+ },
101
+ { immediate: true }
102
+ );
103
+ watch(
104
+ [
105
+ () => theme,
106
+ () => extensions,
107
+ () => height,
108
+ () => minHeight,
109
+ () => maxHeight,
110
+ () => width,
111
+ () => minWidth,
112
+ () => maxWidth,
113
+ () => placeholderStr,
114
+ () => editable,
115
+ () => readOnly,
116
+ () => defaultIndentWithTab,
117
+ () => defaultBasicSetup,
118
+ () => onChange,
119
+ () => onUpdate
120
+ ],
121
+ () => {
122
+ if (viewRef.value) {
123
+ viewRef.value.dispatch({ effects: StateEffect.reconfigure.of(getExtensions) });
124
+ }
125
+ },
126
+ { immediate: true }
127
+ );
128
+ watchEffect(() => {
129
+ if (props.modelValue === void 0) {
130
+ return;
131
+ }
132
+ const currentValue = viewRef.value ? viewRef.value.state.doc.toString() : "";
133
+ if (viewRef.value && props.modelValue !== currentValue) {
134
+ viewRef.value.dispatch({
135
+ changes: { from: 0, to: currentValue.length, insert: props.modelValue || "" },
136
+ annotations: [External.of(true)]
137
+ });
138
+ }
139
+ });
140
+ watch(
141
+ [() => autoFocus, () => viewRef.value],
142
+ ([autoFocus2, view]) => {
143
+ if (autoFocus2 && view) {
144
+ view.focus();
145
+ }
146
+ },
147
+ { immediate: true }
148
+ );
149
+ onBeforeUnmount(() => {
150
+ if (viewRef) {
151
+ viewRef.value?.destroy();
152
+ viewRef.value = void 0;
153
+ }
154
+ });
155
+ return {
156
+ containerRef,
157
+ viewRef,
158
+ stateRef
159
+ };
160
+ }
@@ -0,0 +1,13 @@
1
+ import { type Extension } from '@codemirror/state';
2
+ import { type BasicSetupOptions } from '@uiw/codemirror-extensions-basic-setup';
3
+ export * from '@codemirror/theme-one-dark';
4
+ export * from './theme/light.js';
5
+ export interface DefaultExtensionsOptions {
6
+ indentWithTab?: boolean;
7
+ basicSetup?: boolean | BasicSetupOptions;
8
+ placeholder?: string | HTMLElement;
9
+ theme?: 'light' | 'dark' | 'none' | Extension;
10
+ readOnly?: boolean;
11
+ editable?: boolean;
12
+ }
13
+ export declare const getDefaultExtensions: (optios?: DefaultExtensionsOptions) => Extension[];
@@ -0,0 +1,52 @@
1
+ import { indentWithTab } from "@codemirror/commands";
2
+ import { basicSetup } from "@uiw/codemirror-extensions-basic-setup";
3
+ import { EditorView, keymap, placeholder } from "@codemirror/view";
4
+ import { oneDark } from "@codemirror/theme-one-dark";
5
+ import { EditorState } from "@codemirror/state";
6
+ import { defaultLightThemeOption } from "./theme/light.js";
7
+ export * from "@codemirror/theme-one-dark";
8
+ export * from "./theme/light.js";
9
+ export const getDefaultExtensions = (optios = {}) => {
10
+ const {
11
+ indentWithTab: defaultIndentWithTab = true,
12
+ editable = true,
13
+ readOnly = false,
14
+ theme = "light",
15
+ placeholder: placeholderStr = "",
16
+ basicSetup: defaultBasicSetup = true
17
+ } = optios;
18
+ const getExtensions = [];
19
+ if (defaultIndentWithTab) {
20
+ getExtensions.unshift(keymap.of([indentWithTab]));
21
+ }
22
+ if (defaultBasicSetup) {
23
+ if (typeof defaultBasicSetup === "boolean") {
24
+ getExtensions.unshift(basicSetup());
25
+ } else {
26
+ getExtensions.unshift(basicSetup(defaultBasicSetup));
27
+ }
28
+ }
29
+ if (placeholderStr) {
30
+ getExtensions.unshift(placeholder(placeholderStr));
31
+ }
32
+ switch (theme) {
33
+ case "light":
34
+ getExtensions.push(defaultLightThemeOption);
35
+ break;
36
+ case "dark":
37
+ getExtensions.push(oneDark);
38
+ break;
39
+ case "none":
40
+ break;
41
+ default:
42
+ getExtensions.push(theme);
43
+ break;
44
+ }
45
+ if (editable === false) {
46
+ getExtensions.push(EditorView.editable.of(false));
47
+ }
48
+ if (readOnly) {
49
+ getExtensions.push(EditorState.readOnly.of(true));
50
+ }
51
+ return [...getExtensions];
52
+ };
@@ -0,0 +1,2 @@
1
+ declare const _default: import("#app").Plugin<Record<string, unknown>> & import("#app").ObjectPlugin<Record<string, unknown>>;
2
+ export default _default;
@@ -0,0 +1,4 @@
1
+ import { defineNuxtPlugin } from "#app";
2
+ export default defineNuxtPlugin((_nuxtApp) => {
3
+ console.log("Plugin injected by my-module!");
4
+ });
@@ -0,0 +1 @@
1
+ export declare const defaultLightThemeOption: import("@codemirror/state").Extension;
@@ -0,0 +1,11 @@
1
+ import { EditorView } from "@codemirror/view";
2
+ export const defaultLightThemeOption = EditorView.theme(
3
+ {
4
+ "&": {
5
+ backgroundColor: "#fff"
6
+ }
7
+ },
8
+ {
9
+ dark: false
10
+ }
11
+ );
@@ -0,0 +1,123 @@
1
+ import type { EditorState, EditorStateConfig, Extension, StateField, EditorSelection, SelectionRange, Line } from '@codemirror/state'
2
+ import type { EditorView, ViewUpdate } from '@codemirror/view'
3
+ import type { BasicSetupOptions } from '@uiw/codemirror-extensions-basic-setup'
4
+ import type { Ref } from '#imports'
5
+
6
+ export interface NuxtCodeMirrorProps
7
+ extends Omit<EditorStateConfig, 'doc' | 'extensions'> {
8
+ /** value of the auto created model in the editor. */
9
+ modelValue?: string
10
+ height?: string
11
+ minHeight?: string
12
+ maxHeight?: string
13
+ width?: string
14
+ minWidth?: string
15
+ maxWidth?: string
16
+ /** focus on the editor. */
17
+ autoFocus?: boolean
18
+ /** Enables a placeholderโ€”a piece of example content to show when the editor is empty. */
19
+ placeholder?: string | HTMLElement
20
+ /**
21
+ * `light` / `dark` / `Extension` Defaults to `light`.
22
+ * @default light
23
+ */
24
+ theme?: 'light' | 'dark' | 'none' | Extension
25
+ /**
26
+ * Whether to optional basicSetup by default
27
+ * @default true
28
+ */
29
+ basicSetup?: boolean | BasicSetupOptions
30
+ /**
31
+ * This disables editing of the editor content by the user.
32
+ * @default true
33
+ */
34
+ editable?: boolean
35
+ /**
36
+ * This disables editing of the editor content by the user.
37
+ * @default false
38
+ */
39
+ readOnly?: boolean
40
+ /**
41
+ * Controls whether pressing the `Tab` key inserts a tab character and indents the text (`true`)
42
+ * or behaves according to the browser's default behavior (`false`).
43
+ * @default true
44
+ */
45
+ indentWithTab?: boolean
46
+ /** Fired whenever a change occurs to the document. */
47
+ onChange?(value: string, viewUpdate: ViewUpdate): void
48
+ /** Some data on the statistics editor. */
49
+ onStatistics?(data: Statistics): void
50
+ /** Fired whenever any state change occurs within the editor, including non-document changes like lint results. */
51
+ onUpdate?(viewUpdate: ViewUpdate): void
52
+ /** The first time the editor executes the event. */
53
+ onCreateEditor?(view: EditorView, state: EditorState): void
54
+ /** Fired whenever the editor is focused. */
55
+ onFocus?(view: ViewUpdate): void
56
+ /** Fired whenever the editor is blurred. */
57
+ onBlur?(view: ViewUpdate): void
58
+ /**
59
+ * Extension values can be [provided](https://codemirror.net/6/docs/ref/#state.EditorStateConfig.extensions) when creating a state to attach various kinds of configuration and behavior information.
60
+ * They can either be built-in extension-providing objects,
61
+ * such as [state fields](https://codemirror.net/6/docs/ref/#state.StateField) or [facet providers](https://codemirror.net/6/docs/ref/#state.Facet.of),
62
+ * or objects with an extension in its `extension` property. Extensions can be nested in arrays arbitrarily deepโ€”they will be flattened when processed.
63
+ */
64
+ extensions?: Extension[]
65
+ /**
66
+ * If the view is going to be mounted in a shadow root or document other than the one held by the global variable document (the default), you should pass it here.
67
+ * Originally from the [config of EditorView](https://codemirror.net/6/docs/ref/#view.EditorView.constructor%5Econfig.root)
68
+ */
69
+ root?: ShadowRoot | Document
70
+ /**
71
+ * Create a state from its JSON representation serialized with [toJSON](https://codemirror.net/docs/ref/#state.EditorState.toJSON) function
72
+ */
73
+ initialState?: {
74
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
+ json: any
76
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
77
+ fields?: Record<string, StateField<any>>
78
+ }
79
+ }
80
+
81
+ export interface UseCodeMirrorProps extends NuxtCodeMirrorProps {
82
+ container?: HTMLDivElement | null
83
+ viewRef: Ref<EditorView | undefined>
84
+ stateRef: Ref<EditorState | undefined>
85
+ containerRef: Ref<HTMLDivElement | null>
86
+ }
87
+
88
+ export interface Statistics {
89
+ /** total length of the document */
90
+ length: number
91
+ /** Get the number of lines in the editor. */
92
+ lineCount: number
93
+ /** Get the currently line description around the given position. */
94
+ line: Line
95
+ /** Get the proper [line-break](https://codemirror.net/docs/ref/#state.EditorState^lineSeparator) string for this state. */
96
+ lineBreak: string
97
+ /** Returns true when the editor is [configured](https://codemirror.net/6/docs/ref/#state.EditorState^readOnly) to be read-only. */
98
+ readOnly: boolean
99
+ /** The size (in columns) of a tab in the document, determined by the [`tabSize`](https://codemirror.net/6/docs/ref/#state.EditorState^tabSize) facet. */
100
+ tabSize: number
101
+ /** Cursor Position */
102
+ selection: EditorSelection
103
+ /** Make sure the selection only has one range. */
104
+ selectionAsSingle: SelectionRange
105
+ /** Retrieves a list of all current selections. */
106
+ ranges: readonly SelectionRange[]
107
+ /** Get the currently selected code. */
108
+ selectionCode: string
109
+ /**
110
+ * The length of the given array should be the same as the number of active selections.
111
+ * Replaces the content of the selections with the strings in the array.
112
+ */
113
+ selections: string[]
114
+ /** Return true if any text is selected. */
115
+ selectedText: boolean
116
+ }
117
+
118
+ export interface CodeMirrorRef {
119
+ container: HTMLDivElement | null
120
+ view: EditorView | undefined
121
+ state: EditorState | undefined
122
+ editor: HTMLDivElement | null
123
+ }
@@ -0,0 +1,3 @@
1
+ import type { ViewUpdate } from '@codemirror/view';
2
+ import type { Statistics } from '../types/nuxt-codemirror.js';
3
+ export declare const getStatistics: (view: ViewUpdate) => Statistics;
@@ -0,0 +1,16 @@
1
+ export const getStatistics = (view) => {
2
+ return {
3
+ line: view.state.doc.lineAt(view.state.selection.main.from),
4
+ lineCount: view.state.doc.lines,
5
+ lineBreak: view.state.lineBreak,
6
+ length: view.state.doc.length,
7
+ readOnly: view.state.readOnly,
8
+ tabSize: view.state.tabSize,
9
+ selection: view.state.selection,
10
+ selectionAsSingle: view.state.selection.asSingle().main,
11
+ ranges: view.state.selection.ranges,
12
+ selectionCode: view.state.sliceDoc(view.state.selection.main.from, view.state.selection.main.to),
13
+ selections: view.state.selection.ranges.map((r) => view.state.sliceDoc(r.from, r.to)),
14
+ selectedText: view.state.selection.ranges.some((r) => !r.empty)
15
+ };
16
+ };
@@ -0,0 +1 @@
1
+ export { type ModuleOptions, default } from './module.js'
@@ -0,0 +1 @@
1
+ export { type ModuleOptions, default } from './module'
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "nuxt-codemirror",
3
+ "version": "0.0.1",
4
+ "description": "Nuxt codemirror module",
5
+ "repository": "https://github.com/ThimoDEV/nuxt-codemirror",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/types.d.ts",
11
+ "import": "./dist/module.mjs",
12
+ "require": "./dist/module.cjs"
13
+ }
14
+ },
15
+ "main": "./dist/module.cjs",
16
+ "types": "./dist/types.d.ts",
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "prepack": "nuxt-module-build build",
22
+ "dev": "nuxi dev playground",
23
+ "dev:build": "nuxi build playground",
24
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
25
+ "release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
26
+ "lint": "eslint .",
27
+ "test": "vitest run",
28
+ "test:watch": "vitest watch",
29
+ "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
30
+ },
31
+ "dependencies": {
32
+ "@codemirror/commands": "^6.6.0",
33
+ "@codemirror/lang-javascript": "^6.2.2",
34
+ "@codemirror/state": "6.4.1",
35
+ "@codemirror/theme-one-dark": "^6.1.1",
36
+ "@codemirror/view": "6.28.1",
37
+ "@nuxt/kit": "^3.12.4",
38
+ "@uiw/codemirror-extensions-basic-setup": "^4.23.0"
39
+ },
40
+ "devDependencies": {
41
+ "@nuxt/devtools": "^1.3.9",
42
+ "@nuxt/eslint-config": "^0.3.13",
43
+ "@nuxt/module-builder": "^0.8.1",
44
+ "@nuxt/schema": "^3.12.4",
45
+ "@nuxt/test-utils": "^3.13.1",
46
+ "@types/node": "^20.14.11",
47
+ "changelogen": "^0.5.5",
48
+ "eslint": "^9.7.0",
49
+ "nuxt": "^3.12.4",
50
+ "typescript": "latest",
51
+ "vitest": "^2.0.3",
52
+ "vue-tsc": "^2.0.26"
53
+ }
54
+ }