@fibery/ui-kit 1.39.1 → 1.40.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +1 -2
  3. package/src/button/select-button.tsx +11 -3
  4. package/src/collapsible/index.tsx +2 -2
  5. package/src/command-menu/index.tsx +4 -2
  6. package/src/copy-to-clipboard.ts +10 -0
  7. package/src/file-item-2.tsx +218 -128
  8. package/src/file-item.tsx +2 -0
  9. package/src/guide-link.tsx +1 -1
  10. package/src/html-styles.ts +2 -12
  11. package/src/icons/ast/FileImage.ts +1 -1
  12. package/src/icons/ast/Mermaid.ts +8 -0
  13. package/src/icons/ast/TextNoWrap.ts +8 -0
  14. package/src/icons/ast/TextWrap.ts +8 -0
  15. package/src/icons/ast/TypeId.ts +8 -0
  16. package/src/icons/ast/index.tsx +4 -0
  17. package/src/icons/react/Mermaid.tsx +13 -0
  18. package/src/icons/react/TextNoWrap.tsx +13 -0
  19. package/src/icons/react/TextWrap.tsx +13 -0
  20. package/src/icons/react/TypeId.tsx +13 -0
  21. package/src/icons/react/index.tsx +4 -0
  22. package/src/icons/svg/file-image.svg +2 -2
  23. package/src/icons/svg/mermaid.svg +3 -0
  24. package/src/icons/svg/text-no-wrap.svg +3 -0
  25. package/src/icons/svg/text-wrap.svg +3 -0
  26. package/src/icons/svg/type/id.svg +3 -0
  27. package/src/images-gallery/images-gallery-fall-through-provider.tsx +2 -1
  28. package/src/images-gallery/images-gallery.tsx +524 -185
  29. package/src/{images-gallery-2 → images-gallery}/slide-buttons.tsx +25 -13
  30. package/src/images-gallery/zoom.tsx +5 -94
  31. package/src/popover/index.tsx +5 -3
  32. package/src/select/components/menu-list-virtualized.tsx +123 -84
  33. package/src/select/components/menu.tsx +5 -3
  34. package/src/table.tsx +13 -10
  35. package/src/toggle-button/toggle-button.tsx +5 -0
  36. package/src/images-gallery-2/images-gallery-2.tsx +0 -522
  37. package/src/images-gallery-2/zoom.tsx +0 -35
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @fibery/ui-kit
2
2
 
3
+ ## 1.40.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 589e0f6: add new icon TypeId
8
+
3
9
  ## 1.39.1
4
10
 
5
11
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fibery/ui-kit",
3
- "version": "1.39.1",
3
+ "version": "1.40.0",
4
4
  "private": false,
5
5
  "license": "UNLICENSED",
6
6
  "dependencies": {
@@ -39,7 +39,6 @@
39
39
  "react-color": "2.19.3",
40
40
  "react-day-picker": "8.10.1",
41
41
  "react-intersection-observer": "9.3.5",
42
- "react-medium-image-zoom": "5.2.10",
43
42
  "react-popper": "2.3.0",
44
43
  "react-select": "5.3.2",
45
44
  "react-select-country-list": "2.2.1",
@@ -34,10 +34,18 @@ export type SelectButtonProps = {
34
34
  * Should be used as an escape hatch for components like ui-kit/src/popup that don't set "aria-expanded"
35
35
  */
36
36
  open?: boolean;
37
- } & Omit<ButtonProps, "iconEnd">;
37
+ } & ButtonProps;
38
38
 
39
39
  export const SelectButton = forwardRef<HTMLButtonElement, SelectButtonProps>(function SelectButton(
40
- {size = "medium", className, open, variant = "ghost", color = "neutral", ...rest},
40
+ {
41
+ size = "medium",
42
+ className,
43
+ open,
44
+ variant = "ghost",
45
+ iconEnd = <ArrowBottom className={iconSize[size]} />,
46
+ color = "neutral",
47
+ ...rest
48
+ },
41
49
  forwardedRef
42
50
  ) {
43
51
  return (
@@ -45,7 +53,7 @@ export const SelectButton = forwardRef<HTMLButtonElement, SelectButtonProps>(fun
45
53
  ref={forwardedRef}
46
54
  aria-expanded={open}
47
55
  size={size}
48
- iconEnd={<ArrowBottom className={iconSize[size]} />}
56
+ iconEnd={iconEnd}
49
57
  variant={variant}
50
58
  color={color}
51
59
  className={className}
@@ -36,10 +36,10 @@ export const CollapsibleContent = styled(Collapsible.Content)`
36
36
 
37
37
  @media (prefers-reduced-motion: no-preference) {
38
38
  &[data-state="open"] {
39
- animation: slideDown 150ms ease-out;
39
+ animation: slideDown 120ms ease-out;
40
40
  }
41
41
  &[data-state="closed"] {
42
- animation: slideUp 150ms ease-out;
42
+ animation: slideUp 120ms ease-out;
43
43
  }
44
44
  }
45
45
  `;
@@ -10,8 +10,10 @@ import Search from "../icons/react/Search";
10
10
 
11
11
  export const CommandMenuRoot = styled(CommandRoot)`
12
12
  display: flex;
13
- height: 100%;
14
- width: 100%;
13
+ :where(&) {
14
+ height: 100%;
15
+ width: 100%;
16
+ }
15
17
  flex-direction: column;
16
18
  overflow: hidden;
17
19
  border-radius: ${border.radius8}px;
@@ -1 +1,11 @@
1
1
  export const copyToClipboard = (text: string) => window.navigator.clipboard.writeText(text);
2
+ export const copyUrlToClipboard = ({url, label}: {url: string; label?: string}) => {
3
+ const htmlString = `<a href="${url}" target="_blank">${label || url}</a>`;
4
+
5
+ return window.navigator.clipboard.write([
6
+ new ClipboardItem({
7
+ "text/html": new Blob([htmlString], {type: "text/html"}),
8
+ "text/plain": url,
9
+ }),
10
+ ]);
11
+ };
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable max-lines */
2
2
  import {css, cx} from "@linaria/core";
3
- import {useCallback, useEffect, useState} from "react";
3
+ import {CSSProperties, useCallback, useEffect, useState} from "react";
4
4
  import {ActionsMenu, ActionsMenuItem, ActionsMenuSeparator} from "./actions-menu";
5
5
  import {ActionsButtonCompact} from "./button/actions-button-compact";
6
6
  import {border, colors, space, themeVars, fontSize, fontWeight, lineHeight} from "./design-system";
@@ -17,11 +17,12 @@ import Link from "./icons/react/Link";
17
17
  import RicheditorOpenLink from "./icons/react/RicheditorOpenLink";
18
18
  import Spinner from "./icons/react/Spinner";
19
19
  import AppWiki from "./icons/react/AppWiki";
20
- import {copyToClipboard} from "./copy-to-clipboard";
20
+ import {copyUrlToClipboard} from "./copy-to-clipboard";
21
21
  import {useToast} from "./toast/toast-provider";
22
22
  import {Icon} from "./icons/Icon";
23
23
  import {useImagesGalleryMethods, useImagesGalleryRegistry} from "./images-gallery/images-gallery";
24
24
  import {isPhoneApp} from "./use-is-phone";
25
+ import Pencil from "./icons/react/Pencil";
25
26
 
26
27
  const fileItemStyle = css`
27
28
  display: block;
@@ -30,13 +31,20 @@ const fileItemStyle = css`
30
31
  background-size: cover;
31
32
  text-decoration: none;
32
33
  border-radius: ${space.s8}px;
33
- border: 1px solid ${themeVars.separatorColor};
34
34
  background-clip: padding-box;
35
35
  &:focus {
36
36
  text-decoration: none;
37
37
  }
38
38
  `;
39
39
 
40
+ const thumbnailStyle = css`
41
+ border: 1px solid ${themeVars.separatorColor};
42
+ `;
43
+
44
+ const iconOnlyStyle = css`
45
+ border: 1px solid ${themeVars.colorBorderButtonOutlineNeutralDefault};
46
+ `;
47
+
40
48
  const overlayStyle = css`
41
49
  width: 100%;
42
50
  height: 100%;
@@ -64,7 +72,15 @@ const fileOverlayStyle = css`
64
72
  background: transparent;
65
73
  `;
66
74
 
75
+ const actionsButtonStyle = css`
76
+ position: absolute;
77
+ top: ${space.s8}px;
78
+ right: ${space.s8}px;
79
+ opacity: 0;
80
+ `;
81
+
67
82
  export type FileItemType = {
83
+ uid: string;
68
84
  name: string;
69
85
  url: string;
70
86
  downloadUrl?: string | null;
@@ -82,6 +98,7 @@ export type FileItemProps = {
82
98
  data: FileItemType;
83
99
  onDownloadClick?: () => void;
84
100
  onRemoveClick?: (x: FileItemType) => void;
101
+ onRenameClick?: (x: {id: string; name: string}) => void;
85
102
  disabled?: boolean;
86
103
  };
87
104
 
@@ -89,7 +106,8 @@ export function FileItem(props: FileItemProps) {
89
106
  const {onDownloadClick, onRemoveClick} = props;
90
107
  const {name, thumbnailUrl, status, previewData: preview, contentType} = props.data;
91
108
  const isPending = status === "uploading" || status === "deleting";
92
- const isBackgroundReady = Boolean(thumbnailUrl && !isPending);
109
+ const [isThumbnailLoadFailed, setIsThumbnailLoadFailed] = useState(false);
110
+ const isBackgroundReady = !isThumbnailLoadFailed && Boolean(thumbnailUrl && !isPending);
93
111
  const [isActionsOpened, setIsActionsOpened] = useState(false);
94
112
 
95
113
  const showFileIcon = !isPending && !isBackgroundReady;
@@ -106,6 +124,7 @@ export function FileItem(props: FileItemProps) {
106
124
  imagesRegistry.set(preview.originalSrc, {
107
125
  type: preview.type,
108
126
  src: preview.originalSrc,
127
+ label: name,
109
128
  zoomed: false,
110
129
  setZoomed,
111
130
  actions: <FilePreviewActions url={preview.originalSrc} name={name} onDownloadClick={onDownloadClick} />,
@@ -127,6 +146,7 @@ export function FileItem(props: FileItemProps) {
127
146
  imagesRegistry.set(preview.originalSrc, {
128
147
  type: preview.type,
129
148
  src: preview.originalSrc,
149
+ label: name,
130
150
  zoomed,
131
151
  setZoomed,
132
152
  actions: <FilePreviewActions url={preview.originalSrc} name={name} onDownloadClick={onDownloadClick} />,
@@ -143,63 +163,69 @@ export function FileItem(props: FileItemProps) {
143
163
  }, [preview, onDownloadClick]);
144
164
 
145
165
  return (
146
- <div
147
- className={cx(
148
- css`
149
- flex: 1 0 0;
150
- height: 100%;
151
- `,
152
- isBackgroundReady &&
153
- css`
154
- &:hover .${overlayStyle} {
155
- opacity: 1;
156
- background-position: 0 0;
157
- color: ${themeVars.whiteColor};
158
- background-color: rgba(0, 0, 0, 0.6);
159
- }
160
- `,
161
- isBackgroundReady &&
162
- isActionsOpened &&
163
- css`
164
- .${overlayStyle} {
165
- opacity: 1;
166
- background-position: 0 0;
167
- color: ${themeVars.whiteColor};
168
- background-color: rgba(0, 0, 0, 0.6);
169
- }
170
- `
171
- )}
172
- >
166
+ <>
173
167
  <div
174
- style={isBackgroundReady ? {backgroundImage: `url(${thumbnailUrl})`} : {}}
175
- onClick={onContainerClick}
176
168
  className={cx(
177
169
  css`
178
- flex-shrink: 0;
170
+ flex: 1 0 0;
171
+ height: 100%;
179
172
  `,
180
- fileItemStyle,
181
- isPending &&
173
+ isBackgroundReady &&
174
+ css`
175
+ &:hover .${overlayStyle} {
176
+ opacity: 1;
177
+ background-position: 0 0;
178
+ color: ${themeVars.whiteColor};
179
+ background-color: rgba(0, 0, 0, 0.6);
180
+ }
181
+ `,
182
+ isBackgroundReady &&
183
+ isActionsOpened &&
184
+ css`
185
+ .${overlayStyle} {
186
+ opacity: 1;
187
+ background-position: 0 0;
188
+ color: ${themeVars.whiteColor};
189
+ background-color: rgba(0, 0, 0, 0.6);
190
+ }
191
+ `,
192
+ !isBackgroundReady &&
193
+ css`
194
+ &:hover .${overlayStyle} {
195
+ background-color: ${themeVars.colorBgMenuItemHover};
196
+ }
197
+ &:hover .${actionsButtonStyle} {
198
+ opacity: 1;
199
+ }
200
+ `,
201
+ !isBackgroundReady &&
202
+ isActionsOpened &&
182
203
  css`
183
- ${{backgroundColor: themeVars.entityCardSelectedColor}}
204
+ .${overlayStyle} {
205
+ background-color: ${themeVars.colorBgMenuItemHover};
206
+ }
207
+ .${actionsButtonStyle} {
208
+ opacity: 1;
209
+ }
184
210
  `
185
211
  )}
186
212
  >
187
- {isPending && (
188
- <div
189
- className={css`
190
- display: flex;
191
- flex-direction: column;
192
- justify-content: center; /* centers vertically */
193
- align-items: center; /* centers horizontally */
194
- height: 100%;
195
- width: 100%;
196
- `}
197
- >
198
- <Spinner />
199
- </div>
200
- )}
201
- {showFileIcon && (
202
- <div className={cx(overlayStyle, fileOverlayStyle)}>
213
+ <div
214
+ style={isBackgroundReady ? {backgroundImage: `url(${thumbnailUrl})`} : {}}
215
+ onClick={onContainerClick}
216
+ className={cx(
217
+ css`
218
+ flex-shrink: 0;
219
+ `,
220
+ fileItemStyle,
221
+ showFileIcon ? iconOnlyStyle : thumbnailStyle,
222
+ isPending &&
223
+ css`
224
+ ${{backgroundColor: themeVars.entityCardSelectedColor}}
225
+ `
226
+ )}
227
+ >
228
+ {isPending && (
203
229
  <div
204
230
  className={css`
205
231
  display: flex;
@@ -208,101 +234,122 @@ export function FileItem(props: FileItemProps) {
208
234
  align-items: center; /* centers horizontally */
209
235
  height: 100%;
210
236
  width: 100%;
211
- padding-top: ${space.s1}px;
212
- gap: ${space.s2}px;
213
237
  `}
214
238
  >
215
- <Icon containerSize={40} iconSize={40}>
216
- <FileIcon contentType={contentType} />
217
- </Icon>
239
+ <Spinner />
240
+ </div>
241
+ )}
242
+ {showFileIcon && (
243
+ <div className={cx(overlayStyle, fileOverlayStyle)}>
218
244
  <div
219
245
  className={css`
220
- align-content: center;
221
-
222
246
  display: flex;
223
- align-items: center;
224
- gap: 10px;
225
- flex-shrink: 0;
226
- color: ${themeVars.colorTextMenuItem};
227
- text-overflow: ellipsis;
228
- overflow: hidden;
247
+ flex-direction: column;
248
+ justify-content: center; /* centers vertically */
249
+ align-items: center; /* centers horizontally */
250
+ height: 100%;
251
+ width: 100%;
252
+ padding-top: ${space.s1}px;
253
+ gap: ${space.s2}px;
229
254
  `}
230
255
  >
231
- <FileTitle
232
- title={name}
256
+ <Icon containerSize={40} iconSize={40}>
257
+ <FileIcon contentType={contentType} />
258
+ </Icon>
259
+ <div
233
260
  className={css`
234
- -webkit-line-clamp: 1;
235
- -webkit-box-orient: vertical;
236
- overflow: hidden;
261
+ align-content: center;
262
+
263
+ display: flex;
264
+ align-items: center;
265
+ gap: 10px;
266
+ flex-shrink: 0;
267
+ color: ${themeVars.colorTextMenuItem};
237
268
  text-overflow: ellipsis;
269
+ overflow: hidden;
238
270
  `}
239
- />
271
+ >
272
+ <FileTitle
273
+ title={name}
274
+ className={css`
275
+ -webkit-line-clamp: 1;
276
+ -webkit-box-orient: vertical;
277
+ overflow: hidden;
278
+ text-overflow: ellipsis;
279
+ `}
280
+ />
281
+ </div>
240
282
  </div>
241
- </div>
242
- <div
243
- className={css`
244
- position: absolute;
245
- top: ${space.s8}px;
246
- right: ${space.s8}px;
247
- `}
248
- >
249
- <FileActionsMenu
250
- setIsActionsOpened={setIsActionsOpened}
251
- data={props.data}
252
- disabled={props.disabled}
253
- isBackgroundReady={isBackgroundReady}
254
- onDownloadClick={onDownloadClick}
255
- onRemoveClick={onRemoveClick}
256
- />
257
- </div>
258
- </div>
259
- )}
260
- {!isPending && !showFileIcon && (
261
- <div className={cx(overlayStyle, isBackgroundReady ? imageOverlayStyle : fileOverlayStyle)}>
262
- <div
263
- className={css`
264
- position: relative;
265
- display: flex;
266
- flex-direction: column;
267
- justify-content: space-between; /* Top + bottom placement */
268
- width: 100%;
269
- height: 100%;
270
- overflow: hidden;
271
- box-sizing: border-box;
272
- gap: ${space.s8}px;
273
- `}
274
- >
275
- <div
276
- className={css`
277
- align-self: flex-end;
278
- `}
279
- >
283
+ <div className={actionsButtonStyle}>
280
284
  <FileActionsMenu
281
285
  setIsActionsOpened={setIsActionsOpened}
282
286
  data={props.data}
283
287
  disabled={props.disabled}
284
- isBackgroundReady={isBackgroundReady}
285
288
  onDownloadClick={onDownloadClick}
286
- onRemoveClick={props.onRemoveClick}
289
+ onRemoveClick={onRemoveClick}
290
+ onRenameClick={props.onRenameClick}
287
291
  />
288
292
  </div>
293
+ </div>
294
+ )}
295
+ {!isPending && !showFileIcon && (
296
+ <div className={cx(overlayStyle, isBackgroundReady ? imageOverlayStyle : fileOverlayStyle)}>
289
297
  <div
290
298
  className={css`
299
+ position: relative;
291
300
  display: flex;
292
- align-self: flex-start;
293
- align-items: flex-end;
294
- text-overflow: ellipsis;
295
- //overflow: hidden;
301
+ flex-direction: column;
302
+ justify-content: space-between; /* Top + bottom placement */
303
+ width: 100%;
304
+ height: 100%;
305
+ overflow: hidden;
296
306
  box-sizing: border-box;
307
+ gap: ${space.s8}px;
297
308
  `}
298
309
  >
299
- <FileTitle title={name} />
310
+ <div
311
+ className={css`
312
+ align-self: flex-end;
313
+ `}
314
+ >
315
+ <FileActionsMenu
316
+ setIsActionsOpened={setIsActionsOpened}
317
+ data={props.data}
318
+ disabled={props.disabled}
319
+ actionsButtonStyle={
320
+ isBackgroundReady ? makeButtonColors(colors.inversedTextColor, "ghost") : undefined
321
+ }
322
+ onDownloadClick={onDownloadClick}
323
+ onRemoveClick={props.onRemoveClick}
324
+ onRenameClick={props.onRenameClick}
325
+ />
326
+ </div>
327
+ <div
328
+ className={css`
329
+ display: flex;
330
+ align-self: flex-start;
331
+ align-items: flex-end;
332
+ text-overflow: ellipsis;
333
+ //overflow: hidden;
334
+ box-sizing: border-box;
335
+ `}
336
+ >
337
+ <FileTitle title={name} />
338
+ </div>
300
339
  </div>
301
340
  </div>
302
- </div>
303
- )}
341
+ )}
342
+ </div>
343
+ {thumbnailUrl ? (
344
+ <img
345
+ style={{display: "none"}}
346
+ onError={() => setIsThumbnailLoadFailed(true)}
347
+ src={thumbnailUrl}
348
+ alt="invisible"
349
+ />
350
+ ) : null}
304
351
  </div>
305
- </div>
352
+ </>
306
353
  );
307
354
  }
308
355
 
@@ -312,14 +359,16 @@ function FileActionsMenu({
312
359
  setIsActionsOpened,
313
360
  onDownloadClick,
314
361
  onRemoveClick,
315
- isBackgroundReady,
362
+ onRenameClick,
363
+ actionsButtonStyle,
316
364
  }: {
317
365
  data: FileItemType;
318
366
  onDownloadClick?: () => void;
319
367
  onRemoveClick?: (data: FileItemType) => void;
368
+ onRenameClick?: (data: {id: string; name: string}) => void;
320
369
  disabled?: boolean;
321
370
  setIsActionsOpened: (val: boolean) => void;
322
- isBackgroundReady: boolean;
371
+ actionsButtonStyle?: CSSProperties;
323
372
  }) {
324
373
  const toast = useToast();
325
374
 
@@ -331,14 +380,14 @@ function FileActionsMenu({
331
380
  className={css`
332
381
  z-index: 1;
333
382
  `}
334
- style={isBackgroundReady ? makeButtonColors(colors.inversedTextColor, "ghost") : undefined}
383
+ style={actionsButtonStyle}
335
384
  />
336
385
  }
337
386
  >
338
387
  <ActionsMenuItem
339
388
  Icon={Link}
340
389
  onSelect={() => {
341
- copyToClipboard(`${window.origin}${data.url}`)
390
+ copyUrlToClipboard({url: `${window.origin}${data.url}`, label: data.name})
342
391
  .then(() => toast.success({title: "Link copied to clipboard"}))
343
392
  .catch((error) => toast.error({title: "Unable to copy link to clipboard", subTitle: error.message}));
344
393
  }}
@@ -359,6 +408,14 @@ function FileActionsMenu({
359
408
  <ActionsMenuItem Icon={FileDownload}>Download</ActionsMenuItem>
360
409
  </a>
361
410
  )}
411
+ {onRenameClick && data.status === "done" ? (
412
+ <>
413
+ <ActionsMenuSeparator />
414
+ <ActionsMenuItem Icon={Pencil} onSelect={() => onRenameClick?.({id: data.uid, name: data.name})}>
415
+ Rename
416
+ </ActionsMenuItem>
417
+ </>
418
+ ) : null}
362
419
  <ActionsMenuSeparator />
363
420
  <ActionsMenuItem Icon={Delete} onSelect={() => onRemoveClick?.(data)} dangerous disabled={disabled}>
364
421
  Delete
@@ -368,6 +425,10 @@ function FileActionsMenu({
368
425
  }
369
426
 
370
427
  function FileTitle({title, className}: {title: string; className?: string}) {
428
+ const parts = title.split(".");
429
+ const ext = parts.length > 1 ? "." + parts[parts.length - 1] : "";
430
+ const name = title.substring(0, title.length - ext.length);
431
+
371
432
  return (
372
433
  <div
373
434
  className={cx(
@@ -383,7 +444,7 @@ function FileTitle({title, className}: {title: string; className?: string}) {
383
444
  overflow: hidden;
384
445
  font-size: ${fontSize.mini}px;
385
446
  font-weight: ${fontWeight.medium};
386
- line-height: ${lineHeight.narrow};
447
+ line-height: ${lineHeight.heading};
387
448
  text-transform: none;
388
449
  text-overflow: ellipsis;
389
450
  -webkit-line-clamp: 1;
@@ -397,7 +458,33 @@ function FileTitle({title, className}: {title: string; className?: string}) {
397
458
  className
398
459
  )}
399
460
  >
400
- {title}
461
+ <div
462
+ className={css`
463
+ display: flex;
464
+ min-width: 0;
465
+ align-items: center;
466
+ max-width: 120px;
467
+ `}
468
+ >
469
+ <span
470
+ className={css`
471
+ white-space: nowrap;
472
+ overflow: hidden;
473
+ text-overflow: ellipsis;
474
+ /* ellipsis shows ONLY if this span overflows */
475
+ min-width: 0;
476
+ `}
477
+ >
478
+ {name}
479
+ </span>
480
+ <span
481
+ className={css`
482
+ flex: 0 0 auto;
483
+ `}
484
+ >
485
+ {ext}
486
+ </span>
487
+ </div>
401
488
  </div>
402
489
  );
403
490
  }
@@ -428,7 +515,10 @@ function FilePreviewActions({url, name, onDownloadClick}: {url: string; name: st
428
515
  );
429
516
  }
430
517
 
431
- function FileIcon({contentType}: {contentType: string}) {
518
+ function FileIcon({contentType}: {contentType?: string}) {
519
+ if (!contentType) {
520
+ return <AppWiki />;
521
+ }
432
522
  if (contentType.startsWith("image/")) {
433
523
  return <FileImage />;
434
524
  }
package/src/file-item.tsx CHANGED
@@ -111,6 +111,7 @@ export function FileItem(props: FileItemProps) {
111
111
  imagesRegistry.set(preview.originalSrc, {
112
112
  type: preview.type,
113
113
  src: preview.originalSrc,
114
+ label: name,
114
115
  contentType: preview.contentType,
115
116
  zoomed: false,
116
117
  setZoomed,
@@ -136,6 +137,7 @@ export function FileItem(props: FileItemProps) {
136
137
  imagesRegistry.set(preview.originalSrc, {
137
138
  type: preview.type,
138
139
  src: preview.originalSrc,
140
+ label: name,
139
141
  contentType: preview.contentType,
140
142
  zoomed,
141
143
  setZoomed,
@@ -12,7 +12,7 @@ export const GuideLink: React.FC<GuideLinkProps> = ({href, children, size = "sma
12
12
  return (
13
13
  <a href={href} rel="noreferrer" target={"_blank"}>
14
14
  {children ? (
15
- <Button iconStart={<HintIcon />} variant={variant} color="neutral" size={size}>
15
+ <Button iconStart={<HintIcon />} variant={variant} color="neutral" size={size} supportMobile>
16
16
  {children}
17
17
  </Button>
18
18
  ) : (
@@ -181,12 +181,8 @@ const htmlStyles = {
181
181
  paddingBottom: space.s24 + space.s4,
182
182
  paddingLeft: space.s12 + space.s4,
183
183
  paddingRight: space.s12 + space.s4,
184
- backgroundColor: themeVars.codeBlockBgColor,
185
- borderRadius: 6,
186
184
  ...textStyles.code,
187
- "& *:last-child": {
188
- marginBottom: 0,
189
- },
185
+ marginBottom: 0,
190
186
  },
191
187
  "& code": {
192
188
  ...textStyles.code,
@@ -395,12 +391,8 @@ const smallHtmlStyles = {
395
391
  paddingBottom: space.s20 + space.s4,
396
392
  paddingLeft: space.s10 + space.s4,
397
393
  paddingRight: space.s10 + space.s4,
398
- backgroundColor: themeVars.codeBlockBgColor,
399
- borderRadius: 6,
400
394
  ...textStyles.code,
401
- "& *:last-child": {
402
- marginBottom: 0,
403
- },
395
+ marginBottom: 0,
404
396
  },
405
397
  "& code": {
406
398
  ...textStyles.code,
@@ -596,8 +588,6 @@ const chatHtmlStyles = {
596
588
  paddingBottom: space.s20 + space.s4,
597
589
  paddingLeft: space.s10 + space.s4,
598
590
  paddingRight: space.s10 + space.s4,
599
- backgroundColor: themeVars.codeBlockBgColor,
600
- borderRadius: 6,
601
591
  ...textStyles.code,
602
592
  fontSize: typeSizes[5],
603
593
  "& *:last-child": {