@jhits/plugin-content 0.0.11 → 0.0.12

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.
@@ -1,2 +1,8 @@
1
- export default function TranslationEditor(): import("react/jsx-runtime").JSX.Element | null;
1
+ interface TranslationEditorProps {
2
+ messages: Record<string, any>;
3
+ locale: string;
4
+ }
5
+ declare function TranslationEditorInner({ messages: initialMessages, locale: initialLocale }: TranslationEditorProps): import("react/jsx-runtime").JSX.Element | null;
6
+ export default TranslationEditorInner;
7
+ export type { TranslationEditorProps };
2
8
  //# sourceMappingURL=TranslationEditor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TranslationEditor.d.ts","sourceRoot":"","sources":["../../src/components/TranslationEditor.tsx"],"names":[],"mappings":"AASA,MAAM,CAAC,OAAO,UAAU,iBAAiB,mDA4SxC"}
1
+ {"version":3,"file":"TranslationEditor.d.ts","sourceRoot":"","sources":["../../src/components/TranslationEditor.tsx"],"names":[],"mappings":"AAQA,UAAU,sBAAsB;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,iBAAS,sBAAsB,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,sBAAsB,kDA8S3G;AAeD,eAAe,sBAAsB,CAAC;AACtC,YAAY,EAAE,sBAAsB,EAAE,CAAC"}
@@ -2,31 +2,57 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useRouter, usePathname } from 'next/navigation';
4
4
  import { useState, useEffect, useMemo, useRef } from 'react';
5
- import { useLocale, useMessages } from 'next-intl';
6
5
  import { motion, AnimatePresence } from 'framer-motion';
7
6
  import { X, Globe, Search, ChevronRight, Plus, CornerDownRight, ShieldCheck, Lock, Bold, Italic, Type } from 'lucide-react';
8
7
  import { parse } from '../utils/parser';
9
- export default function TranslationEditor() {
8
+ function TranslationEditorInner({ messages: initialMessages, locale: initialLocale }) {
10
9
  const router = useRouter();
11
10
  const pathname = usePathname();
12
- const messages = useMessages();
13
- const locale = useLocale();
11
+ const [mounted, setMounted] = useState(false);
14
12
  const [open, setOpen] = useState(false);
15
13
  const [userData, setUserData] = useState(null);
16
14
  const [loadingAuth, setLoadingAuth] = useState(true);
17
- const [jsonData, setJsonData] = useState(messages);
15
+ const [jsonData, setJsonData] = useState(initialMessages);
18
16
  const [searchQuery, setSearchQuery] = useState('');
19
17
  const [saving, setSaving] = useState(false);
20
18
  const [activePath, setActivePath] = useState(null);
21
19
  const [showAddForm, setShowAddForm] = useState(false);
22
20
  const [newKey, setNewKey] = useState('');
23
21
  const [newValue, setNewValue] = useState('');
24
- // Get all top-level keys for the dropdown (home, about, services, etc.)
22
+ const [selectedSection, setSelectedSection] = useState('');
23
+ const textareaRefs = useRef({});
24
+ // All useMemo calls
25
25
  const availableSections = useMemo(() => {
26
26
  return Object.keys(jsonData).filter(key => typeof jsonData[key] === 'object');
27
27
  }, [jsonData]);
28
- const [selectedSection, setSelectedSection] = useState('');
29
- const textareaRefs = useRef({});
28
+ const filteredItems = useMemo(() => {
29
+ const allPaths = getFlattenedPaths(jsonData);
30
+ const filtered = allPaths.filter(item => {
31
+ if (activePath === item.path)
32
+ return true;
33
+ const matchesSearch = item.path.toLowerCase().includes(searchQuery.toLowerCase()) ||
34
+ item.value.toLowerCase().includes(searchQuery.toLowerCase());
35
+ if (searchQuery)
36
+ return matchesSearch;
37
+ return item.path.startsWith(`${selectedSection}.`) || item.path.startsWith('common.');
38
+ });
39
+ return [...filtered].sort((a, b) => {
40
+ const getPriority = (path) => {
41
+ if (path.startsWith(`${selectedSection}.`))
42
+ return 1;
43
+ if (path.startsWith('common.'))
44
+ return 3;
45
+ return 2;
46
+ };
47
+ const priorityA = getPriority(a.path);
48
+ const priorityB = getPriority(b.path);
49
+ return priorityA !== priorityB ? priorityA - priorityB : a.path.localeCompare(b.path);
50
+ });
51
+ }, [jsonData, searchQuery, selectedSection, activePath]);
52
+ // All useEffect calls
53
+ useEffect(() => {
54
+ setMounted(true);
55
+ }, []);
30
56
  useEffect(() => {
31
57
  async function checkAuth() {
32
58
  try {
@@ -46,19 +72,36 @@ export default function TranslationEditor() {
46
72
  }, []);
47
73
  useEffect(() => {
48
74
  const handleLocaleUpdate = (event) => {
49
- if (event.detail.locale === locale) {
75
+ if (event.detail.locale === initialLocale) {
50
76
  setJsonData(event.detail.messages);
51
77
  router.refresh();
52
78
  }
53
79
  };
54
80
  window.addEventListener('locale-updated', handleLocaleUpdate);
55
81
  return () => window.removeEventListener('locale-updated', handleLocaleUpdate);
56
- }, [locale, router]);
82
+ }, [initialLocale, router]);
57
83
  useEffect(() => {
58
- setJsonData(messages);
59
- }, [messages]);
84
+ setJsonData(initialMessages);
85
+ }, [initialMessages]);
86
+ useEffect(() => {
87
+ const parts = pathname.split('/').filter(Boolean);
88
+ const cleanParts = (parts[0]?.length === 2) ? parts.slice(1) : parts;
89
+ const urlKey = cleanParts[0] || 'home';
90
+ if (availableSections.includes(urlKey)) {
91
+ setSelectedSection(urlKey);
92
+ }
93
+ else if (availableSections.length > 0 && !selectedSection) {
94
+ setSelectedSection(availableSections[0]);
95
+ }
96
+ }, [pathname, availableSections, selectedSection]);
97
+ // Don't render anything until mounted
98
+ if (!mounted) {
99
+ return null;
100
+ }
60
101
  const isAdmin = userData?.role === 'admin' || userData?.role === 'dev';
61
102
  const isDev = userData?.role === 'dev';
103
+ if (loadingAuth || !isAdmin)
104
+ return null;
62
105
  const applyFormatting = (path, type) => {
63
106
  const el = textareaRefs.current[path];
64
107
  if (!el)
@@ -126,13 +169,13 @@ export default function TranslationEditor() {
126
169
  const res = await fetch('/api/plugin-content/save', {
127
170
  method: 'POST',
128
171
  headers: { 'Content-Type': 'application/json' },
129
- body: JSON.stringify({ locale, messages: jsonData }),
172
+ body: JSON.stringify({ locale: initialLocale, messages: jsonData }),
130
173
  });
131
174
  if (res.ok) {
132
175
  router.refresh();
133
176
  setShowAddForm(false);
134
177
  window.dispatchEvent(new CustomEvent('locale-updated', {
135
- detail: { locale, messages: jsonData }
178
+ detail: { locale: initialLocale, messages: jsonData }
136
179
  }));
137
180
  }
138
181
  else {
@@ -154,46 +197,6 @@ export default function TranslationEditor() {
154
197
  setNewValue('');
155
198
  setShowAddForm(false);
156
199
  };
157
- // Set the initial section based on the URL, but only if it matches a JSON key
158
- useEffect(() => {
159
- const parts = pathname.split('/').filter(Boolean);
160
- const cleanParts = (parts[0]?.length === 2) ? parts.slice(1) : parts;
161
- const urlKey = cleanParts[0] || 'home';
162
- // If "over-mij" isn't in JSON, but "about" is, this helps her pick
163
- if (availableSections.includes(urlKey)) {
164
- setSelectedSection(urlKey);
165
- }
166
- else if (availableSections.length > 0 && !selectedSection) {
167
- setSelectedSection(availableSections[0]);
168
- }
169
- }, [pathname, availableSections]);
170
- const filteredItems = useMemo(() => {
171
- const allPaths = getFlattenedPaths(jsonData);
172
- const filtered = allPaths.filter(item => {
173
- if (activePath === item.path)
174
- return true;
175
- const matchesSearch = item.path.toLowerCase().includes(searchQuery.toLowerCase()) ||
176
- item.value.toLowerCase().includes(searchQuery.toLowerCase());
177
- if (searchQuery)
178
- return matchesSearch;
179
- // Default view: Selected Section + Common
180
- return item.path.startsWith(`${selectedSection}.`) || item.path.startsWith('common.');
181
- });
182
- return [...filtered].sort((a, b) => {
183
- const getPriority = (path) => {
184
- if (path.startsWith(`${selectedSection}.`))
185
- return 1;
186
- if (path.startsWith('common.'))
187
- return 3;
188
- return 2;
189
- };
190
- const priorityA = getPriority(a.path);
191
- const priorityB = getPriority(b.path);
192
- return priorityA !== priorityB ? priorityA - priorityB : a.path.localeCompare(b.path);
193
- });
194
- }, [jsonData, searchQuery, selectedSection, activePath]);
195
- if (loadingAuth || !isAdmin)
196
- return null;
197
200
  return (_jsxs(_Fragment, { children: [_jsxs("button", { onClick: () => setOpen(true), className: "fixed bottom-6 right-6 bg-neutral-950 dark:bg-white text-white dark:text-neutral-950 px-6 py-3 rounded-full flex items-center gap-3 shadow-2xl z-50 hover:bg-neutral-900 dark:hover:bg-neutral-100 transition-all border border-neutral-800/20 dark:border-neutral-200/20", children: [_jsx(Globe, { size: 18 }), " ", _jsx("span", { className: "font-bold", children: "Editor" })] }), _jsx(AnimatePresence, { children: open && (_jsxs(_Fragment, { children: [_jsx(motion.div, { className: "fixed inset-0 bg-neutral-950/50 dark:bg-neutral-950/70 z-40", initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, onClick: () => setOpen(false) }), _jsxs(motion.div, { className: "fixed right-0 top-0 bottom-0 bg-card text-foreground shadow-2xl z-50 flex flex-col border-l border-border w-[550px]", initial: { x: '100%' }, animate: { x: 0 }, exit: { x: '100%' }, children: [_jsxs("div", { className: "p-6 bg-card border-b border-border flex justify-between items-center", children: [_jsxs("div", { children: [_jsxs("h2", { className: "text-2xl font-serif flex items-center gap-2", children: [isDev ? 'Dev Mode' : 'Content Editor', isDev ? _jsx(ShieldCheck, { className: "text-primary", size: 20 }) : _jsx(Lock, { className: "text-primary", size: 16 })] }), _jsxs("p", { className: "text-[10px] uppercase font-bold text-neutral-500 dark:text-neutral-400", children: ["Welkom, ", userData?.name] })] }), _jsxs("div", { className: "flex gap-2", children: [isDev && (_jsx("button", { onClick: () => setShowAddForm(!showAddForm), className: `p-2 rounded-full transition-colors ${showAddForm ? 'bg-primary text-white' : 'hover:bg-neutral-100 dark:hover:bg-neutral-800 text-neutral-600 dark:text-neutral-400'}`, children: _jsx(Plus, { size: 22 }) })), _jsx("button", { onClick: () => setOpen(false), className: "p-2 hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-full text-neutral-600 dark:text-neutral-400", children: _jsx(X, { size: 24 }) })] })] }), isDev && showAddForm && (_jsxs(motion.div, { initial: { height: 0 }, animate: { height: 'auto' }, className: "bg-neutral-100/50 dark:bg-neutral-800/50 border-b border-border p-6 space-y-4 overflow-hidden", children: [_jsx("input", { value: newKey, onChange: e => setNewKey(e.target.value), placeholder: "pagina.sectie.sleutel", className: "w-full p-3 rounded-xl border border-border bg-card text-foreground placeholder:text-neutral-500 dark:placeholder:text-neutral-400 text-sm font-mono" }), _jsx("textarea", { value: newValue, onChange: e => setNewValue(e.target.value), placeholder: "Nieuwe vertaling...", className: "w-full p-3 rounded-xl border border-border bg-card text-foreground placeholder:text-neutral-500 dark:placeholder:text-neutral-400 text-sm min-h-[80px]" }), _jsxs("button", { onClick: addNewEntry, className: "w-full py-3 bg-primary text-white rounded-xl font-bold text-sm flex items-center justify-center gap-2", children: [_jsx(CornerDownRight, { size: 16 }), " Toevoegen"] })] })), _jsx("div", { className: "px-6 py-4 bg-card border-b border-border", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-500 dark:text-neutral-400" }), _jsx("input", { type: "text", placeholder: "Zoek in teksten...", className: "w-full pl-10 pr-4 py-2.5 bg-neutral-100/50 dark:bg-neutral-800/50 border border-border rounded-xl focus:outline-none focus:ring-2 focus:ring-primary/20 text-foreground placeholder:text-neutral-500 dark:placeholder:text-neutral-400", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value) })] }) }), _jsx("div", { className: "flex-1 overflow-y-auto p-6 space-y-10 bg-background pb-32", children: filteredItems.map((item) => (_jsxs("div", { className: "group relative", children: [_jsxs("div", { className: "flex justify-between items-center mb-3", children: [_jsx("div", { className: "flex items-center gap-2", children: item.path.split('.').map((part, i, arr) => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: `px-2 py-1 rounded-md text-[10px] font-bold uppercase tracking-wider ${i === arr.length - 1 ? 'bg-primary text-white' : 'bg-neutral-100 dark:bg-neutral-800 text-neutral-600 dark:text-neutral-400 border border-border'}`, children: part.replace(/_/g, ' ') }), i !== arr.length - 1 && _jsx(ChevronRight, { size: 10, className: "text-neutral-400 dark:text-neutral-500" })] }, i))) }), _jsx(AnimatePresence, { children: activePath === item.path && (_jsxs(motion.div, { initial: { opacity: 0, y: 5 }, animate: { opacity: 1, y: 0 }, className: "formatting-toolbar flex gap-1 bg-card border border-border rounded-lg p-1 shadow-sm", children: [_jsx("button", { type: "button", tabIndex: -1, onClick: () => applyFormatting(item.path, 'bold'), className: "p-1.5 hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded text-foreground", children: _jsx(Bold, { size: 14 }) }), _jsx("button", { type: "button", tabIndex: -1, onClick: () => applyFormatting(item.path, 'italic'), className: "p-1.5 hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded text-foreground", children: _jsx(Italic, { size: 14 }) }), _jsx("button", { type: "button", tabIndex: -1, onClick: () => applyFormatting(item.path, 'both'), className: "p-1.5 hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded text-foreground", children: _jsx(Type, { size: 14 }) })] })) })] }), _jsxs("div", { className: "relative w-full min-h-[60px]", children: [_jsx("div", { className: "absolute inset-0 p-5 text-lg leading-relaxed pointer-events-none whitespace-pre-wrap break-words border-2 border-transparent text-foreground", "aria-hidden": "true", children: parse(item.value, true) }), _jsx("textarea", { ref: (el) => { textareaRefs.current[item.path] = el; }, className: `
198
201
  w-full p-5 bg-transparent border-2 rounded-2xl
199
202
  text-transparent caret-primary leading-relaxed shadow-sm
@@ -222,3 +225,4 @@ function getFlattenedPaths(obj, prefix = '') {
222
225
  }
223
226
  return paths;
224
227
  }
228
+ export default TranslationEditorInner;
package/dist/index.d.ts CHANGED
@@ -5,19 +5,22 @@
5
5
  export interface ContentPluginProps {
6
6
  /** Whether to show the editor (default: true) */
7
7
  enabled?: boolean;
8
+ /** Locale string - can be passed explicitly or will be fetched from context */
9
+ locale?: string;
10
+ /** Messages object - can be passed explicitly or will be fetched from context */
11
+ messages?: Record<string, any>;
8
12
  }
9
13
  /**
10
14
  * Content Plugin Component
11
15
  * Renders the translation editor for editing website content
12
16
  */
13
- declare function ContentPlugin({ enabled }: ContentPluginProps): import("react/jsx-runtime").JSX.Element | null;
14
- export default ContentPlugin;
17
+ export default function ContentPlugin({ enabled, locale, messages }: ContentPluginProps): import("react/jsx-runtime").JSX.Element | null;
15
18
  export { ContentPlugin };
16
- export { default as TranslationEditor } from './components/TranslationEditor';
17
19
  export { default as MultilineText } from './components/MultilineText';
18
20
  export type { MultilineTextProps } from './components/MultilineText';
19
21
  export { default as ParsedText } from './components/ParsedText';
20
22
  export type { ParsedTextProps } from './components/ParsedText';
23
+ export type { TranslationEditorProps } from './components/TranslationEditor';
21
24
  export { ParserConfigProvider, useParserConfig } from './context/ParserConfigContext';
22
25
  export type { ParserConfigProviderProps } from './context/ParserConfigContext';
23
26
  export { useParse } from './hooks/useParse';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,kBAAkB;IAC/B,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,iBAAS,aAAa,CAAC,EAAE,OAAc,EAAE,EAAE,kBAAkB,kDAI5D;AAGD,eAAe,aAAa,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,CAAC;AAGzB,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACtE,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG/D,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACtF,YAAY,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAG/E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAItD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,WAAW,kBAAkB;IAC/B,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AAoBD;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,OAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,kBAAkB,kDAmB7F;AAkBD,OAAO,EAAE,aAAa,EAAE,CAAC;AAGzB,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACtE,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAG7E,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACtF,YAAY,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAG/E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAItD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -3,22 +3,44 @@
3
3
  * Provides content editing functionality for website translations
4
4
  */
5
5
  'use client';
6
- import { jsx as _jsx } from "react/jsx-runtime";
7
- import TranslationEditor from './components/TranslationEditor';
6
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
7
+ import { useState, useEffect, lazy, Suspense } from 'react';
8
+ const TranslationEditor = lazy(() => import('./components/TranslationEditor'));
9
+ function ContentPluginWithIntl({ locale, messages }) {
10
+ return (_jsx(Suspense, { fallback: null, children: _jsx(TranslationEditor, { messages: messages, locale: locale }) }));
11
+ }
12
+ function ClientOnly({ children }) {
13
+ const [mounted, setMounted] = useState(false);
14
+ useEffect(() => {
15
+ setMounted(true);
16
+ }, []);
17
+ return mounted ? _jsx(_Fragment, { children: children }) : null;
18
+ }
8
19
  /**
9
20
  * Content Plugin Component
10
21
  * Renders the translation editor for editing website content
11
22
  */
12
- function ContentPlugin({ enabled = true }) {
23
+ export default function ContentPlugin({ enabled = true, locale, messages }) {
13
24
  if (!enabled)
14
25
  return null;
15
- return _jsx(TranslationEditor, {});
26
+ // If locale and messages are provided as props, use them directly
27
+ if (locale && messages) {
28
+ return (_jsx(ClientOnly, { children: _jsx(ContentPluginWithIntl, { locale: locale, messages: messages }) }));
29
+ }
30
+ // Otherwise, try to use context (for backward compatibility)
31
+ // This path might have issues with context not being found
32
+ return (_jsx(ClientOnly, { children: _jsx(ContentPluginWithIntlFallback, {}) }));
33
+ }
34
+ function ContentPluginWithIntlFallback() {
35
+ // Dynamic import to avoid SSR issues with next-intl hooks
36
+ const { useMessages, useLocale, NextIntlClientProvider } = require('next-intl');
37
+ const messages = useMessages();
38
+ const locale = useLocale();
39
+ return (_jsx(NextIntlClientProvider, { locale: locale, messages: messages, children: _jsx(Suspense, { fallback: null, children: _jsx(TranslationEditor, { messages: messages, locale: locale }) }) }));
16
40
  }
17
- // Export as both default and named export for flexibility
18
- export default ContentPlugin;
41
+ // Export named export for flexibility
19
42
  export { ContentPlugin };
20
43
  // Export components
21
- export { default as TranslationEditor } from './components/TranslationEditor';
22
44
  export { default as MultilineText } from './components/MultilineText';
23
45
  export { default as ParsedText } from './components/ParsedText';
24
46
  // Export context
package/package.json CHANGED
@@ -1,26 +1,33 @@
1
1
  {
2
2
  "name": "@jhits/plugin-content",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "description": "Content management and localization plugin for the JHITS ecosystem",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
8
- "main": "./dist/index.js",
9
- "types": "./dist/index.d.ts",
8
+ "main": "./src/index.ts",
9
+ "types": "./src/index.ts",
10
10
  "exports": {
11
11
  ".": {
12
- "types": "./dist/index.d.ts",
13
- "default": "./dist/index.js"
12
+ "types": "./src/index.tsx",
13
+ "import": "./src/index.tsx",
14
+ "default": "./src/index.tsx"
15
+ },
16
+ "./src": {
17
+ "types": "./src/index.tsx",
18
+ "import": "./src/index.tsx",
19
+ "default": "./src/index.tsx"
14
20
  },
15
21
  "./server": {
16
- "types": "./dist/index.server.d.ts",
17
- "default": "./dist/index.server.js"
22
+ "types": "./src/index.server.ts",
23
+ "import": "./src/index.server.ts",
24
+ "default": "./src/index.server.ts"
18
25
  }
19
26
  },
20
27
  "dependencies": {
21
28
  "framer-motion": "^12.34.0",
22
29
  "lucide-react": "^0.564.0",
23
- "@jhits/plugin-core": "0.0.6"
30
+ "@jhits/plugin-core": "0.0.7"
24
31
  },
25
32
  "peerDependencies": {
26
33
  "next": ">=15.0.0",