@aquera/nile-elements 0.0.125 → 0.0.127

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Webcomponent nile-elements following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "nile-elements",
6
- "version": "0.0.125",
6
+ "version": "0.0.127",
7
7
  "main": "dist/src/index.js",
8
8
  "type": "module",
9
9
  "module": "dist/src/index.js",
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  KeyBinding,
3
- lineNumbers,
4
3
  highlightActiveLineGutter,
5
4
  highlightSpecialChars,
6
5
  drawSelection,
@@ -68,7 +67,6 @@ export const basicSetup = (options: BasicSetupOptions = {}): Extension[] => {
68
67
  isValidSetup(options.foldKeymap) && keymaps.push(...foldKeymap);
69
68
  isValidSetup(options.lintKeymap) && keymaps.push(...lintKeymap);
70
69
  const extensions: Extension[] = [];
71
- isValidSetup(options.lineNumbers) && extensions.push(lineNumbers());
72
70
  isValidSetup(options.highlightActiveLineGutter) && extensions.push(highlightActiveLineGutter());
73
71
  isValidSetup(options.highlightSpecialChars) && extensions.push(highlightSpecialChars());
74
72
  isValidSetup(options.history) && extensions.push(history());
@@ -31,7 +31,7 @@ import {
31
31
  } from '@codemirror/lang-javascript';
32
32
  import { sql } from '@codemirror/lang-sql';
33
33
  import { json } from '@codemirror/lang-json';
34
- import { autocompletion } from '@codemirror/autocomplete';
34
+ import { autocompletion,CompletionContext,CompletionResult } from '@codemirror/autocomplete';
35
35
  import NileElement from '../internal/nile-element';
36
36
  import { basicSetup } from './extensionSetup';
37
37
  import { classMap } from 'lit/directives/class-map.js';
@@ -53,7 +53,7 @@ export class NileCodeEditor extends NileElement {
53
53
 
54
54
  @property({ type: String, reflect: true , attribute: true }) value = '';
55
55
 
56
- @property({ type: Object, reflect: true , attribute: true }) customAutoCompletions: object = {};
56
+ @property({ type: Object, reflect: true , attribute: true }) customAutoCompletions: object | any = {};
57
57
 
58
58
  @property({ type: String, reflect: true , attribute: true}) language: 'javascript' | 'sql' | 'json' = 'javascript';
59
59
 
@@ -65,6 +65,8 @@ export class NileCodeEditor extends NileElement {
65
65
 
66
66
  @property({ type: Boolean, reflect: true , attribute: true }) multiline: boolean = false;
67
67
 
68
+ @property({ type: Boolean, reflect: true , attribute: true }) suggestionBracketSupport: boolean = false;
69
+
68
70
  @property({ type: Boolean, reflect: true , attribute: true }) lineNumbers: boolean = false;
69
71
 
70
72
  @property({ type: Boolean, reflect: true , attribute: true }) lineNumbersMultiline: boolean = true;
@@ -145,11 +147,11 @@ export class NileCodeEditor extends NileElement {
145
147
  ]
146
148
  })
147
149
  }
148
- if(changedProperties.has('customAutoCompletions')){
150
+ if(changedProperties.has('customAutoCompletions') || changedProperties.has('suggestionBracketSupport') ){
149
151
  this.view.dispatch({
150
152
  effects: [
151
153
  this.customCompletionComp.reconfigure(javascriptLanguage.data.of({
152
- autocomplete: scopeCompletionSource(this.customAutoCompletions),
154
+ autocomplete: this.suggestionBracketSupport?this.customAutocomplete: scopeCompletionSource(this.customAutoCompletions),
153
155
  }))
154
156
  ]
155
157
  })
@@ -206,14 +208,13 @@ export class NileCodeEditor extends NileElement {
206
208
  const readOnlyExtension = this.readOnlyComp.of(this.getReadOnlyExtension());
207
209
  const restrictSingleLineExtension = this.restrictSingleLineComp.of(this.getSingleLineExtension())
208
210
  const customAutoCompletions = this.customCompletionComp.of(javascriptLanguage.data.of({
209
- autocomplete: scopeCompletionSource(this.customAutoCompletions),
211
+ autocomplete: this.suggestionBracketSupport?this.customAutocomplete: scopeCompletionSource(this.customAutoCompletions),
210
212
  }));
211
213
  const language = this.getLanguageExtension()
212
214
  this.viewState = EditorState.create({
213
215
  doc: !this.multiline ? this.convertToSingleLine(this.value) : this.value,
214
216
  extensions: [
215
217
  basicSetup({
216
- lineNumbers: (!this.multiline && this.lineNumbers) || (this.multiline && this.lineNumbersMultiline),
217
218
  highlightActiveLine: false,
218
219
  foldGutter: false,
219
220
  }),
@@ -271,7 +272,6 @@ export class NileCodeEditor extends NileElement {
271
272
 
272
273
  //EXTENSION CONFIGURATIONS
273
274
  getLineNumbersExension() {
274
-
275
275
  return (!this.multiline && this.lineNumbers) || (this.multiline && this.lineNumbersMultiline) ? lineNumbers() : [];
276
276
  }
277
277
 
@@ -287,7 +287,7 @@ export class NileCodeEditor extends NileElement {
287
287
  }
288
288
 
289
289
  getReadOnlyExtension() {
290
- return EditorState.readOnly.of(this.readonly);
290
+ return this.readonly ? EditorState.readOnly.of(true) : [];
291
291
  }
292
292
 
293
293
  getSingleLineExtension() {
@@ -306,6 +306,101 @@ export class NileCodeEditor extends NileElement {
306
306
  this.emit('nile-expand', { expand: true },false);
307
307
  }
308
308
 
309
+ customAutocomplete = (context: CompletionContext): CompletionResult | null => {
310
+ // Getting the valid last line, last text from the code editor
311
+ let text = context.state.doc.sliceString(0, context.pos);
312
+ const [textBeforeCursor,textAfterSeperation]=this.splitStringAtLastSeparator(text.split('\n').at(-1)?.split(' ').at(-1)+'')
313
+
314
+ if (!this.isValidPath(textBeforeCursor)) return { from: context.pos, options: [] };
315
+ if(['.', '['].includes(textBeforeCursor[textBeforeCursor.length - 1])){
316
+ // Parse the path for dot or bracket notation
317
+ const path = this.parsePath(textBeforeCursor);
318
+ if (path) {
319
+ let resolved = this.resolveNestedProperties(this.customAutoCompletions, path);
320
+ if(textAfterSeperation){
321
+ const obj:any={}
322
+ Object.keys(resolved).forEach((key)=>{
323
+ if(key.startsWith(textAfterSeperation)){
324
+ obj[key]=resolved[key]
325
+ }
326
+ })
327
+ resolved=obj
328
+ }
329
+ // If resolved is an object, provide its keys as suggestions
330
+ if (resolved && typeof resolved === 'object') {
331
+ return {
332
+ from: context.pos,
333
+ options: Object.keys(resolved).map((key) => ({
334
+ label: key,
335
+ type: 'property',
336
+ info: `Key of ${path[path.length - 1]}`,
337
+ apply: key.slice(textAfterSeperation.length),
338
+ boost: 999
339
+ })),
340
+ };
341
+ }
342
+ }
343
+ }
344
+
345
+ // Match for top-level object suggestions, e.g., "a"
346
+ const baseMatch: any = textBeforeCursor.match(/([a-zA-Z_$][\w$]*)$/);
347
+ if (baseMatch) {
348
+ const optionsList=Object.keys(this.customAutoCompletions).filter(key=>key.startsWith(textBeforeCursor));
349
+ return {
350
+ from: context.pos - baseMatch[1].length,
351
+ options: optionsList.map((key) => ({
352
+ label: key,
353
+ type: 'property',
354
+ apply: key.slice(textBeforeCursor.length),
355
+ boost: 999
356
+ }))
357
+ }
358
+ }
359
+ // Default to an empty list if no match
360
+ return { from: context.pos, options: [] };
361
+ };
362
+
363
+ resolveNestedProperties = (obj:any, keys:any[]) => {
364
+ return keys.reduce((acc, key) => {
365
+ if (acc && typeof acc === 'object') {
366
+ return acc[key];
367
+ }
368
+ return null;
369
+ }, obj);
370
+ };
371
+
372
+ parsePath(text: string) {
373
+ const regex = /([a-zA-Z_$][\w$]*)(\[(?:[^\]]+)\]|\.[a-zA-Z_$][\w$]*)*/g;
374
+ const matches = [...text.matchAll(regex)];
375
+ if (matches.length > 0) {
376
+ const base = matches[0][1]; // The base object name
377
+ const keys = [base];
378
+ // Extract keys from dot or bracket notation
379
+ const pathMatches = text.match(/\[(.*?)\]|\.(\w+)/g) || [];
380
+ for (const match of pathMatches) {
381
+ if (match.startsWith('[')) {
382
+ keys.push(match.slice(1, -1).replace(/['"]/g, '')); // Remove brackets and quotes
383
+ } else if (match.startsWith('.')) {
384
+ keys.push(match.slice(1));
385
+ }
386
+ }
387
+ return keys;
388
+ }
389
+ return null;
390
+ };
391
+
392
+ isValidPath(path: string) {
393
+ // Regex to validate the format of the string
394
+ const regex = /^([a-zA-Z_$][\w$]*)(\.[a-zA-Z_$][\w$]*|\[\s*(['"]?[a-zA-Z0-9_$]*['"]?)\s*\])*([\.\[])?$/;
395
+ // Test the string against the regex
396
+ return regex.test(path);
397
+ }
398
+
399
+ splitStringAtLastSeparator(input:string) {
400
+ const lastSeparatorIndex = Math.max(input.lastIndexOf('.'), input.lastIndexOf('['));
401
+ if (lastSeparatorIndex === -1) return [input, ''];
402
+ return [input.slice(0, lastSeparatorIndex + 1), input.slice(lastSeparatorIndex + 1).replace(/["'\[]/g, '')];
403
+ }
309
404
  /* #endregion */
310
405
  }
311
406
 
@@ -726,7 +726,7 @@
726
726
  },
727
727
  {
728
728
  "name": "nile-code-editor",
729
- "description": "Nile icon component.\n\nEvents:\n\n * `nile-focus` {`Event`} - \n\n * `nile-blur` {`Event`} - \n\nAttributes:\n\n * `value` {`string`} - \n\n * `customAutoCompletions` {`object`} - \n\n * `language` {`\"javascript\" | \"sql\" | \"json\"`} - \n\n * `error-message` {`string`} - \n\n * `error` {`boolean`} - \n\n * `noborder` {`boolean`} - \n\n * `multiline` {`boolean`} - \n\n * `lineNumbers` {`boolean`} - \n\n * `lineNumbersMultiline` {`boolean`} - \n\n * `hasScroller` {`boolean`} - \n\n * `expandable` {`boolean`} - \n\n * `readonly` {`boolean`} - \n\n * `debounce` {`boolean`} - \n\nProperties:\n\n * `codeEditor` {`HTMLInputElement`} - \n\n * `value` {`string`} - \n\n * `customAutoCompletions` {`object`} - \n\n * `language` {`\"javascript\" | \"sql\" | \"json\"`} - \n\n * `errorMessage` {`string`} - \n\n * `error` {`boolean`} - \n\n * `noborder` {`boolean`} - \n\n * `multiline` {`boolean`} - \n\n * `lineNumbers` {`boolean`} - \n\n * `lineNumbersMultiline` {`boolean`} - \n\n * `hasScroller` {`boolean`} - \n\n * `expandable` {`boolean`} - \n\n * `readonly` {`boolean`} - \n\n * `debounce` {`boolean`} - \n\n * `view` - \n\n * `viewState` - \n\n * `timeOut` - \n\n * `lineNumbersComp` - \n\n * `restrictSingleLineComp` - \n\n * `readOnlyComp` - \n\n * `customCompletionComp` - \n\n * `insertBetweenCode` - \n\n * `BUBBLES` {`boolean`} - \n\n * `COMPOSED` {`boolean`} - \n\n * `CANCELABLE` {`boolean`} - ",
729
+ "description": "Nile icon component.\n\nEvents:\n\n * `nile-focus` {`Event`} - \n\n * `nile-blur` {`Event`} - \n\nAttributes:\n\n * `value` {`string`} - \n\n * `customAutoCompletions` - \n\n * `language` {`\"javascript\" | \"sql\" | \"json\"`} - \n\n * `error-message` {`string`} - \n\n * `error` {`boolean`} - \n\n * `noborder` {`boolean`} - \n\n * `multiline` {`boolean`} - \n\n * `suggestionBracketSupport` {`boolean`} - \n\n * `lineNumbers` {`boolean`} - \n\n * `lineNumbersMultiline` {`boolean`} - \n\n * `hasScroller` {`boolean`} - \n\n * `expandable` {`boolean`} - \n\n * `readonly` {`boolean`} - \n\n * `debounce` {`boolean`} - \n\nProperties:\n\n * `codeEditor` {`HTMLInputElement`} - \n\n * `value` {`string`} - \n\n * `customAutoCompletions` - \n\n * `language` {`\"javascript\" | \"sql\" | \"json\"`} - \n\n * `errorMessage` {`string`} - \n\n * `error` {`boolean`} - \n\n * `noborder` {`boolean`} - \n\n * `multiline` {`boolean`} - \n\n * `suggestionBracketSupport` {`boolean`} - \n\n * `lineNumbers` {`boolean`} - \n\n * `lineNumbersMultiline` {`boolean`} - \n\n * `hasScroller` {`boolean`} - \n\n * `expandable` {`boolean`} - \n\n * `readonly` {`boolean`} - \n\n * `debounce` {`boolean`} - \n\n * `view` - \n\n * `viewState` - \n\n * `timeOut` - \n\n * `lineNumbersComp` - \n\n * `restrictSingleLineComp` - \n\n * `readOnlyComp` - \n\n * `customCompletionComp` - \n\n * `insertBetweenCode` - \n\n * `customAutocomplete` - \n\n * `resolveNestedProperties` - \n\n * `BUBBLES` {`boolean`} - \n\n * `COMPOSED` {`boolean`} - \n\n * `CANCELABLE` {`boolean`} - ",
730
730
  "attributes": [
731
731
  {
732
732
  "name": "value",
@@ -734,7 +734,7 @@
734
734
  },
735
735
  {
736
736
  "name": "customAutoCompletions",
737
- "description": "`customAutoCompletions` {`object`} - \n\nProperty: customAutoCompletions\n\nDefault: [object Object]"
737
+ "description": "`customAutoCompletions` - \n\nProperty: customAutoCompletions\n\nDefault: [object Object]"
738
738
  },
739
739
  {
740
740
  "name": "language",
@@ -770,6 +770,11 @@
770
770
  "description": "`multiline` {`boolean`} - \n\nProperty: multiline\n\nDefault: false",
771
771
  "valueSet": "v"
772
772
  },
773
+ {
774
+ "name": "suggestionBracketSupport",
775
+ "description": "`suggestionBracketSupport` {`boolean`} - \n\nProperty: suggestionBracketSupport\n\nDefault: false",
776
+ "valueSet": "v"
777
+ },
773
778
  {
774
779
  "name": "lineNumbers",
775
780
  "description": "`lineNumbers` {`boolean`} - \n\nProperty: lineNumbers\n\nDefault: false",