@stack-spot/ai-chat-widget 1.22.0-beta.4 → 1.22.0-beta.5

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stack-spot/ai-chat-widget",
3
- "version": "1.22.0-beta.4",
4
- "date": "Tue May 27 2025 19:19:09 GMT-0300 (Horário Padrão de Brasília)",
3
+ "version": "1.22.0-beta.5",
4
+ "date": "Wed May 28 2025 09:44:26 GMT-0300 (Horário Padrão de Brasília)",
5
5
  "dependencies": [
6
6
  {
7
7
  "name": "@stack-spot/app-metadata",
@@ -1 +1 @@
1
- {"version":3,"file":"Code.d.ts","sourceRoot":"","sources":["../../src/components/Code.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAI3C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEvC,MAAM,MAAM,UAAU,GAAG,CACvB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,KACb,IAAI,CAAA;AAET,KAAK,SAAS,GAAG,KAAK,CAAC,eAAe,CAAC,WAAW,CAAC,GAC/C,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,GACjC,UAAU,GACV;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAE1B,MAAM,WAAW,KAAM,SAAQ,YAAY;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA6DD,eAAO,MAAM,IAAI,qHAUd,IAAI,CAAC,SAAS,EAAE,WAAW,GAAG,WAAW,CAAC,GAAG,KAAK,4CA+FpD,CAAA"}
1
+ {"version":3,"file":"Code.d.ts","sourceRoot":"","sources":["../../src/components/Code.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAI3C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAGvC,MAAM,MAAM,UAAU,GAAG,CACvB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,KACb,IAAI,CAAA;AAET,KAAK,SAAS,GAAG,KAAK,CAAC,eAAe,CAAC,WAAW,CAAC,GAC/C,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,GACjC,UAAU,GACV;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAE1B,MAAM,WAAW,KAAM,SAAQ,YAAY;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAkED,eAAO,MAAM,IAAI,qHAUd,IAAI,CAAC,SAAS,EAAE,WAAW,GAAG,WAAW,CAAC,GAAG,KAAK,4CA4HpD,CAAA"}
@@ -2,7 +2,8 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
2
2
  /**
3
3
  * Copied from the extension's webview.
4
4
  */
5
- import { AddCode, ChevronDoubleDown, Collapse, Copy } from '@citric/icons';
5
+ import { Text } from '@citric/core';
6
+ import { AddCode, ChevronDoubleDown, Collapse, Copy, Download } from '@citric/icons';
6
7
  import { IconButton } from '@citric/ui';
7
8
  import { theme, useThemeKind } from '@stack-spot/portal-theme';
8
9
  import { useTranslate } from '@stack-spot/portal-translate';
@@ -10,6 +11,7 @@ import { useState } from 'react';
10
11
  import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
11
12
  import { materialDark, vs } from 'react-syntax-highlighter/dist/esm/styles/prism/index.js';
12
13
  import styled from 'styled-components';
14
+ import { languages } from '../utils/programming-languages.js';
13
15
  const CodeBox = styled.code `
14
16
  background: ${theme.color.light[500]};
15
17
  border-radius: 6px;
@@ -31,23 +33,28 @@ const CodeBox = styled.code `
31
33
  }
32
34
  }
33
35
 
34
- .action-bar {
36
+ .header-code {
35
37
  display: flex;
36
38
  flex-direction: row;
37
- justify-content: flex-end;
39
+ justify-content: space-between;
38
40
  background: ${theme.color.light[600]};
39
41
  padding: 4px 6px;
40
42
  border-top-left-radius: 6px;
41
43
  border-top-right-radius: 6px;
42
44
 
43
- button {
44
- background: transparent;
45
- border: none;
46
- opacity: 0.75;
47
- transition: opacity 0.2s;
45
+ .action-bar {
46
+ display: flex;
47
+ flex-direction: row;
48
+
49
+ button {
50
+ background: transparent;
51
+ border: none;
52
+ opacity: 0.75;
53
+ transition: opacity 0.2s;
48
54
 
49
- &:hover {
50
- opacity: 1;
55
+ &:hover {
56
+ opacity: 1;
57
+ }
51
58
  }
52
59
  }
53
60
  }
@@ -74,6 +81,7 @@ export const Code = ({ className, onInsertCode, onNewFile, onCopyCode, language,
74
81
  const match = /language-(\w+)/.exec(className || '');
75
82
  const computedLanguage = language ?? (match ?? [])[1]?.toLowerCase() ?? 'txt';
76
83
  const content = String(children ?? '').replaceAll(/\n\t/g, '\n').trim();
84
+ const languageExtension = languages.find(l => l.value === computedLanguage)?.extensions?.[0] ?? '.txt';
77
85
  function onClickInsert() {
78
86
  onInsertCode?.(content, computedLanguage);
79
87
  }
@@ -93,11 +101,28 @@ export const Code = ({ className, onInsertCode, onNewFile, onCopyCode, language,
93
101
  if (computedLanguage === 'txt') {
94
102
  return (_jsx("code", { ...props, className: className, children: children }));
95
103
  }
96
- return (_jsxs(CodeBox, { className: ['code-box', themeKind, className].join(' '), children: [showActionBar && (_jsxs("div", { className: "action-bar", role: "toolbar", children: [_jsx(IconButton, { "aria-label": showLines ? t.hideLines : t.showLines, title: showLines ? t.hideLines : t.showLines, onClick: () => setShowLines(v => !v), style: { position: 'relative', transform: showLines ? undefined : 'rotate(180deg)', transition: 'transform 0.2s' }, children: _jsx(Collapse, {}) }), _jsx(IconButton, { "aria-label": t.copy, title: t.copy, onClick: onClickCopy, style: { position: 'relative' }, children: _jsx(Copy, {}) }), onInsertCode
97
- ? (_jsx(IconButton, { "aria-label": t.insert, title: t.insert, onClick: onClickInsert, style: { position: 'relative' }, children: _jsx(ChevronDoubleDown, { style: { transform: 'rotate(90deg)' } }) }))
98
- : null, onNewFile
99
- ? (_jsx(IconButton, { "aria-label": t.newFile, title: t.newFile, onClick: onClickNewFile, style: { position: 'relative' }, children: _jsx(AddCode, {}) }))
100
- : null] })), _jsx("div", { children: _jsx(SyntaxHighlighter, { ...props, className: "highlighter", style: themeKind === 'dark' ? materialDark : vs, language: computedLanguage, PreTag: "div", showLineNumbers: showLines, lineNumberContainerStyle: lineNumbersStyle, lineNumberStyle: lineNumbersStyle, children: content }) })] }));
104
+ return (_jsxs(CodeBox, { className: ['code-box', themeKind, className].join(' '), children: [showActionBar && (_jsxs("div", { className: "header-code", children: [_jsx("div", { children: _jsx(Text, { appearance: "code2", children: computedLanguage ?? '' }) }), _jsxs("div", { className: "action-bar", role: "toolbar", children: [_jsx(IconButton, { "aria-label": showLines ? t.hideLines : t.showLines, title: showLines ? t.hideLines : t.showLines, onClick: () => setShowLines(v => !v), style: { position: 'relative', transform: showLines ? undefined : 'rotate(180deg)', transition: 'transform 0.2s' }, children: _jsx(Collapse, {}) }), _jsx(IconButton, { "aria-label": t.downloadCode, title: t.downloadCode, onClick: () => {
105
+ try {
106
+ const extension = languageExtension;
107
+ const filename = `download${extension}`;
108
+ const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
109
+ const link = document.createElement('a');
110
+ link.href = URL.createObjectURL(blob);
111
+ link.download = filename;
112
+ document.body.appendChild(link);
113
+ link.click();
114
+ document.body.removeChild(link);
115
+ URL.revokeObjectURL(link.href);
116
+ }
117
+ catch (e) {
118
+ // eslint-disable-next-line no-console
119
+ console.error(t.downloadError, e);
120
+ }
121
+ }, children: _jsx(Download, {}) }), _jsx(IconButton, { "aria-label": t.copy, title: t.copy, onClick: onClickCopy, style: { position: 'relative' }, children: _jsx(Copy, {}) }), onInsertCode
122
+ ? (_jsx(IconButton, { "aria-label": t.insert, title: t.insert, onClick: onClickInsert, style: { position: 'relative' }, children: _jsx(ChevronDoubleDown, { style: { transform: 'rotate(90deg)' } }) }))
123
+ : null, onNewFile
124
+ ? (_jsx(IconButton, { "aria-label": t.newFile, title: t.newFile, onClick: onClickNewFile, style: { position: 'relative' }, children: _jsx(AddCode, {}) }))
125
+ : null] })] })), _jsx("div", { children: _jsx(SyntaxHighlighter, { ...props, className: "highlighter", style: themeKind === 'dark' ? materialDark : vs, language: computedLanguage, PreTag: "div", showLineNumbers: showLines, lineNumberContainerStyle: lineNumbersStyle, lineNumberStyle: lineNumbersStyle, children: content }) })] }));
101
126
  };
102
127
  const dictionary = {
103
128
  en: {
@@ -106,6 +131,8 @@ const dictionary = {
106
131
  newFile: 'Creates a new file with this code as its content',
107
132
  hideLines: 'Hide line numbers',
108
133
  showLines: 'Show line numbers',
134
+ downloadCode: 'Download the code',
135
+ downloadError: 'Error downloading code',
109
136
  },
110
137
  pt: {
111
138
  copy: 'Copiar código para a área de transferência',
@@ -113,6 +140,8 @@ const dictionary = {
113
140
  newFile: 'Criar um novo arquivo com este código como conteúdo',
114
141
  hideLines: 'Esconder números das linhas',
115
142
  showLines: 'Mostrar números das linhas',
143
+ downloadCode: 'Fazer download do código',
144
+ downloadError: 'Erro ao fazer download do código',
116
145
  },
117
146
  };
118
147
  //# sourceMappingURL=Code.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Code.js","sourceRoot":"","sources":["../../src/components/Code.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Code.js","sourceRoot":"","sources":["../../src/components/Code.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stack-spot/ai-chat-widget",
3
- "version": "1.22.0-beta.4",
3
+ "version": "1.22.0-beta.5",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stack-spot/ai-chat-widget",
3
- "version": "1.22.0-beta.4",
4
- "date": "Tue May 27 2025 19:19:09 GMT-0300 (Horário Padrão de Brasília)",
3
+ "version": "1.22.0-beta.5",
4
+ "date": "Wed May 28 2025 09:44:26 GMT-0300 (Horário Padrão de Brasília)",
5
5
  "dependencies": [
6
6
  {
7
7
  "name": "@stack-spot/app-metadata",
@@ -2,7 +2,8 @@
2
2
  * Copied from the extension's webview.
3
3
  */
4
4
 
5
- import { AddCode, ChevronDoubleDown, Collapse, Copy } from '@citric/icons'
5
+ import { Text } from '@citric/core'
6
+ import { AddCode, ChevronDoubleDown, Collapse, Copy, Download } from '@citric/icons'
6
7
  import { IconButton } from '@citric/ui'
7
8
  import { theme, useThemeKind } from '@stack-spot/portal-theme'
8
9
  import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
@@ -12,6 +13,7 @@ import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
12
13
  import { materialDark, vs } from 'react-syntax-highlighter/dist/esm/styles/prism'
13
14
  import styled from 'styled-components'
14
15
  import { WithChildren } from '../types'
16
+ import { languages } from '../utils/programming-languages'
15
17
 
16
18
  export type CodeAction = (
17
19
  code: string,
@@ -53,23 +55,28 @@ const CodeBox = styled.code`
53
55
  }
54
56
  }
55
57
 
56
- .action-bar {
58
+ .header-code {
57
59
  display: flex;
58
60
  flex-direction: row;
59
- justify-content: flex-end;
61
+ justify-content: space-between;
60
62
  background: ${theme.color.light[600]};
61
63
  padding: 4px 6px;
62
64
  border-top-left-radius: 6px;
63
65
  border-top-right-radius: 6px;
64
66
 
65
- button {
66
- background: transparent;
67
- border: none;
68
- opacity: 0.75;
69
- transition: opacity 0.2s;
67
+ .action-bar {
68
+ display: flex;
69
+ flex-direction: row;
70
+
71
+ button {
72
+ background: transparent;
73
+ border: none;
74
+ opacity: 0.75;
75
+ transition: opacity 0.2s;
70
76
 
71
- &:hover {
72
- opacity: 1;
77
+ &:hover {
78
+ opacity: 1;
79
+ }
73
80
  }
74
81
  }
75
82
  }
@@ -108,6 +115,7 @@ export const Code = ({
108
115
  const match = /language-(\w+)/.exec(className || '')
109
116
  const computedLanguage = language ?? (match ?? [])[1]?.toLowerCase() ?? 'txt'
110
117
  const content = String(children ?? '').replaceAll(/\n\t/g, '\n').trim()
118
+ const languageExtension = languages.find(l => l.value === computedLanguage)?.extensions?.[0] ?? '.txt'
111
119
 
112
120
  function onClickInsert() {
113
121
  onInsertCode?.(content, computedLanguage)
@@ -137,47 +145,75 @@ export const Code = ({
137
145
  return (
138
146
  <CodeBox className={['code-box', themeKind, className].join(' ')}>
139
147
  {showActionBar && (
140
- <div className="action-bar" role="toolbar">
141
- <IconButton
142
- aria-label={showLines ? t.hideLines : t.showLines}
143
- title={showLines ? t.hideLines : t.showLines}
144
- onClick={() => setShowLines(v => !v)}
145
- style={{ position: 'relative', transform: showLines ? undefined : 'rotate(180deg)', transition: 'transform 0.2s' }}
146
- >
147
- <Collapse />
148
- </IconButton>
149
- <IconButton
150
- aria-label={t.copy}
151
- title={t.copy}
152
- onClick={onClickCopy}
153
- style={{ position: 'relative' }}
154
- >
155
- <Copy />
156
- </IconButton>
157
- {onInsertCode
158
- ? (
159
- <IconButton
160
- aria-label={t.insert}
161
- title={t.insert}
162
- onClick={onClickInsert}
163
- style={{ position: 'relative' }}
164
- >
165
- <ChevronDoubleDown style={{ transform: 'rotate(90deg)' }} />
166
- </IconButton>
167
- )
168
- : null}
169
- {onNewFile
170
- ? (
171
- <IconButton
172
- aria-label={t.newFile}
173
- title={t.newFile}
174
- onClick={onClickNewFile}
175
- style={{ position: 'relative' }}
176
- >
177
- <AddCode />
178
- </IconButton>
179
- )
180
- : null}
148
+ <div className="header-code">
149
+ <div>
150
+ <Text appearance="code2">{computedLanguage ?? ''}</Text>
151
+ </div>
152
+ <div className="action-bar" role="toolbar">
153
+ <IconButton
154
+ aria-label={showLines ? t.hideLines : t.showLines}
155
+ title={showLines ? t.hideLines : t.showLines}
156
+ onClick={() => setShowLines(v => !v)}
157
+ style={{ position: 'relative', transform: showLines ? undefined : 'rotate(180deg)', transition: 'transform 0.2s' }}
158
+ >
159
+ <Collapse />
160
+ </IconButton>
161
+ <IconButton
162
+ aria-label={t.downloadCode}
163
+ title={t.downloadCode}
164
+ onClick={() => {
165
+ try {
166
+ const extension = languageExtension
167
+ const filename = `download${extension}`
168
+ const blob = new Blob([content], { type: 'text/plain;charset=utf-8' })
169
+ const link = document.createElement('a')
170
+ link.href = URL.createObjectURL(blob)
171
+ link.download = filename
172
+ document.body.appendChild(link)
173
+ link.click()
174
+ document.body.removeChild(link)
175
+ URL.revokeObjectURL(link.href)
176
+ } catch (e) {
177
+ // eslint-disable-next-line no-console
178
+ console.error(t.downloadError, e)
179
+ }
180
+ }}
181
+ >
182
+ <Download />
183
+ </IconButton>
184
+ <IconButton
185
+ aria-label={t.copy}
186
+ title={t.copy}
187
+ onClick={onClickCopy}
188
+ style={{ position: 'relative' }}
189
+ >
190
+ <Copy />
191
+ </IconButton>
192
+ {onInsertCode
193
+ ? (
194
+ <IconButton
195
+ aria-label={t.insert}
196
+ title={t.insert}
197
+ onClick={onClickInsert}
198
+ style={{ position: 'relative' }}
199
+ >
200
+ <ChevronDoubleDown style={{ transform: 'rotate(90deg)' }} />
201
+ </IconButton>
202
+ )
203
+ : null}
204
+ {onNewFile
205
+ ? (
206
+ <IconButton
207
+ aria-label={t.newFile}
208
+ title={t.newFile}
209
+ onClick={onClickNewFile}
210
+ style={{ position: 'relative' }}
211
+ >
212
+ <AddCode />
213
+ </IconButton>
214
+ )
215
+ : null}
216
+ </div>
181
217
  </div>
182
218
  )}
183
219
  <div>
@@ -205,6 +241,8 @@ const dictionary = {
205
241
  newFile: 'Creates a new file with this code as its content',
206
242
  hideLines: 'Hide line numbers',
207
243
  showLines: 'Show line numbers',
244
+ downloadCode: 'Download the code',
245
+ downloadError: 'Error downloading code',
208
246
  },
209
247
  pt: {
210
248
  copy: 'Copiar código para a área de transferência',
@@ -212,5 +250,7 @@ const dictionary = {
212
250
  newFile: 'Criar um novo arquivo com este código como conteúdo',
213
251
  hideLines: 'Esconder números das linhas',
214
252
  showLines: 'Mostrar números das linhas',
253
+ downloadCode: 'Fazer download do código',
254
+ downloadError: 'Erro ao fazer download do código',
215
255
  },
216
256
  } satisfies Dictionary