denwa-react-shared 1.0.87 → 1.0.89
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/dist/denwa-react-shared.cjs.js +1 -1
- package/dist/denwa-react-shared.es.js +1 -1
- package/dist/denwa-react-shared.umd.js +1 -1
- package/dist/{index-B2LJV9hD.js → index-B9Fobz_H.js} +1 -1
- package/dist/{index-Dm99lN_c.cjs → index-DFjIWZK2.cjs} +1 -1
- package/dist/{index-BsL--dhU.js → index-DQufMkbF.js} +1853 -1856
- package/dist/{index-UAPQw7y7.cjs → index-n5OyW3Ln.cjs} +57 -57
- package/dist/{table-head-V4MoUZSY.js → table-head-Dhg7yOFA.js} +1 -1
- package/dist/{table-head-ByE_XMtl.cjs → table-head-Tj5W8nwu.cjs} +1 -1
- package/package.json +11 -2
- package/skills/admin-forms/SKILL.md +121 -0
- package/skills/admin-table/SKILL.md +153 -0
- package/skills/material-map/SKILL.md +65 -0
- package/skills/media-management/SKILL.md +107 -0
- package/skills/session-auth/SKILL.md +100 -0
- package/skills/text-editor/SKILL.md +100 -0
- package/skills/utility-hooks/SKILL.md +97 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: text-editor
|
|
3
|
+
description: >
|
|
4
|
+
Implement rich text editing using BaseTextEditor (Slate.js).
|
|
5
|
+
Covers content synchronization (JSON and HTML) and toolbar configuration.
|
|
6
|
+
type: framework
|
|
7
|
+
library: denwa-react-shared
|
|
8
|
+
framework: react
|
|
9
|
+
library_version: "1.0.88"
|
|
10
|
+
requires:
|
|
11
|
+
- session-auth
|
|
12
|
+
sources:
|
|
13
|
+
- "Denwa799/react-shared:src/shared/ui/text-editor/text-editor.tsx"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Slate Rich Text Editor
|
|
17
|
+
|
|
18
|
+
`BaseTextEditor` provides a rich text editing experience based on Slate.js. It handles serialization to HTML and synchronization with external form state through debounced handlers.
|
|
19
|
+
|
|
20
|
+
## Setup
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { BaseTextEditor, BaseTextEditorRefMethods } from 'denwa-react-shared';
|
|
24
|
+
|
|
25
|
+
const MyForm = () => {
|
|
26
|
+
const editorRef = useRef<BaseTextEditorRefMethods>(null);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<BaseTextEditor
|
|
30
|
+
boldText="Жирный"
|
|
31
|
+
italicText="Курсив"
|
|
32
|
+
underlineText="Подчеркнутый"
|
|
33
|
+
// ... more labels
|
|
34
|
+
onSetContent={(jsonString, lang) => setFieldValue('content', jsonString)}
|
|
35
|
+
onSetHtml={(htmlString, lang) => setFieldValue('contentHtml', htmlString)}
|
|
36
|
+
onErrorMessage={(msg) => alert(msg)}
|
|
37
|
+
/>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Core Patterns
|
|
43
|
+
|
|
44
|
+
### Content Initialization
|
|
45
|
+
To set the editor value (e.g. when loading an existing entity), use the `setValue` method on the ref. It expects the serialized JSON string found in the database.
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (data?.content) {
|
|
50
|
+
editorRef.current?.setValue(data.content);
|
|
51
|
+
}
|
|
52
|
+
}, [data]);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Syncing JSON and HTML
|
|
56
|
+
The editor emits events for both the raw Slate JSON structure (for editing) and the rendered HTML (for display/SEO). Always provide both `onSetContent` and `onSetHtml`.
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
<BaseTextEditor
|
|
60
|
+
onSetContent={(json) => updateJson(json)}
|
|
61
|
+
onSetHtml={(html) => updateHtml(html)}
|
|
62
|
+
/>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Common Mistakes
|
|
66
|
+
|
|
67
|
+
### HIGH Passing raw HTML to setValue
|
|
68
|
+
Wrong:
|
|
69
|
+
```tsx
|
|
70
|
+
editorRef.current?.setValue("<p>Hello world</p>");
|
|
71
|
+
```
|
|
72
|
+
Correct:
|
|
73
|
+
```tsx
|
|
74
|
+
editorRef.current?.setValue(JSON.stringify([{ type: 'paragraph', children: [{ text: 'Hello world' }] }]));
|
|
75
|
+
```
|
|
76
|
+
`setValue` expects a serialized JSON string representing the Slate document structure. Passing raw HTML will cause parsing errors or an empty editor.
|
|
77
|
+
|
|
78
|
+
Source: src/shared/ui/text-editor/text-editor.tsx:113
|
|
79
|
+
|
|
80
|
+
### MEDIUM Missing synchronization handlers
|
|
81
|
+
Wrong:
|
|
82
|
+
```tsx
|
|
83
|
+
<BaseTextEditor onSetHtml={(html) => setHtml(html)} />
|
|
84
|
+
// Missing onSetContent
|
|
85
|
+
```
|
|
86
|
+
Correct:
|
|
87
|
+
```tsx
|
|
88
|
+
<BaseTextEditor
|
|
89
|
+
onSetContent={(json) => setJson(json)}
|
|
90
|
+
onSetHtml={(html) => setHtml(html)}
|
|
91
|
+
/>
|
|
92
|
+
```
|
|
93
|
+
Failing to provide `onSetContent` prevents the application from saving the internal editor state, making future edits impossible even if the HTML is saved.
|
|
94
|
+
|
|
95
|
+
Source: src/shared/ui/text-editor/text-editor.tsx:83
|
|
96
|
+
|
|
97
|
+
### MEDIUM Ignoring the debounce
|
|
98
|
+
The editor uses a 1-second debounce (`TIME.seconds.seconds1`) before firing sync events. Do not expect immediate state updates on every keystroke.
|
|
99
|
+
|
|
100
|
+
Source: src/shared/ui/text-editor/text-editor.tsx:86
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: utility-hooks
|
|
3
|
+
description: >
|
|
4
|
+
Essential helper hooks for responsive design, provider composition,
|
|
5
|
+
and application lifecycle management.
|
|
6
|
+
type: framework
|
|
7
|
+
library: denwa-react-shared
|
|
8
|
+
framework: react
|
|
9
|
+
library_version: "1.0.88"
|
|
10
|
+
requires:
|
|
11
|
+
- session-auth
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Shared Utilities & Hooks
|
|
15
|
+
|
|
16
|
+
Standardized helpers to reduce boilerplate in provider setup and responsive logic.
|
|
17
|
+
|
|
18
|
+
## Setup
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { ProviderComposer, useViewPort } from 'denwa-react-shared';
|
|
22
|
+
|
|
23
|
+
const App = ({ children }) => {
|
|
24
|
+
return (
|
|
25
|
+
<ProviderComposer
|
|
26
|
+
providers={[
|
|
27
|
+
<AuthProvider key="auth" />,
|
|
28
|
+
<ConfigProvider key="config" />,
|
|
29
|
+
<ReactQueryProvider key="query" />,
|
|
30
|
+
]}
|
|
31
|
+
>
|
|
32
|
+
{children}
|
|
33
|
+
</ProviderComposer>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Core Patterns
|
|
39
|
+
|
|
40
|
+
### Responsive Logic with useViewPort
|
|
41
|
+
Standardizes breakpoints across the admin panel.
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
const { isMobile, isTablet, isLaptop } = useViewPort();
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<div>
|
|
48
|
+
{isMobile ? <MobileNav /> : <DesktopNav />}
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Local Storage Wrapper
|
|
54
|
+
Safe wrappers for browser storage with type-safety.
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import { getStorageItem, setStorageItem } from 'denwa-react-shared';
|
|
58
|
+
|
|
59
|
+
const theme = getStorageItem('admin_theme', 'light');
|
|
60
|
+
setStorageItem('admin_theme', 'dark');
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Common Mistakes
|
|
64
|
+
|
|
65
|
+
### MEDIUM Pyramid of doom in Providers
|
|
66
|
+
Wrong:
|
|
67
|
+
```tsx
|
|
68
|
+
<Auth>
|
|
69
|
+
<Config>
|
|
70
|
+
<Query>
|
|
71
|
+
<Layout>{children}</Layout>
|
|
72
|
+
</Query>
|
|
73
|
+
</Config>
|
|
74
|
+
</Auth>
|
|
75
|
+
```
|
|
76
|
+
Correct:
|
|
77
|
+
```tsx
|
|
78
|
+
<ProviderComposer providers={[<Auth/>, <Config/>, <Query/>]}>
|
|
79
|
+
<Layout>{children}</Layout>
|
|
80
|
+
</ProviderComposer>
|
|
81
|
+
```
|
|
82
|
+
`ProviderComposer` simplifies deep nesting of React providers, making the root file more readable.
|
|
83
|
+
|
|
84
|
+
Source: src/shared/lib/provider-composer/index.tsx
|
|
85
|
+
|
|
86
|
+
### MEDIUM Hardcoding breakpoints
|
|
87
|
+
Wrong:
|
|
88
|
+
```tsx
|
|
89
|
+
const isMobile = useMediaQuery('(max-width: 768px)');
|
|
90
|
+
```
|
|
91
|
+
Correct:
|
|
92
|
+
```tsx
|
|
93
|
+
const { isMobile } = useViewPort();
|
|
94
|
+
```
|
|
95
|
+
Internal library components (like `AdminTable`) use breakpoints from `useViewPort`. Custom components should use the same hook to ensure consistent responsive behavior.
|
|
96
|
+
|
|
97
|
+
Source: src/shared/lib/hooks/use-view-port.ts
|