@aquera/nile-elements 0.1.12 → 0.1.14

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.
Files changed (45) hide show
  1. package/README.md +7 -0
  2. package/dist/nile-code-editor/extensionSetup.cjs.js +5 -5
  3. package/dist/nile-code-editor/extensionSetup.cjs.js.map +1 -1
  4. package/dist/nile-code-editor/extensionSetup.esm.js +1 -1
  5. package/dist/nile-code-editor/nile-code-editor.cjs.js +2 -2
  6. package/dist/nile-code-editor/nile-code-editor.cjs.js.map +1 -1
  7. package/dist/nile-code-editor/nile-code-editor.esm.js +3 -3
  8. package/dist/nile-code-editor/theme.cjs.js +1 -1
  9. package/dist/nile-code-editor/theme.cjs.js.map +1 -1
  10. package/dist/nile-code-editor/theme.esm.js +1 -1
  11. package/dist/nile-form-help-text/index.cjs.js +1 -1
  12. package/dist/nile-form-help-text/index.esm.js +1 -1
  13. package/dist/nile-form-help-text/nile-form-help-text.cjs.js +1 -1
  14. package/dist/nile-form-help-text/nile-form-help-text.cjs.js.map +1 -1
  15. package/dist/nile-form-help-text/nile-form-help-text.css.cjs.js +1 -1
  16. package/dist/nile-form-help-text/nile-form-help-text.css.cjs.js.map +1 -1
  17. package/dist/nile-form-help-text/nile-form-help-text.css.esm.js +22 -6
  18. package/dist/nile-form-help-text/nile-form-help-text.esm.js +20 -16
  19. package/dist/nile-form-help-text/nile-form-help-text.test.cjs.js +1 -1
  20. package/dist/nile-form-help-text/nile-form-help-text.test.cjs.js.map +1 -1
  21. package/dist/nile-form-help-text/nile-form-help-text.test.esm.js +1 -1
  22. package/dist/src/nile-code-editor/extensionSetup.js +1 -3
  23. package/dist/src/nile-code-editor/extensionSetup.js.map +1 -1
  24. package/dist/src/nile-code-editor/nile-code-editor.d.ts +5 -0
  25. package/dist/src/nile-code-editor/nile-code-editor.js +32 -2
  26. package/dist/src/nile-code-editor/nile-code-editor.js.map +1 -1
  27. package/dist/src/nile-code-editor/theme.d.ts +24 -0
  28. package/dist/src/nile-code-editor/theme.js +24 -0
  29. package/dist/src/nile-code-editor/theme.js.map +1 -1
  30. package/dist/src/nile-form-help-text/nile-form-help-text.css.js +22 -6
  31. package/dist/src/nile-form-help-text/nile-form-help-text.css.js.map +1 -1
  32. package/dist/src/nile-form-help-text/nile-form-help-text.d.ts +13 -10
  33. package/dist/src/nile-form-help-text/nile-form-help-text.js +61 -82
  34. package/dist/src/nile-form-help-text/nile-form-help-text.js.map +1 -1
  35. package/dist/src/nile-form-help-text/nile-form-help-text.test.js +73 -52
  36. package/dist/src/nile-form-help-text/nile-form-help-text.test.js.map +1 -1
  37. package/dist/tsconfig.tsbuildinfo +1 -1
  38. package/package.json +1 -1
  39. package/src/nile-code-editor/extensionSetup.ts +0 -6
  40. package/src/nile-code-editor/nile-code-editor.ts +34 -2
  41. package/src/nile-code-editor/theme.ts +28 -0
  42. package/src/nile-form-help-text/nile-form-help-text.css.ts +22 -6
  43. package/src/nile-form-help-text/nile-form-help-text.test.ts +83 -59
  44. package/src/nile-form-help-text/nile-form-help-text.ts +64 -82
  45. package/vscode-html-custom-data.json +2 -14
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.1.12",
6
+ "version": "0.1.14",
7
7
  "main": "dist/src/index.js",
8
8
  "type": "module",
9
9
  "module": "dist/src/index.js",
@@ -21,8 +21,6 @@ import {
21
21
  import {
22
22
  foldGutter,
23
23
  indentOnInput,
24
- syntaxHighlighting,
25
- defaultHighlightStyle,
26
24
  bracketMatching,
27
25
  indentUnit,
28
26
  foldKeymap,
@@ -83,10 +81,6 @@ export const basicSetup = (options: BasicSetupOptions = {}): Extension[] => {
83
81
  isValidSetup(options.dropCursor) && extensions.push(dropCursor());
84
82
  isValidSetup(options.allowMultipleSelections) && extensions.push(EditorState.allowMultipleSelections.of(true));
85
83
  isValidSetup(options.indentOnInput) && extensions.push(indentOnInput());
86
- isValidSetup(options.syntaxHighlighting) &&
87
- extensions.push(
88
- syntaxHighlighting(defaultHighlightStyle, { fallback: true })
89
- );
90
84
  isValidSetup(options.bracketMatching) && extensions.push(bracketMatching());
91
85
  isValidSetup(options.closeBrackets) && extensions.push(closeBrackets());
92
86
  isValidSetup(options.autocompletion) && extensions.push(autocompletion());
@@ -22,6 +22,11 @@ import {
22
22
  Extension
23
23
  } from '@codemirror/state';
24
24
 
25
+ import {
26
+ syntaxHighlighting,
27
+ defaultHighlightStyle,
28
+ } from '@codemirror/language';
29
+
25
30
  import { lineNumbers } from '@codemirror/view';
26
31
  import {
27
32
  javascript,
@@ -34,7 +39,7 @@ import { autocompletion,CompletionContext,CompletionResult } from '@codemirror/a
34
39
  import NileElement from '../internal/nile-element';
35
40
  import { basicSetup } from './extensionSetup';
36
41
  import { classMap } from 'lit/directives/class-map.js';
37
- import { Theme } from './theme';
42
+ import { Theme, CustomTheme } from './theme';
38
43
 
39
44
  // Choose the appropriate mode for your use case
40
45
 
@@ -73,6 +78,10 @@ export class NileCodeEditor extends NileElement {
73
78
 
74
79
  @property({ type: Boolean, reflect: true , attribute: true }) lineNumbers: boolean = false;
75
80
 
81
+ @property({ type: Boolean, reflect: true , attribute: false }) disableSyntaxHighlighting: boolean = false;
82
+
83
+ @property({ type: Boolean, reflect: true , attribute: false }) useCustomTextFormatting: boolean = false;
84
+
76
85
  @property({ type: Boolean, reflect: true , attribute: true }) lineNumbersMultiline: boolean = true;
77
86
 
78
87
  @property({ type: Boolean, reflect: true , attribute: true }) hasScroller: boolean = true;
@@ -95,6 +104,7 @@ export class NileCodeEditor extends NileElement {
95
104
  private readOnlyComp = new Compartment();
96
105
  private customCompletionComp = new Compartment();
97
106
  private placeholderComp = new Compartment();
107
+ private defaultSyntaxHighlightingComp = new Compartment();
98
108
 
99
109
  /**
100
110
  * The styles for CodeEditor
@@ -169,6 +179,13 @@ export class NileCodeEditor extends NileElement {
169
179
  ]
170
180
  })
171
181
  }
182
+ if(changedProperties.has('disableSyntaxHighlighting')){
183
+ this.view.dispatch({
184
+ effects: [
185
+ this.defaultSyntaxHighlightingComp.reconfigure(this.getDefaultSyntaxHighlightingExtension())
186
+ ]
187
+ })
188
+ }
172
189
  }
173
190
 
174
191
  public render(): TemplateResult {
@@ -222,6 +239,7 @@ export class NileCodeEditor extends NileElement {
222
239
  const readOnlyExtension = this.readOnlyComp.of(this.getReadOnlyExtension());
223
240
  const restrictSingleLineExtension = this.restrictSingleLineComp.of(this.getSingleLineExtension())
224
241
  const placeholderExtension = this.placeholderComp.of(this.getPlaceholderExtension())
242
+ const defaultSyntaxHighlightingExtension = this.defaultSyntaxHighlightingComp.of(this.getDefaultSyntaxHighlightingExtension());
225
243
  const language = this.getLanguageExtension()
226
244
  const customAutoCompletions = this.customCompletionComp.of(javascriptLanguage.data.of({
227
245
  autocomplete: this.customAutocomplete
@@ -239,9 +257,10 @@ export class NileCodeEditor extends NileElement {
239
257
  restrictSingleLineExtension,
240
258
  customAutoCompletions,
241
259
  placeholderExtension,
260
+ defaultSyntaxHighlightingExtension,
242
261
  autocompletion(),
243
262
  language,
244
- EditorView.theme(Theme),
263
+ EditorView.theme(this.useCustomTextFormatting?CustomTheme:Theme),
245
264
  EditorView.updateListener.of((v: ViewUpdate) => {
246
265
  if (v.docChanged) {
247
266
  this.debounce ? this.emitAfterTimeout({ value: this.view.state.doc.toString() }) : this.emit('nile-change', { value: this.view.state.doc.toString() })
@@ -362,6 +381,15 @@ export class NileCodeEditor extends NileElement {
362
381
  if(this.timeOut) clearTimeout(this.timeOut);
363
382
  this.timeOut=setTimeout(()=> this.emit('nile-change', value, false), this.debounceTimeout)
364
383
  }
384
+
385
+ public focusAtPosition(pos: number=this.view.state.doc.toString().length): void {
386
+ if (this.view) {
387
+ this.view.dispatch({
388
+ selection: { anchor: pos },
389
+ });
390
+ this.view.focus();
391
+ }
392
+ }
365
393
 
366
394
  public insertBetweenCode=(text: string) => {
367
395
  const transaction = this.view.state.changeByRange(range => {
@@ -414,6 +442,10 @@ export class NileCodeEditor extends NileElement {
414
442
  getPlaceholderExtension(){
415
443
  return this.placeholder ? placeholder(this.placeholder) : [];
416
444
  }
445
+
446
+ getDefaultSyntaxHighlightingExtension(){
447
+ return !this.disableSyntaxHighlighting ? syntaxHighlighting(defaultHighlightStyle, { fallback: true }):[]
448
+ }
417
449
 
418
450
  restrictSingleLine() {
419
451
  return EditorState.transactionFilter.of(tr =>
@@ -8,4 +8,32 @@ export const Theme = {
8
8
  ".cm-scroller": {
9
9
  scrollbarWidth:'thin',
10
10
  },
11
+ };
12
+
13
+ export const CustomTheme = {
14
+ '&': {
15
+ fontSize: 'inherit',
16
+ fontStyle: 'inherit',
17
+ fontFamily: 'inherit',
18
+ fontWeight: 'inherit',
19
+ lineHeight:'inherit',
20
+ letterSpacing:'inherit'
21
+ },
22
+
23
+ '.cm-content': {
24
+ fontSize: 'inherit',
25
+ fontStyle: 'inherit',
26
+ fontFamily: 'inherit',
27
+ fontWeight: 'inherit',
28
+ lineHeight:'inherit',
29
+ letterSpacing:'inherit'
30
+ },
31
+
32
+ ".cm-scroller":{
33
+ fontFamily: 'inherit'
34
+ },
35
+
36
+ ".cm-gutters": {
37
+ fontFamily: 'inherit', // Ensure the gutter font matches
38
+ },
11
39
  };
@@ -12,23 +12,28 @@ import { css } from 'lit';
12
12
  */
13
13
  export const styles = css`
14
14
  :host {
15
- }
16
-
17
- .nile-form-help-text {
18
- display: flex;
19
- align-items: center;
15
+ width:100%;
20
16
  color: var(--nile-form-help-text-color);
21
17
  font-family: var(--nile-font-family-serif);
22
18
  font-size: var(--nile-form-help-text-font-size);
23
19
  font-style: normal;
24
- font-weight: 400;
25
20
  line-height: var(--nile-form-help-text-line-height);
21
+ }
22
+
23
+ .nile-form-help-text {
24
+ display:flex;
25
+ font-weight: 400;
26
26
  letter-spacing: 0.2px;
27
27
  margin-top: 6px;
28
28
  margin-right: 4px;
29
29
  width: auto;
30
30
  }
31
31
 
32
+
33
+ .nile-form-help-text--expanded{
34
+ display:block;
35
+ }
36
+
32
37
  .nile-form-help-text__more-button {
33
38
  display: inline-flex;
34
39
  gap: 4px;
@@ -37,6 +42,17 @@ export const styles = css`
37
42
  white-space: nowrap;
38
43
  align-items: center;
39
44
  }
45
+
46
+ .help__text__full{
47
+ overflow: hidden;
48
+ text-overflow: ellipsis;
49
+ white-space: nowrap;
50
+ display:inline;
51
+ }
52
+
53
+ .help__text__full--expanded{
54
+ white-space: wrap;
55
+ }
40
56
  `;
41
57
 
42
58
  export default [styles];
@@ -1,86 +1,110 @@
1
- import { fixture, expect, html } from '@open-wc/testing';
1
+ import { fixture, expect, html, elementUpdated } from '@open-wc/testing';
2
2
  import './nile-form-help-text';
3
3
  import { NileFormHelpText } from './nile-form-help-text';
4
4
 
5
5
  const wait = (ms: number = 50000) => new Promise(resolve => setTimeout(resolve, ms))
6
6
 
7
+
7
8
  describe('NileFormHelpText', () => {
8
9
  it('should render with default properties', async () => {
9
- const el: NileFormHelpText = await fixture(html`<nile-form-help-text>This is a very short text</nile-form-help-text>`);
10
-
11
- // Check if the displayed text is empty initially (no content in slot)
12
- const textContent = el.shadowRoot!.querySelector('div>span:first-child')?.textContent?.trim()
13
- expect(textContent).to.equal('This is a very short text');
10
+ const el = await fixture<NileFormHelpText>(html`<nile-form-help-text>This is a short text</nile-form-help-text>`);
11
+ expect(el).to.be.instanceOf(NileFormHelpText);
12
+ expect(el.isExpanded).to.be.false;
13
+
14
+ // Check if text content matches
15
+ const textContent = el?.textContent?.trim();
16
+ expect(textContent).to.equal('This is a short text');
14
17
  });
15
18
 
16
- it('should truncate the text if it exceeds textLimit and show "View More" button', async () => {
17
- const longText = "This is a very long help text that should be truncated and should show a 'View More' button.";
18
- const el: NileFormHelpText = await fixture(html`<nile-form-help-text><span>${longText}</span></nile-form-help-text>`);
19
-
20
- // Check if the displayed text is truncated
21
- const textContent = el.shadowRoot!.querySelector('div>span:first-child')?.textContent?.trim()
22
- expect(textContent?.endsWith('...')).to.be.true;
19
+ it('should not show "View More" button if the text fits within the container', async () => {
20
+ const el = await fixture<NileFormHelpText>(html`<nile-form-help-text>This is a short text</nile-form-help-text>`);
21
+ await elementUpdated(el);
22
+
23
+ const moreButton = el.shadowRoot?.querySelector('.nile-form-help-text__more-button');
24
+ expect(moreButton).to.be.null;
25
+ expect(el.showButton).to.be.false;
26
+ });
27
+
28
+ it('should show "View More" button if the text overflows the container', async () => {
29
+ const longText = 'This is a very long help text that exceeds the container width and should show a "View More" button.';
30
+ const el = await fixture<NileFormHelpText>(html`<nile-form-help-text>${longText}</nile-form-help-text>`);
23
31
 
24
- // Check if the "View More" button is visible
25
- const moreButton = el.shadowRoot!.querySelector('.nile-form-help-text__more-button');
32
+ // Simulate overflow
33
+ const textContainer = el.shadowRoot?.querySelector('.help__text__full') as HTMLSpanElement;
34
+ Object.defineProperty(textContainer, 'scrollWidth', { value: 300 });
35
+ Object.defineProperty(textContainer, 'clientWidth', { value: 200 });
36
+ el.decideToToggleShowButton();
37
+ await elementUpdated(el);
38
+
39
+ const moreButton = el.shadowRoot?.querySelector('.nile-form-help-text__more-button');
26
40
  expect(moreButton).to.exist;
27
- expect(moreButton?.textContent).to.include('View More');
41
+ expect(el.showButton).to.be.true;
28
42
  });
29
43
 
30
44
  it('should expand to show full text when "View More" is clicked', async () => {
31
- const longText = "This is a very long help text that should be truncated and should show a 'View More' button.";
32
- const el: NileFormHelpText = await fixture(html`<nile-form-help-text><span>${longText}</span></nile-form-help-text>`);
33
-
34
- // Simulate clicking the "View More" button
35
- const moreButton = el.shadowRoot!.querySelector<HTMLElement>('.nile-form-help-text__more-button');
45
+ const longText = 'This is a very long help text that exceeds the container width and should show a "View More" button.';
46
+ const el = await fixture<NileFormHelpText>(html`<nile-form-help-text>${longText}</nile-form-help-text>`);
47
+
48
+ // Simulate overflow
49
+ const textContainer = el.shadowRoot?.querySelector('.help__text__full') as HTMLSpanElement;
50
+ Object.defineProperty(textContainer, 'scrollWidth', { value: 300 });
51
+ Object.defineProperty(textContainer, 'clientWidth', { value: 200 });
52
+ el.decideToToggleShowButton();
53
+ await elementUpdated(el);
54
+
55
+ // Click "View More"
56
+ const moreButton = el.shadowRoot?.querySelector<HTMLElement>('.nile-form-help-text__more-button');
36
57
  moreButton?.click();
37
- await el.updateComplete;
58
+ await elementUpdated(el);
38
59
 
39
- // Verify that the full text is displayed
40
- const textContent = el.shadowRoot!.querySelector('div>span:first-child')?.textContent?.trim()
41
- expect(textContent).to.equal(longText);
42
-
43
- // Check if the "View Less" button is now visible
44
- const lessButton = el.shadowRoot!.querySelector('.nile-form-help-text__more-button');
45
- expect(lessButton).to.exist;
46
- expect(lessButton?.textContent).to.include('View Less');
60
+ expect(el.isExpanded).to.be.true;
61
+ expect(textContainer).to.have.class('help__text__full--expanded');
62
+ expect(moreButton?.textContent).to.include('View Less');
47
63
  });
48
64
 
49
65
  it('should collapse back to truncated text when "View Less" is clicked', async () => {
50
- const longText = "This is a very long help text that should be truncated and should show a 'View More' button.";
51
- const el: NileFormHelpText = await fixture(html`<nile-form-help-text><span>${longText}</span></nile-form-help-text>`);
52
-
53
- // Expand the text
54
- const moreButton = el.shadowRoot!.querySelector<HTMLElement>('.nile-form-help-text__more-button');
66
+ const longText = 'This is a very long help text that exceeds the container width and should show a "View More" button.';
67
+ const el = await fixture<NileFormHelpText>(html`<nile-form-help-text>${longText}</nile-form-help-text>`);
68
+
69
+ // Simulate overflow
70
+ const textContainer = el.shadowRoot?.querySelector('.help__text__full') as HTMLSpanElement;
71
+ Object.defineProperty(textContainer, 'scrollWidth', { value: 300 });
72
+ Object.defineProperty(textContainer, 'clientWidth', { value: 200 });
73
+ el.decideToToggleShowButton();
74
+ await elementUpdated(el);
75
+
76
+ // Expand and then collapse
77
+ const moreButton = el.shadowRoot?.querySelector<HTMLElement>('.nile-form-help-text__more-button');
55
78
  moreButton?.click();
56
- await el.updateComplete;
79
+ await elementUpdated(el);
57
80
 
58
- // Collapse the text by clicking "View Less"
59
- const lessButton = el.shadowRoot!.querySelector<HTMLElement>('.nile-form-help-text__more-button');
60
- lessButton?.click();
61
- await el.updateComplete;
81
+ moreButton?.click(); // Collapse
82
+ await elementUpdated(el);
62
83
 
63
- // Verify that the text is truncated again
64
- const textContent = el.shadowRoot!.querySelector('div>span:first-child')?.textContent?.trim()
65
- expect(textContent?.endsWith('...')).to.be.true;
66
-
67
- // Check if the "View More" button is visible again
68
- const viewMoreButton = el.shadowRoot!.querySelector('.nile-form-help-text__more-button');
69
- expect(viewMoreButton).to.exist;
70
- expect(viewMoreButton?.textContent).to.include('View More');
84
+ expect(el.isExpanded).to.be.false;
85
+ expect(textContainer).not.to.have.class('help__text__full--expanded');
86
+ expect(moreButton?.textContent).to.include('View More');
71
87
  });
72
88
 
73
- it('should not show "View More" button when text is within limit', async () => {
74
- const shortText = "Short help text.";
75
- const el: NileFormHelpText = await fixture(html`<nile-form-help-text><span>${shortText}</span></nile-form-help-text>`);
76
-
77
- // Check if the displayed text is not truncated
78
- const textContent = el.shadowRoot!.querySelector('div>span:first-child')?.textContent?.trim()
79
- expect(textContent).to.equal(shortText);
89
+ // it('should dynamically adjust "View More" visibility on text change', async () => {
90
+ // const el = await fixture<NileFormHelpText>(html`<nile-form-help-text>Initial text</nile-form-help-text>`);
91
+ // await elementUpdated(el);
80
92
 
81
- // Verify that "View More" button is not rendered
82
- const moreButton = el.shadowRoot!.querySelector('.nile-form-help-text__more-button');
83
- expect(moreButton).to.be.null;
84
- });
93
+ // const textContainer = el.shadowRoot?.querySelector('.help__text__full') as HTMLSpanElement;
94
+ // Object.defineProperty(textContainer, 'scrollWidth', { value: 300 });
95
+ // Object.defineProperty(textContainer, 'clientWidth', { value: 200 });
96
+ // el.decideToToggleShowButton();
97
+ // await elementUpdated(el);
98
+
99
+ // expect(el.showButton).to.be.true;
100
+
101
+ // // Change slot content to short text
102
+ // textContainer.textContent = 'Short text';
103
+ // Object.defineProperty(textContainer, 'scrollWidth', { value: 100 });
104
+ // Object.defineProperty(textContainer, 'clientWidth', { value: 200 });
105
+ // el.decideToToggleShowButton();
106
+ // await elementUpdated(el);
85
107
 
108
+ // expect(el.showButton).to.be.false;
109
+ // });
86
110
  });
@@ -5,9 +5,10 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import {LitElement, html, CSSResultArray, TemplateResult} from 'lit';
9
- import { customElement, query, property } from 'lit/decorators.js';
8
+ import {LitElement, html, CSSResultArray, TemplateResult, nothing, PropertyValues} from 'lit';
9
+ import { customElement, query, property, state } from 'lit/decorators.js';
10
10
  import {styles} from './nile-form-help-text.css';
11
+ import { classMap } from 'lit/directives/class-map.js';
11
12
 
12
13
  /**
13
14
  * Nile icon component.
@@ -27,78 +28,86 @@ export class NileFormHelpText extends LitElement {
27
28
 
28
29
  @property({ type: Boolean, reflect: true }) isExpanded: boolean = false;
29
30
 
30
- @property({ type: String, reflect: true }) fullText: string = '';
31
+ @state() showButton: boolean = false;
31
32
 
32
- @property({ type: Number, reflect: true }) textLimit: number = 47;
33
+ @query('.help__text__full') textContainer:HTMLSpanElement;
33
34
 
34
- @property({ type: String, reflect: true }) displayedText: string = '';
35
+ private resizeObserver:ResizeObserver;
35
36
 
36
- @query('slot') slotElement!: HTMLSlotElement;
37
-
38
- connectedCallback() {
39
- super.connectedCallback();
40
- requestAnimationFrame(() => {
41
- this.slotElement?.addEventListener('slotchange', this.handleSlotChange.bind(this));
42
- });
43
- }
37
+ /* #endregion */
44
38
 
45
- firstUpdated() {
46
- this.handleSlotChange();
47
- }
39
+ /* #region Methods */
48
40
 
49
- handleSlotChange() {
50
- const nodes = this.slotElement.assignedNodes({flatten: true});
51
- const textContent = nodes.map(node => node.textContent).join('');
52
- this.fullText = textContent.trim();
53
- this.updateDisplayedText()
41
+ protected firstUpdated(_changedProperties: PropertyValues): void {
42
+ this.resizeObserver=this.observeWidthChange(this.textContainer);
54
43
  }
55
44
 
56
- toggleExpanded() {
57
- this.isExpanded = !this.isExpanded;
58
- this.updateDisplayedText()
45
+ disconnectedCallback(): void {
46
+ this.resizeObserver.disconnect();
59
47
  }
60
48
 
61
- updateDisplayedText() {
62
- if (this.isExpanded) {
63
- this.displayedText = this.fullText;
64
- } else {
65
- const validConcatNumber=concatSentence(this.fullText, this.textLimit)
66
- const truncatedText = this.fullText.slice(0, validConcatNumber);
67
- const ellipsis = this.fullText.length > validConcatNumber ? '...' : '';
68
- this.displayedText = `${truncatedText}${ellipsis}`;
69
- }
70
- }
71
-
72
- /* #endregion */
73
-
74
- /* #region Methods */
75
-
76
49
  /**
77
50
  * Render method
78
51
  * @slot This is a slot test
79
52
  */
80
53
  public render(): TemplateResult {
81
- const showMoreButton = this.fullText.length > this.textLimit;
82
54
  const iconName = this.isExpanded ? 'arrowup' : 'arrowdown';
83
55
 
84
56
  return html`
85
- <div class="nile-form-help-text" part="container">
86
- <slot hidden>${this.fullText}</slot>
87
- <div part="text">
88
- <span>${this.displayedText}</span>
89
- ${showMoreButton ? html`
90
- <span
91
- class="nile-form-help-text__more-button"
92
- part="toggle-button"
93
- @click=${this.toggleExpanded}
94
- >${this.isExpanded ? 'View Less' : 'View More'}
95
- <nile-icon color="#005EA6" part="icon" size="14" name="${iconName}"></nile-icon>
96
- </span>
97
- ` : ''}
98
- </div>
57
+ <div
58
+ class="${classMap({
59
+ 'nile-form-help-text':true,
60
+ "nile-form-help-text--expanded":this.isExpanded
61
+ })}"
62
+ part="container"
63
+ >
64
+ <span
65
+ class="${classMap({
66
+ "help__text__full":true,
67
+ "help__text__full--expanded":this.isExpanded
68
+ })}"
69
+ >
70
+ <slot @slotchange="${this.decideToToggleShowButton}"></slot>
71
+ </span>
72
+ ${this.showButton?html`
73
+ <span
74
+ class="nile-form-help-text__more-button"
75
+ part="toggle-button"
76
+ @click=${this.toggleExpanded}
77
+ >${this.isExpanded ? 'View Less' : 'View More'}
78
+ <nile-icon color="#005EA6" part="icon" size="14" name="${iconName}"></nile-icon>
79
+ </span>
80
+ `:nothing}
99
81
  </div>
100
82
  `;
101
83
  }
84
+
85
+ toggleExpanded() {
86
+ this.isExpanded = !this.isExpanded;
87
+ }
88
+
89
+ decideToToggleShowButton(){
90
+ if(!this.textContainer) return;
91
+ this.showButton=this.textContainer.clientWidth<this.textContainer.scrollWidth
92
+ }
93
+
94
+ /**
95
+ * Logs whenever the width of an element changes.
96
+ * @param {HTMLElement} element - The element to observe for width changes.
97
+ */
98
+ observeWidthChange(element:HTMLElement) {
99
+
100
+ const resizeObserver = new ResizeObserver(entries => {
101
+ for (let entry of entries) {
102
+ const newWidth = entry.contentRect.width;
103
+ if (newWidth) this.decideToToggleShowButton();
104
+ }
105
+ });
106
+
107
+ resizeObserver.observe(element);
108
+
109
+ return resizeObserver; // Return observer to allow disconnection if needed
110
+ }
102
111
  }
103
112
 
104
113
  export default NileFormHelpText;
@@ -107,31 +116,4 @@ declare global {
107
116
  interface HTMLElementTagNameMap {
108
117
  'nile-form-help-text': NileFormHelpText;
109
118
  }
110
- }
111
-
112
- function concatSentence(sentence:string, n:number) {
113
- if (n < 0 || n > sentence.length) {
114
- return n;
115
- }
116
-
117
- // Adjust n if it falls in the middle of a word
118
- if (sentence[n] !== " " && n !== 0 && n !== sentence.length) {
119
- // Move left until the start of the word or the beginning of the sentence
120
- let left = n;
121
- while (left > 0 && sentence[left - 1] !== " ") {
122
- left--;
123
- }
124
-
125
- // Move right until the end of the word or the end of the sentence
126
- let right = n;
127
- while (right < sentence.length && sentence[right] !== " ") {
128
- right++;
129
- }
130
-
131
- // Adjust n to the closer boundary
132
- n = (n - left <= right - n) ? left : right;
133
- }
134
-
135
- // Return the substring from the start to the adjusted n
136
- return n;
137
- }
119
+ }
@@ -784,7 +784,7 @@
784
784
  },
785
785
  {
786
786
  "name": "nile-code-editor",
787
- "description": "Nile icon component.\n\nEvents:\n\n * `nile-focus` {`Event`} - \n\n * `nile-blur` {`Event`} - \n\nAttributes:\n\n * `value` {`string`} - \n\n * `expandIcon` {`string`} - \n\n * `placeholder` {`string`} - \n\n * `customAutoCompletions` - \n\n * `customCompletionsPaths` {`string[]`} - \n\n * `language` {`\"html\" | \"javascript\" | \"sql\" | \"json\"`} - \n\n * `error-message` {`string`} - \n\n * `error` {`boolean`} - \n\n * `noborder` {`boolean`} - \n\n * `multiline` {`boolean`} - \n\n * `allowVariableInCustomSuggestion` {`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 * `debounceTimeout` {`number`} - \n\nProperties:\n\n * `codeEditor` {`HTMLInputElement`} - \n\n * `value` {`string`} - \n\n * `expandIcon` {`string`} - \n\n * `placeholder` {`string`} - \n\n * `customAutoCompletions` - \n\n * `customCompletionsPaths` {`string[]`} - \n\n * `language` {`\"html\" | \"javascript\" | \"sql\" | \"json\"`} - \n\n * `errorMessage` {`string`} - \n\n * `error` {`boolean`} - \n\n * `noborder` {`boolean`} - \n\n * `multiline` {`boolean`} - \n\n * `allowVariableInCustomSuggestion` {`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 * `debounceTimeout` {`number`} - \n\n * `view` - \n\n * `viewState` - \n\n * `timeOut` - \n\n * `lineNumbersComp` - \n\n * `restrictSingleLineComp` - \n\n * `readOnlyComp` - \n\n * `customCompletionComp` - \n\n * `placeholderComp` - \n\n * `customAutocomplete` - Custom autocomplete handler for code editor suggestions\n\n * `insertBetweenCode` - \n\n * `BUBBLES` {`boolean`} - \n\n * `COMPOSED` {`boolean`} - \n\n * `CANCELABLE` {`boolean`} - ",
787
+ "description": "Nile icon component.\n\nEvents:\n\n * `nile-focus` {`Event`} - \n\n * `nile-blur` {`Event`} - \n\nAttributes:\n\n * `value` {`string`} - \n\n * `expandIcon` {`string`} - \n\n * `placeholder` {`string`} - \n\n * `customAutoCompletions` - \n\n * `customCompletionsPaths` {`string[]`} - \n\n * `language` {`\"html\" | \"javascript\" | \"sql\" | \"json\"`} - \n\n * `error-message` {`string`} - \n\n * `error` {`boolean`} - \n\n * `noborder` {`boolean`} - \n\n * `multiline` {`boolean`} - \n\n * `allowVariableInCustomSuggestion` {`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 * `debounceTimeout` {`number`} - \n\nProperties:\n\n * `codeEditor` {`HTMLInputElement`} - \n\n * `value` {`string`} - \n\n * `expandIcon` {`string`} - \n\n * `placeholder` {`string`} - \n\n * `customAutoCompletions` - \n\n * `customCompletionsPaths` {`string[]`} - \n\n * `language` {`\"html\" | \"javascript\" | \"sql\" | \"json\"`} - \n\n * `errorMessage` {`string`} - \n\n * `error` {`boolean`} - \n\n * `noborder` {`boolean`} - \n\n * `multiline` {`boolean`} - \n\n * `allowVariableInCustomSuggestion` {`boolean`} - \n\n * `lineNumbers` {`boolean`} - \n\n * `disableSyntaxHighlighting` {`boolean`} - \n\n * `useCustomTextFormatting` {`boolean`} - \n\n * `lineNumbersMultiline` {`boolean`} - \n\n * `hasScroller` {`boolean`} - \n\n * `expandable` {`boolean`} - \n\n * `readonly` {`boolean`} - \n\n * `debounce` {`boolean`} - \n\n * `debounceTimeout` {`number`} - \n\n * `view` - \n\n * `viewState` - \n\n * `timeOut` - \n\n * `lineNumbersComp` - \n\n * `restrictSingleLineComp` - \n\n * `readOnlyComp` - \n\n * `customCompletionComp` - \n\n * `placeholderComp` - \n\n * `defaultSyntaxHighlightingComp` - \n\n * `customAutocomplete` - Custom autocomplete handler for code editor suggestions\n\n * `insertBetweenCode` - \n\n * `BUBBLES` {`boolean`} - \n\n * `COMPOSED` {`boolean`} - \n\n * `CANCELABLE` {`boolean`} - ",
788
788
  "attributes": [
789
789
  {
790
790
  "name": "value",
@@ -1370,24 +1370,12 @@
1370
1370
  },
1371
1371
  {
1372
1372
  "name": "nile-form-help-text",
1373
- "description": "Nile icon component.\n\nAttributes:\n\n * `isExpanded` {`boolean`} - \n\n * `fullText` {`string`} - \n\n * `textLimit` {`number`} - \n\n * `displayedText` {`string`} - \n\nProperties:\n\n * `isExpanded` {`boolean`} - \n\n * `fullText` {`string`} - \n\n * `textLimit` {`number`} - \n\n * `displayedText` {`string`} - \n\n * `slotElement` {`HTMLSlotElement`} - ",
1373
+ "description": "Nile icon component.\n\nAttributes:\n\n * `isExpanded` {`boolean`} - \n\nProperties:\n\n * `isExpanded` {`boolean`} - \n\n * `showButton` {`boolean`} - \n\n * `textContainer` {`HTMLSpanElement`} - \n\n * `resizeObserver` - ",
1374
1374
  "attributes": [
1375
1375
  {
1376
1376
  "name": "isExpanded",
1377
1377
  "description": "`isExpanded` {`boolean`} - \n\nProperty: isExpanded\n\nDefault: false",
1378
1378
  "valueSet": "v"
1379
- },
1380
- {
1381
- "name": "fullText",
1382
- "description": "`fullText` {`string`} - \n\nProperty: fullText\n\nDefault: "
1383
- },
1384
- {
1385
- "name": "textLimit",
1386
- "description": "`textLimit` {`number`} - \n\nProperty: textLimit\n\nDefault: 47"
1387
- },
1388
- {
1389
- "name": "displayedText",
1390
- "description": "`displayedText` {`string`} - \n\nProperty: displayedText\n\nDefault: "
1391
1379
  }
1392
1380
  ]
1393
1381
  },