@alfakit/react 0.1.11 → 0.1.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/components/entries/other-entries.d.ts.map +1 -1
  3. package/dist/components/entries/other-entries.js +1 -1
  4. package/dist/components/entries/other-entries.js.map +1 -1
  5. package/dist/components/fields/builder.d.ts.map +1 -1
  6. package/dist/components/fields/builder.js +3 -3
  7. package/dist/components/fields/builder.js.map +1 -1
  8. package/dist/components/fields/file-upload.d.ts.map +1 -1
  9. package/dist/components/fields/file-upload.js +2 -5
  10. package/dist/components/fields/file-upload.js.map +1 -1
  11. package/dist/components/fields/repeater.d.ts.map +1 -1
  12. package/dist/components/fields/repeater.js +3 -3
  13. package/dist/components/fields/repeater.js.map +1 -1
  14. package/dist/components/fields/rich-editor-extensions.js +5 -2
  15. package/dist/components/fields/rich-editor-extensions.js.map +1 -1
  16. package/dist/components/layout/wizard.d.ts.map +1 -1
  17. package/dist/components/layout/wizard.js +4 -1
  18. package/dist/components/layout/wizard.js.map +1 -1
  19. package/dist/components/notifications/flash-toasts.d.ts.map +1 -1
  20. package/dist/components/notifications/flash-toasts.js +11 -1
  21. package/dist/components/notifications/flash-toasts.js.map +1 -1
  22. package/dist/components/notifications/notifications-menu.js +3 -3
  23. package/dist/components/notifications/notifications-menu.js.map +1 -1
  24. package/dist/components/panel/pwa.d.ts.map +1 -1
  25. package/dist/components/panel/pwa.js +8 -7
  26. package/dist/components/panel/pwa.js.map +1 -1
  27. package/dist/components/panel/shortcuts-overlay.js +1 -1
  28. package/dist/components/panel/shortcuts-overlay.js.map +1 -1
  29. package/dist/components/table/cells.js +1 -1
  30. package/dist/components/table/cells.js.map +1 -1
  31. package/dist/components.css +19 -0
  32. package/dist/eject-manifest.json +2 -2
  33. package/dist/pages/page.js +1 -1
  34. package/dist/pages/page.js.map +1 -1
  35. package/package.json +2 -2
  36. package/src/components/entries/other-entries.tsx +2 -0
  37. package/src/components/fields/builder.tsx +7 -2
  38. package/src/components/fields/file-upload.tsx +2 -7
  39. package/src/components/fields/repeater.tsx +6 -3
  40. package/src/components/fields/rich-editor-extensions.tsx +9 -5
  41. package/src/components/layout/wizard.tsx +5 -1
  42. package/src/components/notifications/flash-toasts.tsx +8 -0
  43. package/src/components/notifications/notifications-menu.tsx +3 -3
  44. package/src/components/panel/pwa.tsx +23 -9
  45. package/src/components/panel/shortcuts-overlay.tsx +1 -1
  46. package/src/components/table/cells.tsx +3 -1
  47. package/src/pages/page.tsx +1 -1
@@ -152,11 +152,15 @@ export function useRichEditorExtensions(
152
152
 
153
153
  if (!result || !editor || editor.isDestroyed) return
154
154
 
155
- editor
156
- .chain()
157
- .focus()
158
- .insertContent({ type: 'customBlock', attrs: { id: result.id, config: result.config } })
159
- .run()
155
+ const block = { type: 'customBlock', attrs: { id: result.id, config: result.config } }
156
+ // A block inserted just before is still selected (a node selection): insert after it
157
+ // instead of replacing it (W-S2-05).
158
+ const { selection } = editor.state
159
+ const chain = editor.chain().focus()
160
+ ;('node' in selection && selection.node
161
+ ? chain.insertContentAt(selection.to, block)
162
+ : chain.insertContent(block)
163
+ ).run()
160
164
  }
161
165
 
162
166
  return { extensions, suggestions, insertBlock, context }
@@ -21,6 +21,7 @@ import { cn } from '../../lib/utils'
21
21
  import { ActionButton } from '../actions/action-button'
22
22
  import { usePageActionContext } from '../actions/action-context'
23
23
  import { useOptionalFormStore } from '../form/form-context'
24
+ import { useFieldActionContext } from '../schema/field-actions'
24
25
  import { SchemaRenderer } from '../schema/schema-renderer'
25
26
  import { Button } from '../ui/button'
26
27
  import { DeferredSchema } from './deferred'
@@ -52,6 +53,9 @@ export function WizardComponent({ component }: { component: WizardSchema }) {
52
53
  if (stepQueryKey) persistWizardStep(current, stepQueryKey)
53
54
  }, [current, stepQueryKey])
54
55
  const store = useOptionalFormStore()
56
+ // Inside a form the submit action runs as a field action, so `$get` / `$set` work (W-S2-09).
57
+ const fieldContext = useFieldActionContext(component)
58
+ const submitContext = store ? fieldContext : actionContext
55
59
 
56
60
  // An action modal around this wizard shows its submit button on the last step only.
57
61
  useEffect(() => {
@@ -229,7 +233,7 @@ export function WizardComponent({ component }: { component: WizardSchema }) {
229
233
  </Button>
230
234
  )
231
235
  ) : component.submitAction ? (
232
- <ActionButton action={component.submitAction} context={actionContext} />
236
+ <ActionButton action={component.submitAction} context={submitContext} />
233
237
  ) : component.submitActionHtml ? (
234
238
  <div
235
239
  data-slot="wizard-submit"
@@ -43,6 +43,14 @@ export function setToasterId(id: string | undefined): void {
43
43
  toasterId = id
44
44
  }
45
45
 
46
+ /**
47
+ * Options for a direct `toast.*()` call: the starter kit toaster's id merged in, so PWA and
48
+ * notification messages reach AlfaKit's toaster in a starter kit too (W-S1-03).
49
+ */
50
+ export function toastOptions<T extends object>(options?: T): T & { toasterId?: string } {
51
+ return { ...(options ?? ({} as T)), toasterId }
52
+ }
53
+
46
54
  /** `closeNotification(id)` (or a `close-notification` event) dismisses that toast. */
47
55
  export function listenForClosedNotifications(): void {
48
56
  if (closeListening || typeof window === 'undefined') return
@@ -19,7 +19,7 @@ import { Button } from '../ui/button'
19
19
  import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'
20
20
  import { ScrollArea } from '../ui/scroll-area'
21
21
  import { Spinner } from '../ui/spinner'
22
- import { NotificationActionButton } from './flash-toasts'
22
+ import { NotificationActionButton, toastOptions } from './flash-toasts'
23
23
 
24
24
  export interface NotificationsMenuProps {
25
25
  /**
@@ -104,8 +104,8 @@ export function NotificationsMenu({ variant = 'topbar' }: NotificationsMenuProps
104
104
  const { message } = await togglePushNotifications()
105
105
  const text = t(message.key, {}, message.fallback)
106
106
 
107
- if (message.error) toast.error(text)
108
- else toast.success(text)
107
+ if (message.error) toast.error(text, toastOptions())
108
+ else toast.success(text, toastOptions())
109
109
  }
110
110
 
111
111
  const pushLabel =
@@ -14,6 +14,7 @@ import { toast } from 'sonner'
14
14
  import { usePanel, useT } from '../../context'
15
15
  import { useStore } from '../../hooks/use-store'
16
16
  import { Icon } from '../../lib/icons'
17
+ import { toastOptions } from '../notifications/flash-toasts'
17
18
  import { DropdownMenuItem } from '../ui/dropdown-menu'
18
19
 
19
20
  const UPDATE_TOAST_ID = 'alfakit-pwa-update'
@@ -27,7 +28,7 @@ export async function installPwa(t: Translator['t']): Promise<void> {
27
28
  {},
28
29
  'To install this app, tap the Share button and then “Add to Home Screen”.',
29
30
  ),
30
- { duration: 10000 },
31
+ toastOptions({ duration: 10000 }),
31
32
  )
32
33
  }
33
34
  }
@@ -49,11 +50,14 @@ export function PwaManager() {
49
50
  useEffect(() => {
50
51
  if (!updateAvailable) return
51
52
 
52
- toast(t('pwa.update_available', {}, 'A new version is available'), {
53
- id: UPDATE_TOAST_ID,
54
- duration: Infinity,
55
- action: { label: t('pwa.reload', {}, 'Reload'), onClick: () => applyPwaUpdate() },
56
- })
53
+ toast(
54
+ t('pwa.update_available', {}, 'A new version is available'),
55
+ toastOptions({
56
+ id: UPDATE_TOAST_ID,
57
+ duration: Infinity,
58
+ action: { label: t('pwa.reload', {}, 'Reload'), onClick: () => applyPwaUpdate() },
59
+ }),
60
+ )
57
61
  }, [updateAvailable, t])
58
62
 
59
63
  return null
@@ -74,15 +78,25 @@ export function PwaMenuItems() {
74
78
  state.push === 'subscribed' ? await unsubscribeFromPush() : await subscribeToPush()
75
79
 
76
80
  if (outcome === 'subscribed') {
77
- toast.success(t('pwa.notifications.enabled', {}, 'Notifications are on for this device'))
81
+ toast.success(
82
+ t('pwa.notifications.enabled', {}, 'Notifications are on for this device'),
83
+ toastOptions(),
84
+ )
78
85
  } else if (outcome === 'unsubscribed') {
79
- toast.success(t('pwa.notifications.disabled', {}, 'Notifications are off for this device'))
86
+ toast.success(
87
+ t('pwa.notifications.disabled', {}, 'Notifications are off for this device'),
88
+ toastOptions(),
89
+ )
80
90
  } else if (outcome === 'denied') {
81
91
  toast.error(
82
92
  t('pwa.notifications.blocked', {}, 'Notifications are blocked in your browser settings'),
93
+ toastOptions(),
83
94
  )
84
95
  } else {
85
- toast.error(t('pwa.notifications.failed', {}, 'Couldn’t change notifications. Try again.'))
96
+ toast.error(
97
+ t('pwa.notifications.failed', {}, 'Couldn’t change notifications. Try again.'),
98
+ toastOptions(),
99
+ )
86
100
  }
87
101
  }
88
102
 
@@ -221,7 +221,7 @@ export function ShortcutsOverlay({
221
221
  aria-label={t(
222
222
  'shortcuts.reset_label',
223
223
  { label: item.label },
224
- `Restore the default shortcut for ${item.label}`,
224
+ `Reset the shortcut for ${item.label}`,
225
225
  )}
226
226
  onClick={() => void save(item.id, null)}
227
227
  >
@@ -242,7 +242,9 @@ function ImageCell({ column, cell }: CellProps) {
242
242
  <span
243
243
  data-slot="image-remaining"
244
244
  className={cn(
245
- 'text-muted-foreground ms-1',
245
+ 'text-muted-foreground',
246
+ // The last image keeps the stack's negative end margin (W-S3-03).
247
+ schema.stacked && usesDefaultImageStack(schema) ? 'ms-3' : 'ms-1',
246
248
  remainingTextSizeClass(schema.limitedRemainingTextSize),
247
249
  )}
248
250
  >
@@ -281,7 +281,7 @@ export function ContentBlockRenderer({ block }: { block: ContentBlock }) {
281
281
  <div data-slot="infolist" className="contents">
282
282
  <SchemaRenderer
283
283
  components={(block as InfolistBlock).components}
284
- columns={{ default: 1, lg: 2 }}
284
+ columns={(block as InfolistBlock).columns ?? { default: 1, lg: 2 }}
285
285
  />
286
286
  </div>
287
287
  )