@backstage/plugin-techdocs 0.12.14 → 0.13.2-next.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.
- package/CHANGELOG.md +132 -0
- package/dist/index.d.ts +42 -5
- package/dist/index.esm.js +51 -36
- package/dist/index.esm.js.map +1 -1
- package/package.json +16 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,137 @@
|
|
|
1
1
|
# @backstage/plugin-techdocs
|
|
2
2
|
|
|
3
|
+
## 0.13.2-next.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 359c31e31d: Added support for documentation using the raw `<source>` tag to point to relative resources like audio or video files.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @backstage/core-components@0.8.7-next.0
|
|
10
|
+
- @backstage/integration-react@0.1.20-next.0
|
|
11
|
+
- @backstage/plugin-catalog@0.7.11-next.0
|
|
12
|
+
- @backstage/plugin-catalog-react@0.6.13-next.0
|
|
13
|
+
- @backstage/plugin-search@0.6.1-next.0
|
|
14
|
+
|
|
15
|
+
## 0.13.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- bdc53553eb: chore(deps): bump `react-text-truncate` from 0.16.0 to 0.17.0
|
|
20
|
+
- a64f99f734: Code snippets now include a "copy to clipboard" button.
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
- @backstage/core-components@0.8.6
|
|
23
|
+
- @backstage/plugin-search@0.6.0
|
|
24
|
+
- @backstage/plugin-catalog@0.7.10
|
|
25
|
+
|
|
26
|
+
## 0.13.0
|
|
27
|
+
|
|
28
|
+
### Minor Changes
|
|
29
|
+
|
|
30
|
+
- aecfe4f403: Make `TechDocsClient` and `TechDocsStorageClient` use the `FetchApi`. You now
|
|
31
|
+
need to pass in an instance of that API when constructing the client, if you
|
|
32
|
+
create a custom instance in your app.
|
|
33
|
+
|
|
34
|
+
If you are replacing the factory:
|
|
35
|
+
|
|
36
|
+
```diff
|
|
37
|
+
+import { fetchApiRef } from '@backstage/core-plugin-api';
|
|
38
|
+
|
|
39
|
+
createApiFactory({
|
|
40
|
+
api: techdocsStorageApiRef,
|
|
41
|
+
deps: {
|
|
42
|
+
configApi: configApiRef,
|
|
43
|
+
discoveryApi: discoveryApiRef,
|
|
44
|
+
identityApi: identityApiRef,
|
|
45
|
+
+ fetchApi: fetchApiRef,
|
|
46
|
+
},
|
|
47
|
+
factory: ({
|
|
48
|
+
configApi,
|
|
49
|
+
discoveryApi,
|
|
50
|
+
identityApi,
|
|
51
|
+
+ fetchApi,
|
|
52
|
+
}) =>
|
|
53
|
+
new TechDocsStorageClient({
|
|
54
|
+
configApi,
|
|
55
|
+
discoveryApi,
|
|
56
|
+
identityApi,
|
|
57
|
+
+ fetchApi,
|
|
58
|
+
}),
|
|
59
|
+
}),
|
|
60
|
+
createApiFactory({
|
|
61
|
+
api: techdocsApiRef,
|
|
62
|
+
deps: {
|
|
63
|
+
configApi: configApiRef,
|
|
64
|
+
discoveryApi: discoveryApiRef,
|
|
65
|
+
- identityApi: identityApiRef,
|
|
66
|
+
+ fetchApi: fetchApiRef,
|
|
67
|
+
},
|
|
68
|
+
factory: ({
|
|
69
|
+
configApi,
|
|
70
|
+
discoveryApi,
|
|
71
|
+
- identityApi,
|
|
72
|
+
+ fetchApi,
|
|
73
|
+
}) =>
|
|
74
|
+
new TechDocsClient({
|
|
75
|
+
configApi,
|
|
76
|
+
discoveryApi,
|
|
77
|
+
- identityApi,
|
|
78
|
+
+ fetchApi,
|
|
79
|
+
}),
|
|
80
|
+
}),
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
If instantiating directly:
|
|
84
|
+
|
|
85
|
+
```diff
|
|
86
|
+
+import { fetchApiRef } from '@backstage/core-plugin-api';
|
|
87
|
+
|
|
88
|
+
+const fetchApi = useApi(fetchApiRef);
|
|
89
|
+
const storageClient = new TechDocsStorageClient({
|
|
90
|
+
configApi,
|
|
91
|
+
discoveryApi,
|
|
92
|
+
identityApi,
|
|
93
|
+
+ fetchApi,
|
|
94
|
+
});
|
|
95
|
+
const techdocsClient = new TechDocsClient({
|
|
96
|
+
configApi,
|
|
97
|
+
discoveryApi,
|
|
98
|
+
- identityApi,
|
|
99
|
+
+ fetchApi,
|
|
100
|
+
}),
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Patch Changes
|
|
104
|
+
|
|
105
|
+
- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods.
|
|
106
|
+
- 29710c91c2: use lighter color for block quotes and horizontal rulers
|
|
107
|
+
- Updated dependencies
|
|
108
|
+
- @backstage/core-components@0.8.5
|
|
109
|
+
- @backstage/integration@0.7.2
|
|
110
|
+
- @backstage/plugin-search@0.5.6
|
|
111
|
+
- @backstage/core-plugin-api@0.6.0
|
|
112
|
+
- @backstage/plugin-catalog@0.7.9
|
|
113
|
+
- @backstage/plugin-catalog-react@0.6.12
|
|
114
|
+
- @backstage/config@0.1.13
|
|
115
|
+
- @backstage/catalog-model@0.9.10
|
|
116
|
+
- @backstage/integration-react@0.1.19
|
|
117
|
+
|
|
118
|
+
## 0.12.15-next.0
|
|
119
|
+
|
|
120
|
+
### Patch Changes
|
|
121
|
+
|
|
122
|
+
- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods.
|
|
123
|
+
- 29710c91c2: use lighter color for block quotes and horizontal rulers
|
|
124
|
+
- Updated dependencies
|
|
125
|
+
- @backstage/core-components@0.8.5-next.0
|
|
126
|
+
- @backstage/core-plugin-api@0.6.0-next.0
|
|
127
|
+
- @backstage/plugin-catalog@0.7.9-next.0
|
|
128
|
+
- @backstage/config@0.1.13-next.0
|
|
129
|
+
- @backstage/plugin-catalog-react@0.6.12-next.0
|
|
130
|
+
- @backstage/plugin-search@0.5.6-next.0
|
|
131
|
+
- @backstage/catalog-model@0.9.10-next.0
|
|
132
|
+
- @backstage/integration-react@0.1.19-next.0
|
|
133
|
+
- @backstage/integration@0.7.2-next.0
|
|
134
|
+
|
|
3
135
|
## 0.12.14
|
|
4
136
|
|
|
5
137
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
3
|
-
import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';
|
|
3
|
+
import { DiscoveryApi, FetchApi, IdentityApi } from '@backstage/core-plugin-api';
|
|
4
4
|
import * as _backstage_catalog_model from '@backstage/catalog-model';
|
|
5
5
|
import { Entity, LocationSpec, EntityName } from '@backstage/catalog-model';
|
|
6
6
|
import { Config } from '@backstage/config';
|
|
@@ -19,10 +19,33 @@ declare type TechDocsEntityMetadata = Entity & {
|
|
|
19
19
|
locationMetadata?: LocationSpec;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Utility API reference for the {@link TechDocsStorageApi}.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
22
27
|
declare const techdocsStorageApiRef: _backstage_core_plugin_api.ApiRef<TechDocsStorageApi>;
|
|
28
|
+
/**
|
|
29
|
+
* Utility API reference for the {@link TechDocsApi}.
|
|
30
|
+
*
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
23
33
|
declare const techdocsApiRef: _backstage_core_plugin_api.ApiRef<TechDocsApi>;
|
|
34
|
+
/**
|
|
35
|
+
* The outcome of a docs sync operation.
|
|
36
|
+
*
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
24
39
|
declare type SyncResult = 'cached' | 'updated';
|
|
40
|
+
/**
|
|
41
|
+
* API which talks to TechDocs storage to fetch files to render.
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
25
45
|
interface TechDocsStorageApi {
|
|
46
|
+
/**
|
|
47
|
+
* Set to techdocs.requestUrl as the URL for techdocs-backend API.
|
|
48
|
+
*/
|
|
26
49
|
getApiOrigin(): Promise<string>;
|
|
27
50
|
getStorageUrl(): Promise<string>;
|
|
28
51
|
getBuilder(): Promise<string>;
|
|
@@ -30,7 +53,15 @@ interface TechDocsStorageApi {
|
|
|
30
53
|
syncEntityDocs(entityId: EntityName, logHandler?: (line: string) => void): Promise<SyncResult>;
|
|
31
54
|
getBaseUrl(oldBaseUrl: string, entityId: EntityName, path: string): Promise<string>;
|
|
32
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* API to talk to techdocs-backend.
|
|
58
|
+
*
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
33
61
|
interface TechDocsApi {
|
|
62
|
+
/**
|
|
63
|
+
* Set to techdocs.requestUrl as the URL for techdocs-backend API.
|
|
64
|
+
*/
|
|
34
65
|
getApiOrigin(): Promise<string>;
|
|
35
66
|
getTechDocsMetadata(entityId: EntityName): Promise<TechDocsMetadata>;
|
|
36
67
|
getEntityMetadata(entityId: EntityName): Promise<TechDocsEntityMetadata>;
|
|
@@ -38,15 +69,17 @@ interface TechDocsApi {
|
|
|
38
69
|
|
|
39
70
|
/**
|
|
40
71
|
* API to talk to `techdocs-backend`.
|
|
72
|
+
*
|
|
73
|
+
* @public
|
|
41
74
|
*/
|
|
42
75
|
declare class TechDocsClient implements TechDocsApi {
|
|
43
76
|
configApi: Config;
|
|
44
77
|
discoveryApi: DiscoveryApi;
|
|
45
|
-
|
|
46
|
-
constructor(
|
|
78
|
+
private fetchApi;
|
|
79
|
+
constructor(options: {
|
|
47
80
|
configApi: Config;
|
|
48
81
|
discoveryApi: DiscoveryApi;
|
|
49
|
-
|
|
82
|
+
fetchApi: FetchApi;
|
|
50
83
|
});
|
|
51
84
|
getApiOrigin(): Promise<string>;
|
|
52
85
|
/**
|
|
@@ -71,15 +104,19 @@ declare class TechDocsClient implements TechDocsApi {
|
|
|
71
104
|
}
|
|
72
105
|
/**
|
|
73
106
|
* API which talks to TechDocs storage to fetch files to render.
|
|
107
|
+
*
|
|
108
|
+
* @public
|
|
74
109
|
*/
|
|
75
110
|
declare class TechDocsStorageClient implements TechDocsStorageApi {
|
|
76
111
|
configApi: Config;
|
|
77
112
|
discoveryApi: DiscoveryApi;
|
|
78
113
|
identityApi: IdentityApi;
|
|
79
|
-
|
|
114
|
+
private fetchApi;
|
|
115
|
+
constructor(options: {
|
|
80
116
|
configApi: Config;
|
|
81
117
|
discoveryApi: DiscoveryApi;
|
|
82
118
|
identityApi: IdentityApi;
|
|
119
|
+
fetchApi: FetchApi;
|
|
83
120
|
});
|
|
84
121
|
getApiOrigin(): Promise<string>;
|
|
85
122
|
getStorageUrl(): Promise<string>;
|
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createApiRef, createRouteRef, useRouteRef, useApi, configApiRef, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, createRoutableExtension, createComponentExtension } from '@backstage/core-plugin-api';
|
|
1
|
+
import { createApiRef, createRouteRef, useRouteRef, useApi, configApiRef, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, fetchApiRef, createRoutableExtension, createComponentExtension } from '@backstage/core-plugin-api';
|
|
2
2
|
import { ResponseError, NotFoundError } from '@backstage/errors';
|
|
3
3
|
import { EventSourcePolyfill } from 'event-source-polyfill';
|
|
4
4
|
import React, { useEffect, useState, useReducer, useRef, useMemo, createContext, useContext, useCallback } from 'react';
|
|
@@ -37,14 +37,10 @@ const techdocsApiRef = createApiRef({
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
class TechDocsClient {
|
|
40
|
-
constructor({
|
|
41
|
-
configApi
|
|
42
|
-
discoveryApi
|
|
43
|
-
|
|
44
|
-
}) {
|
|
45
|
-
this.configApi = configApi;
|
|
46
|
-
this.discoveryApi = discoveryApi;
|
|
47
|
-
this.identityApi = identityApi;
|
|
40
|
+
constructor(options) {
|
|
41
|
+
this.configApi = options.configApi;
|
|
42
|
+
this.discoveryApi = options.discoveryApi;
|
|
43
|
+
this.fetchApi = options.fetchApi;
|
|
48
44
|
}
|
|
49
45
|
async getApiOrigin() {
|
|
50
46
|
var _a;
|
|
@@ -54,10 +50,7 @@ class TechDocsClient {
|
|
|
54
50
|
const { kind, namespace, name } = entityId;
|
|
55
51
|
const apiOrigin = await this.getApiOrigin();
|
|
56
52
|
const requestUrl = `${apiOrigin}/metadata/techdocs/${namespace}/${kind}/${name}`;
|
|
57
|
-
const
|
|
58
|
-
const request = await fetch(`${requestUrl}`, {
|
|
59
|
-
headers: token ? { Authorization: `Bearer ${token}` } : {}
|
|
60
|
-
});
|
|
53
|
+
const request = await this.fetchApi.fetch(`${requestUrl}`);
|
|
61
54
|
if (!request.ok) {
|
|
62
55
|
throw await ResponseError.fromResponse(request);
|
|
63
56
|
}
|
|
@@ -67,10 +60,7 @@ class TechDocsClient {
|
|
|
67
60
|
const { kind, namespace, name } = entityId;
|
|
68
61
|
const apiOrigin = await this.getApiOrigin();
|
|
69
62
|
const requestUrl = `${apiOrigin}/metadata/entity/${namespace}/${kind}/${name}`;
|
|
70
|
-
const
|
|
71
|
-
const request = await fetch(`${requestUrl}`, {
|
|
72
|
-
headers: token ? { Authorization: `Bearer ${token}` } : {}
|
|
73
|
-
});
|
|
63
|
+
const request = await this.fetchApi.fetch(`${requestUrl}`);
|
|
74
64
|
if (!request.ok) {
|
|
75
65
|
throw await ResponseError.fromResponse(request);
|
|
76
66
|
}
|
|
@@ -78,14 +68,11 @@ class TechDocsClient {
|
|
|
78
68
|
}
|
|
79
69
|
}
|
|
80
70
|
class TechDocsStorageClient {
|
|
81
|
-
constructor({
|
|
82
|
-
configApi
|
|
83
|
-
discoveryApi
|
|
84
|
-
identityApi
|
|
85
|
-
|
|
86
|
-
this.configApi = configApi;
|
|
87
|
-
this.discoveryApi = discoveryApi;
|
|
88
|
-
this.identityApi = identityApi;
|
|
71
|
+
constructor(options) {
|
|
72
|
+
this.configApi = options.configApi;
|
|
73
|
+
this.discoveryApi = options.discoveryApi;
|
|
74
|
+
this.identityApi = options.identityApi;
|
|
75
|
+
this.fetchApi = options.fetchApi;
|
|
89
76
|
}
|
|
90
77
|
async getApiOrigin() {
|
|
91
78
|
var _a;
|
|
@@ -102,10 +89,7 @@ class TechDocsStorageClient {
|
|
|
102
89
|
const { kind, namespace, name } = entityId;
|
|
103
90
|
const storageUrl = await this.getStorageUrl();
|
|
104
91
|
const url = `${storageUrl}/${namespace}/${kind}/${name}/${path}`;
|
|
105
|
-
const
|
|
106
|
-
const request = await fetch(`${url.endsWith("/") ? url : `${url}/`}index.html`, {
|
|
107
|
-
headers: token ? { Authorization: `Bearer ${token}` } : {}
|
|
108
|
-
});
|
|
92
|
+
const request = await this.fetchApi.fetch(`${url.endsWith("/") ? url : `${url}/`}index.html`);
|
|
109
93
|
let errorMessage = "";
|
|
110
94
|
switch (request.status) {
|
|
111
95
|
case 404:
|
|
@@ -125,7 +109,7 @@ class TechDocsStorageClient {
|
|
|
125
109
|
const { kind, namespace, name } = entityId;
|
|
126
110
|
const apiOrigin = await this.getApiOrigin();
|
|
127
111
|
const url = `${apiOrigin}/sync/${namespace}/${kind}/${name}`;
|
|
128
|
-
const token = await this.identityApi.
|
|
112
|
+
const { token } = await this.identityApi.getCredentials();
|
|
129
113
|
return new Promise((resolve, reject) => {
|
|
130
114
|
const source = new EventSourcePolyfill(url, {
|
|
131
115
|
withCredentials: true,
|
|
@@ -495,12 +479,14 @@ const techdocsPlugin = createPlugin({
|
|
|
495
479
|
deps: {
|
|
496
480
|
configApi: configApiRef,
|
|
497
481
|
discoveryApi: discoveryApiRef,
|
|
498
|
-
identityApi: identityApiRef
|
|
482
|
+
identityApi: identityApiRef,
|
|
483
|
+
fetchApi: fetchApiRef
|
|
499
484
|
},
|
|
500
|
-
factory: ({ configApi, discoveryApi, identityApi }) => new TechDocsStorageClient({
|
|
485
|
+
factory: ({ configApi, discoveryApi, identityApi, fetchApi }) => new TechDocsStorageClient({
|
|
501
486
|
configApi,
|
|
502
487
|
discoveryApi,
|
|
503
|
-
identityApi
|
|
488
|
+
identityApi,
|
|
489
|
+
fetchApi
|
|
504
490
|
})
|
|
505
491
|
}),
|
|
506
492
|
createApiFactory({
|
|
@@ -508,12 +494,12 @@ const techdocsPlugin = createPlugin({
|
|
|
508
494
|
deps: {
|
|
509
495
|
configApi: configApiRef,
|
|
510
496
|
discoveryApi: discoveryApiRef,
|
|
511
|
-
|
|
497
|
+
fetchApi: fetchApiRef
|
|
512
498
|
},
|
|
513
|
-
factory: ({ configApi, discoveryApi,
|
|
499
|
+
factory: ({ configApi, discoveryApi, fetchApi }) => new TechDocsClient({
|
|
514
500
|
configApi,
|
|
515
501
|
discoveryApi,
|
|
516
|
-
|
|
502
|
+
fetchApi
|
|
517
503
|
})
|
|
518
504
|
})
|
|
519
505
|
],
|
|
@@ -598,6 +584,7 @@ const addBaseUrl = ({
|
|
|
598
584
|
await Promise.all([
|
|
599
585
|
updateDom(dom.querySelectorAll("img"), "src"),
|
|
600
586
|
updateDom(dom.querySelectorAll("script"), "src"),
|
|
587
|
+
updateDom(dom.querySelectorAll("source"), "src"),
|
|
601
588
|
updateDom(dom.querySelectorAll("link"), "href"),
|
|
602
589
|
updateDom(dom.querySelectorAll("a[download]"), "href")
|
|
603
590
|
]);
|
|
@@ -696,6 +683,22 @@ const addLinkClickListener = ({
|
|
|
696
683
|
};
|
|
697
684
|
};
|
|
698
685
|
|
|
686
|
+
const copyToClipboard = () => {
|
|
687
|
+
return (dom) => {
|
|
688
|
+
Array.from(dom.querySelectorAll("code")).forEach((codeElem) => {
|
|
689
|
+
var _a;
|
|
690
|
+
const button = document.createElement("button");
|
|
691
|
+
const toBeCopied = codeElem.textContent || "";
|
|
692
|
+
button.className = "md-clipboard md-icon";
|
|
693
|
+
button.title = "Copy to clipboard";
|
|
694
|
+
button.innerHTML = '<svg viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg>';
|
|
695
|
+
button.addEventListener("click", () => navigator.clipboard.writeText(toBeCopied));
|
|
696
|
+
(_a = codeElem == null ? void 0 : codeElem.parentElement) == null ? void 0 : _a.prepend(button);
|
|
697
|
+
});
|
|
698
|
+
return dom;
|
|
699
|
+
};
|
|
700
|
+
};
|
|
701
|
+
|
|
699
702
|
const removeMkdocsHeader = () => {
|
|
700
703
|
return (dom) => {
|
|
701
704
|
var _a;
|
|
@@ -1330,6 +1333,8 @@ const useTechDocsReaderDom = (entityRef) => {
|
|
|
1330
1333
|
|
|
1331
1334
|
--md-code-fg-color: ${theme.palette.text.primary};
|
|
1332
1335
|
--md-code-bg-color: ${theme.palette.background.paper};
|
|
1336
|
+
--md-accent-fg-color: ${theme.palette.primary.main};
|
|
1337
|
+
--md-default-fg-color--lightest: ${theme.palette.textVerySubtle};
|
|
1333
1338
|
}
|
|
1334
1339
|
.md-main__inner { margin-top: 0; }
|
|
1335
1340
|
.md-sidebar { position: fixed; bottom: 100px; width: 20rem; }
|
|
@@ -1342,6 +1347,13 @@ const useTechDocsReaderDom = (entityRef) => {
|
|
|
1342
1347
|
.md-typeset h1, .md-typeset h2, .md-typeset h3 { font-weight: bold; }
|
|
1343
1348
|
.md-nav { font-size: 1rem; }
|
|
1344
1349
|
.md-grid { max-width: 90vw; margin: 0 }
|
|
1350
|
+
.md-typeset blockquote {
|
|
1351
|
+
color: ${theme.palette.textSubtle};
|
|
1352
|
+
border-left: 0.2rem solid ${theme.palette.textVerySubtle};
|
|
1353
|
+
}
|
|
1354
|
+
.md-typeset hr {
|
|
1355
|
+
border-bottom: 0.05rem dotted ${theme.palette.textVerySubtle};
|
|
1356
|
+
}
|
|
1345
1357
|
.md-typeset table:not([class]) {
|
|
1346
1358
|
font-size: 1rem;
|
|
1347
1359
|
border: 1px solid ${theme.palette.text.primary};
|
|
@@ -1452,11 +1464,14 @@ const useTechDocsReaderDom = (entityRef) => {
|
|
|
1452
1464
|
theme.palette.primary.main,
|
|
1453
1465
|
theme.palette.success.main,
|
|
1454
1466
|
theme.palette.text.primary,
|
|
1467
|
+
theme.palette.textSubtle,
|
|
1468
|
+
theme.palette.textVerySubtle,
|
|
1455
1469
|
theme.typography.fontFamily,
|
|
1456
1470
|
isPinned
|
|
1457
1471
|
]);
|
|
1458
1472
|
const postRender = useCallback(async (transformedElement) => transform(transformedElement, [
|
|
1459
1473
|
scrollIntoAnchor(),
|
|
1474
|
+
copyToClipboard(),
|
|
1460
1475
|
addLinkClickListener({
|
|
1461
1476
|
baseUrl: window.location.origin,
|
|
1462
1477
|
onClick: (event, url) => {
|