@qkix/strapi-plugin-better-blocks 0.23.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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +795 -0
  3. package/dist/_chunks/en-BcPniuRQ.js +1 -0
  4. package/dist/_chunks/en-DYxpcVy9.mjs +4 -0
  5. package/dist/admin/index.js +1933 -0
  6. package/dist/admin/index.mjs +17091 -0
  7. package/dist/admin/src/components/BlocksInput/Blocks/Audio.d.ts +6 -0
  8. package/dist/admin/src/components/BlocksInput/Blocks/AudioEditorModal.d.ts +21 -0
  9. package/dist/admin/src/components/BlocksInput/Blocks/Button.d.ts +11 -0
  10. package/dist/admin/src/components/BlocksInput/Blocks/ButtonEditorModal.d.ts +17 -0
  11. package/dist/admin/src/components/BlocksInput/Blocks/Callout.d.ts +21 -0
  12. package/dist/admin/src/components/BlocksInput/Blocks/Code.d.ts +18 -0
  13. package/dist/admin/src/components/BlocksInput/Blocks/Details.d.ts +12 -0
  14. package/dist/admin/src/components/BlocksInput/Blocks/Diagram.d.ts +15 -0
  15. package/dist/admin/src/components/BlocksInput/Blocks/Embed.d.ts +22 -0
  16. package/dist/admin/src/components/BlocksInput/Blocks/EmbedEditorModal.d.ts +27 -0
  17. package/dist/admin/src/components/BlocksInput/Blocks/Heading.d.ts +14 -0
  18. package/dist/admin/src/components/BlocksInput/Blocks/HorizontalLine.d.ts +10 -0
  19. package/dist/admin/src/components/BlocksInput/Blocks/Image.d.ts +5 -0
  20. package/dist/admin/src/components/BlocksInput/Blocks/Link.d.ts +3 -0
  21. package/dist/admin/src/components/BlocksInput/Blocks/List.d.ts +3 -0
  22. package/dist/admin/src/components/BlocksInput/Blocks/Math.d.ts +17 -0
  23. package/dist/admin/src/components/BlocksInput/Blocks/MediaEmbed.d.ts +7 -0
  24. package/dist/admin/src/components/BlocksInput/Blocks/Paragraph.d.ts +3 -0
  25. package/dist/admin/src/components/BlocksInput/Blocks/Quote.d.ts +3 -0
  26. package/dist/admin/src/components/BlocksInput/Blocks/SocialEmbed.d.ts +8 -0
  27. package/dist/admin/src/components/BlocksInput/Blocks/SocialEmbedEditorModal.d.ts +41 -0
  28. package/dist/admin/src/components/BlocksInput/Blocks/SourceEditorModal.d.ts +19 -0
  29. package/dist/admin/src/components/BlocksInput/Blocks/Table.d.ts +14 -0
  30. package/dist/admin/src/components/BlocksInput/Blocks/TableGridPicker.d.ts +20 -0
  31. package/dist/admin/src/components/BlocksInput/Blocks/TableIcons.d.ts +31 -0
  32. package/dist/admin/src/components/BlocksInput/Blocks/TableToolbar.d.ts +14 -0
  33. package/dist/admin/src/components/BlocksInput/Blocks/Video.d.ts +6 -0
  34. package/dist/admin/src/components/BlocksInput/Blocks/VideoEditorModal.d.ts +29 -0
  35. package/dist/admin/src/components/BlocksInput/Blocks/embedProviders.d.ts +43 -0
  36. package/dist/admin/src/components/BlocksInput/Blocks/muxClient.d.ts +40 -0
  37. package/dist/admin/src/components/BlocksInput/Blocks/socialFrame.d.ts +13 -0
  38. package/dist/admin/src/components/BlocksInput/Blocks/tableGrid.d.ts +90 -0
  39. package/dist/admin/src/components/BlocksInput/Blocks/tableOperations.d.ts +124 -0
  40. package/dist/admin/src/components/BlocksInput/Blocks/videoProviders.d.ts +37 -0
  41. package/dist/admin/src/components/BlocksInput/BlocksContent.d.ts +7 -0
  42. package/dist/admin/src/components/BlocksInput/BlocksEditor.d.ts +71 -0
  43. package/dist/admin/src/components/BlocksInput/BlocksToolbar.d.ts +27 -0
  44. package/dist/admin/src/components/BlocksInput/EditorLayout.d.ts +10 -0
  45. package/dist/admin/src/components/BlocksInput/EmojiPicker.d.ts +5 -0
  46. package/dist/admin/src/components/BlocksInput/FindReplace.d.ts +11 -0
  47. package/dist/admin/src/components/BlocksInput/FloatingSelectionToolbar.d.ts +11 -0
  48. package/dist/admin/src/components/BlocksInput/FontModifiersIcons.d.ts +32 -0
  49. package/dist/admin/src/components/BlocksInput/InlineColorPicker.d.ts +3 -0
  50. package/dist/admin/src/components/BlocksInput/MenuScrollbar.d.ts +30 -0
  51. package/dist/admin/src/components/BlocksInput/Modifiers.d.ts +16 -0
  52. package/dist/admin/src/components/BlocksInput/SlashCommands.d.ts +3 -0
  53. package/dist/admin/src/components/BlocksInput/SpecialCharPicker.d.ts +5 -0
  54. package/dist/admin/src/components/BlocksInput/WordCount.d.ts +3 -0
  55. package/dist/admin/src/components/BlocksInput/plugins/withAutoTransform.d.ts +3 -0
  56. package/dist/admin/src/components/BlocksInput/plugins/withLinks.d.ts +8 -0
  57. package/dist/admin/src/components/BlocksInput/plugins/withMarkdownPaste.d.ts +3 -0
  58. package/dist/admin/src/components/BlocksInput/plugins/withStrapiSchema.d.ts +6 -0
  59. package/dist/admin/src/components/BlocksInput/utils/constants.d.ts +13 -0
  60. package/dist/admin/src/components/BlocksInput/utils/conversions.d.ts +14 -0
  61. package/dist/admin/src/components/BlocksInput/utils/enterKey.d.ts +6 -0
  62. package/dist/admin/src/components/BlocksInput/utils/links.d.ts +12 -0
  63. package/dist/admin/src/components/BlocksInput/utils/optionsDefaults.d.ts +28 -0
  64. package/dist/admin/src/components/BlocksInput/utils/optionsParser.d.ts +34 -0
  65. package/dist/admin/src/components/BlocksInput/utils/parseMarkdownToSlate.d.ts +2 -0
  66. package/dist/admin/src/components/BlocksInput/utils/prefixFileUrlWithBackendUrl.d.ts +8 -0
  67. package/dist/admin/src/components/BlocksInput/utils/shiki.d.ts +29 -0
  68. package/dist/admin/src/components/BlocksInput/utils/shortcuts.d.ts +25 -0
  69. package/dist/admin/src/components/BlocksInput/utils/types.d.ts +404 -0
  70. package/dist/admin/src/components/Initializer.d.ts +5 -0
  71. package/dist/admin/src/components/Input.d.ts +45 -0
  72. package/dist/admin/src/components/PluginIcon.d.ts +3 -0
  73. package/dist/admin/src/hooks/useDragAndDrop.d.ts +51 -0
  74. package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +14 -0
  75. package/dist/admin/src/index.d.ts +10 -0
  76. package/dist/admin/src/pages/App.d.ts +3 -0
  77. package/dist/admin/src/pages/HomePage.d.ts +3 -0
  78. package/dist/admin/src/pluginId.d.ts +1 -0
  79. package/dist/admin/src/utils/getTranslation.d.ts +2 -0
  80. package/dist/server/index.js +1 -0
  81. package/dist/server/index.mjs +393 -0
  82. package/dist/server/src/bootstrap.d.ts +5 -0
  83. package/dist/server/src/config/index.d.ts +94 -0
  84. package/dist/server/src/content-types/index.d.ts +2 -0
  85. package/dist/server/src/controllers/controller.d.ts +12 -0
  86. package/dist/server/src/controllers/index.d.ts +14 -0
  87. package/dist/server/src/controllers/oembed.d.ts +12 -0
  88. package/dist/server/src/destroy.d.ts +5 -0
  89. package/dist/server/src/index.d.ts +125 -0
  90. package/dist/server/src/middlewares/index.d.ts +2 -0
  91. package/dist/server/src/policies/index.d.ts +2 -0
  92. package/dist/server/src/register.d.ts +5 -0
  93. package/dist/server/src/routes/admin.d.ts +9 -0
  94. package/dist/server/src/routes/content-api.d.ts +9 -0
  95. package/dist/server/src/routes/index.d.ts +25 -0
  96. package/dist/server/src/services/index.d.ts +14 -0
  97. package/dist/server/src/services/oembed.d.ts +27 -0
  98. package/dist/server/src/services/service.d.ts +7 -0
  99. package/package.json +131 -0
@@ -0,0 +1,90 @@
1
+ import { Editor, Path } from 'slate';
2
+ import type { CustomElement, TableCellElement } from '../utils/types';
3
+ /**
4
+ * Span-aware view of a table.
5
+ *
6
+ * Once cells can carry `colSpan` / `rowSpan`, a cell's index within its row
7
+ * stops being its visual column: a row of three cells can cover four columns,
8
+ * and a cell with `rowSpan: 2` occupies a slot in the row below without having
9
+ * a node there. Every structural operation therefore works against this grid —
10
+ * a slot-by-slot map of what covers what — rather than against raw child
11
+ * indices.
12
+ */
13
+ /** A cell as it sits in the grid. One per node, shared by every slot it covers. */
14
+ export interface GridCell {
15
+ node: TableCellElement;
16
+ /** Path of the node itself: [...tablePath, rowIndex, indexWithinRow]. */
17
+ path: Path;
18
+ /** Row this cell's node lives in. */
19
+ row: number;
20
+ /** Leftmost grid column this cell covers. */
21
+ col: number;
22
+ rowSpan: number;
23
+ colSpan: number;
24
+ /** Index of the node among its row's children. */
25
+ indexInRow: number;
26
+ }
27
+ export interface TableGrid {
28
+ tablePath: Path;
29
+ rowCount: number;
30
+ /** Total grid columns, spans included. */
31
+ colCount: number;
32
+ /** `matrix[row][col]` — the cell covering that slot, or undefined if ragged. */
33
+ matrix: (GridCell | undefined)[][];
34
+ /** Every cell once, in document order. */
35
+ cells: GridCell[];
36
+ }
37
+ /** A rectangle of grid slots, inclusive on both ends. */
38
+ export interface GridRange {
39
+ top: number;
40
+ left: number;
41
+ bottom: number;
42
+ right: number;
43
+ }
44
+ /**
45
+ * Lays a table's cells out into grid slots.
46
+ *
47
+ * Standard table layout: walk each row left to right, skipping slots already
48
+ * claimed by a `rowSpan` from an earlier row, and stamp each cell across every
49
+ * slot it covers.
50
+ */
51
+ export declare const buildTableGrid: (table: CustomElement, tablePath: Path) => TableGrid;
52
+ /** The cell whose node sits at `path`, or undefined. */
53
+ export declare const findCellByPath: (grid: TableGrid, path: Path) => GridCell | undefined;
54
+ /** Cells that originate in `row`, left to right. */
55
+ export declare const cellsOriginatingInRow: (grid: TableGrid, row: number) => GridCell[];
56
+ /**
57
+ * Where a new cell covering grid column `col` has to be inserted among row
58
+ * `row`'s children — i.e. how many of that row's own cells start left of it.
59
+ * Cells that merely reach into the row from above have no node here and so
60
+ * don't count.
61
+ */
62
+ export declare const nodeIndexForColumn: (grid: TableGrid, row: number, col: number) => number;
63
+ /** Whether `cell` covers the given slot. */
64
+ export declare const covers: (cell: GridCell, row: number, col: number) => boolean;
65
+ /**
66
+ * Grows `range` until every cell it touches is fully inside it.
67
+ *
68
+ * Selecting two cells that a third one straddles can't produce a rectangle
69
+ * without swallowing that third cell — so the range expands to include it,
70
+ * which may in turn pull in others. Repeats to a fixed point, which always
71
+ * terminates because the range only ever grows and is bounded by the table.
72
+ */
73
+ export declare const expandRangeToRectangle: (grid: TableGrid, range: GridRange) => GridRange;
74
+ /** Every cell with at least one slot inside `range`, without duplicates. */
75
+ export declare const cellsInRange: (grid: TableGrid, range: GridRange) => GridCell[];
76
+ /**
77
+ * The rectangle of cells the selection covers, or null when it stays within a
78
+ * single cell.
79
+ *
80
+ * The selection model is Slate's own — dragging across cells already produces a
81
+ * range spanning both, and Shift+arrow already extends it, so there's no
82
+ * separate cell-selection state to keep in sync.
83
+ *
84
+ * Only the two *endpoints* define the rectangle, though. A document range is
85
+ * linear, so everything between r2c1 and r3c2 includes the whole tail of row 2
86
+ * — taking the bounding box of every touched cell would turn a 2x2 pick into a
87
+ * full-width 2x5 one. Treating anchor and focus as opposite corners gives the
88
+ * 2D behaviour authors expect from a table.
89
+ */
90
+ export declare const getSelectedRange: (editor: Editor, grid: TableGrid) => GridRange | null;
@@ -0,0 +1,124 @@
1
+ import { Editor, Path } from 'slate';
2
+ import type { CustomElement, TableCellAlign } from '../utils/types';
3
+ import { type GridCell, type GridRange, type TableGrid } from './tableGrid';
4
+ declare const CELL_TYPES: readonly ["table-cell", "table-header-cell"];
5
+ declare const TABLE_TYPES: readonly ["table", "table-row", "table-cell", "table-header-cell"];
6
+ declare const createTableCell: (isHeader?: boolean) => CustomElement;
7
+ declare const createTableRow: (cols: number, isHeader?: boolean) => CustomElement;
8
+ /**
9
+ * Builds a table of `rows` x `cols`. The first row is a header row unless
10
+ * `withHeader` is false, in which case every row holds plain data cells.
11
+ */
12
+ declare const createTable: (rows: number, cols: number, withHeader?: boolean) => CustomElement;
13
+ /**
14
+ * Inserts a table at the current selection, followed by an empty paragraph so
15
+ * the author always has somewhere to continue writing below it.
16
+ */
17
+ declare const insertTable: (editor: Editor, rows?: number, cols?: number, withHeader?: boolean) => void;
18
+ /**
19
+ * Runs `fn` with the table structure protection in `withTables` temporarily
20
+ * lifted. Everything that legitimately adds/removes rows, columns or the table
21
+ * itself has to go through here, otherwise `editor.apply` swallows the ops.
22
+ */
23
+ declare const allowTableEdit: (editor: Editor, fn: () => void) => void;
24
+ declare const isCellType: (node: unknown) => boolean;
25
+ declare const isTableElement: (node: unknown) => boolean;
26
+ interface TableLocation {
27
+ tablePath: Path;
28
+ table: CustomElement;
29
+ /** Span-aware layout of the whole table. */
30
+ grid: TableGrid;
31
+ /** The cell holding the caret, with its grid coordinates. */
32
+ focused: GridCell;
33
+ /** Rectangle of cells the selection covers, or null within a single cell. */
34
+ range: GridRange | null;
35
+ /** Row the caret's cell lives in. */
36
+ rowIndex: number;
37
+ /** Leftmost grid column the caret's cell covers. */
38
+ colIndex: number;
39
+ rowCount: number;
40
+ /** Total grid columns, spans included. */
41
+ colCount: number;
42
+ cell: CustomElement;
43
+ cellPath: Path;
44
+ }
45
+ /**
46
+ * Resolves the table cell the caret currently sits in, together with the grid
47
+ * it belongs to. Returns null when the selection is outside any table.
48
+ */
49
+ declare const getTableLocation: (editor: Editor) => TableLocation | null;
50
+ /** A row is a header row when every one of its cells is a header cell. */
51
+ declare const isHeaderRow: (row: CustomElement) => boolean;
52
+ declare const isHeaderRowAt: (table: CustomElement, rowIndex: number) => boolean;
53
+ /**
54
+ * Inserts a column beside the caret's cell.
55
+ *
56
+ * A cell that straddles the insertion boundary is widened rather than given a
57
+ * new neighbour — otherwise the merge would visually break apart. Every other
58
+ * row gets a fresh cell, placed at the child index that lands it in the new
59
+ * grid column (which is not the same as the column number once spans exist).
60
+ */
61
+ declare const insertColumn: (editor: Editor, location: TableLocation, position: 'left' | 'right') => void;
62
+ /**
63
+ * Deletes the grid column the caret's cell starts in. Cells that span across it
64
+ * shrink by one instead of disappearing.
65
+ */
66
+ declare const deleteColumn: (editor: Editor, location: TableLocation) => void;
67
+ /**
68
+ * Inserts a row above or below the caret's cell. Cells whose rowSpan straddles
69
+ * the boundary are stretched instead of being split by the new row, and the new
70
+ * row only gets cells for the columns those stretched cells don't already cover.
71
+ */
72
+ declare const insertRow: (editor: Editor, location: TableLocation, position: 'above' | 'below') => void;
73
+ /**
74
+ * Deletes the row the caret sits in.
75
+ *
76
+ * Cells reaching into the row from above simply shrink. Cells that *start* in
77
+ * the row but continue below it can't just be removed — they're re-inserted
78
+ * into the following row, one row shorter, so the merge survives.
79
+ */
80
+ declare const deleteRow: (editor: Editor, location: TableLocation) => void;
81
+ declare const deleteTable: (editor: Editor, location: TableLocation) => void;
82
+ /**
83
+ * Whether a range straddles the header/body divide.
84
+ *
85
+ * A header cell labels a column; one that runs from the header down into the
86
+ * body labels nothing and belongs to neither. HTML agrees — a `rowSpan` may not
87
+ * cross the `<thead>`/`<tbody>` boundary, so a browser would clamp it and render
88
+ * something different from what the editor shows. Merging is therefore confined
89
+ * to one side of the divide. Merging *within* the header (a heading spanning two
90
+ * columns) is perfectly fine and stays allowed.
91
+ */
92
+ declare const rangeCrossesHeaderBoundary: (table: CustomElement, range: GridRange) => boolean;
93
+ /** Whether the selection covers enough distinct cells to merge. */
94
+ declare const canMergeCells: (location: TableLocation) => boolean;
95
+ /** Whether the caret's cell is the result of a merge. */
96
+ declare const canSplitCell: (location: TableLocation) => boolean;
97
+ /**
98
+ * Merges the selected rectangle into its top-left cell.
99
+ *
100
+ * The range arrives already squared off (see expandRangeToRectangle), so the
101
+ * result always tiles the grid. Content from the absorbed cells is appended to
102
+ * the anchor rather than discarded — losing an author's text to a layout
103
+ * operation would be unforgivable.
104
+ */
105
+ declare const mergeCells: (editor: Editor, location: TableLocation) => void;
106
+ /**
107
+ * Undoes a merge: the cell shrinks back to 1x1 and every slot it vacates is
108
+ * refilled with an empty cell. The content stays in the original cell.
109
+ */
110
+ declare const splitCell: (editor: Editor, location: TableLocation) => void;
111
+ /**
112
+ * Applies a horizontal alignment to every cell the selection touches (a single
113
+ * cell in the common case). `left` clears the property rather than storing it,
114
+ * so untouched documents and left-aligned cells stay byte-identical.
115
+ */
116
+ declare const setCellAlign: (editor: Editor, align: TableCellAlign) => void;
117
+ declare const getCellAlign: (location: TableLocation) => TableCellAlign;
118
+ /**
119
+ * Turns the table's first row into header cells, or back into data cells.
120
+ * Header cells render as `<th scope="col">` for screen readers.
121
+ */
122
+ declare const toggleHeaderRow: (editor: Editor, location: TableLocation) => void;
123
+ declare const hasHeaderRow: (location: TableLocation) => boolean;
124
+ export { type TableLocation, CELL_TYPES, TABLE_TYPES, allowTableEdit, canMergeCells, canSplitCell, createTable, createTableCell, createTableRow, deleteColumn, deleteRow, deleteTable, getCellAlign, getTableLocation, hasHeaderRow, insertColumn, insertRow, insertTable, isCellType, isHeaderRow, isHeaderRowAt, isTableElement, mergeCells, rangeCrossesHeaderBoundary, setCellAlign, splitCell, toggleHeaderRow, };
@@ -0,0 +1,37 @@
1
+ import { type VideoProvider } from '../utils/types';
2
+ /** Hosts an app must allow for Mux playback (media-src / img-src). */
3
+ export declare const MUX_HOSTS: {
4
+ stream: string;
5
+ image: string;
6
+ };
7
+ /**
8
+ * HLS manifest for a Mux playback id.
9
+ *
10
+ * Only valid for assets with a **public** playback policy. Signed playback
11
+ * requires a per-request JWT (`?token=…`) that must be minted server-side with
12
+ * a Mux signing key, which this block deliberately does not handle — storing a
13
+ * short-lived token in the document body would break as soon as it expired.
14
+ */
15
+ export declare const muxPlaybackUrl: (playbackId: string) => string;
16
+ /** Auto-generated poster frame for a Mux playback id (public policy only). */
17
+ export declare const muxThumbnailUrl: (playbackId: string) => string;
18
+ export declare const isMuxPlaybackId: (value: string) => boolean;
19
+ export interface DetectedVideo {
20
+ provider: VideoProvider;
21
+ url: string;
22
+ playbackId?: string;
23
+ poster?: string;
24
+ }
25
+ /**
26
+ * Work out what a pasted string is: a Mux playback id, a provider URL, or a
27
+ * plain video file URL. Returns null for empty input.
28
+ */
29
+ export declare const detectVideoSource: (input: string) => DetectedVideo | null;
30
+ /**
31
+ * True when the URL needs an HLS/DASH-capable player rather than a plain
32
+ * `<video src>`. Safari plays HLS natively; other browsers need hls.js or a
33
+ * provider player, which is a frontend-renderer concern — the editor preview
34
+ * degrades to the poster image instead.
35
+ */
36
+ export declare const isStreamingUrl: (url: string) => boolean;
37
+ export declare const VIDEO_PROVIDER_LABELS: Record<VideoProvider, string>;
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+ interface BlocksContentProps {
3
+ placeholder?: string;
4
+ ariaLabelId: string;
5
+ }
6
+ declare const BlocksContent: ({ placeholder, ariaLabelId, }: BlocksContentProps) => React.JSX.Element;
7
+ export { BlocksContent, BlocksContentProps };
@@ -0,0 +1,71 @@
1
+ import * as React from 'react';
2
+ import { type FieldValue } from '@strapi/admin/strapi-admin';
3
+ import { MessageDescriptor } from 'react-intl';
4
+ import { Editor } from 'slate';
5
+ import { type RenderElementProps } from 'slate-react';
6
+ import { type CSSProperties } from 'styled-components';
7
+ import { type BlocksContentProps } from './BlocksContent';
8
+ import { type ModifiersStore } from './Modifiers';
9
+ import { type Schema } from '@strapi/types';
10
+ interface BaseBlock {
11
+ renderElement: (props: RenderElementProps) => React.JSX.Element;
12
+ matchNode: (node: Schema.Attribute.BlocksNode) => boolean;
13
+ handleConvert?: (editor: Editor) => void | (() => React.JSX.Element);
14
+ handleEnterKey?: (editor: Editor) => void;
15
+ handleBackspaceKey?: (editor: Editor, event: React.KeyboardEvent<HTMLElement>) => void;
16
+ handleTab?: (editor: Editor, event: React.KeyboardEvent<HTMLElement>) => void;
17
+ snippets?: string[];
18
+ dragHandleTopMargin?: CSSProperties['marginTop'];
19
+ }
20
+ interface NonSelectorBlock extends BaseBlock {
21
+ isInBlocksSelector: false;
22
+ }
23
+ interface SelectorBlock extends BaseBlock {
24
+ isInBlocksSelector: true;
25
+ icon: React.ComponentType;
26
+ label: MessageDescriptor;
27
+ }
28
+ type NonSelectorBlockKey = 'list-item' | 'link' | 'horizontal-line' | 'table' | 'table-row' | 'table-cell' | 'table-header-cell' | 'media-embed';
29
+ declare const selectorBlockKeys: readonly ["paragraph", "heading-one", "heading-two", "heading-three", "heading-four", "heading-five", "heading-six", "list-ordered", "list-unordered", "list-todo", "image", "audio", "video", "embed", "quote", "code", "math", "diagram", "callout", "details", "button", "social-embed"];
30
+ type SelectorBlockKey = (typeof selectorBlockKeys)[number];
31
+ declare const isSelectorBlockKey: (key: unknown) => key is "image" | "audio" | "math" | "diagram" | "callout" | "details" | "button" | "social-embed" | "embed" | "video" | "code" | "paragraph" | "heading-one" | "heading-two" | "heading-three" | "heading-four" | "heading-five" | "heading-six" | "list-ordered" | "list-unordered" | "list-todo" | "quote";
32
+ type BlocksStore = {
33
+ [K in SelectorBlockKey]: SelectorBlock;
34
+ } & {
35
+ [K in NonSelectorBlockKey]: NonSelectorBlock;
36
+ };
37
+ interface BlocksEditorContextValue {
38
+ blocks: BlocksStore;
39
+ modifiers: ModifiersStore;
40
+ disabled: boolean;
41
+ name: string;
42
+ setLiveText: (text: string) => void;
43
+ isExpandedMode: boolean;
44
+ /** Enters or leaves fullscreen. Surfaced so the toolbar owns the toggle. */
45
+ onToggleExpand: () => void;
46
+ pluginOptions?: Record<string, any>;
47
+ }
48
+ interface BlocksEditorProviderProps {
49
+ children: React.ReactNode;
50
+ blocks: BlocksStore;
51
+ modifiers: ModifiersStore;
52
+ disabled: boolean;
53
+ name: string;
54
+ setLiveText: (text: string) => void;
55
+ isExpandedMode: boolean;
56
+ onToggleExpand: () => void;
57
+ pluginOptions?: Record<string, any>;
58
+ }
59
+ declare function useBlocksEditorContext(consumerName: string): BlocksEditorContextValue & {
60
+ editor: Editor;
61
+ };
62
+ interface BlocksEditorProps extends Pick<FieldValue<Schema.Attribute.BlocksValue>, 'onChange' | 'value' | 'error'>, BlocksContentProps {
63
+ disabled?: boolean;
64
+ name: string;
65
+ pluginOptions?: Record<string, any>;
66
+ }
67
+ declare const BlocksEditor: React.ForwardRefExoticComponent<BlocksEditorProps & React.RefAttributes<{
68
+ focus: () => void;
69
+ }>>;
70
+ declare const BlocksEditorProvider: React.FC<BlocksEditorProviderProps>;
71
+ export { type BlocksStore, type SelectorBlockKey, BlocksEditor, BlocksEditorProvider, useBlocksEditorContext, isSelectorBlockKey, };
@@ -0,0 +1,27 @@
1
+ import * as React from 'react';
2
+ import { MessageDescriptor } from 'react-intl';
3
+ /**
4
+ * Handles the modal component that may be returned by a block when converting it
5
+ */
6
+ declare function useConversionModal(): {
7
+ modalElement: React.JSX.Element | null;
8
+ handleConversionResult: (renderModal: void | (() => React.JSX.Element) | undefined) => void;
9
+ };
10
+ interface ToolbarButtonProps {
11
+ icon: React.ComponentType<React.SVGProps<SVGSVGElement>>;
12
+ name: string;
13
+ label: MessageDescriptor;
14
+ isActive: boolean;
15
+ disabled: boolean;
16
+ handleClick: () => void;
17
+ }
18
+ declare const ToolbarButton: ({ icon: Icon, name, label, isActive, disabled, handleClick, }: ToolbarButtonProps) => React.JSX.Element;
19
+ declare const LinkButton: ({ disabled, location, }: {
20
+ disabled: boolean;
21
+ location?: 'toolbar' | 'menu';
22
+ }) => React.JSX.Element;
23
+ declare const RemoveFormattingButton: ({ disabled }: {
24
+ disabled: boolean;
25
+ }) => React.JSX.Element;
26
+ declare const BlocksToolbar: () => React.JSX.Element;
27
+ export { BlocksToolbar, useConversionModal, ToolbarButton, LinkButton, RemoveFormattingButton, };
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ interface EditorLayoutProps {
3
+ children: React.ReactNode;
4
+ error?: string;
5
+ onCollapse: () => void;
6
+ disabled: boolean;
7
+ ariaDescriptionId: string;
8
+ }
9
+ declare const EditorLayout: ({ children, error, disabled, onCollapse, ariaDescriptionId, }: EditorLayoutProps) => React.JSX.Element;
10
+ export { EditorLayout };
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ declare const EmojiPicker: ({ disabled }: {
3
+ disabled: boolean;
4
+ }) => React.JSX.Element;
5
+ export { EmojiPicker };
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ import { Range } from 'slate';
3
+ /**
4
+ * Decorate function for highlighting search matches.
5
+ * Call this from BlocksContent's decorate prop.
6
+ */
7
+ declare const decorateSearchMatches: (editor: any) => ([node, path]: [any, number[]]) => Range[];
8
+ declare const FindReplace: ({ disabled }: {
9
+ disabled: boolean;
10
+ }) => React.JSX.Element;
11
+ export { FindReplace, decorateSearchMatches };
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ /**
3
+ * Medium/Notion-style mini toolbar that appears over a text selection, so
4
+ * formatting doesn't require a trip up to the main toolbar.
5
+ *
6
+ * It positions itself imperatively (writing to `style` in an effect rather than
7
+ * storing a rect in state) because it has to re-measure on every editor render,
8
+ * and a state write there would loop.
9
+ */
10
+ declare const FloatingSelectionToolbar: () => React.JSX.Element;
11
+ export { FloatingSelectionToolbar };
@@ -0,0 +1,32 @@
1
+ import * as React from 'react';
2
+ type FontModifierIconProps = {
3
+ fill: string;
4
+ };
5
+ export declare const Uppercase: ({ fill }: FontModifierIconProps) => React.JSX.Element;
6
+ export declare const Superscript: ({ fill }: FontModifierIconProps) => React.JSX.Element;
7
+ export declare const UndoIcon: ({ fill, ...props }: React.SVGProps<SVGSVGElement> & {
8
+ fill?: string;
9
+ }) => React.JSX.Element;
10
+ export declare const RedoIcon: ({ fill, ...props }: React.SVGProps<SVGSVGElement> & {
11
+ fill?: string;
12
+ }) => React.JSX.Element;
13
+ export declare const AlignLeftIcon: ({ fill, ...props }: React.SVGProps<SVGSVGElement> & {
14
+ fill?: string;
15
+ }) => React.JSX.Element;
16
+ export declare const AlignCenterIcon: ({ fill, ...props }: React.SVGProps<SVGSVGElement> & {
17
+ fill?: string;
18
+ }) => React.JSX.Element;
19
+ export declare const AlignRightIcon: ({ fill, ...props }: React.SVGProps<SVGSVGElement> & {
20
+ fill?: string;
21
+ }) => React.JSX.Element;
22
+ export declare const AlignJustifyIcon: ({ fill, ...props }: React.SVGProps<SVGSVGElement> & {
23
+ fill?: string;
24
+ }) => React.JSX.Element;
25
+ export declare const LineHeightIcon: ({ fill, ...props }: React.SVGProps<SVGSVGElement> & {
26
+ fill?: string;
27
+ }) => React.JSX.Element;
28
+ export declare const SpecialCharIcon: ({ fill, ...props }: React.SVGProps<SVGSVGElement> & {
29
+ fill?: string;
30
+ }) => React.JSX.Element;
31
+ export declare const Subsscript: ({ fill }: FontModifierIconProps) => React.JSX.Element;
32
+ export {};
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const InlineColorPicker: () => React.JSX.Element;
3
+ export default InlineColorPicker;
@@ -0,0 +1,30 @@
1
+ /// <reference types="react" />
2
+ /**
3
+ * Strapi's design system hides the scrollbar on the popover behind the toolbar
4
+ * dropdown menus (`scrollbar-width: none` + `::-webkit-scrollbar { display: none }`),
5
+ * and only scrolls on overflow. That means longer menus give no visual cue that
6
+ * the list can be scrolled up and down.
7
+ *
8
+ * Every toolbar dropdown (block type, "+" insert, font size, font family,
9
+ * alignment, line height, …) is built on the design-system `Menu` component, so
10
+ * they all share a single scroll container: `[data-radix-menu-content]`. This
11
+ * forces an always-visible, theme-aware scrollbar on it.
12
+ *
13
+ * Implementation notes (verified in Chromium):
14
+ * - `overflow-y: scroll` (not `auto`) keeps the scrollbar visible even when the
15
+ * content fits.
16
+ * - `scrollbar-width` must be overridden to `auto` (not `thin`) to un-hide the
17
+ * design-system's `none`. `auto` keeps the `::-webkit-scrollbar`
18
+ * pseudo-elements active, whereas `thin` — like `scrollbar-color` — makes
19
+ * Chromium fall back to an OS overlay scrollbar that is invisible until you
20
+ * scroll (defeating the purpose on macOS). We therefore do NOT set
21
+ * `scrollbar-color`; Firefox falls back to its own always-visible bar.
22
+ * - The track gets a real background so the channel stays visible even when the
23
+ * content fits and the thumb spans the full height; the colours are
24
+ * mid-range neutrals that contrast with the menu background (`neutral0`) in
25
+ * both the light and dark themes.
26
+ * - `!important` / `display: block` are required to beat the design-system
27
+ * rules, which share the same specificity.
28
+ */
29
+ declare const MenuScrollbarStyles: import("react").NamedExoticComponent<import("styled-components").ExecutionProps & object>;
30
+ export { MenuScrollbarStyles };
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ import { type MessageDescriptor } from 'react-intl';
3
+ import { Editor, Text } from 'slate';
4
+ type ModifierKey = Exclude<keyof Text, 'type' | 'text'>;
5
+ type ModifiersStore = {
6
+ [K in ModifierKey]: {
7
+ icon: React.ComponentType;
8
+ isValidEventKey: (event: React.KeyboardEvent<HTMLElement>) => boolean;
9
+ label: MessageDescriptor;
10
+ checkIsActive: (editor: Editor) => boolean;
11
+ handleToggle: (editor: Editor) => void;
12
+ renderLeaf: (children: React.JSX.Element | string) => React.JSX.Element;
13
+ };
14
+ };
15
+ declare const modifiers: ModifiersStore;
16
+ export { type ModifiersStore, modifiers };
@@ -0,0 +1,3 @@
1
+ import * as React from 'react';
2
+ declare const SlashCommandMenu: () => React.JSX.Element | null;
3
+ export { SlashCommandMenu };
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ declare const SpecialCharPicker: ({ disabled }: {
3
+ disabled: boolean;
4
+ }) => React.JSX.Element;
5
+ export { SpecialCharPicker };
@@ -0,0 +1,3 @@
1
+ import * as React from 'react';
2
+ declare const WordCount: () => React.JSX.Element;
3
+ export { WordCount };
@@ -0,0 +1,3 @@
1
+ import { Editor } from 'slate';
2
+ declare const withAutoTransform: (editor: Editor) => Editor;
3
+ export { withAutoTransform };
@@ -0,0 +1,8 @@
1
+ import { type BaseEditor, Path } from 'slate';
2
+ import { type ReactEditor } from 'slate-react';
3
+ interface LinkEditor extends BaseEditor, ReactEditor {
4
+ lastInsertedLinkPath: Path | null;
5
+ shouldSaveLinkPath: boolean;
6
+ }
7
+ declare const withLinks: (editor: BaseEditor) => LinkEditor;
8
+ export { withLinks, type LinkEditor };
@@ -0,0 +1,3 @@
1
+ import { type BaseEditor } from 'slate';
2
+ declare const withMarkdownPaste: (editor: BaseEditor) => BaseEditor;
3
+ export { withMarkdownPaste };
@@ -0,0 +1,6 @@
1
+ import { Editor } from 'slate';
2
+ /**
3
+ * This plugin is used to normalize the Slate document to match the Strapi schema.
4
+ */
5
+ declare const withStrapiSchema: (editor: Editor) => import("slate").BaseEditor;
6
+ export { withStrapiSchema };
@@ -0,0 +1,13 @@
1
+ export declare const codeLanguages: {
2
+ value: string;
3
+ label: string;
4
+ decorate?: string;
5
+ }[];
6
+ export declare const ItemTypes: {
7
+ readonly COMPONENT: "component";
8
+ readonly EDIT_FIELD: "editField";
9
+ readonly FIELD: "field";
10
+ readonly DYNAMIC_ZONE: "dynamicZone";
11
+ readonly RELATION: "relation";
12
+ readonly BLOCKS: "blocks";
13
+ };
@@ -0,0 +1,14 @@
1
+ import { type Path, Editor } from 'slate';
2
+ import { CustomElement } from './types';
3
+ /**
4
+ * Extracts some logic that is common to most blocks' handleConvert functions.
5
+ * @returns The path of the converted block
6
+ */
7
+ declare const baseHandleConvert: <T extends CustomElement>(editor: Editor, attributesToSet: Partial<T> & {
8
+ type: T['type'];
9
+ }) => void | Path;
10
+ /**
11
+ * Set all attributes except type, children, and font settings to null so that Slate deletes them
12
+ */
13
+ declare const getAttributesToClear: (element: CustomElement) => Record<string, any>;
14
+ export { baseHandleConvert, getAttributesToClear };
@@ -0,0 +1,6 @@
1
+ import { Editor } from 'slate';
2
+ /**
3
+ * Inserts a line break the first time the user presses enter, and exits the node the second time.
4
+ */
5
+ declare const pressEnterTwiceToExit: (editor: Editor) => void;
6
+ export { pressEnterTwiceToExit };
@@ -0,0 +1,12 @@
1
+ import { Editor } from 'slate';
2
+ declare const removeLink: (editor: Editor) => void;
3
+ declare const insertLink: (editor: Editor, { url }: {
4
+ url: string;
5
+ }) => void;
6
+ declare const editLink: (editor: Editor, link: {
7
+ url: string;
8
+ text: string;
9
+ target?: '_blank';
10
+ rel?: string;
11
+ }) => void;
12
+ export { insertLink, editLink, removeLink };
@@ -0,0 +1,28 @@
1
+ import { Option } from './types';
2
+ export declare const COLORS_OPTIONS: {
3
+ label: string;
4
+ value: string;
5
+ }[];
6
+ export declare const BG_COLORS_OPTIONS: {
7
+ label: string;
8
+ value: string;
9
+ }[];
10
+ export declare const FONT_FAMILY_OPTIONS: Option[];
11
+ export declare const FONT_SIZE_OPTIONS: Option[];
12
+ export declare const FONT_LEADING_OPTIONS: Option[];
13
+ export declare const FONT_TRACKING_OPTIONS: Option[];
14
+ export declare const FONT_ALIGNMENT_OPTIONS: Option[];
15
+ export declare const VIEWPORT_OPTIONS: Option[];
16
+ export declare const SEPARATOR_STYLE_OPTIONS: Option[];
17
+ export declare const SEPARATOR_ORIENTATION_OPTIONS: Option[];
18
+ export declare const DEFAULT_COLOR: string;
19
+ export declare const DEFAULT_FONT_FAMILY: string;
20
+ export declare const DEFAULT_FONT_SIZE: string;
21
+ export declare const DEFAULT_FONT_LEADING: string;
22
+ export declare const DEFAULT_FONT_ALIGNMENT: string;
23
+ export declare const DEFAULT_FONT_TRACKING: string;
24
+ export declare const DEFAULT_VIEWPORT: string;
25
+ export declare const DEFAULT_SEPARATOR_SIZE = 1;
26
+ export declare const DEFAULT_SEPARATOR_STYLE: string;
27
+ export declare const DEFAULT_SEPARATOR_ORIENTATION: string;
28
+ export declare const DEFAULT_SEPARATOR_LENGTH = 100;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Parses a string formatted as "Label:value\nLabel2:value2" into an array of options
3
+ * If no colon is found, the value is used as both label and value
4
+ * @param presetString The string to parse
5
+ * @returns Array of {label, value} objects
6
+ */
7
+ export declare const parsePresetString: (presetString?: string) => {
8
+ label: string;
9
+ value: string;
10
+ }[];
11
+ /**
12
+ * Gets the custom options from plugin config if available and enabled
13
+ * Falls back to default options if not
14
+ */
15
+ export declare const getOptionsWithFallback: (defaultOptions: Array<{
16
+ label: string;
17
+ value: string;
18
+ }>, customPresets?: string, useCustom?: boolean) => {
19
+ label: string;
20
+ value: string;
21
+ }[];
22
+ export declare const _testParser: () => {
23
+ name: string;
24
+ passed: boolean;
25
+ input: string;
26
+ expected: {
27
+ label: string;
28
+ value: string;
29
+ }[];
30
+ actual: {
31
+ label: string;
32
+ value: string;
33
+ }[];
34
+ }[];