Skip to content

Commit 83db825

Browse files
benrideiteris
andauthored
API Summary Style Customization (#17)
* Refactor styles, add variable to adjust heading color (#14) * refactor: use variables for font-weights * feat: use existing variables to style endpoints title * feat: add variable to adjust section heading color * docs: adjust readme formatting * add css parts * part: separator, toc, api-title-label * hide toc * update unit tests * margin var * update type def * update doc * bump version Co-authored-by: Yury <RIP95_95@mail.ru>
1 parent 27ea749 commit 83db825

File tree

8 files changed

+90
-16
lines changed

8 files changed

+90
-16
lines changed

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,35 @@ npm install --save @api-components/api-summary
4343
</html>
4444
```
4545

46+
### Styling using CSS Shadow Parts
47+
48+
```html
49+
<html>
50+
<head>
51+
<script type="module">
52+
import '@api-components/api-summary/api-summary.js';
53+
</script>
54+
<style type="text/css">
55+
api-summary::part(api-title) {
56+
font-size: 24px;
57+
}
58+
</style>
59+
</head>
60+
<body>
61+
<api-summary exportparts="api-title"></api-summary>
62+
<script>
63+
const amf = await getAmfModel();
64+
document.body.querySelector('api-summary').api = amf;
65+
window.addEventListener('api-navigation-selection-changed', (e) => {
66+
console.log(e.detail.selected);
67+
console.log(e.detail.type);
68+
});
69+
</script>
70+
</body>
71+
</html>
72+
```
73+
For a complete list of parts, check out this [doc](./Styling.md).
74+
4675
### In a LitElement template
4776

4877
```js

Styling.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Styling
2+
3+
## List of CSS Shadow Parts
4+
5+
- `api-title`
6+
- `api-title-label`
7+
- `api-version`
8+
- `marked-description`
9+
- `info-section`
10+
- `info-inline-desc`
11+
- `license-section`
12+
- `separator`
13+
- `toc`

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@api-components/api-summary",
33
"description": "A summary view for an API base on AMF data model",
4-
"version": "4.5.0",
4+
"version": "4.6.0",
55
"license": "Apache-2.0",
66
"main": "index.js",
77
"module": "index.js",

src/ApiSummary.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ export declare class ApiSummary extends AmfHelperMixin(LitElement) {
2424
* @attribute
2525
*/
2626
titleLevel: string;
27+
/**
28+
* A property to hide the table of contents list of endpoints.
29+
*/
30+
hideToc: boolean;
2731

2832
_providerName: string;
2933
_providerEmail: string;

src/ApiSummary.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ export class ApiSummary extends AmfHelperMixin(LitElement) {
4343
* @default 2
4444
*/
4545
titleLevel: { type: String },
46+
/**
47+
* A property to hide the table of contents list of endpoints.
48+
*/
49+
hideToc: { type: Boolean },
4650

4751
_providerName: { type: String },
4852
_providerEmail: { type: String },
@@ -99,6 +103,7 @@ export class ApiSummary extends AmfHelperMixin(LitElement) {
99103
* @type {string[]}
100104
*/
101105
this.protocols = undefined;
106+
this.hideToc = false;
102107
}
103108

104109
__amfChanged() {
@@ -321,7 +326,7 @@ export class ApiSummary extends AmfHelperMixin(LitElement) {
321326
${this._termsOfServiceTemplate()}
322327
</div>
323328
324-
${this._endpointsTemplate()}
329+
${this.hideToc ? '' : this._endpointsTemplate()}
325330
`;
326331
}
327332

@@ -331,8 +336,8 @@ export class ApiSummary extends AmfHelperMixin(LitElement) {
331336
return '';
332337
}
333338
return html`
334-
<div class="api-title" role="heading" aria-level="${titleLevel}">
335-
<label>API title:</label>
339+
<div class="api-title" role="heading" aria-level="${titleLevel}" part="api-title">
340+
<label part="api-title-label">API title:</label>
336341
<span>${_apiTitle}</span>
337342
</div>`;
338343
}
@@ -343,7 +348,7 @@ export class ApiSummary extends AmfHelperMixin(LitElement) {
343348
return '';
344349
}
345350
return html`
346-
<p class="inline-description version">
351+
<p class="inline-description version" part="api-version">
347352
<label>Version:</label>
348353
<span>${_version}</span>
349354
</p>`;
@@ -355,7 +360,7 @@ export class ApiSummary extends AmfHelperMixin(LitElement) {
355360
return '';
356361
}
357362
return html`
358-
<div role="region" class="marked-description">
363+
<div role="region" class="marked-description" part="marked-description">
359364
<arc-marked .markdown="${_description}" sanitize>
360365
<div slot="markdown-html" class="markdown-body"></div>
361366
</arc-marked>
@@ -427,16 +432,16 @@ export class ApiSummary extends AmfHelperMixin(LitElement) {
427432
`<a href="${_providerUrl}" target="_blank" class="app-link provider-url">${_providerUrl}</a>`,
428433
): undefined;
429434
return html`
430-
<section role="contentinfo" class="docs-section">
435+
<section role="contentinfo" class="docs-section" part="info-section">
431436
<label class="section">Contact information</label>
432-
<p class="inline-description">
437+
<p class="inline-description" part="info-inline-desc">
433438
<span class="provider-name">${_providerName}</span>
434439
${_providerEmail ? html`<a
435440
class="app-link link-padding provider-email"
436441
href="mailto:${_providerEmail}">${_providerEmail}</a>` : ''}
437442
</p>
438443
${_providerUrl ? html`
439-
<p class="inline-description">
444+
<p class="inline-description" part="info-inline-desc">
440445
${unsafeHTML(link)}
441446
</p>` : ''}
442447
</section>`;
@@ -451,7 +456,7 @@ export class ApiSummary extends AmfHelperMixin(LitElement) {
451456
`<a href="${_licenseUrl}" target="_blank" class="app-link">${_licenseName}</a>`,
452457
);
453458
return html`
454-
<section aria-labelledby="licenseLabel" class="docs-section">
459+
<section aria-labelledby="licenseLabel" class="docs-section" part="license-section">
455460
<label class="section" id="licenseLabel">License</label>
456461
<p class="inline-description">
457462
${unsafeHTML(link)}
@@ -481,8 +486,8 @@ export class ApiSummary extends AmfHelperMixin(LitElement) {
481486
const result = _endpoints.map((item) => this._endpointTemplate(item));
482487
const pathLabel = this._isAsyncAPI(this.amf) ? 'channels' : 'endpoints';
483488
return html`
484-
<div class="separator"></div>
485-
<div class="toc">
489+
<div class="separator" part="separator"></div>
490+
<div class="toc" part="toc">
486491
<label class="section endpoints-title">API ${pathLabel}</label>
487492
${result}
488493
</div>

src/Styles.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ a:hover {
103103
.separator {
104104
background-color: var(--api-summary-separator-color, rgba(0, 0, 0, 0.12));
105105
height: 1px;
106-
margin: 40px 0;
106+
margin: var(--api-summary-separator-margin, 40px 0);
107107
}
108108
109109
.endpoint-item {

test/api-summary.test.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ describe('ApiSummary', () => {
4444

4545
it('renders api title', () => {
4646
const node = element.shadowRoot.querySelector('[role="heading"]');
47-
assert.dom.equal(node, `<div aria-level="2" class="api-title" role="heading">
48-
<label>
47+
assert.dom.equal(node, `<div aria-level="2" class="api-title" role="heading" part="api-title">
48+
<label part="api-title-label">
4949
API title:
5050
</label>
5151
<span>
@@ -96,6 +96,11 @@ describe('ApiSummary', () => {
9696
const node = element.shadowRoot.querySelector('api-url');
9797
assert.equal(node.url, `https://{instance}.domain.com`);
9898
});
99+
100+
it('renders endpoints template', () => {
101+
const node = element.shadowRoot.querySelector('.endpoints-title');
102+
assert.dom.equal(node, `<label class="endpoints-title section">API endpoints</label>`);
103+
});
99104
});
100105

101106
describe('OAS properties', () => {
@@ -411,6 +416,24 @@ describe('ApiSummary', () => {
411416
assert.equal(element.shadowRoot.querySelector('.section.endpoints-title').textContent, 'API channels');
412417
});
413418
});
419+
420+
describe('hideToc', () => {
421+
let element = /** @type ApiSummary */ (null);
422+
let amf;
423+
before(async () => {
424+
amf = await AmfLoader.load(compact);
425+
});
426+
beforeEach(async () => {
427+
element = await basicFixture();
428+
element.setAttribute('hideToc', 'true');
429+
await aTimeout(0);
430+
});
431+
432+
it('does not render endpoints template', () => {
433+
const node = element.shadowRoot.querySelector('.toc');
434+
assert.isNull(node);
435+
});
436+
});
414437
});
415438
});
416439

0 commit comments

Comments
 (0)