mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-21 20:55:12 -04:00
First pass at save/upload
This commit is contained in:
@@ -76,3 +76,33 @@
|
||||
outline-offset: -2px;
|
||||
background-color: rgba(76, 175, 80, 0.05) !important;
|
||||
}
|
||||
|
||||
/* Download button styles */
|
||||
.download-button {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
z-index: 100;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 4px;
|
||||
padding: 6px;
|
||||
cursor: pointer;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
transition: all 0.2s ease;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.download-button:hover {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.download-button:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.download-button svg {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import DownloadButton from './DownloadButton';
|
||||
|
||||
// type Props = {
|
||||
// containerRef: React.MutableRefObject<HTMLElement | null>,
|
||||
// editorRef: React.MutableRefObject<HTMLElement | null>,
|
||||
// init: () => void
|
||||
// }
|
||||
export function Code(Props) {
|
||||
const { editorRef, containerRef, init } = Props;
|
||||
const { editorRef, containerRef, init, context } = Props;
|
||||
|
||||
return (
|
||||
<section
|
||||
className={'text-gray-100 cursor-text pb-0 overflow-auto grow'}
|
||||
className={'text-gray-100 cursor-text pb-0 overflow-auto grow relative'}
|
||||
id="code"
|
||||
ref={(el) => {
|
||||
containerRef.current = el;
|
||||
@@ -16,6 +18,8 @@ export function Code(Props) {
|
||||
init();
|
||||
}
|
||||
}}
|
||||
></section>
|
||||
>
|
||||
{context && <DownloadButton context={context} />}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export default function DownloadButton({ context }) {
|
||||
const handleDownload = useCallback(() => {
|
||||
// Get the current code from the editor
|
||||
const code = context.code;
|
||||
|
||||
// Create a blob with the code
|
||||
const blob = new Blob([code], { type: 'text/javascript' });
|
||||
|
||||
// Create a temporary URL for the blob
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
|
||||
// Create a temporary anchor element and trigger download
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `strudel-pattern-${new Date().toISOString().slice(0, 10)}.js`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
|
||||
// Clean up the URL
|
||||
window.URL.revokeObjectURL(url);
|
||||
}, [context.code]);
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={handleDownload}
|
||||
className="download-button"
|
||||
title="Download pattern as .js file"
|
||||
aria-label="Download pattern"
|
||||
>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8 12L3 7L4.4 5.6L7 8.2V0H9V8.2L11.6 5.6L13 7L8 12Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M14 14V10H16V16H0V10H2V14H14Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon';
|
||||
import StopCircleIcon from '@heroicons/react/20/solid/StopCircleIcon';
|
||||
import ArrowDownTrayIcon from '@heroicons/react/20/solid/ArrowDownTrayIcon';
|
||||
import cx from '@src/cx.mjs';
|
||||
import { useSettings, setIsZen } from '../../settings.mjs';
|
||||
import '../Repl.css';
|
||||
|
||||
@@ -20,7 +20,7 @@ export default function ReplEditor(Props) {
|
||||
<Loader active={pending} />
|
||||
<Header context={context} />
|
||||
<div className="grow flex relative overflow-hidden">
|
||||
<Code containerRef={containerRef} editorRef={editorRef} init={init} />
|
||||
<Code containerRef={containerRef} editorRef={editorRef} init={init} context={context} />
|
||||
{!isZen && panelPosition === 'right' && <VerticalPanel context={context} />}
|
||||
</div>
|
||||
<UserFacingErrorMessage error={error} />
|
||||
|
||||
Reference in New Issue
Block a user