@rakun-kit/manager-react 1.4.5 → 1.4.6

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/README.md CHANGED
@@ -1,196 +1,196 @@
1
- # @rakun-kit/manager-react
2
-
3
- React manager UI and client utilities for Rakun.
4
-
5
- Most apps use this package through framework adapters such as
6
- `@rakun-kit/next/manager`, but the runtime components and clients are also
7
- published for custom integrations.
8
-
9
- ## Browser App
10
-
11
- Render the manager with a manager client and navigation implementation:
12
-
13
- ```tsx
14
- import {
15
- ManagerBrowserApp,
16
- createHttpManagerClient,
17
- } from "@rakun-kit/manager-react";
18
- import "@rakun-kit/manager-react/styles.css";
19
-
20
- const client = createHttpManagerClient({
21
- baseUrl: "/api/rakun",
22
- });
23
-
24
- export function ManagerPage() {
25
- return (
26
- <ManagerBrowserApp
27
- client={client}
28
- pathname={window.location.pathname}
29
- basePath="/backend"
30
- />
31
- );
32
- }
33
- ```
34
-
35
- `ManagerBrowserApp` creates browser path navigation by default. Use
36
- `ManagerRuntimeApp` when you need to provide custom navigation.
37
-
38
- ## Clients
39
-
40
- HTTP client:
41
-
42
- ```ts
43
- import { createHttpManagerClient } from "@rakun-kit/manager-react/client/http";
44
-
45
- const client = createHttpManagerClient({
46
- baseUrl: "/api/rakun",
47
- });
48
-
49
- const contentTypes = await client.request("manager.contentTypes");
50
- ```
51
-
52
- tRPC client adapter:
53
-
54
- ```ts
55
- import { createTrpcManagerClient } from "@rakun-kit/manager-react/client/trpc";
56
-
57
- const managerClient = createTrpcManagerClient(trpcProxyClient);
58
- ```
59
-
60
- Custom client:
61
-
62
- ```ts
63
- import { createManagerClient } from "@rakun-kit/manager-react/client/request";
64
-
65
- const client = createManagerClient(async (name, input, options) => {
66
- // call your transport here
67
- });
68
- ```
69
-
70
- ## Navigation
71
-
72
- Use `createPathManagerNavigation` for router integrations:
73
-
74
- ```ts
75
- import { createPathManagerNavigation } from "@rakun-kit/manager-react/state/navigation";
76
-
77
- const navigation = createPathManagerNavigation({
78
- basePath: "/backend",
79
- push: (href) => router.push(href),
80
- replace: (href) => router.replace(href),
81
- });
82
- ```
83
-
84
- ## Styles
85
-
86
- Import the package stylesheet once:
87
-
88
- ```ts
89
- import "@rakun-kit/manager-react/styles.css";
90
- ```
91
-
92
- ## Manager Plugins
93
-
94
- Manager plugins run inside the normal providers and can add dashboard routes,
95
- sidebar items, and custom field editors:
96
-
97
- ```tsx
98
- import {
99
- defineRakunManagerPlugin,
100
- ManagerBrowserApp,
101
- } from '@rakun-kit/manager-react'
102
-
103
- const analyticsManagerPlugin = defineRakunManagerPlugin({
104
- id: '@acme/rakun-analytics',
105
- routes: [{
106
- id: 'dashboard',
107
- path: '/analytics',
108
- component: AnalyticsScreen,
109
- permissions: ['plugin.analytics.view'],
110
- }],
111
- sidebar: [{
112
- id: 'analytics',
113
- title: 'Analytics',
114
- routeId: 'dashboard',
115
- position: 'primary',
116
- group: 'Plugins',
117
- }],
118
- fieldEditors: {
119
- '@acme/rakun-analytics.query': QueryEditor,
120
- },
121
- })
122
-
123
- <ManagerBrowserApp plugins={[analyticsManagerPlugin]} {...props} />
124
- ```
125
-
126
- Use `ManagerFieldEditorProps`, `ManagerFieldEditorRef`, and
127
- `useManagerFieldValue` from `@rakun-kit/manager-react/plugins` when implementing
128
- field editors. Next.js applications should import plugin objects inside a
129
- `'use client'` wrapper around `RakunManagerClientPage`; `RakunManagerPage` accepts
130
- that wrapper through `managerComponent`.
131
-
132
- ### Extending the RichText editor
133
-
134
- Manager plugins can register Lexical nodes and React plugins for every
135
- `RichText` field, including fields rendered inside relations, blocks, and
136
- modules:
137
-
138
- ```tsx
139
- 'use client'
140
-
141
- import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
142
- import {
143
- defineRakunManagerPlugin,
144
- type ManagerRichTextPluginProps,
145
- } from '@rakun-kit/manager-react/plugins'
146
- import { MentionNode } from './MentionNode'
147
-
148
- const MentionsPlugin = ({ id }: ManagerRichTextPluginProps) => {
149
- const [editor] = useLexicalComposerContext()
150
-
151
- // Register commands and listeners on `editor` here.
152
- return null
153
- }
154
-
155
- export const mentionsManagerPlugin = defineRakunManagerPlugin({
156
- id: '@acme/rakun-mentions',
157
- richText: {
158
- nodes: [MentionNode],
159
- plugins: [
160
- {
161
- id: '@acme/rakun-mentions.plugin',
162
- component: MentionsPlugin,
163
- placement: 'editor',
164
- },
165
- ],
166
- },
167
- })
168
- ```
169
-
170
- Lexical plugin components receive `ManagerRichTextPluginProps` (the field id,
171
- configuration, current content type, and related field metadata) and render
172
- inside `LexicalComposer`, so they can use the normal Lexical React hooks.
173
- Supported placements are `toolbar`, `block-format`, `editor` (the default),
174
- `actions-start`, and `actions-end`. `block-format` components render inside the
175
- manager's block selector and can use `ManagerRichTextBlockFormatItem` from
176
- `@rakun-kit/manager-react/rich-text`. Contributions keep declaration order
177
- unless an explicit `order` is provided. Node types and plugin ids must be unique;
178
- conflicts report both plugin owners. Node replacements use Lexical's standard
179
- `LexicalNodeReplacement` configuration.
180
-
181
- ## Exports
182
-
183
- - `@rakun-kit/manager-react`: manager app, providers, clients, navigation, router, layout, media, and state helpers.
184
- - `@rakun-kit/manager-react/client/http`: HTTP manager client.
185
- - `@rakun-kit/manager-react/client/request`: transport-agnostic manager client.
186
- - `@rakun-kit/manager-react/client/trpc`: tRPC proxy client adapter.
187
- - `@rakun-kit/manager-react/app/runtime-app`: `ManagerRuntimeApp`, `ManagerBrowserApp`.
188
- - `@rakun-kit/manager-react/state/navigation`: navigation helpers and provider.
189
- - `@rakun-kit/manager-react/link`: link component provider.
190
- - `@rakun-kit/manager-react/styles.css`: bundled manager styles.
191
-
192
- ## Build
193
-
194
- ```sh
195
- bun run build --workspace @rakun-kit/manager-react
196
- ```
1
+ # @rakun-kit/manager-react
2
+
3
+ React manager UI and client utilities for Rakun.
4
+
5
+ Most apps use this package through framework adapters such as
6
+ `@rakun-kit/next/manager`, but the runtime components and clients are also
7
+ published for custom integrations.
8
+
9
+ ## Browser App
10
+
11
+ Render the manager with a manager client and navigation implementation:
12
+
13
+ ```tsx
14
+ import {
15
+ ManagerBrowserApp,
16
+ createHttpManagerClient,
17
+ } from "@rakun-kit/manager-react";
18
+ import "@rakun-kit/manager-react/styles.css";
19
+
20
+ const client = createHttpManagerClient({
21
+ baseUrl: "/api/rakun",
22
+ });
23
+
24
+ export function ManagerPage() {
25
+ return (
26
+ <ManagerBrowserApp
27
+ client={client}
28
+ pathname={window.location.pathname}
29
+ basePath="/backend"
30
+ />
31
+ );
32
+ }
33
+ ```
34
+
35
+ `ManagerBrowserApp` creates browser path navigation by default. Use
36
+ `ManagerRuntimeApp` when you need to provide custom navigation.
37
+
38
+ ## Clients
39
+
40
+ HTTP client:
41
+
42
+ ```ts
43
+ import { createHttpManagerClient } from "@rakun-kit/manager-react/client/http";
44
+
45
+ const client = createHttpManagerClient({
46
+ baseUrl: "/api/rakun",
47
+ });
48
+
49
+ const contentTypes = await client.request("manager.contentTypes");
50
+ ```
51
+
52
+ tRPC client adapter:
53
+
54
+ ```ts
55
+ import { createTrpcManagerClient } from "@rakun-kit/manager-react/client/trpc";
56
+
57
+ const managerClient = createTrpcManagerClient(trpcProxyClient);
58
+ ```
59
+
60
+ Custom client:
61
+
62
+ ```ts
63
+ import { createManagerClient } from "@rakun-kit/manager-react/client/request";
64
+
65
+ const client = createManagerClient(async (name, input, options) => {
66
+ // call your transport here
67
+ });
68
+ ```
69
+
70
+ ## Navigation
71
+
72
+ Use `createPathManagerNavigation` for router integrations:
73
+
74
+ ```ts
75
+ import { createPathManagerNavigation } from "@rakun-kit/manager-react/state/navigation";
76
+
77
+ const navigation = createPathManagerNavigation({
78
+ basePath: "/backend",
79
+ push: (href) => router.push(href),
80
+ replace: (href) => router.replace(href),
81
+ });
82
+ ```
83
+
84
+ ## Styles
85
+
86
+ Import the package stylesheet once:
87
+
88
+ ```ts
89
+ import "@rakun-kit/manager-react/styles.css";
90
+ ```
91
+
92
+ ## Manager Plugins
93
+
94
+ Manager plugins run inside the normal providers and can add dashboard routes,
95
+ sidebar items, and custom field editors:
96
+
97
+ ```tsx
98
+ import {
99
+ defineRakunManagerPlugin,
100
+ ManagerBrowserApp,
101
+ } from '@rakun-kit/manager-react'
102
+
103
+ const analyticsManagerPlugin = defineRakunManagerPlugin({
104
+ id: '@acme/rakun-analytics',
105
+ routes: [{
106
+ id: 'dashboard',
107
+ path: '/analytics',
108
+ component: AnalyticsScreen,
109
+ permissions: ['plugin.analytics.view'],
110
+ }],
111
+ sidebar: [{
112
+ id: 'analytics',
113
+ title: 'Analytics',
114
+ routeId: 'dashboard',
115
+ position: 'primary',
116
+ group: 'Plugins',
117
+ }],
118
+ fieldEditors: {
119
+ '@acme/rakun-analytics.query': QueryEditor,
120
+ },
121
+ })
122
+
123
+ <ManagerBrowserApp plugins={[analyticsManagerPlugin]} {...props} />
124
+ ```
125
+
126
+ Use `ManagerFieldEditorProps`, `ManagerFieldEditorRef`, and
127
+ `useManagerFieldValue` from `@rakun-kit/manager-react/plugins` when implementing
128
+ field editors. Next.js applications should import plugin objects inside a
129
+ `'use client'` wrapper around `RakunManagerClientPage`; `RakunManagerPage` accepts
130
+ that wrapper through `managerComponent`.
131
+
132
+ ### Extending the RichText editor
133
+
134
+ Manager plugins can register Lexical nodes and React plugins for every
135
+ `RichText` field, including fields rendered inside relations, blocks, and
136
+ modules:
137
+
138
+ ```tsx
139
+ 'use client'
140
+
141
+ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
142
+ import {
143
+ defineRakunManagerPlugin,
144
+ type ManagerRichTextPluginProps,
145
+ } from '@rakun-kit/manager-react/plugins'
146
+ import { MentionNode } from './MentionNode'
147
+
148
+ const MentionsPlugin = ({ id }: ManagerRichTextPluginProps) => {
149
+ const [editor] = useLexicalComposerContext()
150
+
151
+ // Register commands and listeners on `editor` here.
152
+ return null
153
+ }
154
+
155
+ export const mentionsManagerPlugin = defineRakunManagerPlugin({
156
+ id: '@acme/rakun-mentions',
157
+ richText: {
158
+ nodes: [MentionNode],
159
+ plugins: [
160
+ {
161
+ id: '@acme/rakun-mentions.plugin',
162
+ component: MentionsPlugin,
163
+ placement: 'editor',
164
+ },
165
+ ],
166
+ },
167
+ })
168
+ ```
169
+
170
+ Lexical plugin components receive `ManagerRichTextPluginProps` (the field id,
171
+ configuration, current content type, and related field metadata) and render
172
+ inside `LexicalComposer`, so they can use the normal Lexical React hooks.
173
+ Supported placements are `toolbar`, `block-format`, `editor` (the default),
174
+ `actions-start`, and `actions-end`. `block-format` components render inside the
175
+ manager's block selector and can use `ManagerRichTextBlockFormatItem` from
176
+ `@rakun-kit/manager-react/rich-text`. Contributions keep declaration order
177
+ unless an explicit `order` is provided. Node types and plugin ids must be unique;
178
+ conflicts report both plugin owners. Node replacements use Lexical's standard
179
+ `LexicalNodeReplacement` configuration.
180
+
181
+ ## Exports
182
+
183
+ - `@rakun-kit/manager-react`: manager app, providers, clients, navigation, router, layout, media, and state helpers.
184
+ - `@rakun-kit/manager-react/client/http`: HTTP manager client.
185
+ - `@rakun-kit/manager-react/client/request`: transport-agnostic manager client.
186
+ - `@rakun-kit/manager-react/client/trpc`: tRPC proxy client adapter.
187
+ - `@rakun-kit/manager-react/app/runtime-app`: `ManagerRuntimeApp`, `ManagerBrowserApp`.
188
+ - `@rakun-kit/manager-react/state/navigation`: navigation helpers and provider.
189
+ - `@rakun-kit/manager-react/link`: link component provider.
190
+ - `@rakun-kit/manager-react/styles.css`: bundled manager styles.
191
+
192
+ ## Build
193
+
194
+ ```sh
195
+ bun run build --workspace @rakun-kit/manager-react
196
+ ```
@@ -1,91 +1,91 @@
1
- .EditorTheme__code {
2
- background-color: transparent;
3
- font-family: Menlo, Consolas, Monaco, monospace;
4
- display: block;
5
- padding: 8px 8px 8px 52px;
6
- line-height: 1.53;
7
- font-size: 13px;
8
- margin: 0;
9
- margin-top: 8px;
10
- margin-bottom: 8px;
11
- overflow-x: auto;
12
- border: 1px solid #ccc;
13
- position: relative;
14
- border-radius: 8px;
15
- tab-size: 2;
16
- }
17
- .EditorTheme__code:before {
18
- content: attr(data-gutter);
19
- position: absolute;
20
- background-color: transparent;
21
- border-right: 1px solid #ccc;
22
- left: 0;
23
- top: 0;
24
- padding: 8px;
25
- color: #777;
26
- white-space: pre-wrap;
27
- text-align: right;
28
- min-width: 25px;
29
- }
30
- .EditorTheme__table {
31
- border-collapse: collapse;
32
- border-spacing: 0;
33
- overflow-y: scroll;
34
- overflow-x: scroll;
35
- table-layout: fixed;
36
- width: fit-content;
37
- width: 100%;
38
- margin: 0px 0px 30px 0px;
39
- }
40
- .EditorTheme__tokenComment {
41
- color: slategray;
42
- }
43
- .EditorTheme__tokenPunctuation {
44
- color: #999;
45
- }
46
- .EditorTheme__tokenProperty {
47
- color: #905;
48
- }
49
- .EditorTheme__tokenSelector {
50
- color: #690;
51
- }
52
- .EditorTheme__tokenOperator {
53
- color: #9a6e3a;
54
- }
55
- .EditorTheme__tokenAttr {
56
- color: #07a;
57
- }
58
- .EditorTheme__tokenVariable {
59
- color: #e90;
60
- }
61
- .EditorTheme__tokenFunction {
62
- color: #dd4a68;
63
- }
64
-
65
- .Collapsible__container {
66
- background-color: var(--background);
67
- border: 1px solid #ccc;
68
- border-radius: 0.5rem;
69
- margin-bottom: 0.5rem;
70
- }
71
-
72
- .Collapsible__title{
73
- padding: 0.25rem;
74
- padding-left: 1rem;
75
- position: relative;
76
- font-weight: bold;
77
- outline: none;
78
- cursor: pointer;
79
- list-style-type: disclosure-closed;
80
- list-style-position: inside;
81
- }
82
-
83
- .Collapsible__title p{
84
- display: inline-flex;
85
- }
86
- .Collapsible__title::marker{
87
- color: lightgray;
88
- }
89
- .Collapsible__container[open] >.Collapsible__title {
90
- list-style-type: disclosure-open;
91
- }
1
+ .EditorTheme__code {
2
+ background-color: transparent;
3
+ font-family: Menlo, Consolas, Monaco, monospace;
4
+ display: block;
5
+ padding: 8px 8px 8px 52px;
6
+ line-height: 1.53;
7
+ font-size: 13px;
8
+ margin: 0;
9
+ margin-top: 8px;
10
+ margin-bottom: 8px;
11
+ overflow-x: auto;
12
+ border: 1px solid #ccc;
13
+ position: relative;
14
+ border-radius: 8px;
15
+ tab-size: 2;
16
+ }
17
+ .EditorTheme__code:before {
18
+ content: attr(data-gutter);
19
+ position: absolute;
20
+ background-color: transparent;
21
+ border-right: 1px solid #ccc;
22
+ left: 0;
23
+ top: 0;
24
+ padding: 8px;
25
+ color: #777;
26
+ white-space: pre-wrap;
27
+ text-align: right;
28
+ min-width: 25px;
29
+ }
30
+ .EditorTheme__table {
31
+ border-collapse: collapse;
32
+ border-spacing: 0;
33
+ overflow-y: scroll;
34
+ overflow-x: scroll;
35
+ table-layout: fixed;
36
+ width: fit-content;
37
+ width: 100%;
38
+ margin: 0px 0px 30px 0px;
39
+ }
40
+ .EditorTheme__tokenComment {
41
+ color: slategray;
42
+ }
43
+ .EditorTheme__tokenPunctuation {
44
+ color: #999;
45
+ }
46
+ .EditorTheme__tokenProperty {
47
+ color: #905;
48
+ }
49
+ .EditorTheme__tokenSelector {
50
+ color: #690;
51
+ }
52
+ .EditorTheme__tokenOperator {
53
+ color: #9a6e3a;
54
+ }
55
+ .EditorTheme__tokenAttr {
56
+ color: #07a;
57
+ }
58
+ .EditorTheme__tokenVariable {
59
+ color: #e90;
60
+ }
61
+ .EditorTheme__tokenFunction {
62
+ color: #dd4a68;
63
+ }
64
+
65
+ .Collapsible__container {
66
+ background-color: var(--background);
67
+ border: 1px solid #ccc;
68
+ border-radius: 0.5rem;
69
+ margin-bottom: 0.5rem;
70
+ }
71
+
72
+ .Collapsible__title{
73
+ padding: 0.25rem;
74
+ padding-left: 1rem;
75
+ position: relative;
76
+ font-weight: bold;
77
+ outline: none;
78
+ cursor: pointer;
79
+ list-style-type: disclosure-closed;
80
+ list-style-position: inside;
81
+ }
82
+
83
+ .Collapsible__title p{
84
+ display: inline-flex;
85
+ }
86
+ .Collapsible__title::marker{
87
+ color: lightgray;
88
+ }
89
+ .Collapsible__container[open] >.Collapsible__title {
90
+ list-style-type: disclosure-open;
91
+ }
@@ -167,10 +167,10 @@ function Sortable(props) {
167
167
  },
168
168
  }), [value]);
169
169
  const screenReaderInstructions = React.useMemo(() => ({
170
- draggable: `
171
- To pick up a sortable item, press space or enter.
172
- While dragging, use the ${orientation === "vertical" ? "up and down" : orientation === "horizontal" ? "left and right" : "arrow"} keys to move the item.
173
- Press space or enter again to drop the item in its new position, or press escape to cancel.
170
+ draggable: `
171
+ To pick up a sortable item, press space or enter.
172
+ While dragging, use the ${orientation === "vertical" ? "up and down" : orientation === "horizontal" ? "left and right" : "arrow"} keys to move the item.
173
+ Press space or enter again to drop the item in its new position, or press escape to cancel.
174
174
  `,
175
175
  }), [orientation]);
176
176
  const contextValue = React.useMemo(() => ({