Skip to content

Commit

Permalink
Allow to update content dynamically and to render the content inside …
Browse files Browse the repository at this point in the history
…the template (#1)

* feat(*): allow to change content inside template dynamically and to render the content

* refactor(js): disconnect nodesObserver in disconnectedCallback

* fix(styles): CSS var name

* refactor(js): use arrow function instead of bind

* update docs, demo and remove failing test

* test(): with render attribute the code inside the template is rendered
  • Loading branch information
kcmr committed May 30, 2017
1 parent 3400796 commit 47d1183
Show file tree
Hide file tree
Showing 7 changed files with 326 additions and 100 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.DS_Store
bower_components/
coverage-reports/
coverage-reports/
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,25 @@ Forget to worry about spaces, indentation, HTML entities, etc.
## Usage

The code to highlight must be provided inside a `<template>` tag.
The `type` attribute is **optional** and it corresponds to the `class` applied to `<code>` in [highlight.js](https://highlightjs.org/).

```html
<code-sample type="html">
<code-sample>
<template>
<p>your code here...</p>
</template>
</code-sample>
```

To render the code inside the template, use the boolean attribute `render`.

```html
<code-sample render>
<template>
<my-custom-element></my-custom-element>
</template>
</code-sample>
```

## Themes

The component includes 6 themes that must be imported explicitly.
Expand Down Expand Up @@ -112,8 +121,11 @@ The following custom CSS properties are available for styling:
| Custom property | Description | Default |
|:-------------------------------|:-------------------------------------------------------------|:-------------|
| --code-sample-font-family | font-family applied to `<pre>` and `<code>` elements | Operator Mono, Inconsolata, Roboto Mono, monaco, consolas, monospace |
| --code-sample-font-size | font-size applied to `<pre>` and `<code>` elements | 14px |
| --code-sample-font-size | font-size applied to `<pre>` and `<code>` elements | 14px |
| --code-sample-demo-padding | padding applied to the container of the rendered code | 0 0 20px |
| --code-sample-demo | empty mixin applied to the container of the rendered code | {} |

_Note:_ The [CSS mixin shim](https://www.polymer-project.org/2.0/docs/upgrade#css-custom-property-shim) is required to use mixins.

Included themes contain custom CSS properties to set the background and text color.
You may need to add these CSS properties to your own themes.
Expand Down
3 changes: 2 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
},
"devDependencies": {
"web-component-tester": "^6.0.0",
"iron-test-helpers": "PolymerElements/iron-test-helpers#^2.0.0"
"iron-test-helpers": "PolymerElements/iron-test-helpers#^2.0.0",
"transburger-icon": "^3.0.1"
},
"license": "https://github.com/kcmr/code-sample/LICENSE.md",
"homepage": "https://github.com/kcmr/code-sample/",
Expand Down
65 changes: 42 additions & 23 deletions code-sample.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<link rel="import" href="../polymer/polymer-element.html">
<link rel="import" href="../polymer/lib/utils/flattened-nodes-observer.html">
<link rel="import" href="highlight-import.html">

<dom-module id="code-sample">
Expand All @@ -17,9 +18,18 @@
padding: 0 20px;
line-height: 1.3;
}

.demo:not(:empty) {
padding: var(--code-sample-demo-padding, 0 0 20px);
}

.demo {
@apply --code-sample-demo;
}
</style>

<slot></slot>
<div id="demo" class="demo"></div>
<slot id="content"></slot>
<pre id="code"></pre>
</template>
<script>
Expand All @@ -37,47 +47,56 @@
*/
class CodeSample extends Polymer.Element {
static get is() { return 'code-sample' }

static get properties() {
return {
_content: {
type: String,
observer: '_contentChanged'
},

/**
* Code type. (eg.: html, js, css)
* Options are the same as the available classes for `<code>` tag using highlight.js
* Set to true to render the code inside the template.
*/
type: {
type: String
render: {
type: Boolean,
value: false
}
}
}

constructor() {
super();
}

connectedCallback() {
super.connectedCallback();
setTimeout(() => {
if (this.querySelector('template')) {
this._content = this.querySelector('template').innerHTML;
this._observer = new Polymer.FlattenedNodesObserver(this.$.content, () => this._updateContent());
} else if (this.childNodes.length) {
console.error('<code-sample>:', 'content must be provided inside a <template> tag');
}
}, 1);
}

_contentChanged(content) {
let code = document.createElement('code');
if (this.type) {
code.classList.add(this.type);
disconnectedCallback() {
if (this._observer) {
this._observer.disconnect();
this._observer = null;
}
code.innerHTML = this._entitize(this._cleanIndentation(content));
this.$.code.appendChild(code);
hljs.highlightBlock(code);
this.innerHTML = '';
}

_updateContent() {
if (this._code) { this._code.parentNode.removeChild(this._code); }
if (this._demo) { this.$.demo.innerHTML = ''; }

let nodes = Polymer.FlattenedNodesObserver.getFlattenedNodes(this.$.content);
let template = [].filter.call(nodes, (node) => node.nodeType === Node.ELEMENT_NODE)[0];

if (this.render) {
this._demo = this.$.demo.appendChild(document.importNode(template.content, true));
}

this._highlight(template.innerHTML);
}

_highlight(str) {
this._code = document.createElement('code');
this._code.innerHTML = this._entitize(this._cleanIndentation(str));
this.$.code.appendChild(this._code);
hljs.highlightBlock(this._code);
}

_cleanIndentation(str) {
Expand Down
67 changes: 67 additions & 0 deletions demo/css/demo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
body {
font-family: Roboto, sans-serif;
background: #E6E8E8;
-webkit-tap-highlight-color: transparent;
}

h1 {
font-size: 18px;
font-weight: 500;
margin: 0 0 1em;
}

p { font-weight: 300; }

code {
font-family: Roboto Mono, monospace;
}

code-sample {
--code-sample-font-family: Roboto Mono, monospace;
}

.wrapper {
max-width: 800px;
margin: 40px auto 0;
}

.wrapper > .demo {
margin-bottom: 40px;
padding: 40px;
background-color: #fff;
}
.demo-text {
text-align: left;
margin: 0 0 20px;
padding: 0;
border-bottom: 1px solid #e0e0e0;
}

.demo-btn {
font: inherit;
background-color: #EAEDED;
border: 0;
box-shadow: 0 1px 2px rgba(0,0,0,0.25);
height: 40px;
padding: 0 20px;
border-radius: 3px;
}

.demo-btn:active {
background-color: #D7DBDD;
}

.title-button {
display: flex;
justify-content: space-between;
align-items: flex-end;
margin-bottom: 20px;
}

.title-button h1 { margin-bottom: 0; }

.center { text-align: center; }

.toast-text { line-height: 1.5; font-family: Roboto Mono, monaco, monospace; font-size: 13px; }
.toast-text > span { color: #E9D80E; }

Loading

0 comments on commit 47d1183

Please sign in to comment.