@djangocfg/ui-tools 2.1.290 → 2.1.291

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/ui-tools",
3
- "version": "2.1.290",
3
+ "version": "2.1.291",
4
4
  "description": "Heavy React tools with lazy loading - for Electron, Vite, CRA, Next.js apps",
5
5
  "keywords": [
6
6
  "ui-tools",
@@ -74,7 +74,8 @@
74
74
  "import": "./src/tools/CodeEditor/index.ts",
75
75
  "require": "./src/tools/CodeEditor/index.ts"
76
76
  },
77
- "./styles": "./src/styles/index.css"
77
+ "./styles": "./src/styles/index.css",
78
+ "./dist.css": "./dist/index.css"
78
79
  },
79
80
  "files": [
80
81
  "dist",
@@ -90,8 +91,8 @@
90
91
  "check": "tsc --noEmit"
91
92
  },
92
93
  "peerDependencies": {
93
- "@djangocfg/i18n": "^2.1.290",
94
- "@djangocfg/ui-core": "^2.1.290",
94
+ "@djangocfg/i18n": "^2.1.291",
95
+ "@djangocfg/ui-core": "^2.1.291",
95
96
  "consola": "^3.4.2",
96
97
  "lodash-es": "^4.18.1",
97
98
  "lucide-react": "^0.545.0",
@@ -138,10 +139,10 @@
138
139
  "@maplibre/maplibre-gl-geocoder": "^1.7.0"
139
140
  },
140
141
  "devDependencies": {
141
- "@djangocfg/i18n": "^2.1.290",
142
+ "@djangocfg/i18n": "^2.1.291",
142
143
  "@djangocfg/playground": "workspace:*",
143
- "@djangocfg/typescript-config": "^2.1.290",
144
- "@djangocfg/ui-core": "^2.1.290",
144
+ "@djangocfg/typescript-config": "^2.1.291",
145
+ "@djangocfg/ui-core": "^2.1.291",
145
146
  "@types/lodash-es": "^4.17.12",
146
147
  "@types/mapbox__mapbox-gl-draw": "^1.4.8",
147
148
  "@types/node": "^24.7.2",
@@ -47,7 +47,23 @@ export interface MarkdownEditorProps {
47
47
  className?: string;
48
48
  disabled?: boolean;
49
49
  showToolbar?: boolean;
50
- /** @mention autocomplete config */
50
+ /**
51
+ * `@`-mention autocomplete config.
52
+ *
53
+ * IMPORTANT: Tiptap's `useEditor` initialises the editor exactly once.
54
+ * The `Mention` extension is only registered when `mentions` is truthy
55
+ * on the FIRST render — handing in a real config later (e.g. after an
56
+ * async items fetch) silently does nothing, and typing `@` will not
57
+ * open the popover.
58
+ *
59
+ * If you want mentions even with async-loaded items, pass
60
+ * `{ items: [] }` from the very first render and update the array
61
+ * when data arrives. Either keep the `MentionConfig` object identity
62
+ * stable across renders and mutate `items` in place (the suggestion
63
+ * plugin captures the config by closure and reads `items` on each
64
+ * query), or accept that swapping the whole object reference is a
65
+ * no-op for the live editor.
66
+ */
51
67
  mentions?: MentionConfig;
52
68
  /** Called when mentioned IDs change */
53
69
  onMentionIdsChange?: (ids: string[]) => void;
@@ -68,6 +84,31 @@ export function MarkdownEditor({
68
84
  }: MarkdownEditorProps) {
69
85
  const isExternalUpdate = useRef(false);
70
86
 
87
+ // ── Dev-mode trap detector ──
88
+ // Tiptap initialises the editor once with the extensions array from
89
+ // first render. If `mentions` is undefined on mount and becomes
90
+ // truthy later, the Mention extension is never installed and the
91
+ // user-visible @-trigger silently does nothing. Catch this early so
92
+ // future consumers don't spend hours debugging why @ does nothing.
93
+ const initialMentionsDefinedRef = useRef<boolean>(mentions !== undefined);
94
+ const warnedRef = useRef(false);
95
+ if (
96
+ process.env.NODE_ENV !== 'production' &&
97
+ !initialMentionsDefinedRef.current &&
98
+ mentions !== undefined &&
99
+ !warnedRef.current
100
+ ) {
101
+ warnedRef.current = true;
102
+ // eslint-disable-next-line no-console
103
+ console.warn(
104
+ '[MarkdownEditor] `mentions` flipped from undefined to a config ' +
105
+ 'after mount. Tiptap only installs the Mention extension on first ' +
106
+ 'render — the @-popover will NOT work for this editor instance. ' +
107
+ 'Pass `{ items: [] }` from the very first render and mutate `.items` ' +
108
+ 'in place instead.',
109
+ );
110
+ }
111
+
71
112
  const extensions = useMemo(() => {
72
113
  const exts: AnyExtension[] = [
73
114
  StarterKit.configure({ heading: { levels: [1, 2, 3] } }),