-
{{__('playground.title')}}
+
-
-
Template
-
{{ raw('partial/demo.liquid') }}
-
-
-
Context
-
{{ raw('partial/demo.json') }}
-
-
-
Output
-
-
{{__('playground.loading')}}
+
+
+
+
+
Template
+
+
+
{{ raw('partial/demo.liquid') }}
+
+
+
+
+
+
Context
+
+
+
{{ raw('partial/demo.json') }}
+
+
+
+
+
+
Output
+
+
+
+
{{__('playground.loading')}}
+
+
-
diff --git a/docs/themes/navy/source/css/_partial/highlight.styl b/docs/themes/navy/source/css/_partial/highlight.styl
index 86c77609c..dc7254e83 100644
--- a/docs/themes/navy/source/css/_partial/highlight.styl
+++ b/docs/themes/navy/source/css/_partial/highlight.styl
@@ -121,3 +121,40 @@ pre
color: var(--highlight-bash-command)
.operator
color: var(--highlight-purple)
+
+// Prism (playground output) — uses palette tokens for light/dark
+code[class*="language-"]
+ color: var(--highlight-foreground)
+ .token.comment,
+ .token.prolog,
+ .token.doctype,
+ .token.cdata
+ color: var(--highlight-comment)
+ .token.punctuation
+ color: var(--highlight-foreground)
+ .token.property,
+ .token.tag,
+ .token.boolean,
+ .token.number,
+ .token.constant,
+ .token.symbol,
+ .token.deleted
+ color: var(--highlight-red)
+ .token.attr-name,
+ .token.selector,
+ .token.string,
+ .token.char,
+ .token.builtin,
+ .token.inserted
+ color: var(--highlight-green)
+ .token.attr-value,
+ .token.regex,
+ .token.variable
+ color: var(--highlight-blue)
+ .token.operator,
+ .token.entity,
+ .token.url
+ color: var(--highlight-aqua)
+ .token.atrule,
+ .token.keyword
+ color: var(--highlight-purple)
diff --git a/docs/themes/navy/source/css/_partial/playground.styl b/docs/themes/navy/source/css/_partial/playground.styl
index 340bb29b4..876c6466d 100644
--- a/docs/themes/navy/source/css/_partial/playground.styl
+++ b/docs/themes/navy/source/css/_partial/playground.styl
@@ -1,129 +1,230 @@
#playground
+ --playground-gap: 12px
+ --playground-radius: 10px
background: var(--color-content-bg)
overflow: hidden
box-shadow: var(--panel-shadow)
.wrapper
- margin-bottom: 40px
+ margin-bottom: 32px
+ @media mq-mobile
+ margin-bottom: 20px
+
+ .playground-hero
+ display: flex
+ flex-wrap: wrap
+ align-items: flex-end
+ justify-content: space-between
+ gap: 16px 24px
+ padding-top: 32px
+ padding-bottom: 20px
+ @media mq-mobile
+ padding-top: 16px
+ padding-bottom: 12px
+ gap: 10px
+ align-items: flex-start
+
+ .playground-hero-text
+ flex: 1 1 280px
+ min-width: 0
h1
- font-size: 36px
- font-weight: 300
- margin-top: 40px
- margin-bottom: 24px
- color: var(--color-default)
-
- h2
- font-size: 0.8125rem
+ font-size: 28px
font-weight: 600
- text-transform: uppercase
- letter-spacing: 0.04em
- color: var(--color-gray)
+ letter-spacing: -0.02em
+ margin: 0 0 8px
+ color: var(--color-default)
+ @media mq-mobile
+ font-size: 22px
+ margin-bottom: 4px
+
+ .playground-lead
margin: 0
+ font-size: 15px
+ line-height: 1.5
+ color: var(--color-gray)
+ @media mq-mobile
+ font-size: 14px
+ line-height: 1.45
+
+ .playground-version
+ flex: 0 0 auto
+ margin: 0
+ font-size: 12px
+ line-height: 1.4
+ font-family: font-mono
+ padding: 6px 12px
+ border-radius: 999px
+ background: var(--playground-surface)
+ border: 1px solid var(--color-border)
+ color: var(--color-gray)
+ a
+ color: var(--color-default)
+ text-decoration: none
+ font-weight: 500
+ &:hover
+ color: var(--color-link)
+ text-decoration: none
#editors
- display: grid
- overflow: hidden
margin-bottom: 0
- height: 75vh
- min-height: 480px
+
+ .playground-workspace
+ display: grid
+ gap: var(--playground-gap)
grid-template-columns: 1fr 1fr
grid-template-rows: 3fr 2fr
- grid-gap: 16px
align-items: stretch
+ @media mq-normal
+ overflow: hidden
+ height: 75vh
+ max-height: unquote('calc(100vh - 200px)')
+ min-height: 520px
@media mq-mobile
- height: auto
- min-height: 0
grid-template-columns: 1fr
grid-template-rows: auto
- grid-gap: 20px
+ gap: 12px
.area-tpl
grid-row: 1
grid-column: 1
min-height: 0
+ .pane-indicator
+ background: var(--color-link)
.area-data
grid-row: 2
grid-column: 1
min-height: 0
+ .pane-indicator
+ background: var(--highlight-orange)
.area-output
grid-column: 2
grid-row: 1 / -1
min-height: 0
+ min-width: 0
+ .pane-indicator
+ background: var(--highlight-green)
@media mq-mobile
grid-row: auto
grid-column: 1
- .editor-wrapper
+ .playground-pane
display: flex
- gap: 8px
flex-direction: column
min-height: 0
overflow: hidden
- .editor
- flex: 1 1 auto
- min-height: 0
- position: relative
- code-block-chrome()
- overflow: hidden
- @media mq-mobile
- min-height: 240px
- .output-preview
- flex: 1 1 auto
- min-height: 0
- code-block-chrome()
- overflow: auto
- pre.highlight
- margin: 0
- min-height: 100%
- padding: 16px
- border: none
- box-shadow: none
- border-radius: 0
- background: var(--highlight-background)
- code
- display: block
- font-family: font-mono
- font-size: 14px
- line-height: 1.5
- background: transparent
- padding: 0
- white-space: pre-wrap
- word-break: break-word
- .ace_editor
- font-family: font-mono
- font-size: 14px
- line-height: 1.5
- border-radius: 6px
- .ace_scrollbar
- z-index: 2
+ background: var(--playground-pane-head)
+ border: 1px solid var(--code-border)
+ border-radius: var(--playground-radius)
+ box-shadow: var(--code-shadow)
- .version
- font-size: 0.8125rem
- line-height: 1.5
+ .pane-head
+ display: flex
+ align-items: center
+ gap: 10px
+ flex-shrink: 0
+ height: 36px
+ padding: 0 12px
+ border-bottom: 1px solid var(--code-border)
+ @media mq-mobile
+ height: 32px
+ padding: 0 10px
+ h2
+ font-size: 13px
+ font-weight: 600
+ letter-spacing: 0.01em
+ text-transform: none
+ color: var(--color-default)
+ margin: 0
+ @media mq-mobile
+ font-size: 12px
+
+ .pane-indicator
+ width: 8px
+ height: 8px
+ border-radius: 50%
+ flex-shrink: 0
+
+ .pane-body
+ flex: 1 1 auto
+ min-height: 0
+ min-width: 0
+ display: flex
+ flex-direction: column
+ overflow: visible
+ background: var(--highlight-background)
+
+ .editor
+ flex: 1 1 auto
+ min-height: 0
+ position: relative
+ overflow: hidden
+ @media mq-mobile
+ min-height: 180px
+
+ .output-preview
+ flex: 1 1 auto
+ min-height: 0
+ min-width: 0
+ width: 100%
+ overflow: auto
+ @media mq-mobile
+ min-height: 120px
+ pre.highlight
+ margin: 0
+ min-height: 100%
+ width: 100%
+ box-sizing: border-box
+ padding: 16px
+ border: none
+ box-shadow: none
+ border-radius: 0
+ background: transparent
+ color: var(--highlight-foreground)
+ overflow-x: hidden
+ overflow-y: auto
+ white-space: pre-wrap
+ overflow-wrap: break-word
+ @media mq-mobile
+ padding: 12px
+ code
+ display: block
+ width: 100%
+ box-sizing: border-box
+ font-family: font-mono
+ font-size: 14px
+ line-height: 1.55
+ background: transparent
+ padding: 0
+ white-space: inherit
+ overflow-wrap: inherit
+ @media mq-mobile
+ font-size: 13px
+
+ .ace_editor
font-family: font-mono
- color: var(--color-gray)
- margin-top: 20px
- margin-bottom: 32px
- a
- color: inherit
- text-decoration: none
- &:hover
- color: var(--color-link)
- text-decoration: underline
+ font-size: 14px
+ line-height: 1.55
+ border-radius: 0
+ @media mq-mobile
+ font-size: 13px
+ .ace_scrollbar
+ z-index: 2
.hide
display: none
.loader
- width: 48px
- height: 48px
- margin: 150px auto 200px
- border: 3px solid var(--color-border)
+ width: 40px
+ height: 40px
+ margin: 120px auto 160px
+ border: 2px solid var(--color-border)
border-top-color: var(--color-link)
border-radius: 50%
- animation: spin 0.8s infinite linear
+ animation: playground-spin 0.7s infinite linear
+ @media mq-mobile
+ margin: 60px auto 80px
- @keyframes spin
+ @keyframes playground-spin
100%
transform: rotate(360deg)
diff --git a/docs/themes/navy/source/css/_variables.styl b/docs/themes/navy/source/css/_variables.styl
index cac6b94fe..27363cc6b 100644
--- a/docs/themes/navy/source/css/_variables.styl
+++ b/docs/themes/navy/source/css/_variables.styl
@@ -37,6 +37,8 @@ vendor-prefixes = webkit moz ms official
--highlight-aqua: #0550ae
--highlight-blue: #0550ae
--highlight-purple: #8250df
+ --playground-surface: #f3f4f6
+ --playground-pane-head: #fff
}
@media (prefers-color-scheme: dark) {
@@ -75,6 +77,8 @@ vendor-prefixes = webkit moz ms official
--highlight-aqua: #79c0ff
--highlight-blue: #79c0ff
--highlight-purple: #d2a8ff
+ --playground-surface: hsl(218, 26%, 10%)
+ --playground-pane-head: hsl(218, 22%, 16%)
}
}
diff --git a/docs/themes/navy/source/js/main.js b/docs/themes/navy/source/js/main.js
index 4397112da..1289faa73 100644
--- a/docs/themes/navy/source/js/main.js
+++ b/docs/themes/navy/source/js/main.js
@@ -39,7 +39,7 @@
(function() {
// playground
/* global liquidjs, ace, Prism */
- if (!location.pathname.match(/playground.html$/)) return;
+ if (!/\/playground(?:\.html)?$/.test(location.pathname)) return;
updateVersion(liquidjs.version);
const engine = new liquidjs.Liquid({
memoryLimit: 1e5,
@@ -51,8 +51,10 @@
const previewCode = document.getElementById('previewCode');
const editors = [editor, dataEditor];
+ let previewValue = '';
colorScheme.addEventListener('change', function() {
editors.forEach(applyEditorTheme);
+ if (previewValue) setPreview(previewValue);
});
const init = parseArgs(location.hash.slice(1));
@@ -99,9 +101,49 @@
});
editor.getSession().setMode('ace/mode/' + lang);
editor.renderer.setScrollMargin(8, 8, 0, 0);
+ bindClipboard(editor);
return editor;
}
+ function bindClipboard(editor) {
+ editor.commands.addCommand({
+ name: 'copy',
+ bindKey: {win: 'Ctrl-C', mac: 'Command-C'},
+ exec: function (ed) {
+ const text = ed.getCopyText();
+ if (!text) return;
+ if (navigator.clipboard && window.isSecureContext) {
+ navigator.clipboard.writeText(text);
+ }
+ },
+ readOnly: true
+ });
+ editor.commands.addCommand({
+ name: 'cut',
+ bindKey: {win: 'Ctrl-X', mac: 'Command-X'},
+ exec: function (ed) {
+ const text = ed.getCopyText();
+ if (!text) return;
+ if (navigator.clipboard && window.isSecureContext) {
+ navigator.clipboard.writeText(text).then(function () {
+ ed.insert('');
+ });
+ }
+ }
+ });
+ editor.commands.addCommand({
+ name: 'paste',
+ bindKey: {win: 'Ctrl-V', mac: 'Command-V'},
+ exec: function (ed) {
+ if (navigator.clipboard && window.isSecureContext) {
+ navigator.clipboard.readText().then(function (text) {
+ ed.insert(text);
+ });
+ }
+ }
+ });
+ }
+
function parseArgs(hash) {
if (!hash) return;
try {
@@ -116,6 +158,7 @@
}
function setPreview (value) {
+ previewValue = value
previewCode.textContent = value
if (window.Prism) {
delete previewCode.dataset.highlighted
@@ -132,7 +175,6 @@
setPreview(html);
} catch (err) {
setPreview(err.stack);
- throw err;
}
}