panelset 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +111 -0
- package/dist/panelset.css +1 -0
- package/dist/panelset.js +317 -0
- package/dist/panelset.js.map +1 -0
- package/package.json +49 -0
- package/src/docs/assets/scripts/copybutton.js +44 -0
- package/src/docs/assets/scripts/example-async.js +161 -0
- package/src/docs/assets/scripts/example-closable.js +27 -0
- package/src/docs/assets/scripts/example-megamenu.js +84 -0
- package/src/docs/assets/scripts/example.js +29 -0
- package/src/docs/assets/scripts/main.js +7 -0
- package/src/docs/assets/styles/_base.scss +13 -0
- package/src/docs/assets/styles/_code.scss +121 -0
- package/src/docs/assets/styles/_demos.scss +180 -0
- package/src/docs/assets/styles/_landingpage.scss +41 -0
- package/src/docs/assets/styles/_layout.scss +80 -0
- package/src/docs/assets/styles/_sidebar.scss +67 -0
- package/src/docs/assets/styles/_typography.scss +116 -0
- package/src/docs/assets/styles/_variables.scss +32 -0
- package/src/docs/assets/styles/docs.scss +64 -0
- package/src/docs/views/api-reference.pug +474 -0
- package/src/docs/views/configuration.pug +173 -0
- package/src/docs/views/events.pug +222 -0
- package/src/docs/views/examples/async.pug +268 -0
- package/src/docs/views/examples/basic.pug +155 -0
- package/src/docs/views/examples/closable.pug +97 -0
- package/src/docs/views/getting-started.pug +99 -0
- package/src/docs/views/index.pug +38 -0
- package/src/docs/views/templates/includes/_head.pug +11 -0
- package/src/docs/views/templates/includes/_mixins.pug +100 -0
- package/src/docs/views/templates/includes/_scripts.pug +14 -0
- package/src/docs/views/templates/includes/_sidebar.pug +18 -0
- package/src/docs/views/templates/layouts/_base.pug +36 -0
- package/src/docs/views/transitions.pug +141 -0
- package/src/lib/index.ts +685 -0
- package/src/lib/styles/_base.scss +99 -0
- package/src/lib/styles/_loading.scss +47 -0
- package/src/lib/styles/_variables.scss +19 -0
- package/src/lib/styles/panelset.scss +3 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
function renderRecipe(data) {
|
|
2
|
+
return `
|
|
3
|
+
<h2>${data.name}</h2>
|
|
4
|
+
<div class="recipe-meta">
|
|
5
|
+
<span>⏱️ ${data.prepTimeMinutes + data.cookTimeMinutes} mins</span>
|
|
6
|
+
<span>👥 ${data.servings} servings</span>
|
|
7
|
+
<span>🔥 ${data.caloriesPerServing} cal</span>
|
|
8
|
+
<span>⭐ ${data.rating} (${data.reviewCount} reviews)</span>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="recipe">
|
|
11
|
+
<img class="recipe-image" src="${data.image}" alt="${data.name}">
|
|
12
|
+
<div class="recipe-ingredients">
|
|
13
|
+
<h3>Ingredients</h3>
|
|
14
|
+
<ul>
|
|
15
|
+
${data.ingredients.map(ing => `<li>${ing}</li>`).join('')}
|
|
16
|
+
</ul>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="recipe-instructions">
|
|
20
|
+
<h3>Instructions</h3>
|
|
21
|
+
<ol>
|
|
22
|
+
${data.instructions.map(step => `<li>${step}</li>`).join('')}
|
|
23
|
+
</ol>
|
|
24
|
+
</div>
|
|
25
|
+
`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
document.addEventListener('click', e => {
|
|
29
|
+
const button = e.target.closest('button[data-panel]');
|
|
30
|
+
if (!button) return;
|
|
31
|
+
|
|
32
|
+
const panelId = button.dataset.panel;
|
|
33
|
+
const container = document.getElementById(panelId)?.closest('[data-panelset]');
|
|
34
|
+
|
|
35
|
+
container?.panelSet?.show(panelId, true, { trigger: button });
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
function slowfetch(url, options = {}, delayMs = 1500) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
fetch(url, options)
|
|
42
|
+
.then(resolve)
|
|
43
|
+
.catch(reject);
|
|
44
|
+
}, delayMs);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function randomIntFromInterval(min, max) {
|
|
49
|
+
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const asyncDemo = document.getElementById('async-demo');
|
|
53
|
+
const asyncPanelSet = asyncDemo.panelSet;
|
|
54
|
+
|
|
55
|
+
// NORMAL EASY WAY
|
|
56
|
+
|
|
57
|
+
asyncPanelSet.onBeforeActivate((targetPanel, signal) => {
|
|
58
|
+
if (targetPanel.id === 'async-panel-2') {
|
|
59
|
+
return slowfetch(`https://dummyjson.com/recipes/${randomIntFromInterval(1, 10)}`, { signal })
|
|
60
|
+
.then(response => response.json())
|
|
61
|
+
.then(data => {
|
|
62
|
+
targetPanel.innerHTML = renderRecipe(data);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}, { once: false });
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
// EVENT WAY:
|
|
72
|
+
// THIS IS COMMENTED OUT, BUT LEFT HERE FOR REFERENCE
|
|
73
|
+
|
|
74
|
+
// slowDemo.addEventListener('ps:beforeactivate', (e) => {
|
|
75
|
+
// const { panelId, targetPanel, signal } = e.detail;
|
|
76
|
+
|
|
77
|
+
// // Skip if already loaded
|
|
78
|
+
// if (targetPanel.dataset.loaded === 'true') {
|
|
79
|
+
// console.log(`Panel ${panelId} already loaded`);
|
|
80
|
+
// return;
|
|
81
|
+
// }
|
|
82
|
+
|
|
83
|
+
// if (targetPanel.id === 'async-panel-2') {
|
|
84
|
+
// // Just assign the fetch promise directly - no wrapping needed
|
|
85
|
+
// e.detail.promise = slowfetch(`https://dummyjson.com/recipes/${randomIntFromInterval(1, 10)}`, { signal })
|
|
86
|
+
// .then(response => response.json())
|
|
87
|
+
// .then(data => {
|
|
88
|
+
// targetPanel.innerHTML = renderRecipe(data);
|
|
89
|
+
// targetPanel.dataset.loaded = 'true';
|
|
90
|
+
// })
|
|
91
|
+
// .catch(error => {
|
|
92
|
+
// if (error.name === 'AbortError') {
|
|
93
|
+
// console.log(`Load cancelled for ${panelId}`);
|
|
94
|
+
// } else {
|
|
95
|
+
// console.error(`Load failed for ${panelId}:`, error);
|
|
96
|
+
// }
|
|
97
|
+
// // Re-throw so PanelSet can handle it
|
|
98
|
+
// throw error;
|
|
99
|
+
// });
|
|
100
|
+
// }
|
|
101
|
+
// });
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
// document.addEventListener('ps:beforeactivate', (e) => {
|
|
106
|
+
// const { instance, container, panelId, targetPanel, signal } = e.detail;
|
|
107
|
+
|
|
108
|
+
// if (panelId == 'async-panel-2') {
|
|
109
|
+
|
|
110
|
+
// // Skip if already loaded
|
|
111
|
+
// if (targetPanel.dataset.loaded === 'true') {
|
|
112
|
+
// console.log(`Panel ${panelId} already loaded`);
|
|
113
|
+
// return;
|
|
114
|
+
// }
|
|
115
|
+
// console.log(`Loading content for ${panelId}...`);
|
|
116
|
+
// // Simulate slow API call
|
|
117
|
+
// e.detail.promise = new Promise((resolve, reject) => {
|
|
118
|
+
// const timeout = setTimeout(() => {
|
|
119
|
+
// // Simulate loaded content
|
|
120
|
+
// targetPanel.innerHTML = `
|
|
121
|
+
// <h3>Loaded: ${panelId}</h3>
|
|
122
|
+
// <p>This content was loaded asynchronously!</p>
|
|
123
|
+
// <p>Loaded at: ${new Date().toLocaleTimeString()}</p>
|
|
124
|
+
// `;
|
|
125
|
+
// targetPanel.dataset.loaded = 'true';
|
|
126
|
+
// resolve();
|
|
127
|
+
// }, 2000); // 2 second delay
|
|
128
|
+
|
|
129
|
+
// // Handle abort (rapid clicks)
|
|
130
|
+
// signal.addEventListener('abort', () => {
|
|
131
|
+
// console.log(`Load cancelled for ${panelId}`);
|
|
132
|
+
// clearTimeout(timeout);
|
|
133
|
+
// reject(new Error('Aborted'));
|
|
134
|
+
// });
|
|
135
|
+
// });
|
|
136
|
+
|
|
137
|
+
// }
|
|
138
|
+
|
|
139
|
+
// })
|
|
140
|
+
|
|
141
|
+
// Log all events
|
|
142
|
+
|
|
143
|
+
document.addEventListener('ps:ready', (e) => {
|
|
144
|
+
console.log('This panelset is ready:', e.detail.panelId);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
document.addEventListener('ps:beforeactivate', (e) => {
|
|
148
|
+
console.log('Before doing any transitions:', e.detail.panelId);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
document.addEventListener('ps:activationstart', (e) => {
|
|
152
|
+
console.log('Started a transition:', e.detail.panelId);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
document.addEventListener('ps:activationcomplete', (e) => {
|
|
156
|
+
console.log('Completed a transition:', e.detail.panelId);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
document.addEventListener('ps:activationaborted', (e) => {
|
|
160
|
+
console.log('Aborted the loading of a panel:', e.detail.panelId);
|
|
161
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
document.addEventListener('click', e => {
|
|
2
|
+
const button = e.target.closest('button[data-panel]');
|
|
3
|
+
if (!button) return;
|
|
4
|
+
const panelId = button.dataset.panel;
|
|
5
|
+
const container = document.getElementById(panelId)?.closest('[data-panelset]');
|
|
6
|
+
|
|
7
|
+
const panelSet = container?.panelSet;
|
|
8
|
+
panelSet.show(panelId);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
document.addEventListener('click', e => {
|
|
12
|
+
const actions = ['close', 'open', 'toggle'];
|
|
13
|
+
|
|
14
|
+
for (const action of actions) {
|
|
15
|
+
const btn = e.target.closest(`[data-panelset-${action}]`);
|
|
16
|
+
if (btn) {
|
|
17
|
+
const selector = btn.getAttribute(`data-panelset-${action}`);
|
|
18
|
+
const container = document.querySelector(selector);
|
|
19
|
+
|
|
20
|
+
if (container?.panelSet) {
|
|
21
|
+
const withTransition = !btn.hasAttribute('data-no-transition');
|
|
22
|
+
container.panelSet[action](withTransition);
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
|
|
2
|
+
// Delegated button handler
|
|
3
|
+
// Delegated button handler with megamenu support
|
|
4
|
+
document.addEventListener('click', e => {
|
|
5
|
+
const button = e.target.closest('button[data-panel]');
|
|
6
|
+
if (!button) return;
|
|
7
|
+
|
|
8
|
+
const panelId = button.getAttribute('data-panel');
|
|
9
|
+
const panel = document.getElementById(panelId);
|
|
10
|
+
const container = panel?.closest('[data-panelset]');
|
|
11
|
+
|
|
12
|
+
if (!container?.panelSet) return;
|
|
13
|
+
|
|
14
|
+
const panelSet = container.panelSet;
|
|
15
|
+
const withTransition = !button.hasAttribute('data-no-transition');
|
|
16
|
+
|
|
17
|
+
// Megamenu behavior for closable panelsets
|
|
18
|
+
if (container.hasAttribute('data-closable')) {
|
|
19
|
+
const isClosed = container.classList.contains('is-closed');
|
|
20
|
+
const isClosing = container.classList.contains('is-closing');
|
|
21
|
+
const isOpening = container.classList.contains('is-opening');
|
|
22
|
+
const pendingPanelId = panelSet.pendingPanel?.id;
|
|
23
|
+
|
|
24
|
+
if (isClosed || isClosing) {
|
|
25
|
+
// Closed/closing → open to clicked panel
|
|
26
|
+
panelSet.show(panelId, withTransition, { trigger: button });
|
|
27
|
+
panelSet.open(withTransition);
|
|
28
|
+
} else if (pendingPanelId === panelId) {
|
|
29
|
+
// Same panel clicked
|
|
30
|
+
if (isOpening) {
|
|
31
|
+
// Opening → reverse to close
|
|
32
|
+
panelSet.close(withTransition);
|
|
33
|
+
} else if (!isClosing) {
|
|
34
|
+
// Fully open, not closing → close it
|
|
35
|
+
panelSet.close(withTransition);
|
|
36
|
+
}
|
|
37
|
+
// If closing → do nothing (let it finish)
|
|
38
|
+
} else {
|
|
39
|
+
// Different panel → switch
|
|
40
|
+
panelSet.show(panelId, withTransition, { trigger: button });
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
// Non-closable → just switch panels
|
|
44
|
+
panelSet.show(panelId, withTransition, { trigger: button });
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
document.addEventListener('click', e => {
|
|
49
|
+
// Close action
|
|
50
|
+
const closeBtn = e.target.closest('[data-panelset-close]');
|
|
51
|
+
alert('clicked close');
|
|
52
|
+
if (closeBtn) {
|
|
53
|
+
const selector = closeBtn.getAttribute('data-panelset-close');
|
|
54
|
+
const container = selector ? document.querySelector(selector) : closeBtn.closest('[data-panelset]');
|
|
55
|
+
if (container?.panelSet) {
|
|
56
|
+
const withTransition = !closeBtn.hasAttribute('data-no-transition');
|
|
57
|
+
container.panelSet.close(withTransition);
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Open action
|
|
63
|
+
const openBtn = e.target.closest('[data-panelset-open]');
|
|
64
|
+
if (openBtn) {
|
|
65
|
+
const selector = openBtn.getAttribute('data-panelset-open');
|
|
66
|
+
const container = selector ? document.querySelector(selector) : openBtn.closest('[data-panelset]');
|
|
67
|
+
if (container?.panelSet) {
|
|
68
|
+
const withTransition = !openBtn.hasAttribute('data-no-transition');
|
|
69
|
+
container.panelSet.open(withTransition);
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Toggle action
|
|
75
|
+
const toggleBtn = e.target.closest('[data-panelset-toggle]');
|
|
76
|
+
if (toggleBtn) {
|
|
77
|
+
const selector = toggleBtn.getAttribute('data-panelset-toggle');
|
|
78
|
+
const container = selector ? document.querySelector(selector) : toggleBtn.closest('[data-panelset]');
|
|
79
|
+
if (container?.panelSet) {
|
|
80
|
+
const withTransition = !toggleBtn.hasAttribute('data-no-transition');
|
|
81
|
+
container.panelSet.toggle(withTransition);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
document.addEventListener('click', e => {
|
|
2
|
+
const button = e.target.closest('button[data-panel]');
|
|
3
|
+
if (!button) return;
|
|
4
|
+
const panelId = button.dataset.panel;
|
|
5
|
+
const container = document.getElementById(panelId)?.closest('[data-panelset]');
|
|
6
|
+
container?.panelSet?.show(panelId, true, { trigger: button });
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
// Log all events
|
|
10
|
+
|
|
11
|
+
document.addEventListener('ps:ready', (e) => {
|
|
12
|
+
console.log('This panelset is ready:', e.detail.panelId);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
document.addEventListener('ps:beforeactivate', (e) => {
|
|
16
|
+
console.log('Before doing any transitions:', e.detail.panelId);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
document.addEventListener('ps:activationstart', (e) => {
|
|
20
|
+
console.log('Started a transition:', e.detail.panelId);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
document.addEventListener('ps:activationcomplete', (e) => {
|
|
24
|
+
console.log('Completed a transition:', e.detail.panelId);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
document.addEventListener('ps:activationaborted', (e) => {
|
|
28
|
+
console.log('Aborted the loading of a panel:', e.detail.panelId);
|
|
29
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
document.addEventListener('click', e => {
|
|
2
|
+
const button = e.target.closest('button[data-panel]');
|
|
3
|
+
if (!button) return;
|
|
4
|
+
const panelId = button.dataset.panel;
|
|
5
|
+
const container = document.getElementById(panelId)?.closest('[data-panelset]');
|
|
6
|
+
container?.panelSet?.show(panelId, true, { trigger: button });
|
|
7
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
|
|
2
|
+
code, .code {
|
|
3
|
+
background: var(--doc-gray-100);
|
|
4
|
+
padding: 0.2em 0.4em;
|
|
5
|
+
border-radius: 3px;
|
|
6
|
+
font-size: 1em;
|
|
7
|
+
display: inline-block;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
p code, li code , dl code, dt.code {
|
|
11
|
+
background: var(--doc-code-transparent);
|
|
12
|
+
padding: 0em 0.3em;
|
|
13
|
+
font-size: 0.9em ;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
pre {
|
|
17
|
+
background: var(--doc-gray-50);
|
|
18
|
+
border: 1px solid var(--doc-gray-200);
|
|
19
|
+
border-radius: 6px;
|
|
20
|
+
padding: 1rem;
|
|
21
|
+
overflow-x: auto;
|
|
22
|
+
margin-bottom: 1rem;
|
|
23
|
+
|
|
24
|
+
code {
|
|
25
|
+
background: none;
|
|
26
|
+
padding: 0;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
dl.horizontal {
|
|
31
|
+
display: grid;
|
|
32
|
+
grid-template-columns: max-content auto;
|
|
33
|
+
gap: 1rem;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.code-block {
|
|
37
|
+
position: relative;
|
|
38
|
+
|
|
39
|
+
.code-header {
|
|
40
|
+
background: var(--doc-gray-100);
|
|
41
|
+
padding: 0.5rem 0.5rem 0.5rem 1rem;
|
|
42
|
+
border: 1px solid var(--doc-gray-200);
|
|
43
|
+
border-bottom: none;
|
|
44
|
+
border-radius: 6px 6px 0 0;
|
|
45
|
+
font-size: 0.875rem;
|
|
46
|
+
font-weight: 600;
|
|
47
|
+
color: var(--doc-gray-600);
|
|
48
|
+
display: flex;
|
|
49
|
+
justify-content: space-between;
|
|
50
|
+
align-items: center;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
pre {
|
|
54
|
+
margin: 0;
|
|
55
|
+
border-radius: 0 0 6px 6px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.lane:nth-child(even) & pre {
|
|
59
|
+
background: white;
|
|
60
|
+
}
|
|
61
|
+
.lane:nth-child(even) .example & pre {
|
|
62
|
+
background: var(--doc-gray-50);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// HIGHLIGHTING CODE
|
|
68
|
+
|
|
69
|
+
.hljs-ln td.hljs-ln-numbers {
|
|
70
|
+
-webkit-touch-callout: none;
|
|
71
|
+
-webkit-user-select: none;
|
|
72
|
+
-khtml-user-select: none;
|
|
73
|
+
-moz-user-select: none;
|
|
74
|
+
-ms-user-select: none;
|
|
75
|
+
user-select: none;
|
|
76
|
+
text-align: right;
|
|
77
|
+
color: #ccc;
|
|
78
|
+
padding-right: 1.5rem;
|
|
79
|
+
}
|
|
80
|
+
.hljs-ln-code {
|
|
81
|
+
padding-left: 10px;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
pre code.hljs {
|
|
85
|
+
padding: 0;
|
|
86
|
+
background: none;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.hljs-attribute,
|
|
90
|
+
.hljs-doctag,
|
|
91
|
+
.hljs-keyword,
|
|
92
|
+
.hljs-meta .hljs-keyword,
|
|
93
|
+
.hljs-name,
|
|
94
|
+
.hljs-selector-tag,
|
|
95
|
+
.hljs-section,
|
|
96
|
+
.hljs-title {
|
|
97
|
+
font-weight: 600;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
button.copy {
|
|
101
|
+
background: var(--doc-gray-200);
|
|
102
|
+
border: none;
|
|
103
|
+
border-radius: 3px;
|
|
104
|
+
padding: 0.2rem 0.5rem;
|
|
105
|
+
font-size: 1rem;
|
|
106
|
+
font-weight: 400;
|
|
107
|
+
color: var(--doc-gray-600);
|
|
108
|
+
cursor: pointer;
|
|
109
|
+
|
|
110
|
+
transition: background 0.2s, color 0.2s;
|
|
111
|
+
outline-width: 2px;
|
|
112
|
+
|
|
113
|
+
&:hover {
|
|
114
|
+
background: white;
|
|
115
|
+
color: var(--doc-primary-dark);
|
|
116
|
+
}
|
|
117
|
+
&.copied {
|
|
118
|
+
background: var(--doc-primary);
|
|
119
|
+
color: white;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// Demo block
|
|
2
|
+
|
|
3
|
+
.example {
|
|
4
|
+
position: relative;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
padding: var(--standard-padding);
|
|
8
|
+
border: 2px solid var(--doc-gray-200);
|
|
9
|
+
border-radius: 16px;
|
|
10
|
+
gap: 1rem;
|
|
11
|
+
background: white;
|
|
12
|
+
|
|
13
|
+
h2 {
|
|
14
|
+
margin: 0;
|
|
15
|
+
font-size: 1.5rem;
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@media (max-width: 768px) {
|
|
20
|
+
padding: 1rem;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&.white {
|
|
24
|
+
background: white;
|
|
25
|
+
}
|
|
26
|
+
.code-block + * {
|
|
27
|
+
margin-top: 1rem;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.api {
|
|
32
|
+
gap: 0;
|
|
33
|
+
h3.code {
|
|
34
|
+
font-size: 1.2rem;
|
|
35
|
+
color: var(--doc-primary-dark);
|
|
36
|
+
margin-bottom: 0.5rem;
|
|
37
|
+
}
|
|
38
|
+
h4 {
|
|
39
|
+
font-size: 1.1rem;
|
|
40
|
+
margin-bottom: 0.25rem;
|
|
41
|
+
margin-top: 1rem;
|
|
42
|
+
}
|
|
43
|
+
dt {
|
|
44
|
+
font-weight: 600;
|
|
45
|
+
margin-top: 0.5rem;
|
|
46
|
+
font-size: 0.9em;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.card-row {
|
|
51
|
+
display: flex;
|
|
52
|
+
gap: 1.5rem;
|
|
53
|
+
flex-wrap: wrap;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.card {
|
|
57
|
+
flex: 1;
|
|
58
|
+
min-width: 200px;
|
|
59
|
+
border: 1px solid var(--doc-gray-200);
|
|
60
|
+
border-radius: 8px;
|
|
61
|
+
padding: 1rem;
|
|
62
|
+
background: var(--doc-gray-50);
|
|
63
|
+
|
|
64
|
+
h4 {
|
|
65
|
+
margin-top: 0;
|
|
66
|
+
margin-bottom: 0.5rem;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Demo Styles
|
|
71
|
+
.demo {
|
|
72
|
+
background: var(--doc-gray-50);
|
|
73
|
+
border-radius: 8px;
|
|
74
|
+
padding: var(--standard-padding);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.demo-controls {
|
|
78
|
+
display: flex;
|
|
79
|
+
gap: 1rem;
|
|
80
|
+
margin-bottom: 1.5rem;
|
|
81
|
+
flex-wrap: wrap;
|
|
82
|
+
&.center {
|
|
83
|
+
justify-content: center;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
button {
|
|
87
|
+
background: var(--doc-primary);
|
|
88
|
+
color: white;
|
|
89
|
+
border: none;
|
|
90
|
+
padding: 0.5rem 1rem;
|
|
91
|
+
border-radius: 24px;
|
|
92
|
+
font-size: 1rem;
|
|
93
|
+
cursor: pointer;
|
|
94
|
+
transition: background 0.2s;
|
|
95
|
+
|
|
96
|
+
&:hover {
|
|
97
|
+
background: var(--doc-primary-dark);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
&:disabled {
|
|
101
|
+
opacity: 0.5;
|
|
102
|
+
cursor: not-allowed;
|
|
103
|
+
}
|
|
104
|
+
&.secondary {
|
|
105
|
+
background: var(--doc-secondary);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// SLOW DATA
|
|
111
|
+
|
|
112
|
+
.recipe {
|
|
113
|
+
display: flex;
|
|
114
|
+
gap: 24px;
|
|
115
|
+
align-items: center;
|
|
116
|
+
|
|
117
|
+
& > * {
|
|
118
|
+
flex: 1;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.recipe-meta {
|
|
123
|
+
display: flex;
|
|
124
|
+
gap: 16px;
|
|
125
|
+
margin: 16px 0;
|
|
126
|
+
padding: 12px;
|
|
127
|
+
background: white;
|
|
128
|
+
border-radius: 8px;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
img.testimage {
|
|
132
|
+
display: block;
|
|
133
|
+
margin-top: 1em;
|
|
134
|
+
width: 100%;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
img.recipe-image {
|
|
138
|
+
width: 100%;
|
|
139
|
+
max-width: 256px;
|
|
140
|
+
border-radius: 8px;
|
|
141
|
+
object-fit: cover;
|
|
142
|
+
margin: 0 auto;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.recipe-meta span {
|
|
146
|
+
font-size: 14px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.recipe {
|
|
150
|
+
display: grid;
|
|
151
|
+
grid-template-columns: repeat(2, 1fr);
|
|
152
|
+
grid-template-rows: 1fr;
|
|
153
|
+
grid-column-gap: 2rem;
|
|
154
|
+
grid-row-gap: 0px;
|
|
155
|
+
margin-bottom: 2rem;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
img.recipe-image {
|
|
159
|
+
grid-area: 1 / 1 / 2 / 2;
|
|
160
|
+
}
|
|
161
|
+
.recipe-ingredients {
|
|
162
|
+
grid-area: 1 / 2 / 2 / 3;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@media (max-width: 768px) {
|
|
166
|
+
.recipe {
|
|
167
|
+
display: flex;
|
|
168
|
+
flex-direction: column;
|
|
169
|
+
|
|
170
|
+
img {
|
|
171
|
+
width: 100%;
|
|
172
|
+
max-width: unset;
|
|
173
|
+
max-height: 256px;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
.recipe-ingredients {
|
|
177
|
+
margin-top: 2rem;
|
|
178
|
+
width: 100%;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Landing Page Styles
|
|
2
|
+
|
|
3
|
+
html.intro {
|
|
4
|
+
.docs-content {
|
|
5
|
+
// background: linear-gradient(135deg, var(--doc-primary) 0%, var(--doc-primary-dark) 100%);
|
|
6
|
+
|
|
7
|
+
// min-height: 100vh;
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
padding: var(--standard-padding);
|
|
11
|
+
text-align: center;
|
|
12
|
+
|
|
13
|
+
.container {
|
|
14
|
+
width: 100%;
|
|
15
|
+
margin: auto auto;
|
|
16
|
+
gap: var(--standard-padding);
|
|
17
|
+
}
|
|
18
|
+
.example {
|
|
19
|
+
text-align: left;
|
|
20
|
+
border: none;
|
|
21
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
p.lead {
|
|
25
|
+
font-size: 1.25rem;
|
|
26
|
+
opacity: 0.9;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.badge {
|
|
33
|
+
display: inline-block;
|
|
34
|
+
background: var(--doc-gray-200);
|
|
35
|
+
padding: 0.25rem 0.75rem;
|
|
36
|
+
border-radius: 999px;
|
|
37
|
+
font-size: 1rem;
|
|
38
|
+
font-weight: 400;
|
|
39
|
+
margin-bottom: 1rem;
|
|
40
|
+
line-height: 1.5em;
|
|
41
|
+
}
|