@salesforcedevs/docs-components 1.3.345-spage → 1.3.345-spec-ux-alpha
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/package.json +1 -1
- package/src/modules/doc/contentLayout/contentLayout.ts +21 -4
- package/src/modules/doc/specificationContent/specificationContent.css +3 -0
- package/src/modules/doc/specificationContent/specificationContent.html +124 -34
- package/src/modules/doc/specificationContent/specificationContent.ts +50 -25
package/package.json
CHANGED
|
@@ -124,8 +124,14 @@ export default class ContentLayout extends LightningElement {
|
|
|
124
124
|
const headingElements = this.getHeadingElements();
|
|
125
125
|
headingElements.forEach((headingElement: any) => {
|
|
126
126
|
// Sometimes elements hash and header is not being set when slot content is wrapped with div
|
|
127
|
-
headingElement.hash
|
|
128
|
-
|
|
127
|
+
if (!headingElement.hash) {
|
|
128
|
+
headingElement.hash = headingElement.attributes.hash?.nodeValue;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (!headingElement.header) {
|
|
132
|
+
headingElement.header =
|
|
133
|
+
headingElement.attributes.header?.nodeValue;
|
|
134
|
+
}
|
|
129
135
|
});
|
|
130
136
|
this.updateTocItems(headingElements);
|
|
131
137
|
};
|
|
@@ -138,8 +144,19 @@ export default class ContentLayout extends LightningElement {
|
|
|
138
144
|
tabPanelListItem?.querySelectorAll("dx-tab-panel");
|
|
139
145
|
for (const tabPanelItem of tabPanels) {
|
|
140
146
|
if (tabPanelItem.active) {
|
|
141
|
-
|
|
142
|
-
|
|
147
|
+
// This is needed for Specification tab content
|
|
148
|
+
const specificationElement = tabPanelItem.querySelector(
|
|
149
|
+
"doc-specification-content"
|
|
150
|
+
);
|
|
151
|
+
if (specificationElement) {
|
|
152
|
+
headingElements =
|
|
153
|
+
specificationElement.shadowRoot.querySelectorAll(
|
|
154
|
+
TOC_HEADER_TAG
|
|
155
|
+
);
|
|
156
|
+
} else {
|
|
157
|
+
headingElements =
|
|
158
|
+
tabPanelItem.querySelectorAll(TOC_HEADER_TAG);
|
|
159
|
+
}
|
|
143
160
|
break;
|
|
144
161
|
}
|
|
145
162
|
}
|
|
@@ -1,46 +1,136 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<!-- Display Attributes if they exist -->
|
|
2
|
+
<div class="specification-properties">
|
|
4
3
|
<template if:true={hasAttributes}>
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
<doc-heading
|
|
5
|
+
header="Attributes"
|
|
6
|
+
hash="attributes"
|
|
7
|
+
aria-level="2"
|
|
8
|
+
id="attributes"
|
|
9
|
+
></doc-heading>
|
|
10
|
+
<table>
|
|
11
|
+
<thead>
|
|
12
|
+
<tr>
|
|
13
|
+
<th>Name</th>
|
|
14
|
+
<th>Type</th>
|
|
15
|
+
<th>Required</th>
|
|
16
|
+
<th>Default</th>
|
|
17
|
+
<th>Description</th>
|
|
18
|
+
</tr>
|
|
19
|
+
</thead>
|
|
20
|
+
<tbody>
|
|
21
|
+
<template for:each={attributes} for:item="attribute">
|
|
22
|
+
<tr key={attribute.name}>
|
|
23
|
+
<td>{attribute.nameInKebabCase}</td>
|
|
24
|
+
<td>{attribute.type}</td>
|
|
25
|
+
<td>{attribute.required}</td>
|
|
26
|
+
<td>{attribute.default}</td>
|
|
27
|
+
<td>{attribute.description}</td>
|
|
28
|
+
</tr>
|
|
29
|
+
</template>
|
|
30
|
+
</tbody>
|
|
31
|
+
</table>
|
|
14
32
|
</template>
|
|
15
33
|
|
|
16
|
-
<!-- Display Methods if they exist -->
|
|
17
34
|
<template if:true={hasMethods}>
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
35
|
+
<doc-heading
|
|
36
|
+
header="Methods"
|
|
37
|
+
hash="methods"
|
|
38
|
+
aria-level="2"
|
|
39
|
+
id="methods"
|
|
40
|
+
></doc-heading>
|
|
41
|
+
<table>
|
|
42
|
+
<thead>
|
|
43
|
+
<tr>
|
|
44
|
+
<th>Name</th>
|
|
45
|
+
<th>Arguments</th>
|
|
46
|
+
<th>Description</th>
|
|
47
|
+
</tr>
|
|
48
|
+
</thead>
|
|
49
|
+
<tbody>
|
|
50
|
+
<template for:each={methods} for:item="method">
|
|
51
|
+
<tr key={method.name}>
|
|
52
|
+
<td>{method.nameInKebabCase}</td>
|
|
53
|
+
<td>
|
|
54
|
+
<template if:true={method.arguments.length}>
|
|
55
|
+
<table>
|
|
56
|
+
<thead>
|
|
57
|
+
<tr>
|
|
58
|
+
<th>Name</th>
|
|
59
|
+
<th>Type</th>
|
|
60
|
+
<th>Description</th>
|
|
61
|
+
</tr>
|
|
62
|
+
</thead>
|
|
63
|
+
<tbody>
|
|
64
|
+
<template
|
|
65
|
+
for:each={method.arguments}
|
|
66
|
+
for:item="argument"
|
|
67
|
+
>
|
|
68
|
+
<tr key={argument.name}>
|
|
69
|
+
<td>{argument.name}</td>
|
|
70
|
+
<td>{argument.type}</td>
|
|
71
|
+
<td>
|
|
72
|
+
{argument.description}
|
|
73
|
+
</td>
|
|
74
|
+
</tr>
|
|
75
|
+
</template>
|
|
76
|
+
</tbody>
|
|
77
|
+
</table>
|
|
78
|
+
</template>
|
|
79
|
+
</td>
|
|
80
|
+
<td>{method.description}</td>
|
|
81
|
+
</tr>
|
|
82
|
+
</template>
|
|
83
|
+
</tbody>
|
|
84
|
+
</table>
|
|
27
85
|
</template>
|
|
28
86
|
|
|
29
|
-
<!-- Display Slots if they exist -->
|
|
30
87
|
<template if:true={hasSlots}>
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
88
|
+
<doc-heading
|
|
89
|
+
header="Slots"
|
|
90
|
+
hash="slots"
|
|
91
|
+
aria-level="2"
|
|
92
|
+
id="slots"
|
|
93
|
+
></doc-heading>
|
|
94
|
+
<table>
|
|
95
|
+
<thead>
|
|
96
|
+
<tr>
|
|
97
|
+
<th>Name</th>
|
|
98
|
+
<th>Description</th>
|
|
99
|
+
</tr>
|
|
100
|
+
</thead>
|
|
101
|
+
<tbody>
|
|
102
|
+
<template for:each={slots} for:item="slot">
|
|
103
|
+
<tr key={slot.name}>
|
|
104
|
+
<td>{slot.nameInKebabCase}</td>
|
|
105
|
+
<td>{slot.description}</td>
|
|
106
|
+
</tr>
|
|
107
|
+
</template>
|
|
108
|
+
</tbody>
|
|
109
|
+
</table>
|
|
40
110
|
</template>
|
|
41
111
|
|
|
42
|
-
<template if:true={
|
|
43
|
-
<
|
|
112
|
+
<template if:true={hasEvents}>
|
|
113
|
+
<doc-heading
|
|
114
|
+
header="Events"
|
|
115
|
+
hash="events"
|
|
116
|
+
aria-level="2"
|
|
117
|
+
></doc-heading>
|
|
118
|
+
<table>
|
|
119
|
+
<thead>
|
|
120
|
+
<tr>
|
|
121
|
+
<th>Name</th>
|
|
122
|
+
<th>Description</th>
|
|
123
|
+
</tr>
|
|
124
|
+
</thead>
|
|
125
|
+
<tbody>
|
|
126
|
+
<template for:each={events} for:item="event">
|
|
127
|
+
<tr key={event.name}>
|
|
128
|
+
<td>{event.nameInKebabCase}</td>
|
|
129
|
+
<td>{event.description}</td>
|
|
130
|
+
</tr>
|
|
131
|
+
</template>
|
|
132
|
+
</tbody>
|
|
133
|
+
</table>
|
|
44
134
|
</template>
|
|
45
|
-
</
|
|
135
|
+
</div>
|
|
46
136
|
</template>
|
|
@@ -1,41 +1,66 @@
|
|
|
1
|
-
import { LightningElement, track } from "lwc";
|
|
2
|
-
import { toJson } from "dxUtils/normalizers";
|
|
1
|
+
import { LightningElement, track, api } from "lwc";
|
|
3
2
|
|
|
4
|
-
export default class
|
|
5
|
-
@track data: any;
|
|
6
|
-
|
|
3
|
+
export default class SpecificationContent extends LightningElement {
|
|
4
|
+
@track data: any;
|
|
5
|
+
// TODO: added these default values for testing, will drop this once the backend is ready.
|
|
6
|
+
@api component: string = "button";
|
|
7
|
+
@api model: string = "lwc";
|
|
8
|
+
@api namespace: string = "lightning";
|
|
9
|
+
|
|
10
|
+
/* TODO: The actual URL is as follows:
|
|
11
|
+
* http://api.salesforce.com/doc-platform/developer/v1/{type}/{sub-type}/{component-name}
|
|
12
|
+
* Until the API integration is ready, we will go ahead with mocked-router-url.
|
|
13
|
+
*/
|
|
14
|
+
@api routerUrl: string =
|
|
15
|
+
"https://cx-mock-router-internal-07a18d7b3f61.herokuapp.com";
|
|
16
|
+
|
|
17
|
+
private attributes = [];
|
|
18
|
+
private methods = [];
|
|
19
|
+
private slots = [];
|
|
20
|
+
private events = [];
|
|
7
21
|
|
|
8
|
-
// Lifecycle method to fetch data when the component is inserted into the DOM
|
|
9
22
|
connectedCallback() {
|
|
10
|
-
this.
|
|
23
|
+
this.fetchComponentMetadata();
|
|
11
24
|
}
|
|
12
25
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
async fetchComponentMetadata() {
|
|
27
|
+
const url = `${this.routerUrl}/${this.model}/${this.namespace}/${this.component}`;
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const response = await fetch(url);
|
|
31
|
+
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
// TODO: Will add loader and show error as follow-up
|
|
34
|
+
throw new Error(`Failed to fetch: ${response.statusText}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const result = await response.json();
|
|
38
|
+
this.data = result;
|
|
39
|
+
({
|
|
40
|
+
attributes: this.attributes,
|
|
41
|
+
methods: this.methods,
|
|
42
|
+
slots: this.slots,
|
|
43
|
+
events: this.events
|
|
44
|
+
} = this.data);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
this.data = {};
|
|
47
|
+
console.error("fetchComponentMetadata() failed for:" + url);
|
|
48
|
+
}
|
|
25
49
|
}
|
|
26
50
|
|
|
27
|
-
// Helper to check if attributes exist
|
|
28
51
|
get hasAttributes() {
|
|
29
|
-
return this.
|
|
52
|
+
return this.attributes?.length > 0;
|
|
30
53
|
}
|
|
31
54
|
|
|
32
|
-
// Helper to check if methods exist
|
|
33
55
|
get hasMethods() {
|
|
34
|
-
return this.
|
|
56
|
+
return this.methods?.length > 0;
|
|
35
57
|
}
|
|
36
58
|
|
|
37
|
-
// Helper to check if slots exist
|
|
38
59
|
get hasSlots() {
|
|
39
|
-
return this.
|
|
60
|
+
return this.slots?.length > 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
get hasEvents() {
|
|
64
|
+
return this.events?.length > 0;
|
|
40
65
|
}
|
|
41
66
|
}
|