diff --git a/packages/ordinals-plus-explorer/src/App.tsx b/packages/ordinals-plus-explorer/src/App.tsx
index 7f14f97..7f6c772 100644
--- a/packages/ordinals-plus-explorer/src/App.tsx
+++ b/packages/ordinals-plus-explorer/src/App.tsx
@@ -3,6 +3,7 @@ import ExplorerPage from './pages/ExplorerPage';
import LinkedResourcesPage from './pages/LinkedResourcesPage';
import SettingsPage from './pages/SettingsPage';
import CreatePage from './pages/CreatePage';
+import CreateHtmlPage from './pages/CreateHtmlPage';
import CreateCollectionPage from './pages/CreateCollectionPage';
import CollectionsListPage from './pages/CollectionsListPage';
import CollectionDetailPage from './pages/CollectionDetailPage';
@@ -27,6 +28,7 @@ function App() {
Explorer
Resources
Create
+ Create HTML
Collections
@@ -53,6 +55,7 @@ function App() {
} />
} />
} />
+
} />
} />
} />
} />
diff --git a/packages/ordinals-plus-explorer/src/components/create/GenericOrdinalForm.tsx b/packages/ordinals-plus-explorer/src/components/create/GenericOrdinalForm.tsx
index 3b5416c..649354f 100644
--- a/packages/ordinals-plus-explorer/src/components/create/GenericOrdinalForm.tsx
+++ b/packages/ordinals-plus-explorer/src/components/create/GenericOrdinalForm.tsx
@@ -16,6 +16,7 @@ bitcoin.initEccLib(ecc);
const supportedContentTypes = [
{ mime: 'text/plain', label: 'Text', isText: true },
{ mime: 'application/json', label: 'JSON', isText: true },
+ { mime: 'text/html', label: 'HTML', isText: true },
{ mime: 'image/png', label: 'PNG Image', isText: false },
{ mime: 'image/jpeg', label: 'JPEG Image', isText: false },
{ mime: 'image/svg+xml', label: 'SVG Image', isText: false },
diff --git a/packages/ordinals-plus-explorer/src/components/create/HtmlCompositionForm.tsx b/packages/ordinals-plus-explorer/src/components/create/HtmlCompositionForm.tsx
new file mode 100644
index 0000000..eabf11c
--- /dev/null
+++ b/packages/ordinals-plus-explorer/src/components/create/HtmlCompositionForm.tsx
@@ -0,0 +1,71 @@
+import React, { useRef } from 'react';
+import LinkedResourceList from '../LinkedResourceList';
+import { LinkedResource } from 'ordinalsplus';
+
+interface HtmlCompositionFormProps {
+ html: string;
+ onChange: (value: string) => void;
+ onSubmit: () => void;
+}
+
+const HtmlCompositionForm: React.FC
= ({ html, onChange, onSubmit }) => {
+ const textareaRef = useRef(null);
+
+ const insertAtCursor = (text: string) => {
+ const textarea = textareaRef.current;
+ if (!textarea) {
+ onChange(html + text);
+ return;
+ }
+ const start = textarea.selectionStart ?? html.length;
+ const end = textarea.selectionEnd ?? html.length;
+ const newValue = html.slice(0, start) + text + html.slice(end);
+ onChange(newValue);
+ // Set cursor after inserted text
+ requestAnimationFrame(() => {
+ textarea.focus();
+ const pos = start + text.length;
+ textarea.selectionStart = textarea.selectionEnd = pos;
+ });
+ };
+
+ const handleResourceSelect = (resource: LinkedResource) => {
+ const placeholder = `
`;
+ insertAtCursor(placeholder);
+ };
+
+ return (
+
+ );
+};
+
+export default HtmlCompositionForm;
diff --git a/packages/ordinals-plus-explorer/src/components/create/ResourceCreationForm.tsx b/packages/ordinals-plus-explorer/src/components/create/ResourceCreationForm.tsx
index 7b3fa99..43d8105 100644
--- a/packages/ordinals-plus-explorer/src/components/create/ResourceCreationForm.tsx
+++ b/packages/ordinals-plus-explorer/src/components/create/ResourceCreationForm.tsx
@@ -27,6 +27,7 @@ const truncateMiddle = (str: string | null, length = 10): string => {
const supportedContentTypes = [
{ mime: 'text/plain', label: 'Text', isText: true },
{ mime: 'application/json', label: 'JSON', isText: true },
+ { mime: 'text/html', label: 'HTML', isText: true },
{ mime: 'image/png', label: 'PNG Image', isText: false },
{ mime: 'image/jpeg', label: 'JPEG Image', isText: false },
{ mime: 'image/svg+xml', label: 'SVG Image', isText: false },
diff --git a/packages/ordinals-plus-explorer/src/components/inscription/ContentSelectionStep.tsx b/packages/ordinals-plus-explorer/src/components/inscription/ContentSelectionStep.tsx
index 0200194..7b55c6a 100644
--- a/packages/ordinals-plus-explorer/src/components/inscription/ContentSelectionStep.tsx
+++ b/packages/ordinals-plus-explorer/src/components/inscription/ContentSelectionStep.tsx
@@ -7,6 +7,7 @@ import { Upload, FileText } from 'lucide-react';
const supportedContentTypes = [
{ mime: 'text/plain', label: 'Text', isText: true },
{ mime: 'application/json', label: 'JSON', isText: true },
+ { mime: 'text/html', label: 'HTML', isText: true },
{ mime: 'image/png', label: 'PNG Image', isText: false },
{ mime: 'image/jpeg', label: 'JPEG Image', isText: false },
{ mime: 'image/svg+xml', label: 'SVG Image', isText: false },
diff --git a/packages/ordinals-plus-explorer/src/components/inscription/ResourceInscriptionWizard.tsx b/packages/ordinals-plus-explorer/src/components/inscription/ResourceInscriptionWizard.tsx
index 0ff0958..a4508ae 100644
--- a/packages/ordinals-plus-explorer/src/components/inscription/ResourceInscriptionWizard.tsx
+++ b/packages/ordinals-plus-explorer/src/components/inscription/ResourceInscriptionWizard.tsx
@@ -198,10 +198,22 @@ const ResourceInscriptionContext = createContext = ({ children }) => {
- const [state, dispatch] = useReducer(resourceInscriptionReducer, initialState);
+export const ResourceInscriptionProvider: React.FC = ({ children, initialContentType, initialContent }) => {
+ const [state, dispatch] = useReducer(
+ resourceInscriptionReducer,
+ {
+ ...initialState,
+ contentData: {
+ ...initialState.contentData,
+ type: initialContentType ?? initialState.contentData.type,
+ content: initialContent ?? initialState.contentData.content
+ }
+ }
+ );
const [validationErrors, setValidationErrors] = useState>({});
// Helper functions for common actions
@@ -390,12 +402,14 @@ const ErrorFallback: React.FC<{ error: Error; resetErrorBoundary: () => void }>
// Main wizard container component
interface ResourceInscriptionWizardProps {
children: ReactNode;
+ initialContentType?: string;
+ initialContent?: string;
}
-const ResourceInscriptionWizard: React.FC = ({ children }) => {
+const ResourceInscriptionWizard: React.FC = ({ children, initialContentType, initialContent }) => {
return (
-
+
{children}
diff --git a/packages/ordinals-plus-explorer/src/components/inscription/ResourceInscriptionWizardContainer.tsx b/packages/ordinals-plus-explorer/src/components/inscription/ResourceInscriptionWizardContainer.tsx
index 5e8f371..1d5d26d 100644
--- a/packages/ordinals-plus-explorer/src/components/inscription/ResourceInscriptionWizardContainer.tsx
+++ b/packages/ordinals-plus-explorer/src/components/inscription/ResourceInscriptionWizardContainer.tsx
@@ -33,15 +33,20 @@ const WizardContent: React.FC = () => {
* ResourceInscriptionWizardContainer is the main container component that integrates all the steps
* of the resource inscription wizard into a cohesive flow.
*/
-const ResourceInscriptionWizardContainer: React.FC = () => {
+interface ResourceInscriptionWizardContainerProps {
+ initialContentType?: string;
+ initialContent?: string;
+}
+
+const ResourceInscriptionWizardContainer: React.FC = ({ initialContentType, initialContent }) => {
return (
Resource Inscription Wizard
-
-
+
+
diff --git a/packages/ordinals-plus-explorer/src/pages/CreateHtmlPage.tsx b/packages/ordinals-plus-explorer/src/pages/CreateHtmlPage.tsx
new file mode 100644
index 0000000..6f7781e
--- /dev/null
+++ b/packages/ordinals-plus-explorer/src/pages/CreateHtmlPage.tsx
@@ -0,0 +1,32 @@
+import React, { useState } from 'react';
+import HtmlCompositionForm from '../components/create/HtmlCompositionForm';
+import ResourceInscriptionWizardContainer from '../components/inscription/ResourceInscriptionWizardContainer';
+
+const CreateHtmlPage: React.FC = () => {
+ const [step, setStep] = useState<'compose' | 'inscribe'>('compose');
+ const [html, setHtml] = useState
('');
+
+ if (step === 'compose') {
+ return (
+
+
+
Create HTML
+ setStep('inscribe')}
+ />
+
+
+ );
+ }
+
+ return (
+
+ );
+};
+
+export default CreateHtmlPage;
diff --git a/packages/ordinals-plus-explorer/tests/create-html-page.test.tsx b/packages/ordinals-plus-explorer/tests/create-html-page.test.tsx
new file mode 100644
index 0000000..5144bef
--- /dev/null
+++ b/packages/ordinals-plus-explorer/tests/create-html-page.test.tsx
@@ -0,0 +1,13 @@
+import React from 'react';
+import { render, screen, fireEvent } from '@testing-library/react';
+import CreateHtmlPage from '../src/pages/CreateHtmlPage';
+
+describe('CreateHtmlPage', () => {
+ test('allows composing HTML before launching wizard', () => {
+ render( );
+ expect(screen.getByText(/Create HTML/i)).toBeInTheDocument();
+ const textarea = screen.getByLabelText(/HTML Content/i) as HTMLTextAreaElement;
+ fireEvent.change(textarea, { target: { value: 'Hello
' } });
+ expect(textarea.value).toBe('Hello
');
+ });
+});