@ni/spright-components 5.4.2 → 5.5.0

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.
@@ -5,5 +5,6 @@
5
5
  */
6
6
  import '@ni/nimble-components/dist/esm/all-components';
7
7
  import './chat/conversation';
8
+ import './chat/input';
8
9
  import './chat/message';
9
10
  import './rectangle';
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import '@ni/nimble-components/dist/esm/all-components';
7
7
  import './chat/conversation';
8
+ import './chat/input';
8
9
  import './chat/message';
9
10
  import './rectangle';
10
11
  //# sourceMappingURL=all-components.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"all-components.js","sourceRoot":"","sources":["../../src/all-components.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,+CAA+C,CAAC;AAEvD,OAAO,qBAAqB,CAAC;AAC7B,OAAO,gBAAgB,CAAC;AACxB,OAAO,aAAa,CAAC","sourcesContent":["/**\n * Import of all the web components available in Spright AND Nimble.\n * Production applications are encouraged to import only components\n * that are required instead of leveraging this file.\n */\n\nimport '@ni/nimble-components/dist/esm/all-components';\n\nimport './chat/conversation';\nimport './chat/message';\nimport './rectangle';\n"]}
1
+ {"version":3,"file":"all-components.js","sourceRoot":"","sources":["../../src/all-components.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,+CAA+C,CAAC;AAEvD,OAAO,qBAAqB,CAAC;AAC7B,OAAO,cAAc,CAAC;AACtB,OAAO,gBAAgB,CAAC;AACxB,OAAO,aAAa,CAAC","sourcesContent":["/**\n * Import of all the web components available in Spright AND Nimble.\n * Production applications are encouraged to import only components\n * that are required instead of leveraging this file.\n */\n\nimport '@ni/nimble-components/dist/esm/all-components';\n\nimport './chat/conversation';\nimport './chat/input';\nimport './chat/message';\nimport './rectangle';\n"]}
@@ -6,6 +6,12 @@ export const styles = css `
6
6
 
7
7
  :host {
8
8
  flex-direction: column;
9
+ }
10
+
11
+ .messages {
12
+ flex: 1;
13
+ display: flex;
14
+ flex-direction: column;
9
15
  justify-content: flex-start;
10
16
  row-gap: 32px;
11
17
  padding: ${mediumPadding};
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../src/chat/conversation/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EACH,0BAA0B,EAC1B,aAAa,EAChB,MAAM,6DAA6D,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAExD,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;MACnB,OAAO,CAAC,MAAM,CAAC;;;;;;mBAMF,aAAa;sBACV,0BAA0B;;;CAG/C,CAAC","sourcesContent":["import { css } from '@ni/fast-element';\nimport {\n applicationBackgroundColor,\n mediumPadding\n} from '@ni/nimble-components/dist/esm/theme-provider/design-tokens';\nimport { display } from '../../utilities/style/display';\n\nexport const styles = css`\n ${display('flex')}\n\n :host {\n flex-direction: column;\n justify-content: flex-start;\n row-gap: 32px;\n padding: ${mediumPadding};\n background: ${applicationBackgroundColor};\n overflow-y: auto;\n }\n`;\n"]}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../src/chat/conversation/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EACH,0BAA0B,EAC1B,aAAa,EAChB,MAAM,6DAA6D,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAExD,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;MACnB,OAAO,CAAC,MAAM,CAAC;;;;;;;;;;;;mBAYF,aAAa;sBACV,0BAA0B;;;CAG/C,CAAC","sourcesContent":["import { css } from '@ni/fast-element';\nimport {\n applicationBackgroundColor,\n mediumPadding\n} from '@ni/nimble-components/dist/esm/theme-provider/design-tokens';\nimport { display } from '../../utilities/style/display';\n\nexport const styles = css`\n ${display('flex')}\n\n :host {\n flex-direction: column;\n }\n\n .messages {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n row-gap: 32px;\n padding: ${mediumPadding};\n background: ${applicationBackgroundColor};\n overflow-y: auto;\n }\n`;\n"]}
@@ -1,6 +1,8 @@
1
1
  import { html } from '@ni/fast-element';
2
2
  /* eslint-disable @typescript-eslint/indent */
3
3
  // prettier-ignore
4
- export const template = html `<slot></slot>`;
4
+ export const template = html `
5
+ <div class="messages"><slot></slot></div>
6
+ <div class="input"><slot name="input"></slot></div>`;
5
7
  /* eslint-enable @typescript-eslint/indent */
6
8
  //# sourceMappingURL=template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../../src/chat/conversation/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGxC,8CAA8C;AAC9C,kBAAkB;AAClB,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAkB,eAAe,CAAC;AAC9D,6CAA6C","sourcesContent":["import { html } from '@ni/fast-element';\nimport type { ChatConversation } from '.';\n\n/* eslint-disable @typescript-eslint/indent */\n// prettier-ignore\nexport const template = html<ChatConversation>`<slot></slot>`;\n/* eslint-enable @typescript-eslint/indent */\n"]}
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../../src/chat/conversation/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGxC,8CAA8C;AAC9C,kBAAkB;AAClB,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAkB;;oDAEM,CAAC;AACrD,6CAA6C","sourcesContent":["import { html } from '@ni/fast-element';\nimport type { ChatConversation } from '.';\n\n/* eslint-disable @typescript-eslint/indent */\n// prettier-ignore\nexport const template = html<ChatConversation>`\n<div class=\"messages\"><slot></slot></div>\n<div class=\"input\"><slot name=\"input\"></slot></div>`;\n/* eslint-enable @typescript-eslint/indent */\n"]}
@@ -0,0 +1,48 @@
1
+ import { FoundationElement } from '@ni/fast-foundation';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ 'spright-chat-input': ChatInput;
5
+ }
6
+ }
7
+ /**
8
+ * A Spright component for composing and sending a chat message
9
+ */
10
+ export declare class ChatInput extends FoundationElement {
11
+ placeholder?: string;
12
+ sendButtonLabel?: string;
13
+ value: string;
14
+ /**
15
+ * @internal
16
+ */
17
+ textArea?: HTMLTextAreaElement;
18
+ /**
19
+ * @internal
20
+ */
21
+ disableSendButton: boolean;
22
+ /**
23
+ * Clears the text input and gives it focus.
24
+ */
25
+ resetInput(): void;
26
+ /**
27
+ * @internal
28
+ */
29
+ textAreaKeydownHandler(e: KeyboardEvent): boolean;
30
+ /**
31
+ * @internal
32
+ */
33
+ textAreaInputHandler(): void;
34
+ /**
35
+ * @internal
36
+ */
37
+ valueChanged(): void;
38
+ /**
39
+ * @internal
40
+ */
41
+ connectedCallback(): void;
42
+ /**
43
+ * @internal
44
+ */
45
+ sendButtonClickHandler(): void;
46
+ private shouldDisableSendButton;
47
+ }
48
+ export declare const chatInputTag = "spright-chat-input";
@@ -0,0 +1,102 @@
1
+ import { __decorate } from "tslib";
2
+ import { DesignSystem, FoundationElement } from '@ni/fast-foundation';
3
+ import { keyEnter } from '@ni/fast-web-utilities';
4
+ import { attr, observable } from '@ni/fast-element';
5
+ import { styles } from './styles';
6
+ import { template } from './template';
7
+ /**
8
+ * A Spright component for composing and sending a chat message
9
+ */
10
+ export class ChatInput extends FoundationElement {
11
+ constructor() {
12
+ super(...arguments);
13
+ this.value = '';
14
+ /**
15
+ * @internal
16
+ */
17
+ this.disableSendButton = true;
18
+ }
19
+ /**
20
+ * Clears the text input and gives it focus.
21
+ */
22
+ resetInput() {
23
+ this.value = '';
24
+ this.disableSendButton = true;
25
+ if (this.textArea) {
26
+ this.textArea.value = '';
27
+ this.textArea.focus();
28
+ }
29
+ }
30
+ /**
31
+ * @internal
32
+ */
33
+ textAreaKeydownHandler(e) {
34
+ if (e.key === keyEnter && !e.shiftKey) {
35
+ this.sendButtonClickHandler();
36
+ return false;
37
+ }
38
+ return true;
39
+ }
40
+ /**
41
+ * @internal
42
+ */
43
+ textAreaInputHandler() {
44
+ this.value = this.textArea.value;
45
+ this.disableSendButton = this.shouldDisableSendButton();
46
+ }
47
+ /**
48
+ * @internal
49
+ */
50
+ valueChanged() {
51
+ if (this.textArea) {
52
+ this.textArea.value = this.value;
53
+ this.disableSendButton = this.shouldDisableSendButton();
54
+ }
55
+ }
56
+ /**
57
+ * @internal
58
+ */
59
+ connectedCallback() {
60
+ super.connectedCallback();
61
+ this.textArea.value = this.value;
62
+ this.disableSendButton = this.shouldDisableSendButton();
63
+ }
64
+ /**
65
+ * @internal
66
+ */
67
+ sendButtonClickHandler() {
68
+ if (this.shouldDisableSendButton()) {
69
+ return;
70
+ }
71
+ const eventDetail = {
72
+ text: this.textArea.value
73
+ };
74
+ this.$emit('send', eventDetail);
75
+ }
76
+ shouldDisableSendButton() {
77
+ return this.textArea.value.length === 0;
78
+ }
79
+ }
80
+ __decorate([
81
+ attr
82
+ ], ChatInput.prototype, "placeholder", void 0);
83
+ __decorate([
84
+ attr({ attribute: 'send-button-label' })
85
+ ], ChatInput.prototype, "sendButtonLabel", void 0);
86
+ __decorate([
87
+ attr
88
+ ], ChatInput.prototype, "value", void 0);
89
+ __decorate([
90
+ observable
91
+ ], ChatInput.prototype, "textArea", void 0);
92
+ __decorate([
93
+ observable
94
+ ], ChatInput.prototype, "disableSendButton", void 0);
95
+ const sprightChatInput = ChatInput.compose({
96
+ baseName: 'chat-input',
97
+ template,
98
+ styles
99
+ });
100
+ DesignSystem.getOrCreate().withPrefix('spright').register(sprightChatInput());
101
+ export const chatInputTag = 'spright-chat-input';
102
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/chat/input/index.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAStC;;GAEG;AACH,MAAM,OAAO,SAAU,SAAQ,iBAAiB;IAAhD;;QAQW,UAAK,GAAG,EAAE,CAAC;QAQlB;;WAEG;QAEI,sBAAiB,GAAG,IAAI,CAAC;IAoEpC,CAAC;IAlEG;;OAEG;IACI,UAAU;QACb,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,EAAE,CAAC;YACzB,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;IACL,CAAC;IAED;;OAEG;IACI,sBAAsB,CAAC,CAAgB;QAC1C,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,oBAAoB;QACvB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAS,CAAC,KAAK,CAAC;QAClC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;IAC5D,CAAC;IAED;;OAEG;IACI,YAAY;QACf,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACjC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC5D,CAAC;IACL,CAAC;IAED;;OAEG;IACa,iBAAiB;QAC7B,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,QAAS,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAClC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;IAC5D,CAAC;IAED;;OAEG;IACI,sBAAsB;QACzB,IAAI,IAAI,CAAC,uBAAuB,EAAE,EAAE,CAAC;YACjC,OAAO;QACX,CAAC;QACD,MAAM,WAAW,GAA6B;YAC1C,IAAI,EAAE,IAAI,CAAC,QAAS,CAAC,KAAK;SAC7B,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,CAAC;IAEO,uBAAuB;QAC3B,OAAO,IAAI,CAAC,QAAS,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;IAC7C,CAAC;CACJ;AAtFU;IADN,IAAI;8CACuB;AAGrB;IADN,IAAI,CAAC,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC;kDACT;AAGzB;IADN,IAAI;wCACa;AAMX;IADN,UAAU;2CAC2B;AAM/B;IADN,UAAU;oDACqB;AAsEpC,MAAM,gBAAgB,GAAG,SAAS,CAAC,OAAO,CAAC;IACvC,QAAQ,EAAE,YAAY;IACtB,QAAQ;IACR,MAAM;CACT,CAAC,CAAC;AAEH,YAAY,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAC","sourcesContent":["import { DesignSystem, FoundationElement } from '@ni/fast-foundation';\nimport { keyEnter } from '@ni/fast-web-utilities';\nimport { attr, observable } from '@ni/fast-element';\nimport { styles } from './styles';\nimport { template } from './template';\nimport type { ChatInputSendEventDetail } from './types';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'spright-chat-input': ChatInput;\n }\n}\n\n/**\n * A Spright component for composing and sending a chat message\n */\nexport class ChatInput extends FoundationElement {\n @attr\n public placeholder?: string;\n\n @attr({ attribute: 'send-button-label' })\n public sendButtonLabel?: string;\n\n @attr\n public value = '';\n\n /**\n * @internal\n */\n @observable\n public textArea?: HTMLTextAreaElement;\n\n /**\n * @internal\n */\n @observable\n public disableSendButton = true;\n\n /**\n * Clears the text input and gives it focus.\n */\n public resetInput(): void {\n this.value = '';\n this.disableSendButton = true;\n if (this.textArea) {\n this.textArea.value = '';\n this.textArea.focus();\n }\n }\n\n /**\n * @internal\n */\n public textAreaKeydownHandler(e: KeyboardEvent): boolean {\n if (e.key === keyEnter && !e.shiftKey) {\n this.sendButtonClickHandler();\n return false;\n }\n return true;\n }\n\n /**\n * @internal\n */\n public textAreaInputHandler(): void {\n this.value = this.textArea!.value;\n this.disableSendButton = this.shouldDisableSendButton();\n }\n\n /**\n * @internal\n */\n public valueChanged(): void {\n if (this.textArea) {\n this.textArea.value = this.value;\n this.disableSendButton = this.shouldDisableSendButton();\n }\n }\n\n /**\n * @internal\n */\n public override connectedCallback(): void {\n super.connectedCallback();\n this.textArea!.value = this.value;\n this.disableSendButton = this.shouldDisableSendButton();\n }\n\n /**\n * @internal\n */\n public sendButtonClickHandler(): void {\n if (this.shouldDisableSendButton()) {\n return;\n }\n const eventDetail: ChatInputSendEventDetail = {\n text: this.textArea!.value\n };\n this.$emit('send', eventDetail);\n }\n\n private shouldDisableSendButton(): boolean {\n return this.textArea!.value.length === 0;\n }\n}\n\nconst sprightChatInput = ChatInput.compose({\n baseName: 'chat-input',\n template,\n styles\n});\n\nDesignSystem.getOrCreate().withPrefix('spright').register(sprightChatInput());\nexport const chatInputTag = 'spright-chat-input';\n"]}
@@ -0,0 +1 @@
1
+ export declare const styles: import("@ni/fast-element").ElementStyles;
@@ -0,0 +1,54 @@
1
+ import { css } from '@ni/fast-element';
2
+ import { applicationBackgroundColor, bodyFont, bodyFontColor, borderWidth, controlLabelFontColor, elevation2BoxShadow, mediumPadding, popupBorderColor } from '@ni/nimble-components/dist/esm/theme-provider/design-tokens';
3
+ import { display } from '../../utilities/style/display';
4
+ export const styles = css `
5
+ ${display('flex')}
6
+
7
+ :host {
8
+ width: 100%;
9
+ height: auto;
10
+ }
11
+
12
+ .container {
13
+ display: grid;
14
+ grid-template-rows: auto 1fr;
15
+ grid-template-columns: 1fr auto;
16
+ width: 100%;
17
+ height: 100%;
18
+
19
+ background-color: ${applicationBackgroundColor};
20
+ border: ${borderWidth} solid ${popupBorderColor};
21
+ box-shadow: ${elevation2BoxShadow};
22
+ }
23
+
24
+ textarea {
25
+ grid-row: 1;
26
+ grid-column: 1 / 3;
27
+
28
+ font: ${bodyFont};
29
+ color: ${bodyFontColor};
30
+ background-color: transparent;
31
+
32
+ width: 100%;
33
+ resize: none;
34
+ height: auto;
35
+ max-height: calc(6lh + 2 * ${mediumPadding});
36
+ field-sizing: content;
37
+
38
+ border-width: 0px;
39
+ outline: none;
40
+ padding: ${mediumPadding};
41
+ }
42
+
43
+ textarea::placeholder {
44
+ color: ${controlLabelFontColor};
45
+ }
46
+
47
+ .send-button {
48
+ grid-row: 2;
49
+ grid-column: 2;
50
+ width: 80px;
51
+ margin: ${mediumPadding};
52
+ }
53
+ `;
54
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../src/chat/input/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EACH,0BAA0B,EAC1B,QAAQ,EACR,aAAa,EACb,WAAW,EACX,qBAAqB,EACrB,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EACnB,MAAM,6DAA6D,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAExD,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;MACnB,OAAO,CAAC,MAAM,CAAC;;;;;;;;;;;;;;4BAcO,0BAA0B;kBACpC,WAAW,UAAU,gBAAgB;sBACjC,mBAAmB;;;;;;;gBAOzB,QAAQ;iBACP,aAAa;;;;;;qCAMO,aAAa;;;;;mBAK/B,aAAa;;;;iBAIf,qBAAqB;;;;;;;kBAOpB,aAAa;;CAE9B,CAAC","sourcesContent":["import { css } from '@ni/fast-element';\nimport {\n applicationBackgroundColor,\n bodyFont,\n bodyFontColor,\n borderWidth,\n controlLabelFontColor,\n elevation2BoxShadow,\n mediumPadding,\n popupBorderColor\n} from '@ni/nimble-components/dist/esm/theme-provider/design-tokens';\nimport { display } from '../../utilities/style/display';\n\nexport const styles = css`\n ${display('flex')}\n\n :host {\n width: 100%;\n height: auto;\n }\n\n .container {\n display: grid;\n grid-template-rows: auto 1fr;\n grid-template-columns: 1fr auto;\n width: 100%;\n height: 100%;\n\n background-color: ${applicationBackgroundColor};\n border: ${borderWidth} solid ${popupBorderColor};\n box-shadow: ${elevation2BoxShadow};\n }\n\n textarea {\n grid-row: 1;\n grid-column: 1 / 3;\n\n font: ${bodyFont};\n color: ${bodyFontColor};\n background-color: transparent;\n\n width: 100%;\n resize: none;\n height: auto;\n max-height: calc(6lh + 2 * ${mediumPadding});\n field-sizing: content;\n\n border-width: 0px;\n outline: none;\n padding: ${mediumPadding};\n }\n\n textarea::placeholder {\n color: ${controlLabelFontColor};\n }\n\n .send-button {\n grid-row: 2;\n grid-column: 2;\n width: 80px;\n margin: ${mediumPadding};\n }\n`;\n"]}
@@ -0,0 +1,2 @@
1
+ import type { ChatInput } from '.';
2
+ export declare const template: import("@ni/fast-element").ViewTemplate<ChatInput, any>;
@@ -0,0 +1,29 @@
1
+ import { html, ref } from '@ni/fast-element';
2
+ import { buttonTag } from '@ni/nimble-components/dist/esm/button';
3
+ import { iconPaperPlaneTag } from '@ni/nimble-components/dist/esm/icons/paper-plane';
4
+ /* eslint-disable @typescript-eslint/indent */
5
+ // prettier-ignore
6
+ export const template = html `
7
+ <div class="container">
8
+ <textarea
9
+ ${ref('textArea')}
10
+ placeholder="${x => x.placeholder}"
11
+ rows="1"
12
+ @keydown="${(x, c) => x.textAreaKeydownHandler(c.event)}"
13
+ @input="${x => x.textAreaInputHandler()}"
14
+ ></textarea>
15
+ <${buttonTag}
16
+ class="send-button"
17
+ appearance="block"
18
+ appearance-variant="accent"
19
+ ?disabled=${x => x.disableSendButton}
20
+ @click=${x => x.sendButtonClickHandler()}
21
+ title=${x => x.sendButtonLabel}
22
+ content-hidden
23
+ >
24
+ ${x => x.sendButtonLabel}
25
+ <${iconPaperPlaneTag} slot="start"><${iconPaperPlaneTag}/>
26
+ </${buttonTag}>
27
+ </div>`;
28
+ /* eslint-enable @typescript-eslint/indent */
29
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../../src/chat/input/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AAGrF,8CAA8C;AAC9C,kBAAkB;AAClB,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAW;;;UAG7B,GAAG,CAAC,UAAU,CAAC;uBACF,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW;;oBAErB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,KAAsB,CAAC;kBAC9D,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,oBAAoB,EAAE;;OAExC,SAAS;;;;oBAII,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB;iBAC3B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,sBAAsB,EAAE;gBAChC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe;;;UAG5B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe;WACrB,iBAAiB,kBAAkB,iBAAiB;QACvD,SAAS;OACV,CAAC;AACR,6CAA6C","sourcesContent":["import { html, ref } from '@ni/fast-element';\nimport { buttonTag } from '@ni/nimble-components/dist/esm/button';\nimport { iconPaperPlaneTag } from '@ni/nimble-components/dist/esm/icons/paper-plane';\nimport type { ChatInput } from '.';\n\n/* eslint-disable @typescript-eslint/indent */\n// prettier-ignore\nexport const template = html<ChatInput>`\n<div class=\"container\">\n <textarea\n ${ref('textArea')}\n placeholder=\"${x => x.placeholder}\"\n rows=\"1\"\n @keydown=\"${(x, c) => x.textAreaKeydownHandler(c.event as KeyboardEvent)}\"\n @input=\"${x => x.textAreaInputHandler()}\"\n ></textarea>\n <${buttonTag}\n class=\"send-button\"\n appearance=\"block\"\n appearance-variant=\"accent\"\n ?disabled=${x => x.disableSendButton}\n @click=${x => x.sendButtonClickHandler()}\n title=${x => x.sendButtonLabel}\n content-hidden\n >\n ${x => x.sendButtonLabel}\n <${iconPaperPlaneTag} slot=\"start\"><${iconPaperPlaneTag}/>\n </${buttonTag}> \n</div>`;\n/* eslint-enable @typescript-eslint/indent */\n"]}
@@ -0,0 +1,21 @@
1
+ import type { ChatInput } from '..';
2
+ /**
3
+ * Page object for the `spright-chat-input` component to provide consistent ways
4
+ * of querying and interacting with the component during tests.
5
+ */
6
+ export declare class ChatInputPageObject {
7
+ protected readonly element: ChatInput;
8
+ constructor(element: ChatInput);
9
+ isSendButtonEnabled(): boolean;
10
+ clickSendButton(): void;
11
+ getSendButtonTitle(): string;
12
+ getSendButtonTextContent(): string;
13
+ textAreaHasFocus(): boolean;
14
+ getPlaceholder(): string;
15
+ getRenderedText(): string;
16
+ setText(text: string): void;
17
+ pressEnterKey(): Promise<void>;
18
+ pressShiftEnterKey(): Promise<void>;
19
+ private getSendButton;
20
+ private sendEnterKeyEvents;
21
+ }
@@ -0,0 +1,65 @@
1
+ import { keyEnter } from '@ni/fast-web-utilities';
2
+ import { Button } from '@ni/nimble-components/dist/esm/button';
3
+ import { processUpdates, waitForUpdatesAsync } from '@ni/nimble-components/dist/esm/testing/async-helpers';
4
+ import { sendKeyDownEvent } from '@ni/nimble-components/dist/esm/utilities/testing/component';
5
+ /**
6
+ * Page object for the `spright-chat-input` component to provide consistent ways
7
+ * of querying and interacting with the component during tests.
8
+ */
9
+ export class ChatInputPageObject {
10
+ constructor(element) {
11
+ this.element = element;
12
+ }
13
+ isSendButtonEnabled() {
14
+ return !this.getSendButton().disabled;
15
+ }
16
+ clickSendButton() {
17
+ this.getSendButton().click();
18
+ }
19
+ getSendButtonTitle() {
20
+ return this.getSendButton().title;
21
+ }
22
+ getSendButtonTextContent() {
23
+ return this.getSendButton().textContent?.trim() ?? '';
24
+ }
25
+ textAreaHasFocus() {
26
+ return (document.activeElement === this.element
27
+ && this.element.shadowRoot?.activeElement === this.element.textArea);
28
+ }
29
+ getPlaceholder() {
30
+ if (this.element.textArea.value) {
31
+ throw Error('Placeholder not visible');
32
+ }
33
+ return this.element.textArea.placeholder;
34
+ }
35
+ getRenderedText() {
36
+ return this.element.textArea.value;
37
+ }
38
+ setText(text) {
39
+ this.element.textArea.focus();
40
+ this.element.textArea.value = text;
41
+ this.element.textAreaInputHandler();
42
+ processUpdates();
43
+ }
44
+ async pressEnterKey() {
45
+ this.element.textArea.focus();
46
+ await this.sendEnterKeyEvents(false);
47
+ }
48
+ async pressShiftEnterKey() {
49
+ this.element.textArea.focus();
50
+ await this.sendEnterKeyEvents(true);
51
+ }
52
+ getSendButton() {
53
+ const sendButton = this.element.shadowRoot.querySelector('.send-button');
54
+ return sendButton;
55
+ }
56
+ async sendEnterKeyEvents(shiftKey) {
57
+ const keyDownEvent = await sendKeyDownEvent(this.element.textArea, keyEnter, { shiftKey });
58
+ if (!keyDownEvent.defaultPrevented) {
59
+ this.element.textArea.value += '\n';
60
+ this.element.textArea.dispatchEvent(new InputEvent('input'));
61
+ }
62
+ await waitForUpdatesAsync();
63
+ }
64
+ }
65
+ //# sourceMappingURL=chat-input.pageobject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-input.pageobject.js","sourceRoot":"","sources":["../../../../../src/chat/input/testing/chat-input.pageobject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAC/D,OAAO,EACH,cAAc,EACd,mBAAmB,EACtB,MAAM,sDAAsD,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4DAA4D,CAAC;AAG9F;;;GAGG;AACH,MAAM,OAAO,mBAAmB;IAC5B,YAAsC,OAAkB;QAAlB,YAAO,GAAP,OAAO,CAAW;IAAG,CAAC;IAErD,mBAAmB;QACtB,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC;IAC1C,CAAC;IAEM,eAAe;QAClB,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,CAAC;IACjC,CAAC;IAEM,kBAAkB;QACrB,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC;IACtC,CAAC;IAEM,wBAAwB;QAC3B,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC1D,CAAC;IAEM,gBAAgB;QACnB,OAAO,CACH,QAAQ,CAAC,aAAa,KAAK,IAAI,CAAC,OAAO;eACpC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ,CACtE,CAAC;IACN,CAAC;IAEM,cAAc;QACjB,IAAI,IAAI,CAAC,OAAO,CAAC,QAAS,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,QAAS,CAAC,WAAW,CAAC;IAC9C,CAAC;IAEM,eAAe;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAS,CAAC,KAAK,CAAC;IACxC,CAAC;IAEM,OAAO,CAAC,IAAY;QACvB,IAAI,CAAC,OAAO,CAAC,QAAS,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,QAAS,CAAC,KAAK,GAAG,IAAI,CAAC;QACpC,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;QACpC,cAAc,EAAE,CAAC;IACrB,CAAC;IAEM,KAAK,CAAC,aAAa;QACtB,IAAI,CAAC,OAAO,CAAC,QAAS,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAEM,KAAK,CAAC,kBAAkB;QAC3B,IAAI,CAAC,OAAO,CAAC,QAAS,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAEO,aAAa;QACjB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAW,CAAC,aAAa,CAAS,cAAc,CAAE,CAAC;QACnF,OAAO,UAAU,CAAC;IACtB,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,QAAiB;QAC9C,MAAM,YAAY,GAAG,MAAM,gBAAgB,CACvC,IAAI,CAAC,OAAO,CAAC,QAAS,EACtB,QAAQ,EACR,EAAE,QAAQ,EAAE,CACf,CAAC;QACF,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO,CAAC,QAAS,CAAC,KAAK,IAAI,IAAI,CAAC;YACrC,IAAI,CAAC,OAAO,CAAC,QAAS,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,mBAAmB,EAAE,CAAC;IAChC,CAAC;CACJ","sourcesContent":["import { keyEnter } from '@ni/fast-web-utilities';\nimport { Button } from '@ni/nimble-components/dist/esm/button';\nimport {\n processUpdates,\n waitForUpdatesAsync\n} from '@ni/nimble-components/dist/esm/testing/async-helpers';\nimport { sendKeyDownEvent } from '@ni/nimble-components/dist/esm/utilities/testing/component';\nimport type { ChatInput } from '..';\n\n/**\n * Page object for the `spright-chat-input` component to provide consistent ways\n * of querying and interacting with the component during tests.\n */\nexport class ChatInputPageObject {\n public constructor(protected readonly element: ChatInput) {}\n\n public isSendButtonEnabled(): boolean {\n return !this.getSendButton().disabled;\n }\n\n public clickSendButton(): void {\n this.getSendButton().click();\n }\n\n public getSendButtonTitle(): string {\n return this.getSendButton().title;\n }\n\n public getSendButtonTextContent(): string {\n return this.getSendButton().textContent?.trim() ?? '';\n }\n\n public textAreaHasFocus(): boolean {\n return (\n document.activeElement === this.element\n && this.element.shadowRoot?.activeElement === this.element.textArea\n );\n }\n\n public getPlaceholder(): string {\n if (this.element.textArea!.value) {\n throw Error('Placeholder not visible');\n }\n return this.element.textArea!.placeholder;\n }\n\n public getRenderedText(): string {\n return this.element.textArea!.value;\n }\n\n public setText(text: string): void {\n this.element.textArea!.focus();\n this.element.textArea!.value = text;\n this.element.textAreaInputHandler();\n processUpdates();\n }\n\n public async pressEnterKey(): Promise<void> {\n this.element.textArea!.focus();\n await this.sendEnterKeyEvents(false);\n }\n\n public async pressShiftEnterKey(): Promise<void> {\n this.element.textArea!.focus();\n await this.sendEnterKeyEvents(true);\n }\n\n private getSendButton(): Button {\n const sendButton = this.element.shadowRoot!.querySelector<Button>('.send-button')!;\n return sendButton;\n }\n\n private async sendEnterKeyEvents(shiftKey: boolean): Promise<void> {\n const keyDownEvent = await sendKeyDownEvent(\n this.element.textArea!,\n keyEnter,\n { shiftKey }\n );\n if (!keyDownEvent.defaultPrevented) {\n this.element.textArea!.value += '\\n';\n this.element.textArea!.dispatchEvent(new InputEvent('input'));\n }\n\n await waitForUpdatesAsync();\n }\n}\n"]}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The type of the detail associated with the `send`
3
+ * event on the chat input.
4
+ */
5
+ export interface ChatInputSendEventDetail {
6
+ text: string;
7
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/chat/input/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * The type of the detail associated with the `send`\n * event on the chat input.\n */\nexport interface ChatInputSendEventDetail {\n text: string;\n}\n"]}
@@ -20,7 +20,7 @@ export declare class ChatMessage extends FoundationElement {
20
20
  * @remarks
21
21
  * HTML Attribute: message-type
22
22
  */
23
- readonly messageType: ChatMessageType;
23
+ messageType: ChatMessageType;
24
24
  /** @internal */
25
25
  footerActionsIsEmpty: boolean;
26
26
  /** @internal */
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/chat/message/index.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACH,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,QAAQ,EAGX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAc1C;;GAEG;AACH,MAAM,OAAO,WAAY,SAAQ,iBAAiB;IAAlD;;QACI;;;;;WAKG;QAEa,gBAAW,GAAoB,eAAe,CAAC,MAAM,CAAC;QAEtE,gBAAgB;QAET,yBAAoB,GAAG,IAAI,CAAC;IAYvC,CAAC;IANU,mCAAmC,CACtC,KAAgC,EAChC,IAA+B;QAE/B,IAAI,CAAC,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC;IAC9C,CAAC;CACJ;AAhBmB;IADf,IAAI,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;gDACkC;AAI/D;IADN,UAAU;yDACwB;AAInB;IADf,UAAU;iEACkD;AASjE,WAAW,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AAEnC,MAAM,kBAAkB,GAAG,WAAW,CAAC,OAAO,CAAC;IAC3C,QAAQ,EAAE,cAAc;IACxB,QAAQ;IACR,MAAM;CACT,CAAC,CAAC;AAEH,YAAY,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAChF,MAAM,CAAC,MAAM,cAAc,GAAG,sBAAsB,CAAC","sourcesContent":["import { attr, observable } from '@ni/fast-element';\nimport {\n applyMixins,\n DesignSystem,\n FoundationElement,\n StartEnd,\n type FoundationElementDefinition,\n type StartEndOptions\n} from '@ni/fast-foundation';\nimport { styles } from './styles';\nimport { template } from './template';\nimport { ChatMessageType } from './types';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'spright-chat-message': ChatMessage;\n }\n}\n\n/**\n * SprightChatMessage configuration options\n * @public\n */\nexport type ChatMessageOptions = FoundationElementDefinition & StartEndOptions;\n\n/**\n * A Spright component for displaying a chat message\n */\nexport class ChatMessage extends FoundationElement {\n /**\n * @public\n * The message type of this message in the chat conversation\n * @remarks\n * HTML Attribute: message-type\n */\n @attr({ attribute: 'message-type' })\n public readonly messageType: ChatMessageType = ChatMessageType.system;\n\n /** @internal */\n @observable\n public footerActionsIsEmpty = true;\n\n /** @internal */\n @observable\n public readonly slottedFooterActionsElements?: HTMLElement[];\n\n public slottedFooterActionsElementsChanged(\n _prev: HTMLElement[] | undefined,\n next: HTMLElement[] | undefined\n ): void {\n this.footerActionsIsEmpty = !next?.length;\n }\n}\napplyMixins(ChatMessage, StartEnd);\n\nconst sprightChatMessage = ChatMessage.compose({\n baseName: 'chat-message',\n template,\n styles\n});\n\nDesignSystem.getOrCreate().withPrefix('spright').register(sprightChatMessage());\nexport const chatMessageTag = 'spright-chat-message';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/chat/message/index.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACH,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,QAAQ,EAGX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAc1C;;GAEG;AACH,MAAM,OAAO,WAAY,SAAQ,iBAAiB;IAAlD;;QACI;;;;;WAKG;QAEI,gBAAW,GAAoB,eAAe,CAAC,MAAM,CAAC;QAE7D,gBAAgB;QAET,yBAAoB,GAAG,IAAI,CAAC;IAYvC,CAAC;IANU,mCAAmC,CACtC,KAAgC,EAChC,IAA+B;QAE/B,IAAI,CAAC,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC;IAC9C,CAAC;CACJ;AAhBU;IADN,IAAI,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;gDACyB;AAItD;IADN,UAAU;yDACwB;AAInB;IADf,UAAU;iEACkD;AASjE,WAAW,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AAEnC,MAAM,kBAAkB,GAAG,WAAW,CAAC,OAAO,CAAC;IAC3C,QAAQ,EAAE,cAAc;IACxB,QAAQ;IACR,MAAM;CACT,CAAC,CAAC;AAEH,YAAY,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAChF,MAAM,CAAC,MAAM,cAAc,GAAG,sBAAsB,CAAC","sourcesContent":["import { attr, observable } from '@ni/fast-element';\nimport {\n applyMixins,\n DesignSystem,\n FoundationElement,\n StartEnd,\n type FoundationElementDefinition,\n type StartEndOptions\n} from '@ni/fast-foundation';\nimport { styles } from './styles';\nimport { template } from './template';\nimport { ChatMessageType } from './types';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'spright-chat-message': ChatMessage;\n }\n}\n\n/**\n * SprightChatMessage configuration options\n * @public\n */\nexport type ChatMessageOptions = FoundationElementDefinition & StartEndOptions;\n\n/**\n * A Spright component for displaying a chat message\n */\nexport class ChatMessage extends FoundationElement {\n /**\n * @public\n * The message type of this message in the chat conversation\n * @remarks\n * HTML Attribute: message-type\n */\n @attr({ attribute: 'message-type' })\n public messageType: ChatMessageType = ChatMessageType.system;\n\n /** @internal */\n @observable\n public footerActionsIsEmpty = true;\n\n /** @internal */\n @observable\n public readonly slottedFooterActionsElements?: HTMLElement[];\n\n public slottedFooterActionsElementsChanged(\n _prev: HTMLElement[] | undefined,\n next: HTMLElement[] | undefined\n ): void {\n this.footerActionsIsEmpty = !next?.length;\n }\n}\napplyMixins(ChatMessage, StartEnd);\n\nconst sprightChatMessage = ChatMessage.compose({\n baseName: 'chat-message',\n template,\n styles\n});\n\nDesignSystem.getOrCreate().withPrefix('spright').register(sprightChatMessage());\nexport const chatMessageTag = 'spright-chat-message';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ni/spright-components",
3
- "version": "5.4.2",
3
+ "version": "5.5.0",
4
4
  "description": "NI Spright Components",
5
5
  "scripts": {
6
6
  "build": "npm run build-components && npm run bundle-components",
@@ -50,7 +50,8 @@
50
50
  "dependencies": {
51
51
  "@ni/fast-element": "^10.0.0",
52
52
  "@ni/fast-foundation": "^10.0.0",
53
- "@ni/nimble-components": "^33.11.0",
53
+ "@ni/fast-web-utilities": "^10.0.0",
54
+ "@ni/nimble-components": "^33.11.1",
54
55
  "tslib": "^2.2.0"
55
56
  },
56
57
  "devDependencies": {