@akira-io/ui 1.1.0 → 1.2.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 (68) hide show
  1. package/dist/blocks.d.ts +27 -27
  2. package/dist/blocks.js +79 -66
  3. package/dist/blocks.js.map +1 -1
  4. package/dist/{chunk-SA5LM2GD.js → chunk-2HLBBU3O.js} +44 -20
  5. package/dist/chunk-2HLBBU3O.js.map +1 -0
  6. package/dist/{chunk-MNGNBEYN.js → chunk-3HKIYFWI.js} +263 -166
  7. package/dist/chunk-3HKIYFWI.js.map +1 -0
  8. package/dist/{chunk-UUTXPPRN.js → chunk-DW42Z75X.js} +147 -90
  9. package/dist/chunk-DW42Z75X.js.map +1 -0
  10. package/dist/{chunk-DSD7MVLL.js → chunk-I5UZAJB4.js} +13 -9
  11. package/dist/chunk-I5UZAJB4.js.map +1 -0
  12. package/dist/{chunk-JAHTUAQL.js → chunk-MCMBS2SB.js} +6 -5
  13. package/dist/chunk-MCMBS2SB.js.map +1 -0
  14. package/dist/{chunk-YOVY3KT6.js → chunk-NGMG2UWX.js} +3 -3
  15. package/dist/{chunk-YOVY3KT6.js.map → chunk-NGMG2UWX.js.map} +1 -1
  16. package/dist/{chunk-6QM5BA7B.js → chunk-O5DZTX7D.js} +40 -23
  17. package/dist/chunk-O5DZTX7D.js.map +1 -0
  18. package/dist/{chunk-5AJFQ6C4.js → chunk-QNF4LJVT.js} +2 -2
  19. package/dist/chunk-QNF4LJVT.js.map +1 -0
  20. package/dist/{chunk-LKSM3WLK.js → chunk-SBLZ6T3D.js} +6 -5
  21. package/dist/chunk-SBLZ6T3D.js.map +1 -0
  22. package/dist/{chunk-KYWA5UYN.js → chunk-SH5QZCOW.js} +46 -28
  23. package/dist/chunk-SH5QZCOW.js.map +1 -0
  24. package/dist/chunk-UTSTTTH5.js +48 -0
  25. package/dist/chunk-UTSTTTH5.js.map +1 -0
  26. package/dist/code.d.ts +5 -2
  27. package/dist/code.js +52 -53
  28. package/dist/code.js.map +1 -1
  29. package/dist/{context-VgHq4U98.d.ts → context-OwSoVEri.d.ts} +55 -27
  30. package/dist/editor.d.ts +8 -6
  31. package/dist/editor.js +31 -18
  32. package/dist/editor.js.map +1 -1
  33. package/dist/field-DWm5NXeV.d.ts +39 -0
  34. package/dist/index.d.ts +230 -238
  35. package/dist/index.js +451 -337
  36. package/dist/index.js.map +1 -1
  37. package/dist/inertia.d.ts +1 -1
  38. package/dist/inertia.js +6 -7
  39. package/dist/inertia.js.map +1 -1
  40. package/dist/{button-B6wQRe7p.d.ts → input-Dxnsxi-f.d.ts} +6 -2
  41. package/dist/{json-viewer-BTHBACj9.d.ts → json-viewer-BARA2RCW.d.ts} +3 -2
  42. package/dist/{language-Dgjr9bm3.d.ts → language-Cv_N_53L.d.ts} +5 -2
  43. package/dist/locales/pt.d.ts +9 -9
  44. package/dist/locales/pt.js +7 -1
  45. package/dist/locales/pt.js.map +1 -1
  46. package/dist/shells.d.ts +6 -7
  47. package/dist/shells.js +9 -9
  48. package/dist/shells.js.map +1 -1
  49. package/dist/sidebar-Bp6Q46j-.d.ts +80 -0
  50. package/dist/{types-CT0rBsFc.d.ts → types-B-eGPoFD.d.ts} +3 -2
  51. package/dist/{types-B4QS3h5p.d.ts → types-cmBL8zOc.d.ts} +4 -1
  52. package/package.json +3 -3
  53. package/dist/chunk-5AJFQ6C4.js.map +0 -1
  54. package/dist/chunk-6QM5BA7B.js.map +0 -1
  55. package/dist/chunk-6X4TKSF6.js +0 -21
  56. package/dist/chunk-6X4TKSF6.js.map +0 -1
  57. package/dist/chunk-DSD7MVLL.js.map +0 -1
  58. package/dist/chunk-JAHTUAQL.js.map +0 -1
  59. package/dist/chunk-KYWA5UYN.js.map +0 -1
  60. package/dist/chunk-LKSM3WLK.js.map +0 -1
  61. package/dist/chunk-MNGNBEYN.js.map +0 -1
  62. package/dist/chunk-SA5LM2GD.js.map +0 -1
  63. package/dist/chunk-UUEWFCKT.js +0 -28
  64. package/dist/chunk-UUEWFCKT.js.map +0 -1
  65. package/dist/chunk-UUTXPPRN.js.map +0 -1
  66. package/dist/input-4uxAHW6y.d.ts +0 -5
  67. package/dist/password-input-r39y2pCT.d.ts +0 -50
  68. package/dist/sidebar-BhOIlSjt.d.ts +0 -80
@@ -1,11 +1,12 @@
1
1
  import * as React from 'react';
2
- import { ReactNode } from 'react';
2
+ import { ReactNode, ComponentProps } from 'react';
3
3
  import { LucideIcon } from 'lucide-react';
4
- import { U as UrlLike, c as LinkComponent, I as IconComponent } from './types-B4QS3h5p.js';
4
+ import { S as SlotNameProps, U as UrlLike, d as LinkComponent, I as IconComponent } from './types-cmBL8zOc.js';
5
5
  import { d as TourLabels } from './types-u1qfmJQi.js';
6
- import { a as CodeBlockLabels, c as JsonViewerLabels } from './json-viewer-BTHBACj9.js';
6
+ import * as class_variance_authority_types from 'class-variance-authority/types';
7
7
  import { VariantProps } from 'class-variance-authority';
8
- import { b as buttonVariants } from './button-B6wQRe7p.js';
8
+ import { a as CodeBlockLabels, c as JsonViewerLabels } from './json-viewer-BARA2RCW.js';
9
+ import { b as buttonVariants, a as ButtonProps, I as Input } from './input-Dxnsxi-f.js';
9
10
  import { Column, ColumnDef, Row } from '@tanstack/react-table';
10
11
 
11
12
  interface CommandPaletteItem {
@@ -93,7 +94,7 @@ interface CopyButtonProps extends Omit<React.ComponentProps<'button'>, 'value' |
93
94
  onCopied?: (value: string) => void;
94
95
  onCopyFailed?: (reason: unknown) => void;
95
96
  }
96
- declare function CopyButton({ value, copyLabel, copiedLabel, acknowledgementDuration, onCopied, onCopyFailed, onClick, variant, size, className, ...props }: CopyButtonProps): React.JSX.Element;
97
+ declare function CopyButton({ value, copyLabel, copiedLabel, acknowledgementDuration, onCopied, onCopyFailed, onClick, variant, size, className, slotName, ...props }: CopyButtonProps & SlotNameProps): React.JSX.Element;
97
98
 
98
99
  interface SettingsPageProps {
99
100
  title?: string;
@@ -103,7 +104,7 @@ interface SettingsPageProps {
103
104
  children: ReactNode;
104
105
  className?: string;
105
106
  }
106
- declare function SettingsPage({ title, description, control, linkComponent, children, className, }: SettingsPageProps): React.JSX.Element;
107
+ declare function SettingsPage({ title, description, control, linkComponent, children, className, slotName, }: SettingsPageProps & SlotNameProps): React.JSX.Element;
107
108
  interface SettingsLabels {
108
109
  back: string;
109
110
  }
@@ -119,14 +120,14 @@ interface SettingsSectionProps {
119
120
  children: ReactNode;
120
121
  className?: string;
121
122
  }
122
- declare function SettingsSection({ title, description, control, backHref, backLabel, wide, linkComponent, children, className, }: SettingsSectionProps): React.JSX.Element;
123
+ declare function SettingsSection({ title, description, control, backHref, backLabel, wide, linkComponent, children, className, slotName, }: SettingsSectionProps & SlotNameProps): React.JSX.Element;
123
124
  interface SettingsGroupProps {
124
125
  label?: string;
125
126
  columns?: 1 | 2;
126
127
  children: ReactNode;
127
128
  className?: string;
128
129
  }
129
- declare function SettingsGroup({ label, columns, children, className, }: SettingsGroupProps): React.JSX.Element;
130
+ declare function SettingsGroup({ label, columns, children, className, slotName, }: SettingsGroupProps & SlotNameProps): React.JSX.Element;
130
131
  interface SettingsEntryProps {
131
132
  icon: LucideIcon;
132
133
  iconClassName?: string;
@@ -138,7 +139,21 @@ interface SettingsEntryProps {
138
139
  linkComponent?: LinkComponent;
139
140
  className?: string;
140
141
  }
141
- declare function SettingsEntry({ icon: Icon, iconClassName, title, description, href, badge, disabled, linkComponent, className, }: SettingsEntryProps): React.JSX.Element;
142
+ declare function SettingsEntry({ icon: Icon, iconClassName, title, description, href, badge, disabled, linkComponent, className, slotName, }: SettingsEntryProps & SlotNameProps): React.JSX.Element;
143
+
144
+ declare const alertVariants: (props?: ({
145
+ variant?: "default" | "destructive" | "warning" | "info" | null | undefined;
146
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
147
+ interface AlertLabels {
148
+ warningLabel: string;
149
+ infoLabel: string;
150
+ }
151
+ declare const alertDefaultLabels: AlertLabels;
152
+ declare function Alert({ className, variant, labels, slotName, ...props }: React.ComponentProps<'div'> & VariantProps<typeof alertVariants> & SlotNameProps & {
153
+ labels?: Partial<AlertLabels>;
154
+ }): React.JSX.Element;
155
+ declare function AlertTitle({ className, slotName, ...props }: React.ComponentProps<'div'> & SlotNameProps): React.JSX.Element;
156
+ declare function AlertDescription({ className, slotName, ...props }: React.ComponentProps<'div'> & SlotNameProps): React.JSX.Element;
142
157
 
143
158
  interface AppearanceToggleLabels {
144
159
  groupLabel: string;
@@ -151,7 +166,7 @@ interface AppearanceToggleProps extends React.ComponentProps<'div'> {
151
166
  variant?: 'segmented' | 'menu';
152
167
  labels?: Partial<AppearanceToggleLabels>;
153
168
  }
154
- declare function AppearanceToggle({ className, variant, labels: labelOverrides, ...props }: AppearanceToggleProps): React.JSX.Element;
169
+ declare function AppearanceToggle({ className, variant, labels: labelOverrides, slotName, ...props }: AppearanceToggleProps & SlotNameProps): React.JSX.Element;
155
170
 
156
171
  interface ComboboxOption {
157
172
  value: string;
@@ -163,18 +178,17 @@ interface ComboboxLabels {
163
178
  emptyText: string;
164
179
  }
165
180
  declare const comboboxDefaultLabels: ComboboxLabels;
166
- interface ComboboxProps {
167
- id?: string;
181
+ interface ComboboxProps extends Omit<ButtonProps, 'value' | 'onChange' | 'children' | 'slotName'> {
168
182
  value: string;
169
183
  options: ComboboxOption[];
170
184
  onChange: (value: string) => void;
171
185
  placeholder?: ComboboxLabels['placeholder'];
172
186
  searchPlaceholder?: ComboboxLabels['searchPlaceholder'];
173
187
  emptyText?: ComboboxLabels['emptyText'];
174
- disabled?: boolean;
175
188
  invalid?: boolean;
189
+ required?: boolean;
176
190
  }
177
- declare function Combobox({ id, value, options, onChange, placeholder, searchPlaceholder, emptyText, disabled, invalid, }: ComboboxProps): React.JSX.Element;
191
+ declare function Combobox({ value, options, onChange, placeholder, searchPlaceholder, emptyText, disabled, invalid, required, className, 'aria-invalid': ariaInvalid, slotName, ...trigger }: ComboboxProps & SlotNameProps): React.JSX.Element;
178
192
 
179
193
  interface ConfirmDialogLabels {
180
194
  title: string;
@@ -197,7 +211,7 @@ interface ConfirmDialogProps {
197
211
  onConfirm: () => void;
198
212
  onCancel?: () => void;
199
213
  }
200
- declare function ConfirmDialog({ open, onOpenChange, title, description, confirmText, cancelText, variant, processing, requiredValue, requiredValueLabel, onConfirm, onCancel, }: ConfirmDialogProps): React.JSX.Element;
214
+ declare function ConfirmDialog({ open, onOpenChange, title, description, confirmText, cancelText, variant, processing, requiredValue, requiredValueLabel, onConfirm, onCancel, slotName, }: ConfirmDialogProps & SlotNameProps): React.JSX.Element;
201
215
 
202
216
  interface DataTableFilter {
203
217
  columnId: string;
@@ -237,10 +251,10 @@ interface DataTableRowAction<TData> {
237
251
  variant?: 'default' | 'destructive';
238
252
  onClick: (row: TData) => void;
239
253
  }
240
- declare function RowActionsMenu<TData>({ row, actions, }: {
254
+ declare function RowActionsMenu<TData>({ row, actions, slotName, }: {
241
255
  row: TData;
242
256
  actions: DataTableRowAction<TData>[];
243
- }): React.JSX.Element;
257
+ } & SlotNameProps): React.JSX.Element;
244
258
 
245
259
  interface DataTableLabels {
246
260
  searchPlaceholder: string;
@@ -287,7 +301,7 @@ interface DataTableProps<TData, TValue> {
287
301
  onPageChange?: (pageIndex: number) => void;
288
302
  onCreate?: () => void;
289
303
  }
290
- declare function DataTable<TData, TValue>({ columns, data, searchKey, searchPlaceholder, pageSize, pageSizeOptions, onPageSizeChange, filters, serverFilters, filterValues, onFilterChange, canClearFilters, onClearFilters, toolbarExtra, toolbarAction, emptyLabel, clearFiltersLabel, paginationLabel, noOptionsLabel, totalLabel, renderRow, onRowClick, isRowActive, rowActions, searchValue, onSearchChange, manualPagination, pageCount, pageIndex, total, onPageChange, onCreate, createLabel, }: DataTableProps<TData, TValue>): React.JSX.Element;
304
+ declare function DataTable<TData, TValue>({ columns, data, searchKey, searchPlaceholder, pageSize, pageSizeOptions, onPageSizeChange, filters, serverFilters, filterValues, onFilterChange, canClearFilters, onClearFilters, toolbarExtra, toolbarAction, emptyLabel, clearFiltersLabel, paginationLabel, noOptionsLabel, totalLabel, renderRow, onRowClick, isRowActive, rowActions, searchValue, onSearchChange, manualPagination, pageCount, pageIndex, total, onPageChange, onCreate, createLabel, slotName, }: DataTableProps<TData, TValue> & SlotNameProps): React.JSX.Element;
291
305
 
292
306
  interface DatePickerLabels {
293
307
  placeholder: string;
@@ -295,35 +309,35 @@ interface DatePickerLabels {
295
309
  clearLabel: string;
296
310
  }
297
311
  declare const datePickerDefaultLabels: DatePickerLabels;
298
- interface DatePickerProps extends Partial<DatePickerLabels> {
299
- id?: string;
312
+ type DatePickerTriggerProps = Omit<ComponentProps<'button'>, 'value' | 'defaultValue' | 'onChange' | 'type' | 'children'>;
313
+ interface DatePickerProps extends Partial<DatePickerLabels>, DatePickerTriggerProps {
300
314
  value?: Date;
301
315
  defaultValue?: Date;
302
316
  onChange?: (value: Date | undefined) => void;
303
317
  minDate?: Date;
304
318
  maxDate?: Date;
305
319
  disabledDays?: (date: Date) => boolean;
306
- disabled?: boolean;
307
320
  clearable?: boolean;
308
321
  invalid?: boolean;
322
+ required?: boolean;
309
323
  formatDate?: (value: Date) => string;
310
- className?: string;
311
324
  }
312
- declare function DatePicker(props: DatePickerProps): React.JSX.Element;
325
+ declare function DatePicker(props: DatePickerProps & SlotNameProps): React.JSX.Element;
313
326
 
314
327
  interface DateRangeFilterLabels {
315
328
  emptyLabel: string;
316
329
  dateFormat: string;
317
330
  }
318
331
  declare const dateRangeFilterDefaultLabels: DateRangeFilterLabels;
319
- declare function DateRangeFilter({ from, to, onChange, emptyLabel, dateFormat, }: {
332
+ interface DateRangeFilterProps extends Partial<DateRangeFilterLabels>, Omit<ButtonProps, 'onChange' | 'children' | 'value' | 'slotName'> {
320
333
  from?: string;
321
334
  to?: string;
322
335
  onChange: (range: {
323
336
  from?: string;
324
337
  to?: string;
325
338
  }) => void;
326
- } & Partial<DateRangeFilterLabels>): React.JSX.Element;
339
+ }
340
+ declare function DateRangeFilter({ from, to, onChange, emptyLabel, dateFormat, className, slotName, ...trigger }: DateRangeFilterProps & SlotNameProps): React.JSX.Element;
327
341
 
328
342
  interface FloatingSheetLabels {
329
343
  backLabel: string;
@@ -331,6 +345,18 @@ interface FloatingSheetLabels {
331
345
  }
332
346
  declare const floatingSheetDefaultLabels: FloatingSheetLabels;
333
347
 
348
+ interface PasswordInputLabels {
349
+ showLabel: string;
350
+ hideLabel: string;
351
+ }
352
+ declare const passwordInputDefaultLabels: PasswordInputLabels;
353
+ interface PasswordInputProps extends Omit<React.ComponentProps<typeof Input>, 'type'> {
354
+ revealable?: boolean;
355
+ showLabel?: PasswordInputLabels['showLabel'];
356
+ hideLabel?: PasswordInputLabels['hideLabel'];
357
+ }
358
+ declare function PasswordInput({ className, revealable, showLabel, hideLabel, slotName, ...props }: PasswordInputProps & SlotNameProps): React.JSX.Element;
359
+
334
360
  type SaveStatusState = 'idle' | 'saving' | 'saved' | 'error';
335
361
  interface SaveStatusLabels {
336
362
  error: string;
@@ -347,9 +373,10 @@ interface SaveStatusProps extends React.ComponentProps<'div'> {
347
373
  savedDuration?: number;
348
374
  labels?: Partial<SaveStatusLabels>;
349
375
  }
350
- declare function SaveStatus({ status, message, showIdle, savedDuration, labels, className, ...props }: SaveStatusProps): React.JSX.Element;
376
+ declare function SaveStatus({ status, message, showIdle, savedDuration, labels, className, slotName, ...props }: SaveStatusProps & SlotNameProps): React.JSX.Element;
351
377
 
352
378
  interface UiLabelSections {
379
+ alert: AlertLabels;
353
380
  appearanceToggle: AppearanceToggleLabels;
354
381
  codeBlock: CodeBlockLabels;
355
382
  combobox: ComboboxLabels;
@@ -363,6 +390,7 @@ interface UiLabelSections {
363
390
  dateRangeFilter: DateRangeFilterLabels;
364
391
  floatingSheet: FloatingSheetLabels;
365
392
  jsonViewer: JsonViewerLabels;
393
+ passwordInput: PasswordInputLabels;
366
394
  saveStatus: SaveStatusLabels;
367
395
  settings: SettingsLabels;
368
396
  tour: TourLabels;
@@ -381,4 +409,4 @@ declare function UiLocaleProvider({ labels, children, }: {
381
409
  declare function useUiLocale(): UiLabels;
382
410
  declare function useUiLabels<Section extends keyof UiLabelSections>(section: Section, defaults: UiLabelSections[Section], overrides?: Partial<UiLabelSections[Section]>): UiLabelSections[Section];
383
411
 
384
- export { FacetedFilter as $, useUiLocale as A, AppearanceToggle as B, type CopyButtonLabels as C, type DateFilterValue as D, type AppearanceToggleLabels as E, type FloatingSheetLabels as F, type AppearanceToggleProps as G, Combobox as H, type ComboboxLabels as I, type ComboboxOption as J, ConfirmDialog as K, type ConfirmDialogLabels as L, CopyButton as M, type CopyButtonProps as N, DataTable as O, type DataTableFacetedFilterLabels as P, type DataTableFilter as Q, type DataTableLabels as R, SettingsEntry as S, type DataTableRowAction as T, type UiLabelSections as U, type DataTableServerFilter as V, DatePicker as W, type DatePickerLabels as X, type DatePickerProps as Y, DateRangeFilter as Z, type DateRangeFilterLabels as _, type DateFilterLabels as a, RowActionsMenu as a0, SAVED_DURATION as a1, SaveStatus as a2, type SaveStatusLabels as a3, type SaveStatusProps as a4, type SaveStatusState as a5, ServerFacetedFilter as a6, appearanceToggleDefaultLabels as a7, comboboxDefaultLabels as a8, confirmDialogDefaultLabels as a9, copyButtonLabels as aa, dataTableDefaultLabels as ab, dataTableFacetedFilterDefaultLabels as ac, datePickerDefaultLabels as ad, dateRangeFilterDefaultLabels as ae, floatingSheetDefaultLabels as af, saveStatusLabels as ag, type CommandPaletteLabels as ah, type DateFilterOption as b, type DateFilterUnit as c, CommandPalette as d, type CommandPaletteGroup as e, type CommandPaletteItem as f, type CommandPaletteProps as g, DEFAULT_LABELS as h, DEFAULT_OPERATORS as i, DEFAULT_PRESETS as j, DEFAULT_UNITS as k, type DateFilterMode as l, type DateFilterOperator as m, type SettingsEntryProps as n, SettingsGroup as o, type SettingsGroupProps as p, type SettingsLabels as q, SettingsPage as r, type SettingsPageProps as s, SettingsSection as t, type SettingsSectionProps as u, type UiLabels as v, UiLocaleProvider as w, settingsLabels as x, useCommandPalette as y, useUiLabels as z };
412
+ export { DatePicker as $, useUiLocale as A, Alert as B, type CopyButtonLabels as C, type DateFilterValue as D, AlertDescription as E, type FloatingSheetLabels as F, type AlertLabels as G, AlertTitle as H, AppearanceToggle as I, type AppearanceToggleLabels as J, type AppearanceToggleProps as K, Combobox as L, type ComboboxLabels as M, type ComboboxOption as N, type ComboboxProps as O, ConfirmDialog as P, type ConfirmDialogLabels as Q, CopyButton as R, SettingsEntry as S, type CopyButtonProps as T, type UiLabelSections as U, DataTable as V, type DataTableFacetedFilterLabels as W, type DataTableFilter as X, type DataTableLabels as Y, type DataTableRowAction as Z, type DataTableServerFilter as _, type DateFilterLabels as a, type DatePickerLabels as a0, type DatePickerProps as a1, DateRangeFilter as a2, type DateRangeFilterLabels as a3, type DateRangeFilterProps as a4, FacetedFilter as a5, PasswordInput as a6, type PasswordInputLabels as a7, RowActionsMenu as a8, SAVED_DURATION as a9, SaveStatus as aa, type SaveStatusLabels as ab, type SaveStatusProps as ac, type SaveStatusState as ad, ServerFacetedFilter as ae, alertDefaultLabels as af, appearanceToggleDefaultLabels as ag, comboboxDefaultLabels as ah, confirmDialogDefaultLabels as ai, copyButtonLabels as aj, dataTableDefaultLabels as ak, dataTableFacetedFilterDefaultLabels as al, datePickerDefaultLabels as am, dateRangeFilterDefaultLabels as an, floatingSheetDefaultLabels as ao, passwordInputDefaultLabels as ap, saveStatusLabels as aq, type CommandPaletteLabels as ar, type DateFilterOption as b, type DateFilterUnit as c, CommandPalette as d, type CommandPaletteGroup as e, type CommandPaletteItem as f, type CommandPaletteProps as g, DEFAULT_LABELS as h, DEFAULT_OPERATORS as i, DEFAULT_PRESETS as j, DEFAULT_UNITS as k, type DateFilterMode as l, type DateFilterOperator as m, type SettingsEntryProps as n, SettingsGroup as o, type SettingsGroupProps as p, type SettingsLabels as q, SettingsPage as r, type SettingsPageProps as s, SettingsSection as t, type SettingsSectionProps as u, type UiLabels as v, UiLocaleProvider as w, settingsLabels as x, useCommandPalette as y, useUiLabels as z };
package/dist/editor.d.ts CHANGED
@@ -1,12 +1,14 @@
1
1
  import * as React from 'react';
2
2
  import { ReactNode } from 'react';
3
+ import { S as SlotNameProps } from './types-cmBL8zOc.js';
3
4
  import { Editor as Editor$1, Extensions, JSONContent } from '@tiptap/core';
4
5
  import { LucideIcon } from 'lucide-react';
6
+ import '@tanstack/react-table';
5
7
 
6
8
  interface EditorContentProps {
7
9
  className?: string;
8
10
  }
9
- declare function EditorContent({ className }: EditorContentProps): React.JSX.Element;
11
+ declare function EditorContent({ className, slotName, }: EditorContentProps & SlotNameProps): React.JSX.Element;
10
12
 
11
13
  interface EditorLabels {
12
14
  toolbarLabel: string;
@@ -70,7 +72,7 @@ interface EditorHistoryProps {
70
72
  label?: string;
71
73
  className?: string;
72
74
  }
73
- declare function EditorHistory({ action, label, className, }: EditorHistoryProps): React.JSX.Element;
75
+ declare function EditorHistory({ action, label, className, slotName, }: EditorHistoryProps & SlotNameProps): React.JSX.Element;
74
76
 
75
77
  type EditorOutput = 'html' | 'json';
76
78
  type EditorDocument = string | JSONContent;
@@ -93,7 +95,7 @@ type EditorProps = EditorSharedProps & ({
93
95
  value: JSONContent;
94
96
  onChange: (value: JSONContent) => void;
95
97
  });
96
- declare function Editor({ value, onChange, output, extensions, labels, placeholder, label, disabled, readOnly, className, children, }: EditorProps): React.JSX.Element | null;
98
+ declare function Editor({ value, onChange, output, extensions, labels, placeholder, label, disabled, readOnly, className, children, slotName, }: EditorProps & SlotNameProps): React.JSX.Element | null;
97
99
 
98
100
  declare function isSafeEditorUrl(url: string): boolean;
99
101
  declare function defaultEditorExtensions(): Extensions;
@@ -102,7 +104,7 @@ interface EditorLinkProps {
102
104
  label?: string;
103
105
  className?: string;
104
106
  }
105
- declare function EditorLink({ label, className }: EditorLinkProps): React.JSX.Element;
107
+ declare function EditorLink({ label, className, slotName, }: EditorLinkProps & SlotNameProps): React.JSX.Element;
106
108
 
107
109
  type WithoutChildren<T> = T extends unknown ? Omit<T, 'children'> : never;
108
110
  type RichTextEditorProps = WithoutChildren<EditorProps>;
@@ -112,7 +114,7 @@ interface EditorToolbarProps {
112
114
  children: ReactNode;
113
115
  className?: string;
114
116
  }
115
- declare function EditorToolbar({ children, className }: EditorToolbarProps): React.JSX.Element;
117
+ declare function EditorToolbar({ children, className, slotName, }: EditorToolbarProps & SlotNameProps): React.JSX.Element;
116
118
  interface EditorControlProps {
117
119
  label: string;
118
120
  icon: LucideIcon;
@@ -121,6 +123,6 @@ interface EditorControlProps {
121
123
  onActivate: () => void;
122
124
  className?: string;
123
125
  }
124
- declare function EditorControl({ label, icon: Icon, pressed, disabled, onActivate, className, }: EditorControlProps): React.JSX.Element;
126
+ declare function EditorControl({ label, icon: Icon, pressed, disabled, onActivate, className, slotName, }: EditorControlProps & SlotNameProps): React.JSX.Element;
125
127
 
126
128
  export { Editor, EditorBlockquote, type EditorBlockquoteProps, EditorContent, type EditorContentProps, type EditorContextValue, EditorControl, type EditorControlProps, type EditorDocument, EditorHeading, type EditorHeadingProps, EditorHistory, type EditorHistoryAction, type EditorHistoryProps, type EditorLabels, EditorLink, type EditorLinkProps, EditorList, type EditorListProps, type EditorListVariant, EditorMark, type EditorMarkName, type EditorMarkProps, type EditorOutput, type EditorProps, EditorToolbar, type EditorToolbarProps, RichTextEditor, type RichTextEditorProps, defaultEditorExtensions, editorLabels, isSafeEditorUrl, useEditorContext };
package/dist/editor.js CHANGED
@@ -1,8 +1,7 @@
1
- import { Toggle } from './chunk-LKSM3WLK.js';
2
- import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Label, DialogFooter } from './chunk-6QM5BA7B.js';
3
- import { Separator } from './chunk-UUEWFCKT.js';
4
- import { Input } from './chunk-6X4TKSF6.js';
5
- import { cn, Button, fieldSurface, focusRing } from './chunk-DSD7MVLL.js';
1
+ import { Toggle } from './chunk-SBLZ6T3D.js';
2
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Label, DialogFooter } from './chunk-O5DZTX7D.js';
3
+ import { Input, Separator } from './chunk-UTSTTTH5.js';
4
+ import { cn, Button, fieldSurface, focusRing } from './chunk-I5UZAJB4.js';
6
5
  import { EditorContent as EditorContent$1, useEditor } from '@tiptap/react';
7
6
  import { createContext, useContext, useState, useRef, useMemo, useEffect, useId } from 'react';
8
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -18,32 +17,39 @@ function useEditorContext() {
18
17
  }
19
18
  return context;
20
19
  }
21
- function EditorContent({ className }) {
20
+ function EditorContent({
21
+ className,
22
+ slotName = "editor-content"
23
+ }) {
22
24
  const { editor, placeholder } = useEditorContext();
23
25
  return /* @__PURE__ */ jsx(
24
26
  "div",
25
27
  {
26
- "data-slot": "editor-content",
27
28
  "data-placeholder": placeholder,
28
29
  "data-empty": editor.isEmpty ? "" : void 0,
29
30
  className: cn(
30
31
  "data-empty:before:top-3 data-empty:before:left-4 data-empty:before:text-sm data-empty:before:font-medium relative w-full data-empty:before:pointer-events-none data-empty:before:absolute data-empty:before:text-muted-foreground data-empty:before:content-[attr(data-placeholder)]",
31
32
  className
32
33
  ),
34
+ "data-slot": slotName,
33
35
  children: /* @__PURE__ */ jsx(EditorContent$1, { editor })
34
36
  }
35
37
  );
36
38
  }
37
- function EditorToolbar({ children, className }) {
39
+ function EditorToolbar({
40
+ children,
41
+ className,
42
+ slotName = "editor-toolbar"
43
+ }) {
38
44
  const { labels } = useEditorContext();
39
45
  return /* @__PURE__ */ jsx(
40
46
  "div",
41
47
  {
42
- "data-slot": "editor-toolbar",
43
48
  role: "toolbar",
44
49
  "aria-label": labels.toolbarLabel,
45
50
  "aria-orientation": "horizontal",
46
51
  className: cn("gap-1 flex flex-wrap items-center", className),
52
+ "data-slot": slotName,
47
53
  children
48
54
  }
49
55
  );
@@ -54,13 +60,13 @@ function EditorControl({
54
60
  pressed = false,
55
61
  disabled = false,
56
62
  onActivate,
57
- className
63
+ className,
64
+ slotName = "editor-control"
58
65
  }) {
59
66
  const { editable } = useEditorContext();
60
67
  return /* @__PURE__ */ jsx(
61
68
  Toggle,
62
69
  {
63
- "data-slot": "editor-control",
64
70
  size: "sm",
65
71
  "aria-label": label,
66
72
  title: label,
@@ -68,6 +74,7 @@ function EditorControl({
68
74
  disabled: disabled || !editable,
69
75
  onPressedChange: onActivate,
70
76
  className,
77
+ slotName,
71
78
  children: /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true" })
72
79
  }
73
80
  );
@@ -152,7 +159,8 @@ function EditorBlockquote({ label, className }) {
152
159
  function EditorHistory({
153
160
  action,
154
161
  label,
155
- className
162
+ className,
163
+ slotName = "editor-history"
156
164
  }) {
157
165
  const { editor, labels, editable } = useEditorContext();
158
166
  const undoing = action === "undo";
@@ -161,7 +169,6 @@ function EditorHistory({
161
169
  return /* @__PURE__ */ jsx(
162
170
  Button,
163
171
  {
164
- "data-slot": "editor-history",
165
172
  type: "button",
166
173
  variant: "ghost",
167
174
  size: "icon-sm",
@@ -170,6 +177,7 @@ function EditorHistory({
170
177
  disabled: !available || !editable,
171
178
  onClick: () => undoing ? editor.chain().focus().undo().run() : editor.chain().focus().redo().run(),
172
179
  className,
180
+ slotName,
173
181
  children: /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true" })
174
182
  }
175
183
  );
@@ -240,7 +248,8 @@ function Editor({
240
248
  disabled = false,
241
249
  readOnly = false,
242
250
  className,
243
- children
251
+ children,
252
+ slotName = "editor"
244
253
  }) {
245
254
  const [revision, setRevision] = useState(0);
246
255
  const editable = !disabled && !readOnly;
@@ -308,18 +317,22 @@ function Editor({
308
317
  return /* @__PURE__ */ jsx(EditorContextProvider, { value: context, children: /* @__PURE__ */ jsx(
309
318
  "div",
310
319
  {
311
- "data-slot": "editor",
312
320
  "data-disabled": disabled ? "" : void 0,
313
321
  "data-readonly": readOnly ? "" : void 0,
314
322
  className: cn(
315
323
  "gap-2 flex w-full flex-col data-disabled:opacity-50",
316
324
  className
317
325
  ),
326
+ "data-slot": slotName,
318
327
  children
319
328
  }
320
329
  ) });
321
330
  }
322
- function EditorLink({ label, className }) {
331
+ function EditorLink({
332
+ label,
333
+ className,
334
+ slotName = "editor-link-dialog"
335
+ }) {
323
336
  const { editor, labels, editable } = useEditorContext();
324
337
  const [open, setOpen] = useState(false);
325
338
  const [href, setHref] = useState("");
@@ -352,7 +365,7 @@ function EditorLink({ label, className }) {
352
365
  className
353
366
  }
354
367
  ),
355
- /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(DialogContent, { "data-slot": "editor-link-dialog", children: [
368
+ /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(DialogContent, { slotName, children: [
356
369
  /* @__PURE__ */ jsxs(DialogHeader, { children: [
357
370
  /* @__PURE__ */ jsx(DialogTitle, { children: labels.linkDialogTitle }),
358
371
  /* @__PURE__ */ jsx(DialogDescription, { children: labels.linkDialogDescription })
@@ -363,7 +376,7 @@ function EditorLink({ label, className }) {
363
376
  Input,
364
377
  {
365
378
  id: fieldId,
366
- "data-slot": "editor-link-url",
379
+ slotName: "editor-link-url",
367
380
  value: href,
368
381
  placeholder: labels.linkUrlPlaceholder,
369
382
  onChange: (event) => setHref(event.target.value),
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ui/editor/context.tsx","../src/components/ui/editor/content.tsx","../src/components/ui/editor/toolbar.tsx","../src/components/ui/editor/controls.tsx","../src/components/ui/editor/extensions.ts","../src/components/ui/editor/labels.ts","../src/components/ui/editor/editor.tsx","../src/components/ui/editor/link.tsx","../src/components/ui/editor/rich-text-editor.tsx"],"names":["TiptapContent","jsx","revision","useState","jsxs"],"mappings":"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","file":"editor.js","sourcesContent":["import type { Editor as TiptapEditor } from '@tiptap/core';\nimport { createContext, useContext } from 'react';\n\nimport type { EditorLabels } from '@/components/ui/editor/labels';\n\nexport interface EditorContextValue {\n editor: TiptapEditor;\n labels: EditorLabels;\n editable: boolean;\n placeholder?: string;\n}\n\nconst EditorContext = createContext<EditorContextValue | null>(null);\n\nexport const EditorContextProvider = EditorContext.Provider;\n\nexport function useEditorContext(): EditorContextValue {\n const context = useContext(EditorContext);\n\n if (context === null) {\n throw new Error('Editor parts must be used inside <Editor>.');\n }\n\n return context;\n}\n","import { EditorContent as TiptapContent } from '@tiptap/react';\n\nimport { useEditorContext } from '@/components/ui/editor/context';\nimport { cn } from '@/lib/utils';\n\nexport interface EditorContentProps {\n className?: string;\n}\n\nexport function EditorContent({ className }: EditorContentProps) {\n const { editor, placeholder } = useEditorContext();\n\n return (\n <div\n data-slot=\"editor-content\"\n data-placeholder={placeholder}\n data-empty={editor.isEmpty ? '' : undefined}\n className={cn(\n 'data-empty:before:top-3 data-empty:before:left-4 data-empty:before:text-sm data-empty:before:font-medium relative w-full data-empty:before:pointer-events-none data-empty:before:absolute data-empty:before:text-muted-foreground data-empty:before:content-[attr(data-placeholder)]',\n className,\n )}\n >\n <TiptapContent editor={editor} />\n </div>\n );\n}\n","import type { LucideIcon } from 'lucide-react';\nimport type { ReactNode } from 'react';\n\nimport { useEditorContext } from '@/components/ui/editor/context';\nimport { Toggle } from '@/components/ui/toggle';\nimport { cn } from '@/lib/utils';\n\nexport interface EditorToolbarProps {\n children: ReactNode;\n className?: string;\n}\n\nexport function EditorToolbar({ children, className }: EditorToolbarProps) {\n const { labels } = useEditorContext();\n\n return (\n <div\n data-slot=\"editor-toolbar\"\n role=\"toolbar\"\n aria-label={labels.toolbarLabel}\n aria-orientation=\"horizontal\"\n className={cn('gap-1 flex flex-wrap items-center', className)}\n >\n {children}\n </div>\n );\n}\n\nexport interface EditorControlProps {\n label: string;\n icon: LucideIcon;\n pressed?: boolean;\n disabled?: boolean;\n onActivate: () => void;\n className?: string;\n}\n\nexport function EditorControl({\n label,\n icon: Icon,\n pressed = false,\n disabled = false,\n onActivate,\n className,\n}: EditorControlProps) {\n const { editable } = useEditorContext();\n\n return (\n <Toggle\n data-slot=\"editor-control\"\n size=\"sm\"\n aria-label={label}\n title={label}\n pressed={pressed}\n disabled={disabled || !editable}\n onPressedChange={onActivate}\n className={className}\n >\n <Icon aria-hidden=\"true\" />\n </Toggle>\n );\n}\n","import {\n Bold,\n Code,\n Heading1,\n Heading2,\n Heading3,\n Heading4,\n Heading5,\n Heading6,\n Italic,\n List,\n ListOrdered,\n Quote,\n Redo2,\n Strikethrough,\n Undo2,\n type LucideIcon,\n} from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport { useEditorContext } from '@/components/ui/editor/context';\nimport { EditorControl } from '@/components/ui/editor/toolbar';\n\nexport type EditorMarkName = 'bold' | 'italic' | 'strike' | 'code';\n\nconst MARK_ICONS: Record<EditorMarkName, LucideIcon> = {\n bold: Bold,\n italic: Italic,\n strike: Strikethrough,\n code: Code,\n};\n\nexport interface EditorMarkProps {\n mark: EditorMarkName;\n label?: string;\n className?: string;\n}\n\nexport function EditorMark({ mark, label, className }: EditorMarkProps) {\n const { editor, labels } = useEditorContext();\n\n const names: Record<EditorMarkName, string> = {\n bold: labels.boldLabel,\n italic: labels.italicLabel,\n strike: labels.strikeLabel,\n code: labels.codeLabel,\n };\n\n return (\n <EditorControl\n label={label ?? names[mark]}\n icon={MARK_ICONS[mark]}\n pressed={editor.isActive(mark)}\n disabled={!editor.can().toggleMark(mark)}\n onActivate={() => editor.chain().focus().toggleMark(mark).run()}\n className={className}\n />\n );\n}\n\nconst HEADING_ICONS: Record<number, LucideIcon> = {\n 1: Heading1,\n 2: Heading2,\n 3: Heading3,\n 4: Heading4,\n 5: Heading5,\n 6: Heading6,\n};\n\nexport interface EditorHeadingProps {\n level: 1 | 2 | 3 | 4 | 5 | 6;\n label?: string;\n className?: string;\n}\n\nexport function EditorHeading({ level, label, className }: EditorHeadingProps) {\n const { editor, labels } = useEditorContext();\n\n return (\n <EditorControl\n label={label ?? labels.headingLabel(level)}\n icon={HEADING_ICONS[level]}\n pressed={editor.isActive('heading', { level })}\n disabled={\n !editor.can().toggleNode('heading', 'paragraph', { level })\n }\n onActivate={() =>\n editor.chain().focus().toggleHeading({ level }).run()\n }\n className={className}\n />\n );\n}\n\nexport type EditorListVariant = 'bullet' | 'ordered';\n\nexport interface EditorListProps {\n variant: EditorListVariant;\n label?: string;\n className?: string;\n}\n\nexport function EditorList({ variant, label, className }: EditorListProps) {\n const { editor, labels } = useEditorContext();\n const name = variant === 'bullet' ? 'bulletList' : 'orderedList';\n\n return (\n <EditorControl\n label={\n label ??\n (variant === 'bullet'\n ? labels.bulletListLabel\n : labels.orderedListLabel)\n }\n icon={variant === 'bullet' ? List : ListOrdered}\n pressed={editor.isActive(name)}\n disabled={!editor.can().toggleList(name, 'listItem')}\n onActivate={() =>\n variant === 'bullet'\n ? editor.chain().focus().toggleBulletList().run()\n : editor.chain().focus().toggleOrderedList().run()\n }\n className={className}\n />\n );\n}\n\nexport interface EditorBlockquoteProps {\n label?: string;\n className?: string;\n}\n\nexport function EditorBlockquote({ label, className }: EditorBlockquoteProps) {\n const { editor, labels } = useEditorContext();\n\n return (\n <EditorControl\n label={label ?? labels.blockquoteLabel}\n icon={Quote}\n pressed={editor.isActive('blockquote')}\n disabled={!editor.can().toggleWrap('blockquote')}\n onActivate={() => editor.chain().focus().toggleBlockquote().run()}\n className={className}\n />\n );\n}\n\nexport type EditorHistoryAction = 'undo' | 'redo';\n\nexport interface EditorHistoryProps {\n action: EditorHistoryAction;\n label?: string;\n className?: string;\n}\n\nexport function EditorHistory({\n action,\n label,\n className,\n}: EditorHistoryProps) {\n const { editor, labels, editable } = useEditorContext();\n const undoing = action === 'undo';\n const available = undoing ? editor.can().undo() : editor.can().redo();\n const Icon = undoing ? Undo2 : Redo2;\n\n return (\n <Button\n data-slot=\"editor-history\"\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={\n label ?? (undoing ? labels.undoLabel : labels.redoLabel)\n }\n title={label ?? (undoing ? labels.undoLabel : labels.redoLabel)}\n disabled={!available || !editable}\n onClick={() =>\n undoing\n ? editor.chain().focus().undo().run()\n : editor.chain().focus().redo().run()\n }\n className={className}\n >\n <Icon aria-hidden=\"true\" />\n </Button>\n );\n}\n","import type { Extensions } from '@tiptap/core';\nimport StarterKit from '@tiptap/starter-kit';\n\nconst SAFE_PROTOCOLS = ['http', 'https', 'mailto', 'tel'];\n\nexport function isSafeEditorUrl(url: string): boolean {\n const protocol = /^([a-z][a-z0-9+.-]*):/i.exec(url.trim())?.[1];\n\n return (\n protocol === undefined ||\n SAFE_PROTOCOLS.includes(protocol.toLowerCase())\n );\n}\n\nexport function defaultEditorExtensions(): Extensions {\n return [\n StarterKit.configure({\n link: {\n openOnClick: false,\n autolink: true,\n protocols: SAFE_PROTOCOLS,\n isAllowedUri: (url) => isSafeEditorUrl(url),\n HTMLAttributes: {\n rel: 'noopener noreferrer nofollow',\n target: '_blank',\n },\n },\n }),\n ];\n}\n","export interface EditorLabels {\n toolbarLabel: string;\n boldLabel: string;\n italicLabel: string;\n strikeLabel: string;\n codeLabel: string;\n headingLabel: (level: number) => string;\n bulletListLabel: string;\n orderedListLabel: string;\n blockquoteLabel: string;\n undoLabel: string;\n redoLabel: string;\n linkLabel: string;\n linkDialogTitle: string;\n linkDialogDescription: string;\n linkUrlLabel: string;\n linkUrlPlaceholder: string;\n linkApplyLabel: string;\n linkRemoveLabel: string;\n linkCancelLabel: string;\n}\n\nexport const editorLabels: EditorLabels = {\n toolbarLabel: 'Formatting',\n boldLabel: 'Bold',\n italicLabel: 'Italic',\n strikeLabel: 'Strikethrough',\n codeLabel: 'Code',\n headingLabel: (level) => `Heading ${level}`,\n bulletListLabel: 'Bullet list',\n orderedListLabel: 'Numbered list',\n blockquoteLabel: 'Quote',\n undoLabel: 'Undo',\n redoLabel: 'Redo',\n linkLabel: 'Link',\n linkDialogTitle: 'Link',\n linkDialogDescription: 'Point the selected text at an address.',\n linkUrlLabel: 'Address',\n linkUrlPlaceholder: 'https://example.com',\n linkApplyLabel: 'Apply',\n linkRemoveLabel: 'Remove',\n linkCancelLabel: 'Cancel',\n};\n","import type { Extensions, JSONContent } from '@tiptap/core';\nimport { useEditor } from '@tiptap/react';\nimport { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\n\nimport {\n EditorContextProvider,\n type EditorContextValue,\n} from '@/components/ui/editor/context';\nimport { defaultEditorExtensions } from '@/components/ui/editor/extensions';\nimport { editorLabels, type EditorLabels } from '@/components/ui/editor/labels';\nimport { fieldSurface, focusRing } from '@/lib/language';\nimport { cn } from '@/lib/utils';\n\nexport type EditorOutput = 'html' | 'json';\n\nexport type EditorDocument = string | JSONContent;\n\ninterface EditorSharedProps {\n extensions?: Extensions;\n labels?: EditorLabels;\n placeholder?: string;\n label?: string;\n disabled?: boolean;\n readOnly?: boolean;\n className?: string;\n children: ReactNode;\n}\n\nexport type EditorProps = EditorSharedProps &\n (\n | {\n output?: 'html';\n value: string;\n onChange: (value: string) => void;\n }\n | {\n output: 'json';\n value: JSONContent;\n onChange: (value: JSONContent) => void;\n }\n );\n\nconst editorProse =\n 'text-sm font-medium leading-relaxed [&_p]:my-2 [&_h1]:mt-4 [&_h1]:mb-2 [&_h1]:text-2xl [&_h1]:font-bold [&_h2]:mt-4 [&_h2]:mb-2 [&_h2]:text-xl [&_h2]:font-bold [&_h3]:mt-3 [&_h3]:mb-2 [&_h3]:text-lg [&_h3]:font-semibold [&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-6 [&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-6 [&_li]:my-1 [&_blockquote]:my-3 [&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-4 [&_blockquote]:text-muted-foreground [&_a]:text-primary [&_a]:underline [&_a]:underline-offset-4 [&_code]:rounded-md [&_code]:bg-muted [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:font-normal [&_pre]:my-3 [&_pre]:rounded-xl [&_pre]:bg-muted [&_pre]:p-4 [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_hr]:my-4 [&_hr]:border-border';\n\nconst editingSurface = `${fieldSurface} ${focusRing} ${editorProse} min-h-32 w-full px-4 py-3 selection:bg-primary selection:text-primary-foreground`;\n\nfunction read(\n editor: { getHTML: () => string; getJSON: () => JSONContent },\n output: EditorOutput,\n): EditorDocument {\n return output === 'json' ? editor.getJSON() : editor.getHTML();\n}\n\nfunction isSameDocument(left: EditorDocument, right: EditorDocument): boolean {\n if (typeof left === 'string' && typeof right === 'string') {\n return left === right;\n }\n\n return JSON.stringify(left) === JSON.stringify(right);\n}\n\nexport function Editor({\n value,\n onChange,\n output = 'html',\n extensions,\n labels = editorLabels,\n placeholder,\n label,\n disabled = false,\n readOnly = false,\n className,\n children,\n}: EditorProps) {\n const [revision, setRevision] = useState(0);\n const editable = !disabled && !readOnly;\n const emit = useRef(onChange as (next: EditorDocument) => void);\n emit.current = onChange as (next: EditorDocument) => void;\n const emitted = useRef<EditorDocument | null>(null);\n\n const extensionSet = useMemo(\n () => extensions ?? defaultEditorExtensions(),\n [extensions],\n );\n\n const editor = useEditor(\n {\n extensions: extensionSet,\n content: value,\n editable,\n immediatelyRender: false,\n editorProps: {\n attributes: {\n 'data-slot': 'editor-surface',\n role: 'textbox',\n 'aria-multiline': 'true',\n ...(label === undefined ? {} : { 'aria-label': label }),\n class: editingSurface,\n },\n },\n onUpdate: ({ editor: instance }) => {\n const next = read(instance, output);\n\n emitted.current = next;\n emit.current(next);\n },\n },\n [extensionSet],\n );\n\n useEffect(() => {\n if (editor === null) {\n return;\n }\n\n const rerender = () => setRevision((revision) => revision + 1);\n\n editor.on('transaction', rerender);\n\n return () => {\n editor.off('transaction', rerender);\n };\n }, [editor]);\n\n useEffect(() => {\n editor?.setEditable(editable, false);\n }, [editor, editable]);\n\n useEffect(() => {\n if (editor === null) {\n return;\n }\n\n const echoed =\n emitted.current !== null && isSameDocument(emitted.current, value);\n\n if (echoed || isSameDocument(read(editor, output), value)) {\n return;\n }\n\n emitted.current = null;\n editor.commands.setContent(value, { emitUpdate: false });\n }, [editor, value, output]);\n\n const context = useMemo<EditorContextValue | null>(\n () =>\n editor === null ? null : { editor, labels, editable, placeholder },\n [editor, labels, editable, placeholder, revision],\n );\n\n if (context === null) {\n return null;\n }\n\n return (\n <EditorContextProvider value={context}>\n <div\n data-slot=\"editor\"\n data-disabled={disabled ? '' : undefined}\n data-readonly={readOnly ? '' : undefined}\n className={cn(\n 'gap-2 flex w-full flex-col data-disabled:opacity-50',\n className,\n )}\n >\n {children}\n </div>\n </EditorContextProvider>\n );\n}\n","import { Link2 } from 'lucide-react';\nimport { useId, useState } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@/components/ui/dialog';\nimport { useEditorContext } from '@/components/ui/editor/context';\nimport { isSafeEditorUrl } from '@/components/ui/editor/extensions';\nimport { EditorControl } from '@/components/ui/editor/toolbar';\nimport { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\n\nexport interface EditorLinkProps {\n label?: string;\n className?: string;\n}\n\nexport function EditorLink({ label, className }: EditorLinkProps) {\n const { editor, labels, editable } = useEditorContext();\n const [open, setOpen] = useState(false);\n const [href, setHref] = useState('');\n const attached = editor.isActive('link');\n const fieldId = useId();\n\n function openDialog() {\n setHref(editor.getAttributes('link').href ?? '');\n setOpen(true);\n }\n\n function apply() {\n if (!isSafeEditorUrl(href)) {\n return;\n }\n\n editor\n .chain()\n .focus()\n .extendMarkRange('link')\n .setLink({ href: href.trim() })\n .run();\n\n setOpen(false);\n }\n\n function remove() {\n editor.chain().focus().extendMarkRange('link').unsetLink().run();\n setOpen(false);\n }\n\n return (\n <>\n <EditorControl\n label={label ?? labels.linkLabel}\n icon={Link2}\n pressed={attached}\n disabled={!editable}\n onActivate={openDialog}\n className={className}\n />\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogContent data-slot=\"editor-link-dialog\">\n <DialogHeader>\n <DialogTitle>{labels.linkDialogTitle}</DialogTitle>\n <DialogDescription>\n {labels.linkDialogDescription}\n </DialogDescription>\n </DialogHeader>\n <div className=\"gap-2 flex flex-col\">\n <Label htmlFor={fieldId}>{labels.linkUrlLabel}</Label>\n <Input\n id={fieldId}\n data-slot=\"editor-link-url\"\n value={href}\n placeholder={labels.linkUrlPlaceholder}\n onChange={(event) => setHref(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n apply();\n }\n }}\n />\n </div>\n <DialogFooter>\n {attached && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={remove}\n >\n {labels.linkRemoveLabel}\n </Button>\n )}\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setOpen(false)}\n >\n {labels.linkCancelLabel}\n </Button>\n <Button\n type=\"button\"\n onClick={apply}\n disabled={href.trim() === ''}\n >\n {labels.linkApplyLabel}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","import { EditorContent } from '@/components/ui/editor/content';\nimport {\n EditorBlockquote,\n EditorHeading,\n EditorHistory,\n EditorList,\n EditorMark,\n} from '@/components/ui/editor/controls';\nimport { Editor, type EditorProps } from '@/components/ui/editor/editor';\nimport { EditorLink } from '@/components/ui/editor/link';\nimport { EditorToolbar } from '@/components/ui/editor/toolbar';\nimport { Separator } from '@/components/ui/separator';\n\ntype WithoutChildren<T> = T extends unknown ? Omit<T, 'children'> : never;\n\nexport type RichTextEditorProps = WithoutChildren<EditorProps>;\n\nexport function RichTextEditor(props: RichTextEditorProps) {\n return (\n <Editor {...props}>\n <EditorToolbar>\n <EditorMark mark=\"bold\" />\n <EditorMark mark=\"italic\" />\n <EditorMark mark=\"strike\" />\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <EditorHeading level={2} />\n <EditorHeading level={3} />\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <EditorList variant=\"bullet\" />\n <EditorList variant=\"ordered\" />\n <EditorBlockquote />\n <EditorMark mark=\"code\" />\n <EditorLink />\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <EditorHistory action=\"undo\" />\n <EditorHistory action=\"redo\" />\n </EditorToolbar>\n <EditorContent />\n </Editor>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/ui/editor/context.tsx","../src/components/ui/editor/content.tsx","../src/components/ui/editor/toolbar.tsx","../src/components/ui/editor/controls.tsx","../src/components/ui/editor/extensions.ts","../src/components/ui/editor/labels.ts","../src/components/ui/editor/editor.tsx","../src/components/ui/editor/link.tsx","../src/components/ui/editor/rich-text-editor.tsx"],"names":["TiptapContent","jsx","revision","useState","jsxs"],"mappings":"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","file":"editor.js","sourcesContent":["import type { Editor as TiptapEditor } from '@tiptap/core';\nimport { createContext, useContext } from 'react';\n\nimport type { EditorLabels } from '@/components/ui/editor/labels';\n\nexport interface EditorContextValue {\n editor: TiptapEditor;\n labels: EditorLabels;\n editable: boolean;\n placeholder?: string;\n}\n\nconst EditorContext = createContext<EditorContextValue | null>(null);\n\nexport const EditorContextProvider = EditorContext.Provider;\n\nexport function useEditorContext(): EditorContextValue {\n const context = useContext(EditorContext);\n\n if (context === null) {\n throw new Error('Editor parts must be used inside <Editor>.');\n }\n\n return context;\n}\n","import { EditorContent as TiptapContent } from '@tiptap/react';\n\nimport { useEditorContext } from '@/components/ui/editor/context';\nimport { cn } from '@/lib/utils';\nimport type { SlotNameProps } from '@/types';\n\nexport interface EditorContentProps {\n className?: string;\n}\n\nexport function EditorContent({\n className,\n slotName = 'editor-content',\n}: EditorContentProps & SlotNameProps) {\n const { editor, placeholder } = useEditorContext();\n\n return (\n <div\n data-placeholder={placeholder}\n data-empty={editor.isEmpty ? '' : undefined}\n className={cn(\n 'data-empty:before:top-3 data-empty:before:left-4 data-empty:before:text-sm data-empty:before:font-medium relative w-full data-empty:before:pointer-events-none data-empty:before:absolute data-empty:before:text-muted-foreground data-empty:before:content-[attr(data-placeholder)]',\n className,\n )}\n data-slot={slotName}\n >\n <TiptapContent editor={editor} />\n </div>\n );\n}\n","import type { LucideIcon } from 'lucide-react';\nimport type { ReactNode } from 'react';\n\nimport { useEditorContext } from '@/components/ui/editor/context';\nimport { Toggle } from '@/components/ui/toggle';\nimport { cn } from '@/lib/utils';\nimport type { SlotNameProps } from '@/types';\n\nexport interface EditorToolbarProps {\n children: ReactNode;\n className?: string;\n}\n\nexport function EditorToolbar({\n children,\n className,\n slotName = 'editor-toolbar',\n}: EditorToolbarProps & SlotNameProps) {\n const { labels } = useEditorContext();\n\n return (\n <div\n role=\"toolbar\"\n aria-label={labels.toolbarLabel}\n aria-orientation=\"horizontal\"\n className={cn('gap-1 flex flex-wrap items-center', className)}\n data-slot={slotName}\n >\n {children}\n </div>\n );\n}\n\nexport interface EditorControlProps {\n label: string;\n icon: LucideIcon;\n pressed?: boolean;\n disabled?: boolean;\n onActivate: () => void;\n className?: string;\n}\n\nexport function EditorControl({\n label,\n icon: Icon,\n pressed = false,\n disabled = false,\n onActivate,\n className,\n slotName = 'editor-control',\n}: EditorControlProps & SlotNameProps) {\n const { editable } = useEditorContext();\n\n return (\n <Toggle\n size=\"sm\"\n aria-label={label}\n title={label}\n pressed={pressed}\n disabled={disabled || !editable}\n onPressedChange={onActivate}\n className={className}\n slotName={slotName}\n >\n <Icon aria-hidden=\"true\" />\n </Toggle>\n );\n}\n","import {\n Bold,\n Code,\n Heading1,\n Heading2,\n Heading3,\n Heading4,\n Heading5,\n Heading6,\n Italic,\n List,\n ListOrdered,\n Quote,\n Redo2,\n Strikethrough,\n Undo2,\n type LucideIcon,\n} from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport { useEditorContext } from '@/components/ui/editor/context';\nimport { EditorControl } from '@/components/ui/editor/toolbar';\nimport type { SlotNameProps } from '@/types';\n\nexport type EditorMarkName = 'bold' | 'italic' | 'strike' | 'code';\n\nconst MARK_ICONS: Record<EditorMarkName, LucideIcon> = {\n bold: Bold,\n italic: Italic,\n strike: Strikethrough,\n code: Code,\n};\n\nexport interface EditorMarkProps {\n mark: EditorMarkName;\n label?: string;\n className?: string;\n}\n\nexport function EditorMark({ mark, label, className }: EditorMarkProps) {\n const { editor, labels } = useEditorContext();\n\n const names: Record<EditorMarkName, string> = {\n bold: labels.boldLabel,\n italic: labels.italicLabel,\n strike: labels.strikeLabel,\n code: labels.codeLabel,\n };\n\n return (\n <EditorControl\n label={label ?? names[mark]}\n icon={MARK_ICONS[mark]}\n pressed={editor.isActive(mark)}\n disabled={!editor.can().toggleMark(mark)}\n onActivate={() => editor.chain().focus().toggleMark(mark).run()}\n className={className}\n />\n );\n}\n\nconst HEADING_ICONS: Record<number, LucideIcon> = {\n 1: Heading1,\n 2: Heading2,\n 3: Heading3,\n 4: Heading4,\n 5: Heading5,\n 6: Heading6,\n};\n\nexport interface EditorHeadingProps {\n level: 1 | 2 | 3 | 4 | 5 | 6;\n label?: string;\n className?: string;\n}\n\nexport function EditorHeading({ level, label, className }: EditorHeadingProps) {\n const { editor, labels } = useEditorContext();\n\n return (\n <EditorControl\n label={label ?? labels.headingLabel(level)}\n icon={HEADING_ICONS[level]}\n pressed={editor.isActive('heading', { level })}\n disabled={\n !editor.can().toggleNode('heading', 'paragraph', { level })\n }\n onActivate={() =>\n editor.chain().focus().toggleHeading({ level }).run()\n }\n className={className}\n />\n );\n}\n\nexport type EditorListVariant = 'bullet' | 'ordered';\n\nexport interface EditorListProps {\n variant: EditorListVariant;\n label?: string;\n className?: string;\n}\n\nexport function EditorList({ variant, label, className }: EditorListProps) {\n const { editor, labels } = useEditorContext();\n const name = variant === 'bullet' ? 'bulletList' : 'orderedList';\n\n return (\n <EditorControl\n label={\n label ??\n (variant === 'bullet'\n ? labels.bulletListLabel\n : labels.orderedListLabel)\n }\n icon={variant === 'bullet' ? List : ListOrdered}\n pressed={editor.isActive(name)}\n disabled={!editor.can().toggleList(name, 'listItem')}\n onActivate={() =>\n variant === 'bullet'\n ? editor.chain().focus().toggleBulletList().run()\n : editor.chain().focus().toggleOrderedList().run()\n }\n className={className}\n />\n );\n}\n\nexport interface EditorBlockquoteProps {\n label?: string;\n className?: string;\n}\n\nexport function EditorBlockquote({ label, className }: EditorBlockquoteProps) {\n const { editor, labels } = useEditorContext();\n\n return (\n <EditorControl\n label={label ?? labels.blockquoteLabel}\n icon={Quote}\n pressed={editor.isActive('blockquote')}\n disabled={!editor.can().toggleWrap('blockquote')}\n onActivate={() => editor.chain().focus().toggleBlockquote().run()}\n className={className}\n />\n );\n}\n\nexport type EditorHistoryAction = 'undo' | 'redo';\n\nexport interface EditorHistoryProps {\n action: EditorHistoryAction;\n label?: string;\n className?: string;\n}\n\nexport function EditorHistory({\n action,\n label,\n className,\n slotName = 'editor-history',\n}: EditorHistoryProps & SlotNameProps) {\n const { editor, labels, editable } = useEditorContext();\n const undoing = action === 'undo';\n const available = undoing ? editor.can().undo() : editor.can().redo();\n const Icon = undoing ? Undo2 : Redo2;\n\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={\n label ?? (undoing ? labels.undoLabel : labels.redoLabel)\n }\n title={label ?? (undoing ? labels.undoLabel : labels.redoLabel)}\n disabled={!available || !editable}\n onClick={() =>\n undoing\n ? editor.chain().focus().undo().run()\n : editor.chain().focus().redo().run()\n }\n className={className}\n slotName={slotName}\n >\n <Icon aria-hidden=\"true\" />\n </Button>\n );\n}\n","import type { Extensions } from '@tiptap/core';\nimport StarterKit from '@tiptap/starter-kit';\n\nconst SAFE_PROTOCOLS = ['http', 'https', 'mailto', 'tel'];\n\nexport function isSafeEditorUrl(url: string): boolean {\n const protocol = /^([a-z][a-z0-9+.-]*):/i.exec(url.trim())?.[1];\n\n return (\n protocol === undefined ||\n SAFE_PROTOCOLS.includes(protocol.toLowerCase())\n );\n}\n\nexport function defaultEditorExtensions(): Extensions {\n return [\n StarterKit.configure({\n link: {\n openOnClick: false,\n autolink: true,\n protocols: SAFE_PROTOCOLS,\n isAllowedUri: (url) => isSafeEditorUrl(url),\n HTMLAttributes: {\n rel: 'noopener noreferrer nofollow',\n target: '_blank',\n },\n },\n }),\n ];\n}\n","export interface EditorLabels {\n toolbarLabel: string;\n boldLabel: string;\n italicLabel: string;\n strikeLabel: string;\n codeLabel: string;\n headingLabel: (level: number) => string;\n bulletListLabel: string;\n orderedListLabel: string;\n blockquoteLabel: string;\n undoLabel: string;\n redoLabel: string;\n linkLabel: string;\n linkDialogTitle: string;\n linkDialogDescription: string;\n linkUrlLabel: string;\n linkUrlPlaceholder: string;\n linkApplyLabel: string;\n linkRemoveLabel: string;\n linkCancelLabel: string;\n}\n\nexport const editorLabels: EditorLabels = {\n toolbarLabel: 'Formatting',\n boldLabel: 'Bold',\n italicLabel: 'Italic',\n strikeLabel: 'Strikethrough',\n codeLabel: 'Code',\n headingLabel: (level) => `Heading ${level}`,\n bulletListLabel: 'Bullet list',\n orderedListLabel: 'Numbered list',\n blockquoteLabel: 'Quote',\n undoLabel: 'Undo',\n redoLabel: 'Redo',\n linkLabel: 'Link',\n linkDialogTitle: 'Link',\n linkDialogDescription: 'Point the selected text at an address.',\n linkUrlLabel: 'Address',\n linkUrlPlaceholder: 'https://example.com',\n linkApplyLabel: 'Apply',\n linkRemoveLabel: 'Remove',\n linkCancelLabel: 'Cancel',\n};\n","import type { Extensions, JSONContent } from '@tiptap/core';\nimport { useEditor } from '@tiptap/react';\nimport { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\n\nimport {\n EditorContextProvider,\n type EditorContextValue,\n} from '@/components/ui/editor/context';\nimport { defaultEditorExtensions } from '@/components/ui/editor/extensions';\nimport { editorLabels, type EditorLabels } from '@/components/ui/editor/labels';\nimport { fieldSurface, focusRing } from '@/lib/language';\nimport { cn } from '@/lib/utils';\nimport type { SlotNameProps } from '@/types';\n\nexport type EditorOutput = 'html' | 'json';\n\nexport type EditorDocument = string | JSONContent;\n\ninterface EditorSharedProps {\n extensions?: Extensions;\n labels?: EditorLabels;\n placeholder?: string;\n label?: string;\n disabled?: boolean;\n readOnly?: boolean;\n className?: string;\n children: ReactNode;\n}\n\nexport type EditorProps = EditorSharedProps &\n (\n | {\n output?: 'html';\n value: string;\n onChange: (value: string) => void;\n }\n | {\n output: 'json';\n value: JSONContent;\n onChange: (value: JSONContent) => void;\n }\n );\n\nconst editorProse =\n 'text-sm font-medium leading-relaxed [&_p]:my-2 [&_h1]:mt-4 [&_h1]:mb-2 [&_h1]:text-2xl [&_h1]:font-bold [&_h2]:mt-4 [&_h2]:mb-2 [&_h2]:text-xl [&_h2]:font-bold [&_h3]:mt-3 [&_h3]:mb-2 [&_h3]:text-lg [&_h3]:font-semibold [&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-6 [&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-6 [&_li]:my-1 [&_blockquote]:my-3 [&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-4 [&_blockquote]:text-muted-foreground [&_a]:text-primary [&_a]:underline [&_a]:underline-offset-4 [&_code]:rounded-md [&_code]:bg-muted [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:font-normal [&_pre]:my-3 [&_pre]:rounded-xl [&_pre]:bg-muted [&_pre]:p-4 [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_hr]:my-4 [&_hr]:border-border';\n\nconst editingSurface = `${fieldSurface} ${focusRing} ${editorProse} min-h-32 w-full px-4 py-3 selection:bg-primary selection:text-primary-foreground`;\n\nfunction read(\n editor: { getHTML: () => string; getJSON: () => JSONContent },\n output: EditorOutput,\n): EditorDocument {\n return output === 'json' ? editor.getJSON() : editor.getHTML();\n}\n\nfunction isSameDocument(left: EditorDocument, right: EditorDocument): boolean {\n if (typeof left === 'string' && typeof right === 'string') {\n return left === right;\n }\n\n return JSON.stringify(left) === JSON.stringify(right);\n}\n\nexport function Editor({\n value,\n onChange,\n output = 'html',\n extensions,\n labels = editorLabels,\n placeholder,\n label,\n disabled = false,\n readOnly = false,\n className,\n children,\n slotName = 'editor',\n}: EditorProps & SlotNameProps) {\n const [revision, setRevision] = useState(0);\n const editable = !disabled && !readOnly;\n const emit = useRef(onChange as (next: EditorDocument) => void);\n emit.current = onChange as (next: EditorDocument) => void;\n const emitted = useRef<EditorDocument | null>(null);\n\n const extensionSet = useMemo(\n () => extensions ?? defaultEditorExtensions(),\n [extensions],\n );\n\n const editor = useEditor(\n {\n extensions: extensionSet,\n content: value,\n editable,\n immediatelyRender: false,\n editorProps: {\n attributes: {\n 'data-slot': 'editor-surface',\n role: 'textbox',\n 'aria-multiline': 'true',\n ...(label === undefined ? {} : { 'aria-label': label }),\n class: editingSurface,\n },\n },\n onUpdate: ({ editor: instance }) => {\n const next = read(instance, output);\n\n emitted.current = next;\n emit.current(next);\n },\n },\n [extensionSet],\n );\n\n useEffect(() => {\n if (editor === null) {\n return;\n }\n\n const rerender = () => setRevision((revision) => revision + 1);\n\n editor.on('transaction', rerender);\n\n return () => {\n editor.off('transaction', rerender);\n };\n }, [editor]);\n\n useEffect(() => {\n editor?.setEditable(editable, false);\n }, [editor, editable]);\n\n useEffect(() => {\n if (editor === null) {\n return;\n }\n\n const echoed =\n emitted.current !== null && isSameDocument(emitted.current, value);\n\n if (echoed || isSameDocument(read(editor, output), value)) {\n return;\n }\n\n emitted.current = null;\n editor.commands.setContent(value, { emitUpdate: false });\n }, [editor, value, output]);\n\n const context = useMemo<EditorContextValue | null>(\n () =>\n editor === null ? null : { editor, labels, editable, placeholder },\n [editor, labels, editable, placeholder, revision],\n );\n\n if (context === null) {\n return null;\n }\n\n return (\n <EditorContextProvider value={context}>\n <div\n data-disabled={disabled ? '' : undefined}\n data-readonly={readOnly ? '' : undefined}\n className={cn(\n 'gap-2 flex w-full flex-col data-disabled:opacity-50',\n className,\n )}\n data-slot={slotName}\n >\n {children}\n </div>\n </EditorContextProvider>\n );\n}\n","import { Link2 } from 'lucide-react';\nimport { useId, useState } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@/components/ui/dialog';\nimport { useEditorContext } from '@/components/ui/editor/context';\nimport { isSafeEditorUrl } from '@/components/ui/editor/extensions';\nimport { EditorControl } from '@/components/ui/editor/toolbar';\nimport { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\nimport type { SlotNameProps } from '@/types';\n\nexport interface EditorLinkProps {\n label?: string;\n className?: string;\n}\n\nexport function EditorLink({\n label,\n className,\n slotName = 'editor-link-dialog',\n}: EditorLinkProps & SlotNameProps) {\n const { editor, labels, editable } = useEditorContext();\n const [open, setOpen] = useState(false);\n const [href, setHref] = useState('');\n const attached = editor.isActive('link');\n const fieldId = useId();\n\n function openDialog() {\n setHref(editor.getAttributes('link').href ?? '');\n setOpen(true);\n }\n\n function apply() {\n if (!isSafeEditorUrl(href)) {\n return;\n }\n\n editor\n .chain()\n .focus()\n .extendMarkRange('link')\n .setLink({ href: href.trim() })\n .run();\n\n setOpen(false);\n }\n\n function remove() {\n editor.chain().focus().extendMarkRange('link').unsetLink().run();\n setOpen(false);\n }\n\n return (\n <>\n <EditorControl\n label={label ?? labels.linkLabel}\n icon={Link2}\n pressed={attached}\n disabled={!editable}\n onActivate={openDialog}\n className={className}\n />\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogContent slotName={slotName}>\n <DialogHeader>\n <DialogTitle>{labels.linkDialogTitle}</DialogTitle>\n <DialogDescription>\n {labels.linkDialogDescription}\n </DialogDescription>\n </DialogHeader>\n <div className=\"gap-2 flex flex-col\">\n <Label htmlFor={fieldId}>{labels.linkUrlLabel}</Label>\n <Input\n id={fieldId}\n slotName=\"editor-link-url\"\n value={href}\n placeholder={labels.linkUrlPlaceholder}\n onChange={(event) => setHref(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n apply();\n }\n }}\n />\n </div>\n <DialogFooter>\n {attached && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={remove}\n >\n {labels.linkRemoveLabel}\n </Button>\n )}\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setOpen(false)}\n >\n {labels.linkCancelLabel}\n </Button>\n <Button\n type=\"button\"\n onClick={apply}\n disabled={href.trim() === ''}\n >\n {labels.linkApplyLabel}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","import { EditorContent } from '@/components/ui/editor/content';\nimport {\n EditorBlockquote,\n EditorHeading,\n EditorHistory,\n EditorList,\n EditorMark,\n} from '@/components/ui/editor/controls';\nimport { Editor, type EditorProps } from '@/components/ui/editor/editor';\nimport { EditorLink } from '@/components/ui/editor/link';\nimport { EditorToolbar } from '@/components/ui/editor/toolbar';\nimport { Separator } from '@/components/ui/separator';\n\ntype WithoutChildren<T> = T extends unknown ? Omit<T, 'children'> : never;\n\nexport type RichTextEditorProps = WithoutChildren<EditorProps>;\n\nexport function RichTextEditor(props: RichTextEditorProps) {\n return (\n <Editor {...props}>\n <EditorToolbar>\n <EditorMark mark=\"bold\" />\n <EditorMark mark=\"italic\" />\n <EditorMark mark=\"strike\" />\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <EditorHeading level={2} />\n <EditorHeading level={3} />\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <EditorList variant=\"bullet\" />\n <EditorList variant=\"ordered\" />\n <EditorBlockquote />\n <EditorMark mark=\"code\" />\n <EditorLink />\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <EditorHistory action=\"undo\" />\n <EditorHistory action=\"redo\" />\n </EditorToolbar>\n <EditorContent />\n </Editor>\n );\n}\n"]}