Skip to content

Commit

Permalink
docs: make page for full stories
Browse files Browse the repository at this point in the history
  • Loading branch information
e111077 committed Dec 9, 2023
1 parent 739cf33 commit 3d79187
Show file tree
Hide file tree
Showing 9 changed files with 356 additions and 45 deletions.
3 changes: 2 additions & 1 deletion catalog/eleventy-helpers/shortcodes/playground-example.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function playgroundExample(eleventyConfig) {
<md-icon aria-hidden="true">expand_more</md-icon>
<md-icon aria-hidden="true" slot="selected">expand_less</md-icon>
</md-outlined-icon-button>
Expand interactive demo.
View interactive demo inline.
</summary>
<lit-island on:visible import="/js/hydration-entrypoints/playground-elements.js" class="example" aria-hidden="true">
<playground-project
Expand All @@ -68,6 +68,7 @@ function playgroundExample(eleventyConfig) {
><md-circular-progress indeterminate></md-circular-progress></playground-file-editor>
</lit-island>
</details>
<p><a href="./stories/" target="_blank">Open interactive demo in new tab.</a></p>
`;
});
}
Expand Down
7 changes: 5 additions & 2 deletions catalog/site/_includes/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@
<!-- Inlines the declarative shadow dom polyfill for FF since it's performance sensitive -->
{% inlinejs "ssr-utils/dsd-polyfill.js" %}
<lit-island on:idle import="/js/hydration-entrypoints/navigation.js">
<nav-drawer page-title="{{name}}" {% if hasToc %}has-toc{% endif %}>
<nav-drawer
page-title="{{name}}"
{% if hasToc %}has-toc{% endif %}
{% if fullHeightContent %}full-height-content{% endif %}>
<top-app-bar slot="top-app-bar" baseURI="/">
{% block topappbar %}{{ topappbar | safe }}{% endblock %}
</top-app-bar>
Expand Down Expand Up @@ -97,7 +100,7 @@
<md-list-item
href="{{ file.url }}"
role="menuitem"
{% if file.url == page.url %}selected{% endif %}
{% if file.url == page.url or file.url == tabUrl %}selected{% endif %}
type="link"
tabindex="{% if file.url == page.url %}0{% else %}-1{% endif %}"
>{{ file.data.name }}</md-list-item>
Expand Down
1 change: 1 addition & 0 deletions catalog/site/css/syntax-highlight.css
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@

/* Formats the code boxes themselves */
.example playground-file-editor,
playground-file-editor,
pre[class*='language-'] {
padding: var(--__code-block-font-size);
/* Remove the extra hard coded 3px from line number padding. */
Expand Down
68 changes: 68 additions & 0 deletions catalog/site/stories/stories.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---js
{
pagination: {
data: "collections.component",
size: 1,
alias: "component",
before: components => {
// remove any components that don't have a dirname
return components.filter(component => component.data.dirname)
}
},
permalink: "components/{{component.data.page.fileSlug}}/stories/index.html",
fullHeightContent: "true",
collections: ["stories"],
eleventyComputed: {
dirname: ({component}) => component.data.dirname,
name: ({component}) => component.data.name,
tabUrl: ({component}) => component.data.page.url,
}
}
---

{% extends 'default.html' %} {% block head %}
<script type="module" src="/js/pages/components.js"></script>
<script type="module" src="/js/pages/stories.js"></script>
<script
type="module"
src="/js/hydration-entrypoints/playground-elements.js"
></script>
<link rel="stylesheet" href="/css/md-layout.css" />
<link rel="stylesheet" href="/css/syntax-highlight.css" />
<style>
#dragbar {
max-width: 100%;
}
#editor {
margin-block: 0;
height: 100%;
box-sizing: border-box;
}
#editor-wrapper {
height: 100%;
overflow: hidden;
}
</style>
{% endblock %} {% block content %}
<playground-project
id="project"
project-src="/assets/stories/{{dirname}}/project.json"
>
</playground-project>
<drag-playground id="dragbar">
<playground-preview id="preview" project="project" slot="preview">
<md-circular-progress indeterminate></md-circular-progress>
</playground-preview>
<div slot="editor" id="editor-wrapper">
<playground-file-editor
id="editor"
project="project"
filename="stories.ts"
line-numbers
aria-hidden="true"
>
<md-circular-progress indeterminate></md-circular-progress>
</playground-file-editor>
</div>
</drag-playground>
{% endblock %}
201 changes: 201 additions & 0 deletions catalog/src/components/drag-playground.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
import { LitElement, css, html } from 'lit';
import { customElement, state, query } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { styleMap } from 'lit/directives/style-map.js';
import '@material/web/icon/icon.js';

/**
* A playground preview + editor with a draggable handle.
*/
@customElement('drag-playground')
export class DragPlayground extends LitElement {
static styles = css`
:host {
display: block;
--_drag-bar-height: 24px;
--_drag-bar-border-width: 1px;
--_half-drag-bar-height: calc(
(var(--_drag-bar-height) / 2) + var(--_drag-bar-border-width)
);
}
#wrapper {
display: flex;
flex-direction: column;
}
:host,
#wrapper,
::slotted(*) {
height: 100%;
}
slot {
display: block;
overflow: hidden;
}
[name='preview'] {
height: max(
calc(
100% - var(--editor-percentage, 0%) - var(--_half-drag-bar-height)
),
0px
);
}
[name='editor'] {
height: max(
calc(var(--editor-percentage, 0px) - var(--_half-drag-bar-height)),
0px
);
}
#drag-bar {
touch-action: none;
background-color: var(--md-sys-color-surface-container);
color: var(--md-sys-color-on-surface);
border: var(--_drag-bar-border-width) solid var(--md-sys-color-outline);
border-radius: 12px;
height: var(--_drag-bar-height);
display: flex;
justify-content: center;
align-items: center;
-webkit-user-select: none;
user-select: none;
}
#drag-bar.isDragging {
background-color: var(--md-sys-color-inverse-surface);
color: var(--md-sys-color-inverse-on-surface);
}
`;

/**
* Whether or not we are in the "dragging" state.
*/
@state() private isDragging = false;

/**
* The percentage of the editor height.
*/
@state() private editorHeightPercent = 0;

@query('#wrapper') private wrapperEl!: HTMLElement;

/**
* A set of pointer IDs in the case that the user is dragging with multiple
* pointers.
*/
private pointerIds: Set<number> = new Set();

render() {
return html`<div
id="wrapper"
style=${styleMap({
'--editor-percentage': `${this.editorHeightPercent}%`,
})}
>
<slot name="preview"></slot>
<div
id="drag-bar"
tabindex="0"
role="slider"
aria-orientation="vertical"
aria-valuemax="100"
aria-valuemin="0"
aria-valuenow="${this.editorHeightPercent}"
aria-valuetext="${this.editorHeightPercent} percent"
aria-label="Editor height"
@focus=${this.onFocus}
@blur=${this.onBlur}
@keydown=${this.onKeydown}
@pointerdown=${this.onPointerdown}
@pointerup=${this.onPointerup}
@pointermove=${this.onPointermove}
class=${classMap({
isDragging: this.isDragging,
})}
>
<md-icon aria-hidden="true">drag_handle</md-icon>
</div>
<slot name="editor"></slot>
</div>`;
}

private onFocus() {
this.isDragging = true;
}

private onBlur() {
this.isDragging = false;
}

private onKeydown(event: KeyboardEvent) {
const { key } = event;
switch (key) {
case 'ArrowRight':
case 'ArrowUp':
this.editorHeightPercent = Math.min(this.editorHeightPercent + 1, 100);
break;
case 'ArrowLeft':
case 'ArrowDown':
this.editorHeightPercent = Math.max(this.editorHeightPercent - 1, 0);
break;
case 'PageUp':
this.editorHeightPercent = Math.min(this.editorHeightPercent + 10, 100);
break;
case 'PageDown':
this.editorHeightPercent = Math.max(this.editorHeightPercent - 10, 0);
break;
case 'Home':
this.editorHeightPercent = 0;
break;
case 'End':
this.editorHeightPercent = 100;
break;
}
}

private onPointerdown(event: PointerEvent) {
this.isDragging = true;

if (this.pointerIds.has(event.pointerId)) return;

this.pointerIds.add(event.pointerId);
(event.target as HTMLElement).setPointerCapture(event.pointerId);
}

private onPointerup(event: PointerEvent) {
this.pointerIds.delete(event.pointerId);
(event.target as HTMLElement).releasePointerCapture(event.pointerId);

if (this.pointerIds.size === 0) {
this.isDragging = false;
}
}

private onPointermove(event: PointerEvent) {
if (!this.isDragging) return;

const { clientY: mouseY } = event;
const { top: wrapperTop, bottom: wrapperBottom } =
this.wrapperEl.getBoundingClientRect();

// The height of the wrapper
const height = wrapperBottom - wrapperTop;

// Calculate the percentage of the editor height in which the pointer is
// located
const editorHeightPercent = 100 - ((mouseY - wrapperTop) / height) * 100;

// Clamp the percentage between 0 and 100
this.editorHeightPercent = Math.min(Math.max(editorHeightPercent, 0), 100);
}
}

declare global {
interface HTMLElementTagNameMap {
'drag-playground': DragPlayground;
}
}
Loading

0 comments on commit 3d79187

Please sign in to comment.