@nuasite/cms 0.9.0 → 0.9.1

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/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "directory": "packages/astro-cms"
15
15
  },
16
16
  "license": "Apache-2.0",
17
- "version": "0.9.0",
17
+ "version": "0.9.1",
18
18
  "module": "src/index.ts",
19
19
  "types": "src/index.ts",
20
20
  "type": "module",
@@ -10,7 +10,7 @@ export interface ToolbarCallbacks {
10
10
  onCompare: () => void
11
11
  onSave: () => void
12
12
  onDiscard: () => void
13
- onAIChat?: () => void
13
+ onSelectElement?: () => void
14
14
  onMediaLibrary?: () => void
15
15
  onDismissDeployment?: () => void
16
16
  onNavigateChange?: () => void
@@ -97,7 +97,6 @@ const DeploymentStatusIndicator = ({ onDismiss }: { onDismiss?: () => void }) =>
97
97
  export const Toolbar = ({ callbacks, collectionDefinitions }: ToolbarProps) => {
98
98
  const isEditing = signals.isEditing.value
99
99
  const showingOriginal = signals.showingOriginal.value
100
- const isChatOpen = signals.isChatOpen.value
101
100
  const dirtyCount = signals.totalDirtyCount.value
102
101
  const isSaving = signals.isSaving.value
103
102
  const deploymentStatus = signals.deploymentStatus.value
@@ -107,7 +106,6 @@ export const Toolbar = ({ callbacks, collectionDefinitions }: ToolbarProps) => {
107
106
  const [isMenuOpen, setIsMenuOpen] = useState(false)
108
107
 
109
108
  if (isPreviewingMarkdown) return null
110
- if (isChatOpen && !isEditing) return null
111
109
 
112
110
  const showDeploymentStatus = deploymentStatus !== null
113
111
 
@@ -126,21 +124,23 @@ export const Toolbar = ({ callbacks, collectionDefinitions }: ToolbarProps) => {
126
124
  }
127
125
  }
128
126
 
129
- const isToolbarOpen = isEditing
127
+ const isSelectMode = signals.isSelectMode.value
128
+ const isToolbarOpen = isEditing || isSelectMode
130
129
 
131
130
  // Build menu items dynamically
132
131
  const menuItems: Array<{ label: string; icon: ComponentChildren; onClick: () => void; isActive?: boolean }> = []
133
132
 
134
- if (callbacks.onAIChat) {
133
+ if (callbacks.onSelectElement) {
135
134
  menuItems.push({
136
- label: 'AI Chat',
135
+ label: 'Select Element',
137
136
  icon: (
138
137
  <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
139
- <path d="M12 3l1.912 5.813a2 2 0 0 0 1.275 1.275L21 12l-5.813 1.912a2 2 0 0 0-1.275 1.275L12 21l-1.912-5.813a2 2 0 0 0-1.275-1.275L3 12l5.813-1.912a2 2 0 0 0 1.275-1.275L12 3z" />
138
+ <path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z" />
139
+ <path d="M13 13l6 6" />
140
140
  </svg>
141
141
  ),
142
- onClick: () => callbacks.onAIChat?.(),
143
- isActive: isChatOpen,
142
+ onClick: () => callbacks.onSelectElement?.(),
143
+ isActive: isSelectMode,
144
144
  })
145
145
  }
146
146
 
@@ -58,9 +58,9 @@ export function useElementDetection(): OutlineState {
58
58
  useEffect(() => {
59
59
  const handleMouseMove = (ev: MouseEvent) => {
60
60
  const isEditing = signals.isEditing.value
61
- const chatOpen = signals.isChatOpen.value
61
+ const selectMode = signals.isSelectMode.value
62
62
 
63
- if (!isEditing && !chatOpen) {
63
+ if (!isEditing && !selectMode) {
64
64
  if (hideTimeoutRef.current) {
65
65
  clearTimeout(hideTimeoutRef.current)
66
66
  hideTimeoutRef.current = null
@@ -89,34 +89,6 @@ export function useElementDetection(): OutlineState {
89
89
  const manifest = signals.manifest.value
90
90
  const entries = manifest.entries
91
91
 
92
- // When chat is open, only detect components (not text/image elements)
93
- if (chatOpen) {
94
- const componentEl = getComponentAtPosition(ev.clientX, ev.clientY)
95
- if (componentEl) {
96
- if (hideTimeoutRef.current) {
97
- clearTimeout(hideTimeoutRef.current)
98
- hideTimeoutRef.current = null
99
- }
100
- const rect = componentEl.getBoundingClientRect()
101
- const componentId = componentEl.getAttribute(CSS.COMPONENT_ID_ATTRIBUTE)
102
- const instance = componentId ? getComponentInstance(manifest, componentId) : null
103
-
104
- setOutlineState({
105
- visible: true,
106
- rect,
107
- isComponent: true,
108
- componentName: instance?.componentName,
109
- tagName: componentEl.tagName.toLowerCase(),
110
- element: componentEl,
111
- cmsId: null,
112
- })
113
- return
114
- }
115
-
116
- setOutlineState(INITIAL_STATE)
117
- return
118
- }
119
-
120
92
  // Use the improved elementsFromPoint-based detection
121
93
  const cmsEl = getCmsElementAtPosition(ev.clientX, ev.clientY, entries)
122
94
 
@@ -222,8 +194,8 @@ export function useComponentClickHandler({
222
194
  useEffect(() => {
223
195
  const handleClick = (ev: MouseEvent) => {
224
196
  const isEditing = signals.isEditing.value
225
- const chatOpen = signals.isChatOpen.value
226
- if (!isEditing && !chatOpen) return
197
+ const selectMode = signals.isSelectMode.value
198
+ if (!isEditing && !selectMode) return
227
199
 
228
200
  // Ignore clicks on CMS UI elements
229
201
  if (isEventOnCmsUI(ev)) return
@@ -231,20 +203,6 @@ export function useComponentClickHandler({
231
203
  const manifest = signals.manifest.value
232
204
  const entries = manifest.entries
233
205
 
234
- if (chatOpen) {
235
- // When chat is open, only select components
236
- const componentEl = getComponentAtPosition(ev.clientX, ev.clientY)
237
- if (componentEl) {
238
- const componentId = componentEl.getAttribute(CSS.COMPONENT_ID_ATTRIBUTE)
239
- if (componentId) {
240
- ev.preventDefault()
241
- ev.stopPropagation()
242
- signals.setChatContextElement(componentId)
243
- }
244
- }
245
- return
246
- }
247
-
248
206
  // Normal editing mode behavior
249
207
  // Check for text element first
250
208
  const textEl = getCmsElementAtPosition(ev.clientX, ev.clientY, entries)
@@ -1,17 +1,7 @@
1
1
  import { render } from 'preact'
2
2
  import { useCallback, useEffect, useRef } from 'preact/hooks'
3
3
  import type { CmsElementDeselectedMessage, CmsElementSelectedMessage } from '../types'
4
- import {
5
- buildEditorState,
6
- buildPageNavigatedMessage,
7
- buildReadyMessage,
8
- buildSelectedElement,
9
- buildStateChangedMessage,
10
- postToParent,
11
- } from './post-message'
12
4
  import { fetchManifest } from './api'
13
- import { AIChat } from './components/ai-chat'
14
- import { AITooltip } from './components/ai-tooltip'
15
5
  import { AttributeEditor } from './components/attribute-editor'
16
6
  import { BgImageOverlay } from './components/bg-image-overlay'
17
7
  import { BlockEditor } from './components/block-editor'
@@ -43,7 +33,6 @@ import {
43
33
  } from './editor'
44
34
  import { canRedo, canUndo, performRedo, performUndo } from './history'
45
35
  import {
46
- useAIHandlers,
47
36
  useBgImageHoverDetection,
48
37
  useBlockEditorHandlers,
49
38
  useComponentClickHandler,
@@ -52,6 +41,14 @@ import {
52
41
  useTextSelection,
53
42
  useTooltipState,
54
43
  } from './hooks'
44
+ import {
45
+ buildEditorState,
46
+ buildPageNavigatedMessage,
47
+ buildReadyMessage,
48
+ buildSelectedElement,
49
+ buildStateChangedMessage,
50
+ postToParent,
51
+ } from './post-message'
55
52
  import {
56
53
  openCollectionsBrowser,
57
54
  openMarkdownEditorForCurrentPage,
@@ -218,20 +215,6 @@ const CmsUI = () => {
218
215
  postToParent(buildStateChangedMessage(state))
219
216
  })
220
217
 
221
- const {
222
- handleAIChatToggle,
223
- handleChatClose,
224
- handleChatCancel,
225
- handleTooltipPromptSubmit,
226
- handleChatSend,
227
- handleApplyToElement,
228
- } = useAIHandlers({
229
- config,
230
- showToast: signals.showToast,
231
- onTooltipHide: hideTooltip,
232
- onUIUpdate: updateUI,
233
- })
234
-
235
218
  const {
236
219
  blockEditorCursor,
237
220
  handleComponentSelect,
@@ -252,6 +235,7 @@ const CmsUI = () => {
252
235
  hideTooltip()
253
236
  stopEditMode(updateUI)
254
237
  } else {
238
+ signals.isSelectMode.value = false
255
239
  await startEditMode(config, updateUI)
256
240
  }
257
241
  }, [config, updateUI, hideTooltip])
@@ -310,6 +294,10 @@ const CmsUI = () => {
310
294
  openSeoEditor()
311
295
  }, [])
312
296
 
297
+ const handleSelectElementToggle = useCallback(() => {
298
+ signals.isSelectMode.value = !signals.isSelectMode.value
299
+ }, [])
300
+
313
301
  // Color toolbar handlers
314
302
  const handleColorToolbarChange = useCallback(
315
303
  (
@@ -409,7 +397,6 @@ const CmsUI = () => {
409
397
  // Get reactive values from signals
410
398
  const isEditing = signals.isEditing.value
411
399
  const isAIProcessing = signals.isAIProcessing.value
412
- const isChatOpen = signals.isChatOpen.value
413
400
  const blockEditorState = signals.blockEditorState.value
414
401
  const colorEditorState = signals.colorEditorState.value
415
402
  const manifest = signals.manifest.value
@@ -485,6 +472,7 @@ const CmsUI = () => {
485
472
  onCompare: handleCompare,
486
473
  onSave: handleSave,
487
474
  onDiscard: handleDiscard,
475
+ onSelectElement: handleSelectElementToggle,
488
476
  onMediaLibrary: handleMediaLibrary,
489
477
  onDismissDeployment: handleDismissDeployment,
490
478
  onNavigateChange: () => {
@@ -213,6 +213,7 @@ function createInitialAttributeEditorState(): AttributeEditorState {
213
213
 
214
214
  export const isEnabled = signal(false)
215
215
  export const isEditing = signal(false)
216
+ export const isSelectMode = signal(false)
216
217
  export const isSaving = signal(false)
217
218
  export const showingOriginal = signal(false)
218
219
  export const currentEditingId = signal<string | null>(null)