@droplinked_inc/editor-ui 0.3.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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +91 -0
  3. package/THREAT_MODEL.md +81 -0
  4. package/dist/components/CoverMedia.d.ts +19 -0
  5. package/dist/components/CoverMedia.d.ts.map +1 -0
  6. package/dist/components/CoverMedia.js +21 -0
  7. package/dist/components/CoverMedia.js.map +1 -0
  8. package/dist/components/Editor.d.ts +29 -0
  9. package/dist/components/Editor.d.ts.map +1 -0
  10. package/dist/components/Editor.js +61 -0
  11. package/dist/components/Editor.js.map +1 -0
  12. package/dist/components/HeroSection.d.ts +21 -0
  13. package/dist/components/HeroSection.d.ts.map +1 -0
  14. package/dist/components/HeroSection.js +31 -0
  15. package/dist/components/HeroSection.js.map +1 -0
  16. package/dist/components/PageFooter.d.ts +16 -0
  17. package/dist/components/PageFooter.d.ts.map +1 -0
  18. package/dist/components/PageFooter.js +19 -0
  19. package/dist/components/PageFooter.js.map +1 -0
  20. package/dist/components/PageHeader.d.ts +28 -0
  21. package/dist/components/PageHeader.d.ts.map +1 -0
  22. package/dist/components/PageHeader.js +24 -0
  23. package/dist/components/PageHeader.js.map +1 -0
  24. package/dist/components/UploadImage.d.ts +26 -0
  25. package/dist/components/UploadImage.d.ts.map +1 -0
  26. package/dist/components/UploadImage.js +43 -0
  27. package/dist/components/UploadImage.js.map +1 -0
  28. package/dist/index.d.ts +14 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +8 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/internal/upload.d.ts +30 -0
  33. package/dist/internal/upload.d.ts.map +1 -0
  34. package/dist/internal/upload.js +57 -0
  35. package/dist/internal/upload.js.map +1 -0
  36. package/dist/types.d.ts +76 -0
  37. package/dist/types.d.ts.map +1 -0
  38. package/dist/types.js +12 -0
  39. package/dist/types.js.map +1 -0
  40. package/package.json +62 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Droplinked Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # @droplinked_inc/editor-ui
2
+
3
+ Renderer + image-upload UI for the `@droplinked_inc` visual editor.
4
+
5
+ Initial rebuild port of the page-level renderer (`Editor`, `PageHeader`,
6
+ `PageFooter`, `InnerContent`, `AppStoreProvider`) that the hostile
7
+ `droplinked-editor-configs@1.9.19` shipped tightly coupled to its
8
+ data-only surface. `@droplinked_inc/editor-configs` already ports the
9
+ data substrate; this package owns the renderer.
10
+
11
+ ## Status: 0.1.0 — shell package with bug-fix landing zone
12
+
13
+ The hostile renderer is approximately **19,818 LoC across 1,168 files**
14
+ (per `packages/editor-configs/THREAT_MODEL.md`). Porting it safely
15
+ requires multi-agent work. This 0.1.0 release ships **the structural
16
+ fix for the 2026-05-18 template-builder upload regression** plus a
17
+ typed prop surface so consumers can flip imports without compile breaks.
18
+
19
+ ### What ships in 0.1.0
20
+
21
+ | Surface | State |
22
+ | --- | --- |
23
+ | `Editor` component | **STUB** — renders a placeholder that delegates to `<UploadImage>` so the bug-fix path is exercisable end-to-end. |
24
+ | `UploadImage` component | **WORKING** — minimal unstyled `<label><input type="file"></label>` widget that calls `uploadImageToCdn`. |
25
+ | `uploadImageToCdn` helper | **WORKING** — POSTs `multipart/form-data` to `/uploader/cdn-upload` with `Authorization: Bearer <token>`. |
26
+ | `EditorProps` / `UploadConfig` types | **STABLE** — match the prop surface that `droplinked-shop-builder` consumers used against 1.9.19. |
27
+ | `PageHeader` / `PageFooter` / `InnerContent` / `AppStoreProvider` | **NOT YET PORTED** — see "Porting plan" below. |
28
+ | Configured component renderers (69 files in 1.9.19) | **NOT YET PORTED** — see "Porting plan". |
29
+ | Icon set (849 SVGs) | **NOT IN SCOPE** — belongs in a future `@droplinked_inc/icons` (already flagged in `editor-configs/THREAT_MODEL.md`). |
30
+
31
+ ### The bug this fixes
32
+
33
+ Upload from `droplinked.com/analytics/style-center/template-builder`
34
+ started 401-ing on 2026-05-18 after apiv3 PR #1116 made
35
+ `/uploader/cdn-upload` JWT-required. Root cause: hostile 1.9.19 accepted
36
+ a `token` prop on `<Editor>` but the internal upload call did **not**
37
+ forward it as the `Authorization` header. Since we don't own that source
38
+ we cannot patch it in place — hence this package.
39
+
40
+ The fix is in `src/internal/upload.ts`:
41
+
42
+ ```ts
43
+ headers: {
44
+ Authorization: `Bearer ${config.token}`,
45
+ },
46
+ ```
47
+
48
+ This is the single load-bearing line. The regression test
49
+ (`src/__tests__/upload-auth-forwarded.test.tsx`) pins the contract.
50
+
51
+ ## Porting plan
52
+
53
+ Once published, separate sub-agents can land each block as its own PR
54
+ against this package:
55
+
56
+ 1. **`PageHeader`** — top-of-page editor chrome (save, exit, publish).
57
+ 2. **`PageFooter`** — publish/preview footer.
58
+ 3. **`InnerContent`** — Puck-host wrapper that consumes
59
+ `@droplinked_inc/editor-configs`.
60
+ 4. **`AppStoreProvider`** — zustand store wiring. Audit for telemetry
61
+ /phone-home before porting.
62
+ 5. **Cover Media handler + Logo Change handler** — wire to
63
+ `UploadImage` so they share the JWT-forwarded upload path.
64
+ 6. **Theming / Chakra v3 migration** — drop Chakra v2 carry-overs.
65
+
66
+ Each port MUST repeat the secrets-sweep that
67
+ `editor-configs/THREAT_MODEL.md` documented (eval/new Function, inline
68
+ S3 URLs, console.log, hardcoded `apiv3.droplinked.com`, telemetry).
69
+
70
+ ## Consumer migration (`droplinked-shop-builder`)
71
+
72
+ ```diff
73
+ - import { Editor, EditorProps } from 'droplinked-editor-configs';
74
+ + import { Editor, EditorProps } from '@droplinked_inc/editor-ui';
75
+ ```
76
+
77
+ The prop surface is unchanged. The upload regression is fixed at the
78
+ package boundary; the host application does not need to change how it
79
+ passes `token`.
80
+
81
+ ## Security posture
82
+
83
+ - `sideEffects: false` — bundlers tree-shake everything the consumer
84
+ doesn't import.
85
+ - No `eval`, `new Function`, dynamic `require`, or
86
+ `dangerouslySetInnerHTML`.
87
+ - No `console.log` / `console.debug` in shipped code.
88
+ - Token is forwarded only on the `Authorization` header; never logged,
89
+ never serialized into request body or URL.
90
+ - Default upload endpoint is `https://apiv3.droplinked.com/uploader/cdn-upload`;
91
+ override via `endpoint` config for tests/staging.
@@ -0,0 +1,81 @@
1
+ # Threat model — `@droplinked_inc/editor-ui`
2
+
3
+ ## What this package is (0.1.0)
4
+
5
+ A shell rebuild package that owns the renderer surface deferred out of
6
+ `@droplinked_inc/editor-configs`. 0.1.0 ships only the
7
+ image-upload sub-component with the structural fix for the
8
+ 2026-05-18 template-builder regression, plus a typed `Editor` shell.
9
+
10
+ ## Trust boundaries
11
+
12
+ | Boundary | Direction | Mitigation |
13
+ | --- | --- | --- |
14
+ | `token` prop | host → package → `fetch` | Forwarded only as `Authorization: Bearer <token>` header. Never logged, never written to request body, never written to URL. Empty/missing token throws before any network call. |
15
+ | Upload endpoint | package → apiv3 | Default `https://apiv3.droplinked.com/uploader/cdn-upload`. Overridable via `UploadConfig.endpoint` for tests; production override should be a deliberate decision. |
16
+ | CDN response | apiv3 → consumer | Response is parsed as JSON and the `url` field is strictly type-narrowed (`typeof === 'string' && length > 0`). Non-conforming responses throw before reaching the host's `onUpdate`. |
17
+ | File input | DOM → upload helper | First selected file only. `<input type="file" accept="image/*">` constrains MIME at the browser layer; apiv3 is the source of truth for accepted MIME. |
18
+
19
+ ## What this package is **not** doing (deferred)
20
+
21
+ See `README.md` "Porting plan". The deferred renderer surface is:
22
+
23
+ - `PageHeader` / `PageFooter` / `InnerContent` / `AppStoreProvider`
24
+ - 69 `configured-components/*` renderers from the hostile 1.9.19
25
+ - Chakra UI v3 migration of all of the above
26
+ - The 849-icon `assets/` tree (separate `@droplinked_inc/icons` package)
27
+
28
+ Each follow-up port MUST repeat the secrets-sweep documented in
29
+ `packages/editor-configs/THREAT_MODEL.md`.
30
+
31
+ ## Secrets-sweep result (0.1.0 ported surface)
32
+
33
+ | Pattern | Hits | Action |
34
+ | --- | --- | --- |
35
+ | `pk_live` / `sk_live` / `AKIA…` / `AIza…` / `xoxb-` / `ghp_…` / `npm_…` | 0 | none |
36
+ | PEM private-key blocks | 0 | none |
37
+ | Author email addresses (PII) | 0 | none |
38
+ | `eval` / `new Function` / dynamic `require` | 0 | none |
39
+ | `dangerouslySetInnerHTML` / `.innerHTML =` | 0 | none |
40
+ | `console.log` / `console.debug` | 0 | none |
41
+ | Hardcoded URLs | 1 (`https://apiv3.droplinked.com/uploader/cdn-upload`, named export `DEFAULT_UPLOAD_ENDPOINT` for override) | acceptable for 0.1.0; flagged as a runtime-config target in the editor-configs threat model. |
42
+ | `// TODO` / `// FIXME` / `// HACK` / `// XXX` | 0 | none |
43
+
44
+ ## Dependency surface
45
+
46
+ Runtime dependencies: **none**.
47
+
48
+ Peer dependencies: `react`, `react-dom`, `@droplinked_inc/editor-configs`.
49
+
50
+ The hostile 1.9.19 pulled in Chakra, Radix, Puck, axios, lucide-react,
51
+ zustand, react-query, vaul, cmdk, class-variance-authority, clsx,
52
+ tailwind-merge, lz-string, keen-slider, react-slider, react-icons. None
53
+ of these are re-introduced by 0.1.0. They will re-enter the graph only
54
+ as the deferred renderer surface lands, and each addition MUST be
55
+ justified in a follow-up PR's threat-model diff.
56
+
57
+ ## Upload-call audit (the load-bearing path)
58
+
59
+ ```
60
+ host UploadImage (this pkg) uploadImageToCdn (this pkg)
61
+ ───── ──────────────────── ────────────────────────────
62
+ <Editor token=jwt …/>
63
+
64
+
65
+ <UploadImage token=jwt …/>
66
+ onChange(file)
67
+
68
+
69
+ uploadImageToCdn(file, { token: jwt })
70
+
71
+
72
+ fetch(endpoint, {
73
+ method: 'POST',
74
+ headers: { Authorization: `Bearer ${jwt}` },
75
+ body: FormData(file)
76
+ })
77
+ ```
78
+
79
+ The single regression-prone hop (the `headers.Authorization` line in
80
+ `src/internal/upload.ts`) is pinned by
81
+ `src/__tests__/upload-auth-forwarded.test.tsx`.
@@ -0,0 +1,19 @@
1
+ import * as React from 'react';
2
+ import type { EditorData } from '../types.js';
3
+ export interface CoverMediaProps {
4
+ readonly token: string;
5
+ readonly data: EditorData;
6
+ readonly onUpdate: (next: EditorData) => void;
7
+ readonly fetchImpl?: typeof fetch;
8
+ }
9
+ /**
10
+ * Cover Media section — the large hero banner image at the very top of
11
+ * the storefront, above the Hero Section text block. Maps to the
12
+ * `coverMediaUrl` key on the editor data envelope.
13
+ *
14
+ * This is the surface the template-builder bug-report screenshot called
15
+ * out by name ("Cover Media"). The user clicks the slot to upload an
16
+ * image; that fetch MUST carry Authorization: Bearer <token>.
17
+ */
18
+ export declare function CoverMedia(props: CoverMediaProps): React.JSX.Element;
19
+ //# sourceMappingURL=CoverMedia.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CoverMedia.d.ts","sourceRoot":"","sources":["../../src/components/CoverMedia.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,aAAa,CAAC;AAG5D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA4BpE"}
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from 'react';
3
+ import { UploadImage } from './UploadImage.js';
4
+ /**
5
+ * Cover Media section — the large hero banner image at the very top of
6
+ * the storefront, above the Hero Section text block. Maps to the
7
+ * `coverMediaUrl` key on the editor data envelope.
8
+ *
9
+ * This is the surface the template-builder bug-report screenshot called
10
+ * out by name ("Cover Media"). The user clicks the slot to upload an
11
+ * image; that fetch MUST carry Authorization: Bearer <token>.
12
+ */
13
+ export function CoverMedia(props) {
14
+ const { token, data, onUpdate, fetchImpl } = props;
15
+ const url = typeof data.coverMediaUrl === 'string' ? data.coverMediaUrl : '';
16
+ const handleUploaded = React.useCallback((result) => {
17
+ onUpdate({ ...data, coverMediaUrl: result.url });
18
+ }, [data, onUpdate]);
19
+ return (_jsxs("section", { "data-testid": "editor-ui-section-cover-media", "data-section": "cover-media", children: [_jsx("h2", { children: "Cover Media" }), url !== '' ? (_jsx("img", { src: url, alt: "Cover media", "data-testid": "editor-ui-cover-image" })) : null, _jsx(UploadImage, { token: token, onUploaded: handleUploaded, ...(fetchImpl !== undefined ? { fetchImpl } : {}), label: "Upload cover media" })] }));
20
+ }
21
+ //# sourceMappingURL=CoverMedia.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CoverMedia.js","sourceRoot":"","sources":["../../src/components/CoverMedia.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAS/C;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IACnD,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAE7E,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CAAC,MAAoB,EAAQ,EAAE;QAC7B,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,aAAa,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IACnD,CAAC,EACD,CAAC,IAAI,EAAE,QAAQ,CAAC,CACjB,CAAC;IAEF,OAAO,CACL,kCACc,+BAA+B,kBAC9B,aAAa,aAE1B,uCAAoB,EACnB,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CACZ,cAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAC,aAAa,iBAAa,uBAAuB,GAAG,CACxE,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,WAAW,IACV,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,cAAc,KACtB,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAClD,KAAK,EAAC,oBAAoB,GAC1B,IACM,CACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+ import type { EditorProps } from '../types.js';
3
+ /**
4
+ * `Editor` — top-level page renderer for the @droplinked_inc visual
5
+ * template builder.
6
+ *
7
+ * Layout (mirrors the hostile droplinked-editor-configs@1.9.21 page
8
+ * structure visible in the 2026-05-18 template-builder screenshot):
9
+ *
10
+ * PageHeader (shop name + logo upload slot)
11
+ * ├ CoverMedia (banner image upload)
12
+ * ├ HeroSection (headline + tagline + image)
13
+ * └ Custom sections (PORTING TODO — see README "Porting plan")
14
+ * PageFooter (shop name + year)
15
+ *
16
+ * Each image upload slot routes through the shared `<UploadImage>`
17
+ * component, whose `uploadImageToCdn` helper forwards the `token` prop
18
+ * as `Authorization: Bearer <token>` on every CDN POST. That contract
19
+ * is the structural fix for the 2026-05-18 template-builder upload bug
20
+ * triggered by apiv3 PR #1116 making `/uploader/cdn-upload` JWT-required.
21
+ *
22
+ * Surface still stubbed in this 0.2.0 (tracked in README):
23
+ * - `configured-components/*` (69 product / blog / multicolumn renderers)
24
+ * - `InnerContent` zone with drag-drop slot composition
25
+ * - `AppStoreProvider` (zustand store wiring)
26
+ * - Per-category sidebar UI from `@droplinked_inc/editor-configs`
27
+ */
28
+ export declare function Editor(props: EditorProps): React.JSX.Element;
29
+ //# sourceMappingURL=Editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../../src/components/Editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,aAAa,CAAC;AAM3D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAiD5D"}
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from 'react';
3
+ import { CoverMedia } from './CoverMedia.js';
4
+ import { HeroSection } from './HeroSection.js';
5
+ import { PageFooter } from './PageFooter.js';
6
+ import { PageHeader } from './PageHeader.js';
7
+ /**
8
+ * `Editor` — top-level page renderer for the @droplinked_inc visual
9
+ * template builder.
10
+ *
11
+ * Layout (mirrors the hostile droplinked-editor-configs@1.9.21 page
12
+ * structure visible in the 2026-05-18 template-builder screenshot):
13
+ *
14
+ * PageHeader (shop name + logo upload slot)
15
+ * ├ CoverMedia (banner image upload)
16
+ * ├ HeroSection (headline + tagline + image)
17
+ * └ Custom sections (PORTING TODO — see README "Porting plan")
18
+ * PageFooter (shop name + year)
19
+ *
20
+ * Each image upload slot routes through the shared `<UploadImage>`
21
+ * component, whose `uploadImageToCdn` helper forwards the `token` prop
22
+ * as `Authorization: Bearer <token>` on every CDN POST. That contract
23
+ * is the structural fix for the 2026-05-18 template-builder upload bug
24
+ * triggered by apiv3 PR #1116 making `/uploader/cdn-upload` JWT-required.
25
+ *
26
+ * Surface still stubbed in this 0.2.0 (tracked in README):
27
+ * - `configured-components/*` (69 product / blog / multicolumn renderers)
28
+ * - `InnerContent` zone with drag-drop slot composition
29
+ * - `AppStoreProvider` (zustand store wiring)
30
+ * - Per-category sidebar UI from `@droplinked_inc/editor-configs`
31
+ */
32
+ export function Editor(props) {
33
+ const { token, shopName, initialData, onUpdate, fetchImpl } = props;
34
+ // The editor owns a local copy of the data envelope so partial edits
35
+ // (logo upload, then cover upload, then headline edit) compose without
36
+ // requiring the host to re-feed `initialData` on every keystroke.
37
+ // The host receives every update through `onUpdate`.
38
+ const [data, setData] = React.useState(initialData);
39
+ const handleUpdate = React.useCallback((next) => {
40
+ setData(next);
41
+ onUpdate(next);
42
+ }, [onUpdate]);
43
+ // When the host re-renders with a fresh `initialData` (e.g. after a
44
+ // server reload), sync the local cache. We use a ref to detect real
45
+ // identity changes only — not value-equal updates.
46
+ const lastInitialRef = React.useRef(initialData);
47
+ React.useEffect(() => {
48
+ if (lastInitialRef.current !== initialData) {
49
+ lastInitialRef.current = initialData;
50
+ setData(initialData);
51
+ }
52
+ }, [initialData]);
53
+ const sectionProps = {
54
+ token,
55
+ data,
56
+ onUpdate: handleUpdate,
57
+ ...(fetchImpl !== undefined ? { fetchImpl } : {}),
58
+ };
59
+ return (_jsxs("div", { "data-testid": "editor-ui-editor", "data-shop-name": shopName, "data-section": "editor-root", children: [_jsx(PageHeader, { shopName: shopName, ...sectionProps }), _jsxs("main", { "data-testid": "editor-ui-inner-content", "data-section": "inner-content", children: [_jsx(CoverMedia, { ...sectionProps }), _jsx(HeroSection, { ...sectionProps })] }), _jsx(PageFooter, { shopName: shopName, data: data })] }));
60
+ }
61
+ //# sourceMappingURL=Editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Editor.js","sourceRoot":"","sources":["../../src/components/Editor.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,MAAM,CAAC,KAAkB;IACvC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAEpE,qEAAqE;IACrE,uEAAuE;IACvE,kEAAkE;IAClE,qDAAqD;IACrD,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAa,WAAW,CAAC,CAAC;IAEhE,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CACpC,CAAC,IAAgB,EAAQ,EAAE;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,oEAAoE;IACpE,oEAAoE;IACpE,mDAAmD;IACnD,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACjD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,cAAc,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;YAC3C,cAAc,CAAC,OAAO,GAAG,WAAW,CAAC;YACrC,OAAO,CAAC,WAAW,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,MAAM,YAAY,GAAG;QACnB,KAAK;QACL,IAAI;QACJ,QAAQ,EAAE,YAAY;QACtB,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClD,CAAC;IAEF,OAAO,CACL,8BACc,kBAAkB,oBACd,QAAQ,kBACX,aAAa,aAE1B,KAAC,UAAU,IAAC,QAAQ,EAAE,QAAQ,KAAM,YAAY,GAAI,EACpD,+BAAkB,yBAAyB,kBAAc,eAAe,aACtE,KAAC,UAAU,OAAK,YAAY,GAAI,EAChC,KAAC,WAAW,OAAK,YAAY,GAAI,IAC5B,EACP,KAAC,UAAU,IAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAI,IAC1C,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+ import type { EditorData } from '../types.js';
3
+ export interface HeroSectionProps {
4
+ readonly token: string;
5
+ readonly data: EditorData;
6
+ readonly onUpdate: (next: EditorData) => void;
7
+ readonly fetchImpl?: typeof fetch;
8
+ }
9
+ /**
10
+ * Hero Section — text + CTA + image slot. The hostile package shipped
11
+ * three variants (`heroSectionCover`, `heroSectionImageBelow`,
12
+ * `heroSectionImageWithTextLtr`). 0.2.0 ships the common shell: a single
13
+ * editable headline + tagline + image. Variant selection is deferred.
14
+ *
15
+ * Editable keys on the data envelope:
16
+ * - `heroHeadline: string`
17
+ * - `heroTagline: string`
18
+ * - `heroImageUrl: string`
19
+ */
20
+ export declare function HeroSection(props: HeroSectionProps): React.JSX.Element;
21
+ //# sourceMappingURL=HeroSection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeroSection.d.ts","sourceRoot":"","sources":["../../src/components/HeroSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,aAAa,CAAC;AAG5D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA8DtE"}
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from 'react';
3
+ import { UploadImage } from './UploadImage.js';
4
+ /**
5
+ * Hero Section — text + CTA + image slot. The hostile package shipped
6
+ * three variants (`heroSectionCover`, `heroSectionImageBelow`,
7
+ * `heroSectionImageWithTextLtr`). 0.2.0 ships the common shell: a single
8
+ * editable headline + tagline + image. Variant selection is deferred.
9
+ *
10
+ * Editable keys on the data envelope:
11
+ * - `heroHeadline: string`
12
+ * - `heroTagline: string`
13
+ * - `heroImageUrl: string`
14
+ */
15
+ export function HeroSection(props) {
16
+ const { token, data, onUpdate, fetchImpl } = props;
17
+ const headline = typeof data.heroHeadline === 'string' ? data.heroHeadline : '';
18
+ const tagline = typeof data.heroTagline === 'string' ? data.heroTagline : '';
19
+ const imageUrl = typeof data.heroImageUrl === 'string' ? data.heroImageUrl : '';
20
+ const handleHeadlineChange = React.useCallback((e) => {
21
+ onUpdate({ ...data, heroHeadline: e.target.value });
22
+ }, [data, onUpdate]);
23
+ const handleTaglineChange = React.useCallback((e) => {
24
+ onUpdate({ ...data, heroTagline: e.target.value });
25
+ }, [data, onUpdate]);
26
+ const handleUploaded = React.useCallback((result) => {
27
+ onUpdate({ ...data, heroImageUrl: result.url });
28
+ }, [data, onUpdate]);
29
+ return (_jsxs("section", { "data-testid": "editor-ui-section-hero", "data-section": "hero-section", children: [_jsx("h2", { children: "Hero Section" }), _jsxs("label", { children: ["Headline", _jsx("input", { type: "text", value: headline, onChange: handleHeadlineChange, "data-testid": "editor-ui-hero-headline-input" })] }), _jsxs("label", { children: ["Tagline", _jsx("input", { type: "text", value: tagline, onChange: handleTaglineChange, "data-testid": "editor-ui-hero-tagline-input" })] }), imageUrl !== '' ? (_jsx("img", { src: imageUrl, alt: headline, "data-testid": "editor-ui-hero-image" })) : null, _jsx(UploadImage, { token: token, onUploaded: handleUploaded, ...(fetchImpl !== undefined ? { fetchImpl } : {}), label: "Upload hero image" })] }));
30
+ }
31
+ //# sourceMappingURL=HeroSection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeroSection.js","sourceRoot":"","sources":["../../src/components/HeroSection.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAS/C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IACnD,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhF,MAAM,oBAAoB,GAAG,KAAK,CAAC,WAAW,CAC5C,CAAC,CAAsC,EAAQ,EAAE;QAC/C,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC,EACD,CAAC,IAAI,EAAE,QAAQ,CAAC,CACjB,CAAC;IAEF,MAAM,mBAAmB,GAAG,KAAK,CAAC,WAAW,CAC3C,CAAC,CAAsC,EAAQ,EAAE;QAC/C,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACrD,CAAC,EACD,CAAC,IAAI,EAAE,QAAQ,CAAC,CACjB,CAAC;IAEF,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CAAC,MAAoB,EAAQ,EAAE;QAC7B,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IAClD,CAAC,EACD,CAAC,IAAI,EAAE,QAAQ,CAAC,CACjB,CAAC;IAEF,OAAO,CACL,kCACc,wBAAwB,kBACvB,cAAc,aAE3B,wCAAqB,EACrB,wCAEE,gBACE,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,oBAAoB,iBAClB,+BAA+B,GAC3C,IACI,EACR,uCAEE,gBACE,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,mBAAmB,iBACjB,8BAA8B,GAC1C,IACI,EACP,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,CACjB,cAAK,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,iBAAc,sBAAsB,GAAG,CACzE,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,WAAW,IACV,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,cAAc,KACtB,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAClD,KAAK,EAAC,mBAAmB,GACzB,IACM,CACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ import type { EditorData } from '../types.js';
3
+ export interface PageFooterProps {
4
+ readonly shopName: string;
5
+ readonly data: EditorData;
6
+ }
7
+ /**
8
+ * Minimal `PageFooter` renderer.
9
+ *
10
+ * The hostile package shipped a multi-column footer (about / links /
11
+ * social / newsletter). The 0.2.0 shell renders shop name + year only.
12
+ * Newsletter signup and social links are deferred — they require port
13
+ * of the form-control + analytics subsurfaces.
14
+ */
15
+ export declare function PageFooter(props: PageFooterProps): React.JSX.Element;
16
+ //# sourceMappingURL=PageFooter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageFooter.d.ts","sourceRoot":"","sources":["../../src/components/PageFooter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAcpE"}
@@ -0,0 +1,19 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Minimal `PageFooter` renderer.
4
+ *
5
+ * The hostile package shipped a multi-column footer (about / links /
6
+ * social / newsletter). The 0.2.0 shell renders shop name + year only.
7
+ * Newsletter signup and social links are deferred — they require port
8
+ * of the form-control + analytics subsurfaces.
9
+ */
10
+ export function PageFooter(props) {
11
+ const { shopName } = props;
12
+ // We intentionally do NOT call `new Date()` at render time during tests
13
+ // that snapshot output — but for runtime we want the current year.
14
+ // jsdom test runs see the real Date so this is deterministic per-day,
15
+ // which is acceptable for a footer year.
16
+ const year = new Date().getUTCFullYear();
17
+ return (_jsx("footer", { "data-testid": "editor-ui-page-footer", "data-section": "page-footer", children: _jsxs("small", { children: ["\u00A9 ", year, " ", shopName] }) }));
18
+ }
19
+ //# sourceMappingURL=PageFooter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageFooter.js","sourceRoot":"","sources":["../../src/components/PageFooter.tsx"],"names":[],"mappings":";AASA;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAC3B,wEAAwE;IACxE,mEAAmE;IACnE,sEAAsE;IACtE,yCAAyC;IACzC,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,cAAc,EAAE,CAAC;IACzC,OAAO,CACL,gCAAoB,uBAAuB,kBAAc,aAAa,YACpE,uCACU,IAAI,OAAG,QAAQ,IACjB,GACD,CACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ import * as React from 'react';
2
+ import type { EditorData } from '../types.js';
3
+ export interface PageHeaderProps {
4
+ /** Shop name rendered as the default heading. */
5
+ readonly shopName: string;
6
+ /** Bearer JWT — forwarded to image uploads. */
7
+ readonly token: string;
8
+ /** Current editor data. The header reads `logoUrl` if present. */
9
+ readonly data: EditorData;
10
+ /** Called when the logo image is replaced via the upload widget. */
11
+ readonly onUpdate: (next: EditorData) => void;
12
+ /** Override fetch (testing). */
13
+ readonly fetchImpl?: typeof fetch;
14
+ }
15
+ /**
16
+ * Minimal `PageHeader` renderer.
17
+ *
18
+ * The hostile `droplinked-editor-configs@1.9.21` shipped a Chakra-themed
19
+ * sticky header with navigation, locale switcher, and cart drawer (~600
20
+ * LoC). This 0.2.0 lands a structural shell: shop name + logo upload
21
+ * slot. The point is to give the host page a place to mount the upload
22
+ * UI so the bug-fix path (Authorization-forwarded /uploader/cdn-upload)
23
+ * is exercisable from a real layout, not just a synthetic test.
24
+ *
25
+ * Navigation / locale / cart are deferred. See README "Porting plan".
26
+ */
27
+ export declare function PageHeader(props: PageHeaderProps): React.JSX.Element;
28
+ //# sourceMappingURL=PageHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageHeader.d.ts","sourceRoot":"","sources":["../../src/components/PageHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,aAAa,CAAC;AAG5D,MAAM,WAAW,eAAe;IAC9B,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IAC9C,gCAAgC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA+BpE"}
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from 'react';
3
+ import { UploadImage } from './UploadImage.js';
4
+ /**
5
+ * Minimal `PageHeader` renderer.
6
+ *
7
+ * The hostile `droplinked-editor-configs@1.9.21` shipped a Chakra-themed
8
+ * sticky header with navigation, locale switcher, and cart drawer (~600
9
+ * LoC). This 0.2.0 lands a structural shell: shop name + logo upload
10
+ * slot. The point is to give the host page a place to mount the upload
11
+ * UI so the bug-fix path (Authorization-forwarded /uploader/cdn-upload)
12
+ * is exercisable from a real layout, not just a synthetic test.
13
+ *
14
+ * Navigation / locale / cart are deferred. See README "Porting plan".
15
+ */
16
+ export function PageHeader(props) {
17
+ const { shopName, token, data, onUpdate, fetchImpl } = props;
18
+ const logoUrl = typeof data.logoUrl === 'string' ? data.logoUrl : '';
19
+ const handleUploaded = React.useCallback((result) => {
20
+ onUpdate({ ...data, logoUrl: result.url });
21
+ }, [data, onUpdate]);
22
+ return (_jsx("header", { "data-testid": "editor-ui-page-header", "data-section": "page-header", children: _jsxs("div", { "data-testid": "editor-ui-section-logo", "data-section": "logo", children: [_jsx("span", { "data-testid": "editor-ui-shop-name", children: shopName }), logoUrl !== '' ? (_jsx("img", { src: logoUrl, alt: `${shopName} logo`, "data-testid": "editor-ui-logo-image" })) : null, _jsx(UploadImage, { token: token, onUploaded: handleUploaded, ...(fetchImpl !== undefined ? { fetchImpl } : {}), label: "Upload logo" })] }) }));
23
+ }
24
+ //# sourceMappingURL=PageHeader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageHeader.js","sourceRoot":"","sources":["../../src/components/PageHeader.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAe/C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC7D,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAErE,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CAAC,MAAoB,EAAQ,EAAE;QAC7B,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7C,CAAC,EACD,CAAC,IAAI,EAAE,QAAQ,CAAC,CACjB,CAAC;IAEF,OAAO,CACL,gCAAoB,uBAAuB,kBAAc,aAAa,YACpE,8BAAiB,wBAAwB,kBAAc,MAAM,aAC3D,8BAAkB,qBAAqB,YAAE,QAAQ,GAAQ,EACxD,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAChB,cACE,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,QAAQ,OAAO,iBACX,sBAAsB,GAClC,CACH,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,WAAW,IACV,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,cAAc,KACtB,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAClD,KAAK,EAAC,aAAa,GACnB,IACE,GACC,CACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,26 @@
1
+ import * as React from 'react';
2
+ import type { UploadResult } from '../types.js';
3
+ export interface UploadImageProps {
4
+ /** Bearer token forwarded as `Authorization: Bearer <token>` to the CDN. */
5
+ readonly token: string;
6
+ /** Called with the uploaded asset URL on success. */
7
+ readonly onUploaded: (result: UploadResult) => void;
8
+ /** Called with the thrown Error on failure. */
9
+ readonly onError?: (err: Error) => void;
10
+ /** Override the upload endpoint (testing / staging). */
11
+ readonly endpoint?: string;
12
+ /** Override fetch implementation (testing). */
13
+ readonly fetchImpl?: typeof fetch;
14
+ /** Accepted MIME types for the underlying `<input type=file>`. */
15
+ readonly accept?: string;
16
+ /** Button label. */
17
+ readonly label?: string;
18
+ }
19
+ /**
20
+ * Minimal image-upload UI. The hostile package shipped a Chakra-themed
21
+ * widget tightly coupled to the editor's zustand store; this 0.1.0 ships
22
+ * a plain unstyled input so the bug-fix can land without dragging Chakra
23
+ * into the dependency graph. Consumers can wrap or replace styles.
24
+ */
25
+ export declare function UploadImage(props: UploadImageProps): React.JSX.Element;
26
+ //# sourceMappingURL=UploadImage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UploadImage.d.ts","sourceRoot":"","sources":["../../src/components/UploadImage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,QAAQ,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IACpD,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IACxC,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB;IACpB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA2CtE"}
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from 'react';
3
+ import { uploadImageToCdn } from '../internal/upload.js';
4
+ /**
5
+ * Minimal image-upload UI. The hostile package shipped a Chakra-themed
6
+ * widget tightly coupled to the editor's zustand store; this 0.1.0 ships
7
+ * a plain unstyled input so the bug-fix can land without dragging Chakra
8
+ * into the dependency graph. Consumers can wrap or replace styles.
9
+ */
10
+ export function UploadImage(props) {
11
+ const { token, onUploaded, onError, endpoint, fetchImpl, accept = 'image/*', label = 'Upload image' } = props;
12
+ const [busy, setBusy] = React.useState(false);
13
+ const inputRef = React.useRef(null);
14
+ const onChange = React.useCallback(async (e) => {
15
+ const file = e.target.files?.[0];
16
+ if (!file)
17
+ return;
18
+ setBusy(true);
19
+ try {
20
+ const result = await uploadImageToCdn(file, {
21
+ token,
22
+ ...(endpoint !== undefined ? { endpoint } : {}),
23
+ ...(fetchImpl !== undefined ? { fetchImpl } : {}),
24
+ });
25
+ onUploaded(result);
26
+ }
27
+ catch (err) {
28
+ const e2 = err instanceof Error ? err : new Error(String(err));
29
+ if (onError)
30
+ onError(e2);
31
+ else
32
+ throw e2;
33
+ }
34
+ finally {
35
+ setBusy(false);
36
+ // Reset so the same file can be re-selected.
37
+ if (inputRef.current)
38
+ inputRef.current.value = '';
39
+ }
40
+ }, [token, endpoint, fetchImpl, onUploaded, onError]);
41
+ return (_jsxs("label", { "data-testid": "editor-ui-upload-image", children: [_jsx("span", { children: busy ? 'Uploading…' : label }), _jsx("input", { ref: inputRef, type: "file", accept: accept, disabled: busy, onChange: onChange, "data-testid": "editor-ui-upload-image-input" })] }));
42
+ }
43
+ //# sourceMappingURL=UploadImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UploadImage.js","sourceRoot":"","sources":["../../src/components/UploadImage.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAoBzD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,GAAG,cAAc,EAAE,GAAG,KAAK,CAAC;IAC9G,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAA0B,IAAI,CAAC,CAAC;IAE7D,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAChC,KAAK,EAAE,CAAsC,EAAiB,EAAE;QAC9D,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE;gBAC1C,KAAK;gBACL,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/C,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAClD,CAAC,CAAC;YACH,UAAU,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,EAAE,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/D,IAAI,OAAO;gBAAE,OAAO,CAAC,EAAE,CAAC,CAAC;;gBACpB,MAAM,EAAE,CAAC;QAChB,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,CAAC;YACf,6CAA6C;YAC7C,IAAI,QAAQ,CAAC,OAAO;gBAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,GAAG,EAAE,CAAC;QACpD,CAAC;IACH,CAAC,EACD,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAClD,CAAC;IAEF,OAAO,CACL,gCAAmB,wBAAwB,aACzC,yBAAO,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,GAAQ,EAC1C,gBACE,GAAG,EAAE,QAAQ,EACb,IAAI,EAAC,MAAM,EACX,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,IAAI,EACd,QAAQ,EAAE,QAAQ,iBACN,8BAA8B,GAC1C,IACI,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ export { Editor } from './components/Editor.js';
2
+ export { UploadImage } from './components/UploadImage.js';
3
+ export type { UploadImageProps } from './components/UploadImage.js';
4
+ export { PageHeader } from './components/PageHeader.js';
5
+ export type { PageHeaderProps } from './components/PageHeader.js';
6
+ export { PageFooter } from './components/PageFooter.js';
7
+ export type { PageFooterProps } from './components/PageFooter.js';
8
+ export { CoverMedia } from './components/CoverMedia.js';
9
+ export type { CoverMediaProps } from './components/CoverMedia.js';
10
+ export { HeroSection } from './components/HeroSection.js';
11
+ export type { HeroSectionProps } from './components/HeroSection.js';
12
+ export { uploadImageToCdn, DEFAULT_UPLOAD_ENDPOINT } from './internal/upload.js';
13
+ export type { EditorData, EditorProps, UploadConfig, UploadResult, } from './types.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACjF,YAAY,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export { Editor } from './components/Editor.js';
2
+ export { UploadImage } from './components/UploadImage.js';
3
+ export { PageHeader } from './components/PageHeader.js';
4
+ export { PageFooter } from './components/PageFooter.js';
5
+ export { CoverMedia } from './components/CoverMedia.js';
6
+ export { HeroSection } from './components/HeroSection.js';
7
+ export { uploadImageToCdn, DEFAULT_UPLOAD_ENDPOINT } from './internal/upload.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { UploadConfig, UploadResult } from '../types.js';
2
+ /**
3
+ * Default droplinked CDN uploader endpoint.
4
+ *
5
+ * The hostile `droplinked-editor-configs@1.9.19` hardcoded this URL inline
6
+ * inside the editor renderer. We keep it as a single named export so any
7
+ * future migration to a runtime-config-injected endpoint is a one-line
8
+ * change, and so consumers can override it in tests or for staging
9
+ * environments.
10
+ */
11
+ export declare const DEFAULT_UPLOAD_ENDPOINT = "https://apiv3.droplinked.com/uploader/cdn-upload";
12
+ /**
13
+ * Upload a binary blob (image) to the droplinked CDN.
14
+ *
15
+ * Bug fix vs hostile `droplinked-editor-configs@1.9.19`: the `token`
16
+ * prop is forwarded as the `Authorization` header. The hostile release
17
+ * accepted a `token` prop on `<Editor>` but the internal upload call did
18
+ * not forward it, which produced 401s after apiv3 PR #1116 made the
19
+ * uploader JWT-required on 2026-05-18. This was the trigger for the
20
+ * supply-chain port.
21
+ *
22
+ * Notes:
23
+ * - We do NOT serialize the token into the request body or the URL.
24
+ * - We do NOT log the token. The token is passed through to `fetch`
25
+ * and not retained.
26
+ * - We use `multipart/form-data` (set automatically by `FormData`).
27
+ * - We do not catch errors silently — caller decides how to surface them.
28
+ */
29
+ export declare function uploadImageToCdn(file: Blob, config: UploadConfig): Promise<UploadResult>;
30
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/internal/upload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE9D;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,qDAAqD,CAAC;AAE1F;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAuC9F"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Default droplinked CDN uploader endpoint.
3
+ *
4
+ * The hostile `droplinked-editor-configs@1.9.19` hardcoded this URL inline
5
+ * inside the editor renderer. We keep it as a single named export so any
6
+ * future migration to a runtime-config-injected endpoint is a one-line
7
+ * change, and so consumers can override it in tests or for staging
8
+ * environments.
9
+ */
10
+ export const DEFAULT_UPLOAD_ENDPOINT = 'https://apiv3.droplinked.com/uploader/cdn-upload';
11
+ /**
12
+ * Upload a binary blob (image) to the droplinked CDN.
13
+ *
14
+ * Bug fix vs hostile `droplinked-editor-configs@1.9.19`: the `token`
15
+ * prop is forwarded as the `Authorization` header. The hostile release
16
+ * accepted a `token` prop on `<Editor>` but the internal upload call did
17
+ * not forward it, which produced 401s after apiv3 PR #1116 made the
18
+ * uploader JWT-required on 2026-05-18. This was the trigger for the
19
+ * supply-chain port.
20
+ *
21
+ * Notes:
22
+ * - We do NOT serialize the token into the request body or the URL.
23
+ * - We do NOT log the token. The token is passed through to `fetch`
24
+ * and not retained.
25
+ * - We use `multipart/form-data` (set automatically by `FormData`).
26
+ * - We do not catch errors silently — caller decides how to surface them.
27
+ */
28
+ export async function uploadImageToCdn(file, config) {
29
+ if (!config.token) {
30
+ throw new Error('[@droplinked_inc/editor-ui] uploadImageToCdn: missing token. ' +
31
+ 'apiv3 /uploader/cdn-upload is JWT-required as of 2026-05-18; ' +
32
+ 'pass the Editor `token` prop through to this call.');
33
+ }
34
+ const endpoint = config.endpoint ?? DEFAULT_UPLOAD_ENDPOINT;
35
+ const fetchImpl = config.fetchImpl ?? fetch;
36
+ const form = new FormData();
37
+ form.append('file', file);
38
+ const res = await fetchImpl(endpoint, {
39
+ method: 'POST',
40
+ headers: {
41
+ // CRUCIAL — this is the line whose absence in 1.9.19 caused the
42
+ // template-builder upload bug. Do not remove without coordinating
43
+ // with apiv3 auth on /uploader/cdn-upload.
44
+ Authorization: `Bearer ${config.token}`,
45
+ },
46
+ body: form,
47
+ });
48
+ if (!res.ok) {
49
+ throw new Error(`[@droplinked_inc/editor-ui] uploadImageToCdn: HTTP ${res.status} ${res.statusText}`);
50
+ }
51
+ const json = (await res.json());
52
+ if (typeof json.url !== 'string' || json.url.length === 0) {
53
+ throw new Error('[@droplinked_inc/editor-ui] uploadImageToCdn: malformed response — expected { url: string }');
54
+ }
55
+ return { url: json.url };
56
+ }
57
+ //# sourceMappingURL=upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/internal/upload.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,kDAAkD,CAAC;AAE1F;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAU,EAAE,MAAoB;IACrE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,+DAA+D;YAC7D,+DAA+D;YAC/D,oDAAoD,CACvD,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,uBAAuB,CAAC;IAC5D,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC;IAE5C,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE1B,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,QAAQ,EAAE;QACpC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,gEAAgE;YAChE,kEAAkE;YAClE,2CAA2C;YAC3C,aAAa,EAAE,UAAU,MAAM,CAAC,KAAK,EAAE;SACxC;QACD,IAAI,EAAE,IAAI;KACX,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,sDAAsD,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CACrF,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsB,CAAC;IACrD,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,6FAA6F,CAC9F,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Public types for `@droplinked_inc/editor-ui`.
3
+ *
4
+ * These mirror the prop surface that consumers of the hostile
5
+ * `droplinked-editor-configs@1.9.19` `Editor` component relied on
6
+ * (see `droplinked-shop-builder/src/pages/template-designer/
7
+ * TemplateDesigner.client.tsx`). They are exported up-front so consumers
8
+ * can compile against `@droplinked_inc/editor-ui` even while the renderer
9
+ * implementation is still being ported.
10
+ */
11
+ /**
12
+ * Minimal data envelope passed in/out of the editor.
13
+ *
14
+ * Intentionally typed as `unknown` payloads at this layer — the canonical
15
+ * shape lives in `@droplinked_inc/editor-configs`. Once that package's
16
+ * `Config` / `Data` types are wired through, this will be tightened.
17
+ */
18
+ export interface EditorData {
19
+ readonly [key: string]: unknown;
20
+ }
21
+ /**
22
+ * Props for the top-level `Editor` renderer.
23
+ *
24
+ * `token` MUST be a fresh JWT obtained by the host application. It is
25
+ * forwarded as `Authorization: Bearer <token>` on every upload call.
26
+ * This is the contract that the hostile 1.9.19 release silently violated
27
+ * (it accepted the prop but did not forward it on the CDN upload), which
28
+ * surfaced as the template-builder upload failure on 2026-05-18 after
29
+ * apiv3 PR #1116 enforced JWT on `/uploader/cdn-upload`.
30
+ */
31
+ export interface EditorProps {
32
+ readonly initialData: EditorData;
33
+ readonly shopName: string;
34
+ readonly onUpdate: (next: EditorData) => void;
35
+ readonly publishLoading?: boolean;
36
+ readonly iframe?: boolean;
37
+ readonly themeName?: string;
38
+ readonly isLive?: boolean;
39
+ readonly isNewTheme?: boolean;
40
+ readonly onExit?: () => void;
41
+ readonly updateData?: (next: EditorData) => void;
42
+ readonly token: string;
43
+ /**
44
+ * Inject a `fetch` implementation. Defaults to global `fetch`. Tests
45
+ * pass a `jest.fn()`; production hosts should omit this prop.
46
+ */
47
+ readonly fetchImpl?: typeof fetch;
48
+ }
49
+ /**
50
+ * Result of a successful upload to the droplinked CDN.
51
+ */
52
+ export interface UploadResult {
53
+ readonly url: string;
54
+ }
55
+ /**
56
+ * Configuration for `uploadImageToCdn` and the `<UploadImage>` component.
57
+ */
58
+ export interface UploadConfig {
59
+ /**
60
+ * Bearer token forwarded as `Authorization: Bearer <token>`. Required —
61
+ * `/uploader/cdn-upload` rejects unauthenticated requests as of apiv3
62
+ * PR #1116.
63
+ */
64
+ readonly token: string;
65
+ /**
66
+ * Override the upload endpoint. Defaults to the droplinked production
67
+ * apiv3 CDN uploader. Tests inject a stub here.
68
+ */
69
+ readonly endpoint?: string;
70
+ /**
71
+ * Inject a `fetch` implementation. Defaults to global `fetch`. Tests
72
+ * inject a jest.fn().
73
+ */
74
+ readonly fetchImpl?: typeof fetch;
75
+ }
76
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC"}
package/dist/types.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Public types for `@droplinked_inc/editor-ui`.
3
+ *
4
+ * These mirror the prop surface that consumers of the hostile
5
+ * `droplinked-editor-configs@1.9.19` `Editor` component relied on
6
+ * (see `droplinked-shop-builder/src/pages/template-designer/
7
+ * TemplateDesigner.client.tsx`). They are exported up-front so consumers
8
+ * can compile against `@droplinked_inc/editor-ui` even while the renderer
9
+ * implementation is still being ported.
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@droplinked_inc/editor-ui",
3
+ "version": "0.3.0",
4
+ "description": "Renderer + image-upload UI for the @droplinked_inc visual editor. Initial rebuild port of the page-level renderer from the hostile droplinked-editor-configs@1.9.19. Most surface area is intentionally stubbed in this 0.1.0 — see README for the porting plan.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md",
19
+ "THREAT_MODEL.md",
20
+ "LICENSE"
21
+ ],
22
+ "peerDependencies": {
23
+ "@droplinked_inc/editor-configs": "^0.1.0",
24
+ "react": "^18.0.0 || ^19.0.0",
25
+ "react-dom": "^18.0.0 || ^19.0.0"
26
+ },
27
+ "devDependencies": {
28
+ "@testing-library/jest-dom": "^6.6.3",
29
+ "@testing-library/react": "^16.1.0",
30
+ "@testing-library/user-event": "^14.6.1",
31
+ "@types/jest": "^29.5.14",
32
+ "@types/react": "^19.0.0",
33
+ "@types/react-dom": "^19.0.0",
34
+ "jest-environment-jsdom": "^29.7.0",
35
+ "react": "^19.0.0",
36
+ "react-dom": "^19.0.0",
37
+ "@droplinked_inc/editor-configs": "0.1.1"
38
+ },
39
+ "publishConfig": {
40
+ "provenance": false,
41
+ "access": "public"
42
+ },
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "git+https://github.com/droplinked/droplink-packages.git",
46
+ "directory": "packages/editor-ui"
47
+ },
48
+ "homepage": "https://github.com/droplinked/droplink-packages/tree/main/packages/editor-ui#readme",
49
+ "bugs": {
50
+ "url": "https://github.com/droplinked/droplink-packages/issues"
51
+ },
52
+ "engines": {
53
+ "node": ">=22.0.0"
54
+ },
55
+ "scripts": {
56
+ "build": "tsc -p tsconfig.json",
57
+ "test": "jest",
58
+ "test:coverage": "jest --coverage",
59
+ "lint": "eslint src",
60
+ "typecheck": "tsc --noEmit -p tsconfig.json"
61
+ }
62
+ }