api-viewer-element
Advanced tools
Comparing version 0.3.0 to 0.3.1
@@ -19,2 +19,17 @@ # Change Log | ||
## [0.3.1] - 2019-12-19 | ||
### Added | ||
- Added `knobs` CSS shadow part for theming | ||
### Fixed | ||
- Fixed radio buttons scoping issue in Safari | ||
### Changed | ||
- Replaced `illuminate-js` with `highlight-ts` | ||
- Refactored and simplified internal components | ||
## [0.3.0] - 2019-12-17 | ||
@@ -21,0 +36,0 @@ |
import { __decorate } from "tslib"; | ||
import { LitElement, html, property } from 'lit-element'; | ||
import { until } from 'lit-html/directives/until.js'; | ||
import { fetchJson } from './lib/fetch-json.js'; | ||
import { queryTemplates } from './lib/utils.js'; | ||
import './api-viewer-content.js'; | ||
async function fetchJson(src) { | ||
let result = []; | ||
try { | ||
const file = await fetch(src); | ||
const json = (await file.json()); | ||
if (Array.isArray(json.tags) && json.tags.length) { | ||
result = json.tags; | ||
} | ||
else { | ||
console.error(`No element definitions found at ${src}`); | ||
} | ||
} | ||
catch (e) { | ||
console.error(e); | ||
} | ||
return result; | ||
} | ||
async function renderDocs(jsonFetched, section, selected) { | ||
@@ -8,0 +24,0 @@ const elements = await jsonFetched; |
@@ -5,4 +5,2 @@ import { LitElement } from 'lit-element'; | ||
import './api-viewer-demo.js'; | ||
import './api-viewer-header.js'; | ||
import './api-viewer-marked.js'; | ||
export declare class ApiViewerContent extends LitElement { | ||
@@ -12,2 +10,4 @@ elements: ElementInfo[]; | ||
section: string; | ||
protected _id?: number; | ||
constructor(); | ||
protected createRenderRoot(): this; | ||
@@ -14,0 +14,0 @@ protected render(): import("lit-element").TemplateResult; |
@@ -5,12 +5,13 @@ import { __decorate } from "tslib"; | ||
import { EMPTY_ELEMENT } from './lib/constants.js'; | ||
import { parse } from './lib/markdown.js'; | ||
import './api-viewer-docs.js'; | ||
import './api-viewer-demo.js'; | ||
import './api-viewer-header.js'; | ||
import './api-viewer-marked.js'; | ||
let radioId = 0; | ||
let ApiViewerContent = class ApiViewerContent extends LitElement { | ||
constructor() { | ||
super(...arguments); | ||
super(); | ||
this.elements = []; | ||
this.selected = 0; | ||
this.section = 'docs'; | ||
this._id = ++radioId; | ||
} | ||
@@ -26,45 +27,46 @@ createRenderRoot() { | ||
return html ` | ||
<api-viewer-header .heading="${name}" part="header"> | ||
<input | ||
id="docs" | ||
type="radio" | ||
name="section" | ||
value="docs" | ||
?checked="${section === 'docs'}" | ||
@change="${this._onToggle}" | ||
part="radio-button" | ||
/> | ||
<label part="radio-label" for="docs">Docs</label> | ||
<input | ||
id="demo" | ||
type="radio" | ||
name="section" | ||
value="demo" | ||
?checked="${section === 'demo'}" | ||
@change="${this._onToggle}" | ||
part="radio-button" | ||
/> | ||
<label part="radio-label" for="demo">Demo</label> | ||
<label part="select-label"> | ||
<select | ||
@change="${this._onSelect}" | ||
.value="${String(selected)}" | ||
?hidden="${elements.length === 1}" | ||
part="select" | ||
> | ||
${elements.map((tag, idx) => { | ||
<header part="header"> | ||
<div class="tag-name"><${name}></div> | ||
<nav> | ||
<input | ||
id="docs" | ||
type="radio" | ||
name="section-${this._id}" | ||
value="docs" | ||
?checked="${section === 'docs'}" | ||
@change="${this._onToggle}" | ||
part="radio-button" | ||
/> | ||
<label part="radio-label" for="docs">Docs</label> | ||
<input | ||
id="demo" | ||
type="radio" | ||
name="section-${this._id}" | ||
value="demo" | ||
?checked="${section === 'demo'}" | ||
@change="${this._onToggle}" | ||
part="radio-button" | ||
/> | ||
<label part="radio-label" for="demo">Demo</label> | ||
<label part="select-label"> | ||
<select | ||
@change="${this._onSelect}" | ||
.value="${String(selected)}" | ||
?hidden="${elements.length === 1}" | ||
part="select" | ||
> | ||
${elements.map((tag, idx) => { | ||
return html ` | ||
<option value="${idx}">${tag.name}</option> | ||
`; | ||
<option value="${idx}">${tag.name}</option> | ||
`; | ||
})} | ||
</select> | ||
</label> | ||
</api-viewer-header> | ||
</select> | ||
</label> | ||
</nav> | ||
</header> | ||
${cache(section === 'docs' | ||
? html ` | ||
<api-viewer-marked | ||
.content="${description}" | ||
?hidden="${description === ''}" | ||
part="docs-description" | ||
></api-viewer-marked> | ||
<div ?hidden="${description === ''}" part="docs-description"> | ||
${parse(description)} | ||
</div> | ||
<api-viewer-docs | ||
@@ -71,0 +73,0 @@ .name="${name}" |
import { LitElement, PropertyValues } from 'lit-element'; | ||
import { CSSPropertyInfo, PropertyInfo, SlotInfo, SlotValue, EventInfo, KnobValues } from './lib/types.js'; | ||
import './api-viewer-demo-knobs.js'; | ||
import './api-viewer-demo-snippet.js'; | ||
import './api-viewer-demo-events.js'; | ||
import './api-viewer-demo-css.js'; | ||
import './api-viewer-panel.js'; | ||
@@ -8,0 +6,0 @@ import './api-viewer-tab.js'; |
import { __decorate } from "tslib"; | ||
import { LitElement, html, customElement, property } from 'lit-element'; | ||
import { renderer } from './lib/renderer.js'; | ||
import { getSlotTitle, hasHostTemplate, isEmptyArray, normalizeType } from './lib/utils.js'; | ||
import './api-viewer-demo-knobs.js'; | ||
import { cssPropRenderer, propRenderer, renderKnobs, slotRenderer } from './lib/knobs.js'; | ||
import { getSlotTitle, hasHostTemplate, hasSlotTemplate, isEmptyArray, normalizeType } from './lib/utils.js'; | ||
import './api-viewer-demo-snippet.js'; | ||
import './api-viewer-demo-events.js'; | ||
import './api-viewer-demo-css.js'; | ||
import './api-viewer-panel.js'; | ||
@@ -42,3 +41,4 @@ import './api-viewer-tab.js'; | ||
const noCss = isEmptyArray(this.cssProps); | ||
const noKnobs = isEmptyArray(this.props) && isEmptyArray(this.slots); | ||
const noSlots = isEmptyArray(this.slots); | ||
const noKnobs = isEmptyArray(this.props) && noSlots; | ||
return html ` | ||
@@ -68,10 +68,16 @@ <div part="demo-output" @rendered="${this._onRendered}"> | ||
<api-viewer-panel slot="panel" part="tab-panel"> | ||
<api-viewer-demo-knobs | ||
.tag="${this.tag}" | ||
.props="${this.props}" | ||
.slots="${this.processedSlots}" | ||
@prop-changed="${this._onPropChanged}" | ||
@slot-changed="${this._onSlotChanged}" | ||
?hidden="${noKnobs}" | ||
></api-viewer-demo-knobs> | ||
<div part="knobs" ?hidden="${noKnobs}"> | ||
<section part="knobs-column" @change="${this._onPropChanged}"> | ||
<h3 part="knobs-header">Properties</h3> | ||
${renderKnobs(this.props, 'prop', propRenderer)} | ||
</section> | ||
<section | ||
?hidden="${hasSlotTemplate(this.tag) || noSlots}" | ||
part="knobs-column" | ||
@change="${this._onSlotChanged}" | ||
> | ||
<h3 part="knobs-header">Slots</h3> | ||
${renderKnobs(this.processedSlots, 'slot', slotRenderer)} | ||
</section> | ||
</div> | ||
</api-viewer-panel> | ||
@@ -85,7 +91,8 @@ <api-viewer-tab | ||
<api-viewer-panel slot="panel" part="tab-panel"> | ||
<api-viewer-demo-css | ||
?hidden="${noCss}" | ||
.cssProps="${this.processedCss}" | ||
@css-changed="${this._onCssChanged}" | ||
></api-viewer-demo-css> | ||
<div part="knobs" ?hidden="${noCss}"> | ||
<section part="knobs-column" @change="${this._onCssChanged}"> | ||
<h3 part="knobs-header">Custom CSS Properties</h3> | ||
${renderKnobs(this.cssProps, 'css-prop', cssPropRenderer)} | ||
</section> | ||
</div> | ||
</api-viewer-panel> | ||
@@ -165,3 +172,5 @@ <api-viewer-tab | ||
_onCssChanged(e) { | ||
const { name, value } = e.detail; | ||
const target = e.composedPath()[0]; | ||
const { value, dataset } = target; | ||
const { name } = dataset; | ||
this.processedCss = this.processedCss.map(prop => { | ||
@@ -177,7 +186,15 @@ return prop.name === name | ||
_onPropChanged(e) { | ||
const { name, type, value } = e.detail; | ||
this.knobs = Object.assign(this.knobs, { [name]: { type, value } }); | ||
const target = e.composedPath()[0]; | ||
const { name, type } = target.dataset; | ||
const value = normalizeType(type) === 'boolean' | ||
? target.checked | ||
: target.value; | ||
this.knobs = Object.assign(this.knobs, { | ||
[name]: { type, value } | ||
}); | ||
} | ||
_onSlotChanged(e) { | ||
const { name, content } = e.detail; | ||
const target = e.composedPath()[0]; | ||
const name = target.dataset.slot; | ||
const content = target.value; | ||
this.processedSlots = this.processedSlots.map(slot => { | ||
@@ -184,0 +201,0 @@ return slot.name === name |
import { __decorate } from "tslib"; | ||
import { LitElement, html, customElement, css, property } from 'lit-element'; | ||
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js'; | ||
import { addLanguage, highlight } from 'illuminate-js'; | ||
import { html as htmlSyntax } from 'illuminate-js/esm/languages'; | ||
import { htmlRender } from 'highlight-ts/es/render/html.js'; | ||
import { registerLanguages } from 'highlight-ts/es/languages.js'; | ||
import { XML } from 'highlight-ts/es/languages/xml.js'; | ||
import { init, process } from 'highlight-ts/es/process.js'; | ||
import { CSS } from './lib/highlight-css.js'; | ||
import { getSlotTemplate, normalizeType } from './lib/utils.js'; | ||
import prismTheme from './lib/prism-theme.js'; | ||
addLanguage('html', htmlSyntax); | ||
import highlightTheme from './lib/highlight-theme.js'; | ||
// register languages | ||
registerLanguages(CSS, XML); | ||
// initialize highlighter | ||
const highlighter = init(htmlRender, { | ||
classPrefix: '' | ||
}); | ||
const INDENT = ' '; | ||
@@ -76,5 +84,5 @@ const unindent = (text) => { | ||
} | ||
const snippet = unsafeHTML(highlight(markup, 'html')); | ||
const { value } = process(highlighter, markup, ['xml', 'css']); | ||
return html ` | ||
<pre><code>${snippet}</code></pre> | ||
<pre><code>${unsafeHTML(value)}</code></pre> | ||
`; | ||
@@ -92,3 +100,3 @@ }; | ||
return [ | ||
prismTheme, | ||
highlightTheme, | ||
css ` | ||
@@ -95,0 +103,0 @@ :host { |
import { LitElement, PropertyValues } from 'lit-element'; | ||
import { TemplateResult } from 'lit-html'; | ||
import { PropertyInfo, SlotInfo, AttributeInfo, EventInfo, CSSPartInfo, CSSPropertyInfo } from './lib/types.js'; | ||
import './api-viewer-item.js'; | ||
import './api-viewer-panel.js'; | ||
@@ -6,0 +5,0 @@ import './api-viewer-tab.js'; |
import { __decorate } from "tslib"; | ||
import { LitElement, html, customElement, property } from 'lit-element'; | ||
import { nothing } from 'lit-html'; | ||
import { isEmptyArray } from './lib/utils.js'; | ||
import './api-viewer-item.js'; | ||
import { parse } from './lib/markdown.js'; | ||
import './api-viewer-panel.js'; | ||
@@ -14,2 +15,41 @@ import './api-viewer-tab.js'; | ||
}; | ||
const renderItem = (name, description, valueType, attribute, value) => { | ||
return html ` | ||
<div part="docs-item"> | ||
<div part="docs-row"> | ||
<div part="docs-column"> | ||
<div part="docs-label">Name</div> | ||
<div part="docs-value" class="accent">${name}</div> | ||
</div> | ||
${attribute === undefined | ||
? nothing | ||
: html ` | ||
<div part="docs-column"> | ||
<div part="docs-label">Attribute</div> | ||
<div part="docs-value">${attribute}</div> | ||
</div> | ||
`} | ||
${valueType === undefined | ||
? nothing | ||
: html ` | ||
<div part="docs-column" class="column-type"> | ||
<div part="docs-label">Type</div> | ||
<div part="docs-value"> | ||
${valueType.toLowerCase()} | ||
${value === undefined | ||
? nothing | ||
: html ` | ||
= <span class="accent">${value}</span> | ||
`} | ||
</div> | ||
</div> | ||
`} | ||
</div> | ||
<div ?hidden="${description === undefined}"> | ||
<div part="docs-label">Description</div> | ||
<div part="docs-markdown">${parse(description)}</div> | ||
</div> | ||
</div> | ||
`; | ||
}; | ||
const renderTab = (heading, count, content) => { | ||
@@ -29,13 +69,2 @@ const hidden = count === 0; | ||
}; | ||
const renderEntity = (items) => { | ||
return html ` | ||
${items.map((item) => html ` | ||
<api-viewer-item | ||
.name="${item.name}" | ||
.description="${item.description}" | ||
part="docs-item" | ||
></api-viewer-item> | ||
`)} | ||
`; | ||
}; | ||
let ApiViewerDocs = class ApiViewerDocs extends LitElement { | ||
@@ -77,27 +106,22 @@ constructor() { | ||
${renderTab('Properties', properties.length, html ` | ||
${properties.map(prop => html ` | ||
<api-viewer-item | ||
.name="${prop.name}" | ||
.description="${prop.description}" | ||
.valueType="${prop.type}" | ||
.attribute="${prop.attribute}" | ||
.value="${prop.default}" | ||
part="docs-item" | ||
></api-viewer-item> | ||
`)} | ||
${properties.map(prop => { | ||
const { name, description, type, attribute } = prop; | ||
return renderItem(name, description, type, attribute, prop.default); | ||
})} | ||
`)} | ||
${renderTab('Attributes', attributes.length, html ` | ||
${attributes.map(attr => html ` | ||
<api-viewer-item | ||
.name="${attr.name}" | ||
.description="${attr.description}" | ||
.valueType="${attr.type}" | ||
part="docs-item" | ||
></api-viewer-item> | ||
`)} | ||
${attributes.map(({ name, description, type }) => renderItem(name, description, type))} | ||
`)} | ||
${renderTab('Slots', slots.length, renderEntity(slots))} | ||
${renderTab('Events', events.length, renderEntity(events))} | ||
${renderTab('CSS Custom Properties', cssProps.length, renderEntity(cssProps))} | ||
${renderTab('CSS Shadow Parts', cssParts.length, renderEntity(cssParts))} | ||
${renderTab('Slots', slots.length, html ` | ||
${slots.map(({ name, description }) => renderItem(name, description))} | ||
`)} | ||
${renderTab('Events', events.length, html ` | ||
${events.map(({ name, description }) => renderItem(name, description))} | ||
`)} | ||
${renderTab('CSS Custom Properties', cssProps.length, html ` | ||
${cssProps.map(({ name, description }) => renderItem(name, description))} | ||
`)} | ||
${renderTab('CSS Shadow Parts', cssParts.length, html ` | ||
${cssParts.map(({ name, description }) => renderItem(name, description))} | ||
`)} | ||
</api-viewer-tabs> | ||
@@ -104,0 +128,0 @@ `; |
@@ -72,8 +72,24 @@ import { css } from 'lit-element'; | ||
api-viewer-demo-css, | ||
api-viewer-demo-knobs { | ||
display: block; | ||
padding: 1rem; | ||
header { | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
padding: 0.75rem; | ||
background: var(--ave-primary-color); | ||
border-top-left-radius: var(--ave-border-radius); | ||
border-top-right-radius: var(--ave-border-radius); | ||
} | ||
.tag-name { | ||
color: var(--ave-header-color); | ||
font-family: var(--ave-monospace-font); | ||
font-size: 0.875rem; | ||
line-height: 1.5rem; | ||
} | ||
nav { | ||
display: flex; | ||
align-items: center; | ||
} | ||
[part='warning'] { | ||
@@ -152,3 +168,3 @@ padding: 1rem; | ||
/* Demo styles */ | ||
api-viewer-item:not(:first-of-type), | ||
[part='docs-item']:not(:first-of-type), | ||
.demo-tabs, | ||
@@ -173,4 +189,5 @@ [part='demo-output'] { | ||
.columns { | ||
[part='knobs'] { | ||
display: flex; | ||
padding: 1rem; | ||
} | ||
@@ -217,2 +234,10 @@ | ||
@media (max-width: 480px) { | ||
header { | ||
flex-direction: column; | ||
} | ||
nav { | ||
margin-top: 0.5rem; | ||
} | ||
.api-col-type { | ||
@@ -219,0 +244,0 @@ flex-basis: 100%; |
{ | ||
"name": "api-viewer-element", | ||
"version": "0.3.0", | ||
"version": "0.3.1", | ||
"description": "Web Components API viewer element", | ||
@@ -21,2 +21,4 @@ "author": "Serhii Kulykov <iamkulykov@gmail.com>", | ||
"serve:dist": "es-dev-server --app-index dist/index.html --open", | ||
"size": "size-limit", | ||
"size:why": "size-limit --why", | ||
"watch": "tsc-watch" | ||
@@ -31,3 +33,3 @@ }, | ||
"dompurify": "^2.0.7", | ||
"illuminate-js": "1.0.0-alpha.2", | ||
"highlight-ts": "^9.12.1-2", | ||
"lit-element": "^2.2.1", | ||
@@ -39,7 +41,8 @@ "lit-html": "^1.1.2", | ||
"devDependencies": { | ||
"@open-wc/building-rollup": "^0.16.0", | ||
"@typescript-eslint/eslint-plugin": "^2.11.0", | ||
"@typescript-eslint/parser": "^2.11.0", | ||
"@open-wc/building-rollup": "^0.17.0", | ||
"@size-limit/preset-big-lib": "^2.2.3", | ||
"@typescript-eslint/eslint-plugin": "^2.12.0", | ||
"@typescript-eslint/parser": "^2.12.0", | ||
"@webcomponents/webcomponentsjs": "^2.4.0", | ||
"es-dev-server": "^1.31.1", | ||
"es-dev-server": "^1.32.0", | ||
"eslint": "^6.7.2", | ||
@@ -50,3 +53,3 @@ "eslint-config-airbnb-base": "^14.0.0", | ||
"eslint-plugin-lit": "^1.2.0", | ||
"eslint-plugin-prettier": "^3.1.1", | ||
"eslint-plugin-prettier": "^3.1.2", | ||
"eslint-plugin-wc": "^1.2.0", | ||
@@ -59,3 +62,3 @@ "husky": "^3.1.0", | ||
"rimraf": "^3.0.0", | ||
"rollup": "^1.27.12", | ||
"rollup": "^1.27.13", | ||
"rollup-plugin-cpy": "^2.0.1", | ||
@@ -82,3 +85,9 @@ "stylelint": "^12.0.0", | ||
] | ||
} | ||
}, | ||
"size-limit": [ | ||
{ | ||
"path": "lib/api-viewer.js", | ||
"limit": "32.5 KB" | ||
} | ||
] | ||
} |
@@ -37,2 +37,8 @@ # <api-viewer> | ||
Or grab from [unpkg.com CDN](https://unpkg.com/api-viewer-element?module): | ||
```html | ||
<script src="https://unpkg.com/api-viewer-element?module" type="module"></script> | ||
``` | ||
## Usage | ||
@@ -234,2 +240,3 @@ | ||
| `event-record` | `<p>` used as a record in the event log | | ||
| `knobs` | Wrapper of in the properties / styles knobs panel | | ||
| `knobs-column` | Column in the properties / styles knobs panel | | ||
@@ -236,0 +243,0 @@ | `knobs-header` | Header of the properties / styles knobs column | |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
293
191636
29
84
2133
+ Addedhighlight-ts@^9.12.1-2
+ Addedhighlight-ts@9.12.1-2(transitive)
- Removedilluminate-js@1.0.0-alpha.2
- Removedilluminate-js@1.0.0-alpha.2(transitive)