@backstage/plugin-techdocs-react 0.0.0-nightly-20220413023505
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 +34 -0
- package/README.md +9 -0
- package/alpha/package.json +6 -0
- package/dist/index.alpha.d.ts +199 -0
- package/dist/index.beta.d.ts +122 -0
- package/dist/index.d.ts +122 -0
- package/dist/index.esm.js +173 -0
- package/dist/index.esm.js.map +1 -0
- package/package.json +65 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# @backstage/plugin-techdocs-react
|
|
2
|
+
|
|
3
|
+
## 0.0.0-nightly-20220413023505
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ff1cc8bced: This package will house frontend utilities related to TechDocs to be shared across other frontend Backstage packages.
|
|
8
|
+
|
|
9
|
+
In this release, it introduces a framework that can be used create TechDocs addons.
|
|
10
|
+
|
|
11
|
+
Note: this package is not necessarily stable yet. After iteration on this package, its stability will be signaled by a major-version bump.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
- @backstage/catalog-model@0.0.0-nightly-20220413023505
|
|
17
|
+
- @backstage/core-components@0.0.0-nightly-20220413023505
|
|
18
|
+
- @backstage/core-plugin-api@0.0.0-nightly-20220413023505
|
|
19
|
+
|
|
20
|
+
## 0.1.0-next.0
|
|
21
|
+
|
|
22
|
+
### Minor Changes
|
|
23
|
+
|
|
24
|
+
- ff1cc8bced: This package will house frontend utilities related to TechDocs to be shared across other frontend Backstage packages.
|
|
25
|
+
|
|
26
|
+
In this release, it introduces a framework that can be used create TechDocs addons.
|
|
27
|
+
|
|
28
|
+
Note: this package is not necessarily stable yet. After iteration on this package, its stability will be signaled by a major-version bump.
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- Updated dependencies
|
|
33
|
+
- @backstage/core-components@0.9.3-next.2
|
|
34
|
+
- @backstage/core-plugin-api@1.0.1-next.0
|
package/README.md
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package encapsulating utilities to be shared by frontend TechDocs plugins.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ApiRef } from '@backstage/core-plugin-api';
|
|
8
|
+
import { AsyncState } from 'react-use/lib/useAsync';
|
|
9
|
+
import { ComponentType } from 'react';
|
|
10
|
+
import { CompoundEntityRef } from '@backstage/catalog-model';
|
|
11
|
+
import { Dispatch } from 'react';
|
|
12
|
+
import { Entity } from '@backstage/catalog-model';
|
|
13
|
+
import { Extension } from '@backstage/core-plugin-api';
|
|
14
|
+
import { default as React_2 } from 'react';
|
|
15
|
+
import { ReactNode } from 'react';
|
|
16
|
+
import { SetStateAction } from 'react';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Create a TechDocs addon.
|
|
20
|
+
* @alpha
|
|
21
|
+
*/
|
|
22
|
+
export declare function createTechDocsAddonExtension<TComponentProps>(options: TechDocsAddonOptions<TComponentProps>): Extension<ComponentType<TComponentProps>>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @alpha
|
|
26
|
+
*/
|
|
27
|
+
export declare const defaultTechDocsReaderPageValue: TechDocsReaderPageValue;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Marks the <TechDocsAddons> registry component.
|
|
31
|
+
* @alpha
|
|
32
|
+
*/
|
|
33
|
+
export declare const TECHDOCS_ADDONS_WRAPPER_KEY = "techdocs.addons.wrapper.v1";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Locations for which TechDocs addons may be declared and rendered.
|
|
37
|
+
* @alpha
|
|
38
|
+
*/
|
|
39
|
+
export declare const TechDocsAddonLocations: Readonly<{
|
|
40
|
+
/**
|
|
41
|
+
* These addons fill up the header from the right, on the same line as the
|
|
42
|
+
* title.
|
|
43
|
+
*/
|
|
44
|
+
readonly Header: "Header";
|
|
45
|
+
/**
|
|
46
|
+
* These addons appear below the header and above all content; tooling addons
|
|
47
|
+
* can be inserted for convenience.
|
|
48
|
+
*/
|
|
49
|
+
readonly Subheader: "Subheader";
|
|
50
|
+
/**
|
|
51
|
+
* These addons appear left of the content and above the navigation.
|
|
52
|
+
*/
|
|
53
|
+
readonly PrimarySidebar: "PrimarySidebar";
|
|
54
|
+
/**
|
|
55
|
+
* These addons appear right of the content and above the table of contents.
|
|
56
|
+
*/
|
|
57
|
+
readonly SecondarySidebar: "SecondarySidebar";
|
|
58
|
+
/**
|
|
59
|
+
* A virtual location which allows mutation of all content within the shadow
|
|
60
|
+
* root by transforming DOM nodes. These addons should return null on render.
|
|
61
|
+
*/
|
|
62
|
+
readonly Content: "Content";
|
|
63
|
+
}>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Options for creating a TechDocs addon.
|
|
67
|
+
* @alpha
|
|
68
|
+
*/
|
|
69
|
+
export declare type TechDocsAddonOptions<TAddonProps = {}> = {
|
|
70
|
+
name: string;
|
|
71
|
+
location: keyof typeof TechDocsAddonLocations;
|
|
72
|
+
component: ComponentType<TAddonProps>;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* TechDocs Addon registry.
|
|
77
|
+
* @alpha
|
|
78
|
+
*/
|
|
79
|
+
export declare const TechDocsAddons: React_2.ComponentType;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* API to talk to techdocs-backend.
|
|
83
|
+
*
|
|
84
|
+
* @public
|
|
85
|
+
*/
|
|
86
|
+
export declare interface TechDocsApi {
|
|
87
|
+
getApiOrigin(): Promise<string>;
|
|
88
|
+
getTechDocsMetadata(entityId: CompoundEntityRef): Promise<TechDocsMetadata>;
|
|
89
|
+
getEntityMetadata(entityId: CompoundEntityRef): Promise<TechDocsEntityMetadata>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Utility API reference for the {@link TechDocsApi}.
|
|
94
|
+
*
|
|
95
|
+
* @public
|
|
96
|
+
*/
|
|
97
|
+
export declare const techdocsApiRef: ApiRef<TechDocsApi>;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Metadata for TechDocs Entity
|
|
101
|
+
*
|
|
102
|
+
* @public
|
|
103
|
+
*/
|
|
104
|
+
export declare type TechDocsEntityMetadata = Entity & {
|
|
105
|
+
locationMetadata?: {
|
|
106
|
+
type: string;
|
|
107
|
+
target: string;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Metadata for TechDocs page
|
|
113
|
+
*
|
|
114
|
+
* @public
|
|
115
|
+
*/
|
|
116
|
+
export declare type TechDocsMetadata = {
|
|
117
|
+
site_name: string;
|
|
118
|
+
site_description: string;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* A context to store the reader page state
|
|
123
|
+
* @public
|
|
124
|
+
*/
|
|
125
|
+
export declare const TechDocsReaderPageProvider: React_2.MemoExoticComponent<({ entityRef, children }: TechDocsReaderPageProviderProps) => JSX.Element>;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Props for {@link TechDocsReaderPageProvider}
|
|
129
|
+
*
|
|
130
|
+
* @public
|
|
131
|
+
*/
|
|
132
|
+
export declare type TechDocsReaderPageProviderProps = {
|
|
133
|
+
entityRef: CompoundEntityRef;
|
|
134
|
+
children: TechDocsReaderPageProviderRenderFunction | ReactNode;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* render function for {@link TechDocsReaderPageProvider}
|
|
139
|
+
*
|
|
140
|
+
* @public
|
|
141
|
+
*/
|
|
142
|
+
export declare type TechDocsReaderPageProviderRenderFunction = (value: TechDocsReaderPageValue) => JSX.Element;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @public type for the value of the TechDocsReaderPageContext
|
|
146
|
+
*/
|
|
147
|
+
export declare type TechDocsReaderPageValue = {
|
|
148
|
+
metadata: AsyncState<TechDocsMetadata>;
|
|
149
|
+
entityRef: CompoundEntityRef;
|
|
150
|
+
entityMetadata: AsyncState<TechDocsEntityMetadata>;
|
|
151
|
+
shadowRoot?: ShadowRoot;
|
|
152
|
+
setShadowRoot: Dispatch<SetStateAction<ShadowRoot | undefined>>;
|
|
153
|
+
title: string;
|
|
154
|
+
setTitle: Dispatch<SetStateAction<string>>;
|
|
155
|
+
subtitle: string;
|
|
156
|
+
setSubtitle: Dispatch<SetStateAction<string>>;
|
|
157
|
+
/**
|
|
158
|
+
* @deprecated property can be passed down directly to the `TechDocsReaderPageContent` instead.
|
|
159
|
+
*/
|
|
160
|
+
onReady?: () => void;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Hook for use within TechDocs addons that provides access to the underlying
|
|
165
|
+
* shadow root of the current page, allowing the DOM within to be mutated.
|
|
166
|
+
* @alpha
|
|
167
|
+
*/
|
|
168
|
+
export declare const useShadowRoot: () => ShadowRoot | undefined;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Convenience hook for use within TechDocs addons that provides access to
|
|
172
|
+
* elements that match a given selector within the shadow root.
|
|
173
|
+
*
|
|
174
|
+
* @alpha
|
|
175
|
+
*/
|
|
176
|
+
export declare const useShadowRootElements: <TReturnedElement extends HTMLElement = HTMLElement>(selectors: string[]) => TReturnedElement[];
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Hook for retreiving a selection within the ShadowRoot.
|
|
180
|
+
* @alpha
|
|
181
|
+
*/
|
|
182
|
+
export declare const useShadowRootSelection: (wait?: number) => Selection | null;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* hook to use addons in components
|
|
186
|
+
* @alpha
|
|
187
|
+
*/
|
|
188
|
+
export declare const useTechDocsAddons: () => {
|
|
189
|
+
renderComponentByName: (name: string) => JSX.Element | null;
|
|
190
|
+
renderComponentsByLocation: (location: keyof typeof TechDocsAddonLocations) => (JSX.Element | null)[] | null;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Hook used to get access to shared state between reader page components.
|
|
195
|
+
* @alpha
|
|
196
|
+
*/
|
|
197
|
+
export declare const useTechDocsReaderPage: () => TechDocsReaderPageValue;
|
|
198
|
+
|
|
199
|
+
export { }
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package encapsulating utilities to be shared by frontend TechDocs plugins.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ApiRef } from '@backstage/core-plugin-api';
|
|
8
|
+
import { AsyncState } from 'react-use/lib/useAsync';
|
|
9
|
+
import { ComponentType } from 'react';
|
|
10
|
+
import { CompoundEntityRef } from '@backstage/catalog-model';
|
|
11
|
+
import { Dispatch } from 'react';
|
|
12
|
+
import { Entity } from '@backstage/catalog-model';
|
|
13
|
+
import { Extension } from '@backstage/core-plugin-api';
|
|
14
|
+
import { default as React_2 } from 'react';
|
|
15
|
+
import { ReactNode } from 'react';
|
|
16
|
+
import { SetStateAction } from 'react';
|
|
17
|
+
|
|
18
|
+
/* Excluded from this release type: createTechDocsAddonExtension */
|
|
19
|
+
|
|
20
|
+
/* Excluded from this release type: defaultTechDocsReaderPageValue */
|
|
21
|
+
|
|
22
|
+
/* Excluded from this release type: TECHDOCS_ADDONS_WRAPPER_KEY */
|
|
23
|
+
|
|
24
|
+
/* Excluded from this release type: TechDocsAddonLocations */
|
|
25
|
+
|
|
26
|
+
/* Excluded from this release type: TechDocsAddonOptions */
|
|
27
|
+
|
|
28
|
+
/* Excluded from this release type: TechDocsAddons */
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* API to talk to techdocs-backend.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
export declare interface TechDocsApi {
|
|
36
|
+
getApiOrigin(): Promise<string>;
|
|
37
|
+
getTechDocsMetadata(entityId: CompoundEntityRef): Promise<TechDocsMetadata>;
|
|
38
|
+
getEntityMetadata(entityId: CompoundEntityRef): Promise<TechDocsEntityMetadata>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Utility API reference for the {@link TechDocsApi}.
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export declare const techdocsApiRef: ApiRef<TechDocsApi>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Metadata for TechDocs Entity
|
|
50
|
+
*
|
|
51
|
+
* @public
|
|
52
|
+
*/
|
|
53
|
+
export declare type TechDocsEntityMetadata = Entity & {
|
|
54
|
+
locationMetadata?: {
|
|
55
|
+
type: string;
|
|
56
|
+
target: string;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Metadata for TechDocs page
|
|
62
|
+
*
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export declare type TechDocsMetadata = {
|
|
66
|
+
site_name: string;
|
|
67
|
+
site_description: string;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A context to store the reader page state
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
export declare const TechDocsReaderPageProvider: React_2.MemoExoticComponent<({ entityRef, children }: TechDocsReaderPageProviderProps) => JSX.Element>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Props for {@link TechDocsReaderPageProvider}
|
|
78
|
+
*
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
81
|
+
export declare type TechDocsReaderPageProviderProps = {
|
|
82
|
+
entityRef: CompoundEntityRef;
|
|
83
|
+
children: TechDocsReaderPageProviderRenderFunction | ReactNode;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* render function for {@link TechDocsReaderPageProvider}
|
|
88
|
+
*
|
|
89
|
+
* @public
|
|
90
|
+
*/
|
|
91
|
+
export declare type TechDocsReaderPageProviderRenderFunction = (value: TechDocsReaderPageValue) => JSX.Element;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @public type for the value of the TechDocsReaderPageContext
|
|
95
|
+
*/
|
|
96
|
+
export declare type TechDocsReaderPageValue = {
|
|
97
|
+
metadata: AsyncState<TechDocsMetadata>;
|
|
98
|
+
entityRef: CompoundEntityRef;
|
|
99
|
+
entityMetadata: AsyncState<TechDocsEntityMetadata>;
|
|
100
|
+
shadowRoot?: ShadowRoot;
|
|
101
|
+
setShadowRoot: Dispatch<SetStateAction<ShadowRoot | undefined>>;
|
|
102
|
+
title: string;
|
|
103
|
+
setTitle: Dispatch<SetStateAction<string>>;
|
|
104
|
+
subtitle: string;
|
|
105
|
+
setSubtitle: Dispatch<SetStateAction<string>>;
|
|
106
|
+
/**
|
|
107
|
+
* @deprecated property can be passed down directly to the `TechDocsReaderPageContent` instead.
|
|
108
|
+
*/
|
|
109
|
+
onReady?: () => void;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/* Excluded from this release type: useShadowRoot */
|
|
113
|
+
|
|
114
|
+
/* Excluded from this release type: useShadowRootElements */
|
|
115
|
+
|
|
116
|
+
/* Excluded from this release type: useShadowRootSelection */
|
|
117
|
+
|
|
118
|
+
/* Excluded from this release type: useTechDocsAddons */
|
|
119
|
+
|
|
120
|
+
/* Excluded from this release type: useTechDocsReaderPage */
|
|
121
|
+
|
|
122
|
+
export { }
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package encapsulating utilities to be shared by frontend TechDocs plugins.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ApiRef } from '@backstage/core-plugin-api';
|
|
8
|
+
import { AsyncState } from 'react-use/lib/useAsync';
|
|
9
|
+
import { ComponentType } from 'react';
|
|
10
|
+
import { CompoundEntityRef } from '@backstage/catalog-model';
|
|
11
|
+
import { Dispatch } from 'react';
|
|
12
|
+
import { Entity } from '@backstage/catalog-model';
|
|
13
|
+
import { Extension } from '@backstage/core-plugin-api';
|
|
14
|
+
import { default as React_2 } from 'react';
|
|
15
|
+
import { ReactNode } from 'react';
|
|
16
|
+
import { SetStateAction } from 'react';
|
|
17
|
+
|
|
18
|
+
/* Excluded from this release type: createTechDocsAddonExtension */
|
|
19
|
+
|
|
20
|
+
/* Excluded from this release type: defaultTechDocsReaderPageValue */
|
|
21
|
+
|
|
22
|
+
/* Excluded from this release type: TECHDOCS_ADDONS_WRAPPER_KEY */
|
|
23
|
+
|
|
24
|
+
/* Excluded from this release type: TechDocsAddonLocations */
|
|
25
|
+
|
|
26
|
+
/* Excluded from this release type: TechDocsAddonOptions */
|
|
27
|
+
|
|
28
|
+
/* Excluded from this release type: TechDocsAddons */
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* API to talk to techdocs-backend.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
export declare interface TechDocsApi {
|
|
36
|
+
getApiOrigin(): Promise<string>;
|
|
37
|
+
getTechDocsMetadata(entityId: CompoundEntityRef): Promise<TechDocsMetadata>;
|
|
38
|
+
getEntityMetadata(entityId: CompoundEntityRef): Promise<TechDocsEntityMetadata>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Utility API reference for the {@link TechDocsApi}.
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export declare const techdocsApiRef: ApiRef<TechDocsApi>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Metadata for TechDocs Entity
|
|
50
|
+
*
|
|
51
|
+
* @public
|
|
52
|
+
*/
|
|
53
|
+
export declare type TechDocsEntityMetadata = Entity & {
|
|
54
|
+
locationMetadata?: {
|
|
55
|
+
type: string;
|
|
56
|
+
target: string;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Metadata for TechDocs page
|
|
62
|
+
*
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export declare type TechDocsMetadata = {
|
|
66
|
+
site_name: string;
|
|
67
|
+
site_description: string;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A context to store the reader page state
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
export declare const TechDocsReaderPageProvider: React_2.MemoExoticComponent<({ entityRef, children }: TechDocsReaderPageProviderProps) => JSX.Element>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Props for {@link TechDocsReaderPageProvider}
|
|
78
|
+
*
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
81
|
+
export declare type TechDocsReaderPageProviderProps = {
|
|
82
|
+
entityRef: CompoundEntityRef;
|
|
83
|
+
children: TechDocsReaderPageProviderRenderFunction | ReactNode;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* render function for {@link TechDocsReaderPageProvider}
|
|
88
|
+
*
|
|
89
|
+
* @public
|
|
90
|
+
*/
|
|
91
|
+
export declare type TechDocsReaderPageProviderRenderFunction = (value: TechDocsReaderPageValue) => JSX.Element;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @public type for the value of the TechDocsReaderPageContext
|
|
95
|
+
*/
|
|
96
|
+
export declare type TechDocsReaderPageValue = {
|
|
97
|
+
metadata: AsyncState<TechDocsMetadata>;
|
|
98
|
+
entityRef: CompoundEntityRef;
|
|
99
|
+
entityMetadata: AsyncState<TechDocsEntityMetadata>;
|
|
100
|
+
shadowRoot?: ShadowRoot;
|
|
101
|
+
setShadowRoot: Dispatch<SetStateAction<ShadowRoot | undefined>>;
|
|
102
|
+
title: string;
|
|
103
|
+
setTitle: Dispatch<SetStateAction<string>>;
|
|
104
|
+
subtitle: string;
|
|
105
|
+
setSubtitle: Dispatch<SetStateAction<string>>;
|
|
106
|
+
/**
|
|
107
|
+
* @deprecated property can be passed down directly to the `TechDocsReaderPageContent` instead.
|
|
108
|
+
*/
|
|
109
|
+
onReady?: () => void;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/* Excluded from this release type: useShadowRoot */
|
|
113
|
+
|
|
114
|
+
/* Excluded from this release type: useShadowRootElements */
|
|
115
|
+
|
|
116
|
+
/* Excluded from this release type: useShadowRootSelection */
|
|
117
|
+
|
|
118
|
+
/* Excluded from this release type: useTechDocsAddons */
|
|
119
|
+
|
|
120
|
+
/* Excluded from this release type: useTechDocsReaderPage */
|
|
121
|
+
|
|
122
|
+
export { }
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import React, { useCallback, memo, useState, useContext, useMemo, useEffect } from 'react';
|
|
2
|
+
import { useOutlet } from 'react-router-dom';
|
|
3
|
+
import { attachComponentData, createReactExtension, useElementFilter, createApiRef, useApi } from '@backstage/core-plugin-api';
|
|
4
|
+
import useAsync from 'react-use/lib/useAsync';
|
|
5
|
+
import { stringifyEntityRef } from '@backstage/catalog-model';
|
|
6
|
+
import { createVersionedContext, createVersionedValueMap } from '@backstage/version-bridge';
|
|
7
|
+
import debounce from 'lodash/debounce';
|
|
8
|
+
|
|
9
|
+
const TECHDOCS_ADDONS_KEY = "techdocs.addons.addon.v1";
|
|
10
|
+
const TECHDOCS_ADDONS_WRAPPER_KEY = "techdocs.addons.wrapper.v1";
|
|
11
|
+
const TechDocsAddons = () => null;
|
|
12
|
+
attachComponentData(TechDocsAddons, TECHDOCS_ADDONS_WRAPPER_KEY, true);
|
|
13
|
+
const getDataKeyByName = (name) => {
|
|
14
|
+
return `${TECHDOCS_ADDONS_KEY}.${name.toLocaleLowerCase("en-US")}`;
|
|
15
|
+
};
|
|
16
|
+
function createTechDocsAddonExtension(options) {
|
|
17
|
+
const { name, component: TechDocsAddon } = options;
|
|
18
|
+
return createReactExtension({
|
|
19
|
+
name,
|
|
20
|
+
component: {
|
|
21
|
+
sync: (props) => /* @__PURE__ */ React.createElement(TechDocsAddon, {
|
|
22
|
+
...props
|
|
23
|
+
})
|
|
24
|
+
},
|
|
25
|
+
data: {
|
|
26
|
+
[TECHDOCS_ADDONS_KEY]: options,
|
|
27
|
+
[getDataKeyByName(name)]: true
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
const getTechDocsAddonByName = (collection, key) => {
|
|
32
|
+
return collection.selectByComponentData({ key }).getElements()[0];
|
|
33
|
+
};
|
|
34
|
+
const getAllTechDocsAddons = (collection) => {
|
|
35
|
+
return collection.selectByComponentData({
|
|
36
|
+
key: TECHDOCS_ADDONS_WRAPPER_KEY
|
|
37
|
+
}).selectByComponentData({
|
|
38
|
+
key: TECHDOCS_ADDONS_KEY
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
const getAllTechDocsAddonsData = (collection) => {
|
|
42
|
+
return collection.selectByComponentData({
|
|
43
|
+
key: TECHDOCS_ADDONS_WRAPPER_KEY
|
|
44
|
+
}).findComponentData({
|
|
45
|
+
key: TECHDOCS_ADDONS_KEY
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
const useTechDocsAddons = () => {
|
|
49
|
+
const node = useOutlet();
|
|
50
|
+
const collection = useElementFilter(node, getAllTechDocsAddons);
|
|
51
|
+
const options = useElementFilter(node, getAllTechDocsAddonsData);
|
|
52
|
+
const findAddonByData = useCallback((data) => {
|
|
53
|
+
var _a;
|
|
54
|
+
if (!collection || !data)
|
|
55
|
+
return null;
|
|
56
|
+
const nameKey = getDataKeyByName(data.name);
|
|
57
|
+
return (_a = getTechDocsAddonByName(collection, nameKey)) != null ? _a : null;
|
|
58
|
+
}, [collection]);
|
|
59
|
+
const renderComponentByName = useCallback((name) => {
|
|
60
|
+
const data = options.find((option) => option.name === name);
|
|
61
|
+
return data ? findAddonByData(data) : null;
|
|
62
|
+
}, [options, findAddonByData]);
|
|
63
|
+
const renderComponentsByLocation = useCallback((location) => {
|
|
64
|
+
const data = options.filter((option) => option.location === location);
|
|
65
|
+
return data.length ? data.map(findAddonByData) : null;
|
|
66
|
+
}, [options, findAddonByData]);
|
|
67
|
+
return { renderComponentByName, renderComponentsByLocation };
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const techdocsApiRef = createApiRef({
|
|
71
|
+
id: "plugin.techdocs.service"
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const areEntityRefsEqual = (prevEntityRef, nextEntityRef) => {
|
|
75
|
+
return stringifyEntityRef(prevEntityRef) === stringifyEntityRef(nextEntityRef);
|
|
76
|
+
};
|
|
77
|
+
const defaultTechDocsReaderPageValue = {
|
|
78
|
+
title: "",
|
|
79
|
+
subtitle: "",
|
|
80
|
+
setTitle: () => {
|
|
81
|
+
},
|
|
82
|
+
setSubtitle: () => {
|
|
83
|
+
},
|
|
84
|
+
setShadowRoot: () => {
|
|
85
|
+
},
|
|
86
|
+
metadata: { loading: true },
|
|
87
|
+
entityMetadata: { loading: true },
|
|
88
|
+
entityRef: { kind: "", name: "", namespace: "" }
|
|
89
|
+
};
|
|
90
|
+
const TechDocsReaderPageContext = createVersionedContext("techdocs-reader-page-context");
|
|
91
|
+
const TechDocsReaderPageProvider = memo(({ entityRef, children }) => {
|
|
92
|
+
const techdocsApi = useApi(techdocsApiRef);
|
|
93
|
+
const metadata = useAsync(async () => {
|
|
94
|
+
return techdocsApi.getTechDocsMetadata(entityRef);
|
|
95
|
+
}, [entityRef]);
|
|
96
|
+
const entityMetadata = useAsync(async () => {
|
|
97
|
+
return techdocsApi.getEntityMetadata(entityRef);
|
|
98
|
+
}, [entityRef]);
|
|
99
|
+
const [title, setTitle] = useState(defaultTechDocsReaderPageValue.title);
|
|
100
|
+
const [subtitle, setSubtitle] = useState(defaultTechDocsReaderPageValue.subtitle);
|
|
101
|
+
const [shadowRoot, setShadowRoot] = useState(defaultTechDocsReaderPageValue.shadowRoot);
|
|
102
|
+
const value = {
|
|
103
|
+
metadata,
|
|
104
|
+
entityRef,
|
|
105
|
+
entityMetadata,
|
|
106
|
+
shadowRoot,
|
|
107
|
+
setShadowRoot,
|
|
108
|
+
title,
|
|
109
|
+
setTitle,
|
|
110
|
+
subtitle,
|
|
111
|
+
setSubtitle
|
|
112
|
+
};
|
|
113
|
+
const versionedValue = createVersionedValueMap({ 1: value });
|
|
114
|
+
return /* @__PURE__ */ React.createElement(TechDocsReaderPageContext.Provider, {
|
|
115
|
+
value: versionedValue
|
|
116
|
+
}, children instanceof Function ? children(value) : children);
|
|
117
|
+
}, (prevProps, nextProps) => {
|
|
118
|
+
return areEntityRefsEqual(prevProps.entityRef, nextProps.entityRef);
|
|
119
|
+
});
|
|
120
|
+
const useTechDocsReaderPage = () => {
|
|
121
|
+
const versionedContext = useContext(TechDocsReaderPageContext);
|
|
122
|
+
if (versionedContext === void 0) {
|
|
123
|
+
return defaultTechDocsReaderPageValue;
|
|
124
|
+
}
|
|
125
|
+
const context = versionedContext.atVersion(1);
|
|
126
|
+
if (context === void 0) {
|
|
127
|
+
throw new Error("No context found for version 1.");
|
|
128
|
+
}
|
|
129
|
+
return context;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const useShadowRoot = () => {
|
|
133
|
+
const { shadowRoot } = useTechDocsReaderPage();
|
|
134
|
+
return shadowRoot;
|
|
135
|
+
};
|
|
136
|
+
const useShadowRootElements = (selectors) => {
|
|
137
|
+
const shadowRoot = useShadowRoot();
|
|
138
|
+
if (!shadowRoot)
|
|
139
|
+
return [];
|
|
140
|
+
return selectors.map((selector) => shadowRoot == null ? void 0 : shadowRoot.querySelectorAll(selector)).filter((nodeList) => nodeList.length).map((nodeList) => Array.from(nodeList)).flat();
|
|
141
|
+
};
|
|
142
|
+
const isValidSelection = (newSelection) => {
|
|
143
|
+
return newSelection.toString() && newSelection.rangeCount && newSelection.getRangeAt(0).getBoundingClientRect().top;
|
|
144
|
+
};
|
|
145
|
+
const useShadowRootSelection = (wait = 0) => {
|
|
146
|
+
const shadowRoot = useShadowRoot();
|
|
147
|
+
const [selection, setSelection] = useState(null);
|
|
148
|
+
const handleSelectionChange = useMemo(() => debounce(() => {
|
|
149
|
+
const shadowDocument = shadowRoot;
|
|
150
|
+
const newSelection = shadowDocument.getSelection ? shadowDocument.getSelection() : document.getSelection();
|
|
151
|
+
if (newSelection && isValidSelection(newSelection)) {
|
|
152
|
+
setSelection(newSelection);
|
|
153
|
+
} else {
|
|
154
|
+
setSelection(null);
|
|
155
|
+
}
|
|
156
|
+
}, wait), [shadowRoot, setSelection, wait]);
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
window.document.addEventListener("selectionchange", handleSelectionChange);
|
|
159
|
+
return () => window.document.removeEventListener("selectionchange", handleSelectionChange);
|
|
160
|
+
}, [handleSelectionChange]);
|
|
161
|
+
return selection;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const TechDocsAddonLocations = Object.freeze({
|
|
165
|
+
Header: "Header",
|
|
166
|
+
Subheader: "Subheader",
|
|
167
|
+
PrimarySidebar: "PrimarySidebar",
|
|
168
|
+
SecondarySidebar: "SecondarySidebar",
|
|
169
|
+
Content: "Content"
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
export { TECHDOCS_ADDONS_WRAPPER_KEY, TechDocsAddonLocations, TechDocsAddons, TechDocsReaderPageProvider, createTechDocsAddonExtension, defaultTechDocsReaderPageValue, techdocsApiRef, useShadowRoot, useShadowRootElements, useShadowRootSelection, useTechDocsAddons, useTechDocsReaderPage };
|
|
173
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/addons.tsx","../src/api.ts","../src/context.tsx","../src/hooks.ts","../src/types.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { ComponentType, useCallback } from 'react';\nimport { useOutlet } from 'react-router-dom';\n\nimport {\n attachComponentData,\n createReactExtension,\n ElementCollection,\n Extension,\n useElementFilter,\n} from '@backstage/core-plugin-api';\n\nimport { TechDocsAddonLocations, TechDocsAddonOptions } from './types';\n\nexport const TECHDOCS_ADDONS_KEY = 'techdocs.addons.addon.v1';\n\n/**\n * Marks the <TechDocsAddons> registry component.\n * @alpha\n */\nexport const TECHDOCS_ADDONS_WRAPPER_KEY = 'techdocs.addons.wrapper.v1';\n\n/**\n * TechDocs Addon registry.\n * @alpha\n */\nexport const TechDocsAddons: React.ComponentType = () => null;\n\nattachComponentData(TechDocsAddons, TECHDOCS_ADDONS_WRAPPER_KEY, true);\n\nconst getDataKeyByName = (name: string) => {\n return `${TECHDOCS_ADDONS_KEY}.${name.toLocaleLowerCase('en-US')}`;\n};\n\n/**\n * Create a TechDocs addon.\n * @alpha\n */\nexport function createTechDocsAddonExtension<TComponentProps>(\n options: TechDocsAddonOptions<TComponentProps>,\n): Extension<ComponentType<TComponentProps>> {\n const { name, component: TechDocsAddon } = options;\n return createReactExtension({\n name,\n component: {\n sync: (props: TComponentProps) => <TechDocsAddon {...props} />,\n },\n data: {\n [TECHDOCS_ADDONS_KEY]: options,\n [getDataKeyByName(name)]: true,\n },\n });\n}\n\nconst getTechDocsAddonByName = (\n collection: ElementCollection,\n key: string,\n): JSX.Element | undefined => {\n return collection.selectByComponentData({ key }).getElements()[0];\n};\n\nconst getAllTechDocsAddons = (collection: ElementCollection) => {\n return collection\n .selectByComponentData({\n key: TECHDOCS_ADDONS_WRAPPER_KEY,\n })\n .selectByComponentData({\n key: TECHDOCS_ADDONS_KEY,\n });\n};\n\nconst getAllTechDocsAddonsData = (collection: ElementCollection) => {\n return collection\n .selectByComponentData({\n key: TECHDOCS_ADDONS_WRAPPER_KEY,\n })\n .findComponentData<TechDocsAddonOptions>({\n key: TECHDOCS_ADDONS_KEY,\n });\n};\n\n/**\n * hook to use addons in components\n * @alpha\n */\nexport const useTechDocsAddons = () => {\n const node = useOutlet();\n const collection = useElementFilter(node, getAllTechDocsAddons);\n const options = useElementFilter(node, getAllTechDocsAddonsData);\n\n const findAddonByData = useCallback(\n (data: TechDocsAddonOptions | undefined) => {\n if (!collection || !data) return null;\n const nameKey = getDataKeyByName(data.name);\n return getTechDocsAddonByName(collection, nameKey) ?? null;\n },\n [collection],\n );\n\n const renderComponentByName = useCallback(\n (name: string) => {\n const data = options.find(option => option.name === name);\n return data ? findAddonByData(data) : null;\n },\n [options, findAddonByData],\n );\n\n const renderComponentsByLocation = useCallback(\n (location: keyof typeof TechDocsAddonLocations) => {\n const data = options.filter(option => option.location === location);\n return data.length ? data.map(findAddonByData) : null;\n },\n [options, findAddonByData],\n );\n\n return { renderComponentByName, renderComponentsByLocation };\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport { createApiRef } from '@backstage/core-plugin-api';\nimport { TechDocsEntityMetadata, TechDocsMetadata } from './types';\n\n/**\n * API to talk to techdocs-backend.\n *\n * @public\n */\nexport interface TechDocsApi {\n getApiOrigin(): Promise<string>;\n getTechDocsMetadata(entityId: CompoundEntityRef): Promise<TechDocsMetadata>;\n getEntityMetadata(\n entityId: CompoundEntityRef,\n ): Promise<TechDocsEntityMetadata>;\n}\n\n/**\n * Utility API reference for the {@link TechDocsApi}.\n *\n * @public\n */\nexport const techdocsApiRef = createApiRef<TechDocsApi>({\n id: 'plugin.techdocs.service',\n});\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, {\n Dispatch,\n SetStateAction,\n useContext,\n useState,\n memo,\n ReactNode,\n} from 'react';\nimport useAsync, { AsyncState } from 'react-use/lib/useAsync';\n\nimport {\n CompoundEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n createVersionedContext,\n createVersionedValueMap,\n} from '@backstage/version-bridge';\n\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { techdocsApiRef } from './api';\nimport { TechDocsEntityMetadata, TechDocsMetadata } from './types';\n\nconst areEntityRefsEqual = (\n prevEntityRef: CompoundEntityRef,\n nextEntityRef: CompoundEntityRef,\n) => {\n return (\n stringifyEntityRef(prevEntityRef) === stringifyEntityRef(nextEntityRef)\n );\n};\n\n/**\n * @public type for the value of the TechDocsReaderPageContext\n */\nexport type TechDocsReaderPageValue = {\n metadata: AsyncState<TechDocsMetadata>;\n entityRef: CompoundEntityRef;\n entityMetadata: AsyncState<TechDocsEntityMetadata>;\n shadowRoot?: ShadowRoot;\n setShadowRoot: Dispatch<SetStateAction<ShadowRoot | undefined>>;\n title: string;\n setTitle: Dispatch<SetStateAction<string>>;\n subtitle: string;\n setSubtitle: Dispatch<SetStateAction<string>>;\n /**\n * @deprecated property can be passed down directly to the `TechDocsReaderPageContent` instead.\n */\n onReady?: () => void;\n};\n\n/**\n * @alpha\n */\nexport const defaultTechDocsReaderPageValue: TechDocsReaderPageValue = {\n title: '',\n subtitle: '',\n setTitle: () => {},\n setSubtitle: () => {},\n setShadowRoot: () => {},\n metadata: { loading: true },\n entityMetadata: { loading: true },\n entityRef: { kind: '', name: '', namespace: '' },\n};\n\nconst TechDocsReaderPageContext = createVersionedContext<{\n 1: TechDocsReaderPageValue;\n}>('techdocs-reader-page-context');\n\n/**\n * render function for {@link TechDocsReaderPageProvider}\n *\n * @public\n */\nexport type TechDocsReaderPageProviderRenderFunction = (\n value: TechDocsReaderPageValue,\n) => JSX.Element;\n\n/**\n * Props for {@link TechDocsReaderPageProvider}\n *\n * @public\n */\nexport type TechDocsReaderPageProviderProps = {\n entityRef: CompoundEntityRef;\n children: TechDocsReaderPageProviderRenderFunction | ReactNode;\n};\n\n/**\n * A context to store the reader page state\n * @public\n */\nexport const TechDocsReaderPageProvider = memo(\n ({ entityRef, children }: TechDocsReaderPageProviderProps) => {\n const techdocsApi = useApi(techdocsApiRef);\n\n const metadata = useAsync(async () => {\n return techdocsApi.getTechDocsMetadata(entityRef);\n }, [entityRef]);\n\n const entityMetadata = useAsync(async () => {\n return techdocsApi.getEntityMetadata(entityRef);\n }, [entityRef]);\n\n const [title, setTitle] = useState(defaultTechDocsReaderPageValue.title);\n const [subtitle, setSubtitle] = useState(\n defaultTechDocsReaderPageValue.subtitle,\n );\n const [shadowRoot, setShadowRoot] = useState<ShadowRoot | undefined>(\n defaultTechDocsReaderPageValue.shadowRoot,\n );\n\n const value = {\n metadata,\n entityRef,\n entityMetadata,\n shadowRoot,\n setShadowRoot,\n title,\n setTitle,\n subtitle,\n setSubtitle,\n };\n const versionedValue = createVersionedValueMap({ 1: value });\n\n return (\n <TechDocsReaderPageContext.Provider value={versionedValue}>\n {children instanceof Function ? children(value) : children}\n </TechDocsReaderPageContext.Provider>\n );\n },\n (prevProps, nextProps) => {\n return areEntityRefsEqual(prevProps.entityRef, nextProps.entityRef);\n },\n);\n\n/**\n * Hook used to get access to shared state between reader page components.\n * @alpha\n */\nexport const useTechDocsReaderPage = () => {\n const versionedContext = useContext(TechDocsReaderPageContext);\n\n if (versionedContext === undefined) {\n return defaultTechDocsReaderPageValue;\n }\n\n const context = versionedContext.atVersion(1);\n if (context === undefined) {\n throw new Error('No context found for version 1.');\n }\n\n return context;\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useState, useEffect, useMemo } from 'react';\nimport debounce from 'lodash/debounce';\nimport { useTechDocsReaderPage } from './context';\n\n/**\n * Hook for use within TechDocs addons that provides access to the underlying\n * shadow root of the current page, allowing the DOM within to be mutated.\n * @alpha\n */\nexport const useShadowRoot = () => {\n const { shadowRoot } = useTechDocsReaderPage();\n return shadowRoot;\n};\n\n/**\n * Convenience hook for use within TechDocs addons that provides access to\n * elements that match a given selector within the shadow root.\n *\n * @alpha\n */\nexport const useShadowRootElements = <\n TReturnedElement extends HTMLElement = HTMLElement,\n>(\n selectors: string[],\n): TReturnedElement[] => {\n const shadowRoot = useShadowRoot();\n if (!shadowRoot) return [];\n return selectors\n .map(selector => shadowRoot?.querySelectorAll<TReturnedElement>(selector))\n .filter(nodeList => nodeList.length)\n .map(nodeList => Array.from(nodeList))\n .flat();\n};\n\nconst isValidSelection = (newSelection: Selection) => {\n // Safari sets the selection rect to top zero\n return (\n newSelection.toString() &&\n newSelection.rangeCount &&\n newSelection.getRangeAt(0).getBoundingClientRect().top\n );\n};\n\n/**\n * Hook for retreiving a selection within the ShadowRoot.\n * @alpha\n */\nexport const useShadowRootSelection = (wait: number = 0) => {\n const shadowRoot = useShadowRoot();\n const [selection, setSelection] = useState<Selection | null>(null);\n const handleSelectionChange = useMemo(\n () =>\n debounce(() => {\n const shadowDocument = shadowRoot as ShadowRoot &\n Pick<Document, 'getSelection'>;\n // Firefox and Safari don't implement getSelection for Shadow DOM\n const newSelection = shadowDocument.getSelection\n ? shadowDocument.getSelection()\n : document.getSelection();\n\n if (newSelection && isValidSelection(newSelection)) {\n setSelection(newSelection);\n } else {\n setSelection(null);\n }\n }, wait),\n [shadowRoot, setSelection, wait],\n );\n\n useEffect(() => {\n window.document.addEventListener('selectionchange', handleSelectionChange);\n return () =>\n window.document.removeEventListener(\n 'selectionchange',\n handleSelectionChange,\n );\n }, [handleSelectionChange]);\n\n return selection;\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ComponentType } from 'react';\nimport { Entity } from '@backstage/catalog-model';\n\n/**\n * Metadata for TechDocs page\n *\n * @public\n */\nexport type TechDocsMetadata = {\n site_name: string;\n site_description: string;\n};\n\n/**\n * Metadata for TechDocs Entity\n *\n * @public\n */\nexport type TechDocsEntityMetadata = Entity & {\n locationMetadata?: { type: string; target: string };\n};\n\n/**\n * Locations for which TechDocs addons may be declared and rendered.\n * @alpha\n */\nexport const TechDocsAddonLocations = Object.freeze({\n /**\n * These addons fill up the header from the right, on the same line as the\n * title.\n */\n Header: 'Header',\n\n /**\n * These addons appear below the header and above all content; tooling addons\n * can be inserted for convenience.\n */\n Subheader: 'Subheader',\n\n /**\n * These addons appear left of the content and above the navigation.\n */\n PrimarySidebar: 'PrimarySidebar',\n\n /**\n * These addons appear right of the content and above the table of contents.\n */\n SecondarySidebar: 'SecondarySidebar',\n\n /**\n * A virtual location which allows mutation of all content within the shadow\n * root by transforming DOM nodes. These addons should return null on render.\n */\n Content: 'Content',\n\n /**\n * todo(backstage/community): This is a proposed virtual location which would\n * help implement a common addon pattern in which many instances of a given\n * element in markdown would be dynamically replaced at render-time based on\n * attributes provided on that element, for example:\n *\n * ```md\n * ## For Fun\n * <TechDocsAddon>CatGif</TechDocsAddon>\n *\n * ## Component Metadata\n * <TechDocsAddon entityRef=\"default:component/some-component-name\">CatalogEntityCard</TechDocsAddon>\n *\n * ## System Metadata\n * <TechDocsAddon entityRef=\"default:system/some-system-name\">CatalogEntityCard</TechDocsAddon>\n * ```\n *\n * Could correspond to a TechDocs addon named `CatalogEntityCard` with\n * location `TechDocsAddonLocations.COMPONENT`, whose `component` would be\n * the react component that would be rendered in place of all instances of\n * the markdown illustrated above.\n *\n * The `@backstage/plugin-techdocs-react` package would need to be updated to, in\n * cases where such addons had been registered, find all instances of the\n * the `<TechDocsAddon>` tag whose `textContent` corresponded with the name of the\n * addon, then replace them with component instances of the addon component,\n * passing any attributes from the tag as props to the component.\n */\n // Component: 'Component',\n} as const);\n\n/**\n * Options for creating a TechDocs addon.\n * @alpha\n */\nexport type TechDocsAddonOptions<TAddonProps = {}> = {\n name: string;\n location: keyof typeof TechDocsAddonLocations;\n component: ComponentType<TAddonProps>;\n};\n"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@backstage/plugin-techdocs-react",
|
|
3
|
+
"description": "Shared frontend utilities for TechDocs and Addons",
|
|
4
|
+
"version": "0.0.0-nightly-20220413023505",
|
|
5
|
+
"private": false,
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public",
|
|
8
|
+
"alphaTypes": "dist/index.alpha.d.ts",
|
|
9
|
+
"main": "dist/index.esm.js",
|
|
10
|
+
"types": "dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"backstage": {
|
|
13
|
+
"role": "web-library"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://backstage.io",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/backstage/backstage",
|
|
19
|
+
"directory": "plugins/techdocs-react"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"backstage",
|
|
23
|
+
"techdocs"
|
|
24
|
+
],
|
|
25
|
+
"license": "Apache-2.0",
|
|
26
|
+
"main": "dist/index.esm.js",
|
|
27
|
+
"types": "dist/index.d.ts",
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "backstage-cli package build --experimental-type-build",
|
|
30
|
+
"lint": "backstage-cli package lint",
|
|
31
|
+
"test": "backstage-cli package test",
|
|
32
|
+
"prepack": "backstage-cli package prepack",
|
|
33
|
+
"postpack": "backstage-cli package postpack",
|
|
34
|
+
"clean": "backstage-cli package clean",
|
|
35
|
+
"start": "backstage-cli package start"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@backstage/catalog-model": "^0.0.0-nightly-20220413023505",
|
|
39
|
+
"@backstage/core-components": "^0.0.0-nightly-20220413023505",
|
|
40
|
+
"@backstage/core-plugin-api": "^0.0.0-nightly-20220413023505",
|
|
41
|
+
"@backstage/version-bridge": "^1.0.0",
|
|
42
|
+
"@material-ui/core": "^4.12.2",
|
|
43
|
+
"@material-ui/lab": "4.0.0-alpha.57",
|
|
44
|
+
"@material-ui/styles": "^4.11.0",
|
|
45
|
+
"jss": "~10.8.2",
|
|
46
|
+
"lodash": "^4.17.21",
|
|
47
|
+
"react-helmet": "6.1.0",
|
|
48
|
+
"react-router-dom": "6.0.0-beta.0",
|
|
49
|
+
"react-use": "^17.2.4"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"@types/react": "^16.13.1 || ^17.0.0",
|
|
53
|
+
"react": "^16.13.1 || ^17.0.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@testing-library/react": "^12.1.3",
|
|
57
|
+
"@testing-library/react-hooks": "^7.0.2",
|
|
58
|
+
"@backstage/test-utils": "^0.0.0-nightly-20220413023505",
|
|
59
|
+
"@backstage/theme": "^0.2.15"
|
|
60
|
+
},
|
|
61
|
+
"files": [
|
|
62
|
+
"alpha",
|
|
63
|
+
"dist"
|
|
64
|
+
]
|
|
65
|
+
}
|