betterstart-cli 0.0.111 → 0.0.113

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.
@@ -112,7 +112,7 @@ export function MediaUrlImporter({ onImportFromUrl, accept, className }: MediaUr
112
112
  <form
113
113
  autoComplete="off"
114
114
  noValidate
115
- onSubmit={form.handleSubmit(handleImport, handleInvalid)}
115
+ onSubmit={(event) => form.handleSubmit(handleImport, handleInvalid)(event)}
116
116
  className="w-full"
117
117
  >
118
118
  <InputGroup className="mx-auto max-w-2xl bg-background">
@@ -23,9 +23,11 @@ export function useContentEditorSlashMenu(editorRef: React.RefObject<Editor | nu
23
23
  const activeSlashIndex =
24
24
  activeSlashIndexState >= filteredSlashCommands.length ? 0 : activeSlashIndexState
25
25
 
26
- slashMenuRef.current = slashMenu
27
- activeSlashIndexRef.current = activeSlashIndex
28
- filteredSlashCommandsRef.current = filteredSlashCommands
26
+ React.useEffect(() => {
27
+ slashMenuRef.current = slashMenu
28
+ activeSlashIndexRef.current = activeSlashIndex
29
+ filteredSlashCommandsRef.current = filteredSlashCommands
30
+ })
29
31
 
30
32
  const updateSlashMenu = React.useCallback((nextEditor: Editor) => {
31
33
  const nextSlashMenu = getSlashMenuState(nextEditor)
@@ -1,5 +1,8 @@
1
1
  'use client'
2
2
 
3
+ // oxlint-disable react/refs -- the CodeMirror widget is constructed during render and compared by
4
+ // callback identity in `eq()`. Dropping the ref-backed callbacks would rebuild the widget DOM on
5
+ // every render, so it needs a verified refactor.
3
6
  import * as React from 'react'
4
7
  import type { ContentEditorSelectionRequest } from '@admin/utils/editor/content-editor-selection-request'
5
8
  import type { MarkdownHeadingLevel } from '@admin/utils/editor/markdown-heading-level'
@@ -151,9 +154,12 @@ export function useContentEditorSourceMode({
151
154
  const [canUndoMarkdownChange, setCanUndoMarkdownChange] = React.useState(false)
152
155
  const [canRedoMarkdownChange, setCanRedoMarkdownChange] = React.useState(false)
153
156
  const valueRef = React.useRef(value)
154
- valueRef.current = value
155
157
  const onChangeRef = React.useRef(onChange)
156
- onChangeRef.current = onChange
158
+
159
+ React.useEffect(() => {
160
+ valueRef.current = value
161
+ onChangeRef.current = onChange
162
+ })
157
163
 
158
164
  const handleMediaSelected = React.useCallback(
159
165
  (url: string) => {
@@ -25,7 +25,9 @@ export function useContentEditorTableAddControls(
25
25
  const tableStateRef = React.useRef<TableAddControlsState | null>(null)
26
26
  const isEditorViewMounted = Boolean(getMountedEditorView(editor))
27
27
 
28
- tableStateRef.current = tableState
28
+ React.useEffect(() => {
29
+ tableStateRef.current = tableState
30
+ })
29
31
 
30
32
  const setTable = React.useCallback((next: TableAddControlsState) => {
31
33
  setTableState((current) => {
@@ -1,5 +1,8 @@
1
1
  'use client'
2
2
 
3
+ // oxlint-disable react/refs -- `latestMarkdownRef` is both the synchronous markdown buffer that
4
+ // callbacks write and the value rendered as `sourceValue`. Splitting it into state changes when the
5
+ // buffer is observable and risks the Markdown round-trip, so it needs a verified refactor.
3
6
  import * as React from 'react'
4
7
  import type { ContentEditorMode } from '@admin/utils/editor/content-editor-mode'
5
8
  import type { ContentEditorSelectionRequest } from '@admin/utils/editor/content-editor-selection-request'
@@ -75,8 +78,6 @@ export function useContentEditor({
75
78
  updateSlashMenu
76
79
  } = useContentEditorSlashMenu(editorRef)
77
80
 
78
- isSlashMenuOpenRef.current = slashMenu !== null
79
-
80
81
  if (value !== lastValuePropRef.current) {
81
82
  lastValuePropRef.current = value
82
83
  latestMarkdownRef.current = value
@@ -173,7 +174,10 @@ export function useContentEditor({
173
174
  }
174
175
  })
175
176
 
176
- editorRef.current = editor
177
+ React.useEffect(() => {
178
+ editorRef.current = editor
179
+ isSlashMenuOpenRef.current = slashMenu !== null
180
+ })
177
181
 
178
182
  const syncRichContent = React.useCallback(
179
183
  (nextValue: string = latestMarkdownRef.current, selectionOffset?: number) => {
@@ -89,11 +89,13 @@ export function useUpload(options: UseUploadOptions = {}): UseUploadReturn {
89
89
  const uploadAbortControllerRef = React.useRef<AbortController | null>(null)
90
90
  const progressIntervalRef = React.useRef<ReturnType<typeof setInterval> | null>(null)
91
91
  const progressResetTimeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)
92
- if (previousIsActiveRef.current !== isActive) {
93
- previousIsActiveRef.current = isActive
94
- activeActivityIdRef.current += 1
95
- }
96
- activeRef.current = isActive
92
+ React.useEffect(() => {
93
+ if (previousIsActiveRef.current !== isActive) {
94
+ previousIsActiveRef.current = isActive
95
+ activeActivityIdRef.current += 1
96
+ }
97
+ activeRef.current = isActive
98
+ })
97
99
 
98
100
  const clearProgressResetTimeout = React.useCallback(() => {
99
101
  if (progressResetTimeoutRef.current) {
@@ -32,7 +32,7 @@ import { Input } from '@admin/components/ui/input'
32
32
  import { Spinner } from '@admin/components/ui/spinner'
33
33
  import { standardSchemaResolver } from '@hookform/resolvers/standard-schema'
34
34
  import { useRouter } from 'next/navigation'
35
- import { useForm } from 'react-hook-form'
35
+ import { useForm, useWatch } from 'react-hook-form'
36
36
  import { toast } from 'sonner'
37
37
  import { z } from 'zod/v3'
38
38
 
@@ -94,8 +94,8 @@ export function ProfileForm({ user }: ProfileFormProps) {
94
94
  reValidateMode: 'onChange'
95
95
  })
96
96
 
97
- const emailDirty = profileForm.watch('email') !== user.email
98
- const imageValue = profileForm.watch('image')
97
+ const emailDirty = useWatch({ control: profileForm.control, name: 'email' }) !== user.email
98
+ const imageValue = useWatch({ control: profileForm.control, name: 'image' })
99
99
 
100
100
  function onProfileSubmit(values: ProfileValues) {
101
101
  startProfileTransition(async () => {
@@ -35,7 +35,7 @@ import { webhookEventSources } from '@admin/data/webhook-events'
35
35
  import { useWebhookSubscriptions } from '@admin/hooks/use-webhooks'
36
36
  import { standardSchemaResolver } from '@hookform/resolvers/standard-schema'
37
37
  import { useMutation, useQueryClient } from '@tanstack/react-query'
38
- import { useForm } from 'react-hook-form'
38
+ import { useForm, useWatch } from 'react-hook-form'
39
39
  import { toast } from 'sonner'
40
40
  import { z } from 'zod/v3'
41
41
 
@@ -81,7 +81,7 @@ export function WebhookEndpointDialog({ webhook, open, onOpenChange }: WebhookEn
81
81
  events: subscribedEvents
82
82
  }
83
83
  })
84
- const events = form.watch('events')
84
+ const events = useWatch({ control: form.control, name: 'events' })
85
85
 
86
86
  React.useEffect(() => {
87
87
  if (!open) return