@rulab/adminjs-components 0.1.0 → 0.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.
- package/README.md +20 -2
- package/dist/components/Editor/Editor.d.ts +7 -9
- package/dist/components/Editor/Editor.js +8 -5
- package/dist/components/Editor/EditorList.d.ts +4 -6
- package/dist/components/Editor/EditorList.js +2 -1
- package/dist/components/Editor/EditorShow.d.ts +4 -6
- package/dist/components/Editor/EditorShow.js +4 -1
- package/dist/components/Slug/SlugEdit.js +1 -1
- package/dist/components/Slug/SlugFeature.js +2 -2
- package/dist/components/Slug/SlugOptions.type.d.ts +1 -0
- package/dist/components/Uuid/UuidEdit.d.ts +5 -0
- package/dist/components/Uuid/UuidEdit.js +34 -0
- package/dist/components/Uuid/UuidFeature.d.ts +4 -0
- package/dist/components/Uuid/UuidFeature.js +21 -0
- package/dist/components/Uuid/UuidOptions.type.d.ts +7 -0
- package/dist/components/Uuid/UuidOptions.type.js +1 -0
- package/dist/components/Uuid/styles.d.ts +4 -0
- package/dist/components/Uuid/styles.js +20 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/package.json +35 -16
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# adminjs-components
|
|
2
2
|
|
|
3
3
|
Prebuilt AdminJS components and features for common UI needs: colored status
|
|
4
|
-
badges, slug generation, Editor.js content, sortable string lists, tabs
|
|
5
|
-
and record preview.
|
|
4
|
+
badges, slug and UUID generation, Editor.js content, sortable string lists, tabs
|
|
5
|
+
layout, and record preview.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -68,6 +68,7 @@ features: [
|
|
|
68
68
|
### Slug
|
|
69
69
|
|
|
70
70
|
Generates a slug from another field and stores it in the target property.
|
|
71
|
+
Use `button` to override the generate button label in edit view.
|
|
71
72
|
|
|
72
73
|
```ts
|
|
73
74
|
import { SlugFeature } from "@rulab/adminjs-components";
|
|
@@ -76,6 +77,23 @@ features: [
|
|
|
76
77
|
SlugFeature({
|
|
77
78
|
key: "slug",
|
|
78
79
|
source: "title",
|
|
80
|
+
button: "Create slug", // optional
|
|
81
|
+
}),
|
|
82
|
+
]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### UUID
|
|
86
|
+
|
|
87
|
+
Adds a UUID field with a "Generate UUID" button in edit view.
|
|
88
|
+
Use `button` to override the generate button label.
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { UuidFeature } from "@rulab/adminjs-components";
|
|
92
|
+
|
|
93
|
+
features: [
|
|
94
|
+
UuidFeature({
|
|
95
|
+
key: "uuid",
|
|
96
|
+
button: "Generate ID", // optional
|
|
79
97
|
}),
|
|
80
98
|
]
|
|
81
99
|
```
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import React from "react";
|
|
2
|
+
type EditorProps = {
|
|
2
3
|
property: any;
|
|
3
4
|
record: any;
|
|
4
5
|
resource: any;
|
|
5
|
-
onChange:
|
|
6
|
-
onChangeAdmin:
|
|
7
|
-
editorId
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
theme: import("styled-components").DefaultTheme | ((outerTheme?: import("styled-components").DefaultTheme | undefined) => import("styled-components").DefaultTheme);
|
|
11
|
-
}>;
|
|
6
|
+
onChange?: (path: string, value: string | undefined) => void;
|
|
7
|
+
onChangeAdmin?: (path: string, value: string | undefined) => void;
|
|
8
|
+
editorId?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const Editor: ({ property, record, resource, onChange, onChangeAdmin, editorId, }: EditorProps) => React.JSX.Element;
|
|
12
11
|
export default Editor;
|
|
13
|
-
import React from "react";
|
|
@@ -22,15 +22,15 @@ const getEditorData = (record, property) => {
|
|
|
22
22
|
try {
|
|
23
23
|
return JSON.parse(raw);
|
|
24
24
|
}
|
|
25
|
-
catch
|
|
25
|
+
catch {
|
|
26
26
|
return "";
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
|
-
export const Editor = ({ property, record, resource, onChange, onChangeAdmin, editorId }) => {
|
|
29
|
+
export const Editor = ({ property, record, resource, onChange, onChangeAdmin, editorId, }) => {
|
|
30
30
|
const [jsonData, setJsonData] = useState();
|
|
31
31
|
const isSavedData = Boolean(record?.params?.[property.path]);
|
|
32
32
|
const holderId = editorId || property?.props?.editorId || `editor-${property.path}`;
|
|
33
|
-
const uploadAction = property?.props?.uploadAction;
|
|
33
|
+
const uploadAction = property?.custom?.uploadAction ?? property?.props?.uploadAction;
|
|
34
34
|
const resourceId = resource?.id;
|
|
35
35
|
const ref = useRef();
|
|
36
36
|
useEffect(() => {
|
|
@@ -78,7 +78,7 @@ export const Editor = ({ property, record, resource, onChange, onChangeAdmin, ed
|
|
|
78
78
|
holder: holderId,
|
|
79
79
|
tools,
|
|
80
80
|
data: isSavedData ? getEditorData(record, property) : "",
|
|
81
|
-
async onChange(api
|
|
81
|
+
async onChange(api) {
|
|
82
82
|
const data = await api.saver.save();
|
|
83
83
|
setJsonData(JSON.stringify(data));
|
|
84
84
|
},
|
|
@@ -91,6 +91,9 @@ export const Editor = ({ property, record, resource, onChange, onChangeAdmin, ed
|
|
|
91
91
|
ref?.current?.destroy?.();
|
|
92
92
|
};
|
|
93
93
|
}, []);
|
|
94
|
-
return (React.createElement(ThemeProvider, { theme: theme },
|
|
94
|
+
return (React.createElement(ThemeProvider, { theme: theme },
|
|
95
|
+
React.createElement(StyledLabel, null, property.label ?? property.path),
|
|
96
|
+
React.createElement(StyledEditorWrapper, null,
|
|
97
|
+
React.createElement(StyledEditor, { id: holderId }))));
|
|
95
98
|
};
|
|
96
99
|
export default Editor;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import React from "react";
|
|
2
|
+
type EditorListProps = {
|
|
2
3
|
property: any;
|
|
3
4
|
record: any;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
theme: import("styled-components").DefaultTheme | ((outerTheme?: import("styled-components").DefaultTheme | undefined) => import("styled-components").DefaultTheme);
|
|
7
|
-
}>;
|
|
5
|
+
};
|
|
6
|
+
export declare const EditorList: ({ property, record }: EditorListProps) => React.JSX.Element;
|
|
8
7
|
export default EditorList;
|
|
9
|
-
import React from "react";
|
|
@@ -5,6 +5,7 @@ import { parseHtml } from "../../utils/parseHtml.js";
|
|
|
5
5
|
import { StyledEditorViewWrapper } from "./styles.js";
|
|
6
6
|
export const EditorList = ({ property, record }) => {
|
|
7
7
|
const htmlContent = parseHtml(record.params[property.path]);
|
|
8
|
-
return (React.createElement(ThemeProvider, { theme: theme },
|
|
8
|
+
return (React.createElement(ThemeProvider, { theme: theme },
|
|
9
|
+
React.createElement(StyledEditorViewWrapper, null, htmlContent && React.createElement("div", { dangerouslySetInnerHTML: { __html: htmlContent } }))));
|
|
9
10
|
};
|
|
10
11
|
export default EditorList;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import React from "react";
|
|
2
|
+
type EditorShowProps = {
|
|
2
3
|
property: any;
|
|
3
4
|
record: any;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
theme: import("styled-components").DefaultTheme | ((outerTheme?: import("styled-components").DefaultTheme | undefined) => import("styled-components").DefaultTheme);
|
|
7
|
-
}>;
|
|
5
|
+
};
|
|
6
|
+
export declare const EditorShow: ({ property, record }: EditorShowProps) => React.JSX.Element;
|
|
8
7
|
export default EditorShow;
|
|
9
|
-
import React from "react";
|
|
@@ -5,6 +5,9 @@ import { parseHtml } from "../../utils/parseHtml.js";
|
|
|
5
5
|
import { StyledEditorShowWrapper, StyledShowLabel } from "./styles.js";
|
|
6
6
|
export const EditorShow = ({ property, record }) => {
|
|
7
7
|
const htmlContent = parseHtml(record.params[property.path]);
|
|
8
|
-
return (React.createElement(ThemeProvider, { theme: theme },
|
|
8
|
+
return (React.createElement(ThemeProvider, { theme: theme },
|
|
9
|
+
React.createElement(StyledEditorShowWrapper, null,
|
|
10
|
+
React.createElement(StyledShowLabel, null, property.label ?? property.path),
|
|
11
|
+
htmlContent && React.createElement("div", { dangerouslySetInnerHTML: { __html: htmlContent } }))));
|
|
9
12
|
};
|
|
10
13
|
export default EditorShow;
|
|
@@ -17,7 +17,7 @@ export const SlugEdit = ({ property, record, resource, onChange, }) => {
|
|
|
17
17
|
React.createElement(StyledLabel, { htmlFor: "customSlug" }, property.label ?? property.path),
|
|
18
18
|
React.createElement(StyledInputWrapper, null,
|
|
19
19
|
React.createElement(StyledCustomInput, { id: property.path, name: property.path, value: inputValue, onChange: handleInput }),
|
|
20
|
-
React.createElement(StyledGenerateButton, { variant: "outlined", onClick: generateSlug }, "Generate Slug"))));
|
|
20
|
+
React.createElement(StyledGenerateButton, { variant: "outlined", onClick: generateSlug }, custom.button ?? "Generate Slug"))));
|
|
21
21
|
function handleInput(e) {
|
|
22
22
|
setInputValue(e.target.value);
|
|
23
23
|
}
|
|
@@ -2,7 +2,7 @@ import { buildFeature } from "adminjs";
|
|
|
2
2
|
import { bundleComponent } from "../../utils/bundle-component.js";
|
|
3
3
|
const COMPONENT_NAME = 'Slug';
|
|
4
4
|
export const SlugFeature = (config) => {
|
|
5
|
-
const { componentLoader, source, key } = config;
|
|
5
|
+
const { componentLoader, source, key, button } = config;
|
|
6
6
|
const editComponent = bundleComponent(componentLoader, COMPONENT_NAME, 'SlugEdit.js');
|
|
7
7
|
return buildFeature({
|
|
8
8
|
properties: {
|
|
@@ -11,7 +11,7 @@ export const SlugFeature = (config) => {
|
|
|
11
11
|
components: {
|
|
12
12
|
edit: editComponent,
|
|
13
13
|
},
|
|
14
|
-
custom: { source, key }
|
|
14
|
+
custom: { source, key, button }
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
17
|
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { ThemeProvider } from "styled-components";
|
|
3
|
+
import { theme } from "@adminjs/design-system";
|
|
4
|
+
import { StyledCustomInput, StyledGenerateButton, StyledInputWrapper, StyledLabel, } from "./styles.js";
|
|
5
|
+
const generateUuidV4 = () => {
|
|
6
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
7
|
+
return crypto.randomUUID();
|
|
8
|
+
}
|
|
9
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (char) => {
|
|
10
|
+
const random = (Math.random() * 16) | 0;
|
|
11
|
+
const value = char === "x" ? random : (random & 0x3) | 0x8;
|
|
12
|
+
return value.toString(16);
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
export const UuidEdit = ({ property, record, onChange, }) => {
|
|
16
|
+
const { custom } = property;
|
|
17
|
+
const [inputValue, setInputValue] = useState(record.params[property.path] ?? "");
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
onChange(property.path, inputValue);
|
|
20
|
+
}, [inputValue]);
|
|
21
|
+
return (React.createElement(ThemeProvider, { theme: theme },
|
|
22
|
+
React.createElement(StyledLabel, { htmlFor: "customUuid" }, property.label ?? property.path),
|
|
23
|
+
React.createElement(StyledInputWrapper, null,
|
|
24
|
+
React.createElement(StyledCustomInput, { id: property.path, name: property.path, value: inputValue, onChange: handleInput }),
|
|
25
|
+
React.createElement(StyledGenerateButton, { variant: "outlined", onClick: generateUuid }, custom?.button ?? "Generate UUID"))));
|
|
26
|
+
function handleInput(e) {
|
|
27
|
+
setInputValue(e.target.value);
|
|
28
|
+
}
|
|
29
|
+
function generateUuid(e) {
|
|
30
|
+
e.preventDefault();
|
|
31
|
+
setInputValue(generateUuidV4());
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
export default UuidEdit;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { buildFeature } from "adminjs";
|
|
2
|
+
import { bundleComponent } from "../../utils/bundle-component.js";
|
|
3
|
+
const COMPONENT_NAME = "Uuid";
|
|
4
|
+
export const UuidFeature = (config) => {
|
|
5
|
+
const { componentLoader, key, button } = config;
|
|
6
|
+
const editComponent = bundleComponent(componentLoader, COMPONENT_NAME, "UuidEdit.js");
|
|
7
|
+
return buildFeature({
|
|
8
|
+
properties: {
|
|
9
|
+
[key]: {
|
|
10
|
+
isVisible: { filter: true, show: true, edit: true, list: true },
|
|
11
|
+
custom: {
|
|
12
|
+
button,
|
|
13
|
+
},
|
|
14
|
+
components: {
|
|
15
|
+
edit: editComponent,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
export default UuidFeature;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import { styled } from "@adminjs/design-system/styled-components";
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import { Box, Button, Input } from "@adminjs/design-system";
|
|
5
|
+
export const StyledInputWrapper = styled(Box) `
|
|
6
|
+
display: flex;
|
|
7
|
+
margin-bottom: 40px;
|
|
8
|
+
`;
|
|
9
|
+
export const StyledCustomInput = styled(Input) `
|
|
10
|
+
width: 100%;
|
|
11
|
+
margin-right: 10px;
|
|
12
|
+
`;
|
|
13
|
+
export const StyledGenerateButton = styled(Button) `
|
|
14
|
+
white-space: nowrap;
|
|
15
|
+
`;
|
|
16
|
+
export const StyledLabel = styled.div `
|
|
17
|
+
font-size: 12px;
|
|
18
|
+
margin-bottom: 8px;
|
|
19
|
+
text-transform: capitalize;
|
|
20
|
+
`;
|
|
@@ -13,3 +13,4 @@ export { StringListFeature } from "./StringList/StringListFeature.js";
|
|
|
13
13
|
export { SlugFeature } from "./Slug/SlugFeature.js";
|
|
14
14
|
export { TabsFeature } from "./Tabs/TabsFeature.js";
|
|
15
15
|
export { PreviewFeature } from "./Preview/PreviewFeature.js";
|
|
16
|
+
export { UuidFeature } from "./Uuid/UuidFeature.js";
|
package/dist/components/index.js
CHANGED
|
@@ -13,3 +13,4 @@ export { StringListFeature } from "./StringList/StringListFeature.js";
|
|
|
13
13
|
export { SlugFeature } from "./Slug/SlugFeature.js";
|
|
14
14
|
export { TabsFeature } from "./Tabs/TabsFeature.js";
|
|
15
15
|
export { PreviewFeature } from "./Preview/PreviewFeature.js";
|
|
16
|
+
export { UuidFeature } from "./Uuid/UuidFeature.js";
|
package/package.json
CHANGED
|
@@ -1,35 +1,55 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulab/adminjs-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Prebuilt AdminJS features for common UI needs.",
|
|
4
5
|
"main": "dist/index.js",
|
|
5
|
-
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"private": false,
|
|
8
8
|
"type": "module",
|
|
9
|
+
"license": "MIT",
|
|
9
10
|
"keywords": [
|
|
10
|
-
"adminjs"
|
|
11
|
+
"adminjs",
|
|
12
|
+
"components",
|
|
13
|
+
"react",
|
|
14
|
+
"editorjs"
|
|
11
15
|
],
|
|
16
|
+
"homepage": "https://github.com/rulab/adminjs-components#readme",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/rulab/adminjs-components/issues"
|
|
19
|
+
},
|
|
12
20
|
"repository": {
|
|
13
21
|
"url": "git+https://github.com/rulab/adminjs-components.git"
|
|
14
22
|
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public",
|
|
25
|
+
"registry": "https://registry.npmjs.org/"
|
|
26
|
+
},
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js",
|
|
31
|
+
"default": "./dist/index.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"sideEffects": false,
|
|
15
35
|
"scripts": {
|
|
16
|
-
"build": "tsc
|
|
17
|
-
"
|
|
18
|
-
"
|
|
36
|
+
"build": "tsc",
|
|
37
|
+
"lint": "tsc",
|
|
38
|
+
"prepublishOnly": "pnpm run build"
|
|
19
39
|
},
|
|
20
40
|
"dependencies": {
|
|
21
41
|
"@dnd-kit/core": "^6.1.0",
|
|
22
42
|
"@dnd-kit/sortable": "^8.0.0",
|
|
23
|
-
"@editorjs/editorjs": "2.30.2",
|
|
24
|
-
"@editorjs/header": "
|
|
25
|
-
"@editorjs/image": "
|
|
26
|
-
"@editorjs/list": "
|
|
27
|
-
"@editorjs/paragraph": "
|
|
28
|
-
"@editorjs/quote": "
|
|
29
|
-
"@editorjs/table": "
|
|
43
|
+
"@editorjs/editorjs": "~2.30.2",
|
|
44
|
+
"@editorjs/header": "~2.8.7",
|
|
45
|
+
"@editorjs/image": "~2.9.2",
|
|
46
|
+
"@editorjs/list": "~1.9.0",
|
|
47
|
+
"@editorjs/paragraph": "~2.11.6",
|
|
48
|
+
"@editorjs/quote": "~2.7.2",
|
|
49
|
+
"@editorjs/table": "~2.4.1",
|
|
30
50
|
"chroma-js": "^3.0.0",
|
|
31
|
-
"editorjs-audio-player": "
|
|
32
|
-
"editorjs-html": "
|
|
51
|
+
"editorjs-audio-player": "~0.0.3",
|
|
52
|
+
"editorjs-html": "~3.4.3",
|
|
33
53
|
"react-select": "^5.8.0",
|
|
34
54
|
"slugify": "^1.6.6"
|
|
35
55
|
},
|
|
@@ -53,7 +73,6 @@
|
|
|
53
73
|
"@types/node": "^20.11.24",
|
|
54
74
|
"@types/react": "^18.2.61",
|
|
55
75
|
"react": "^18.2.0",
|
|
56
|
-
"tsup": "^8.1.0",
|
|
57
76
|
"styled-components": "^6.1.11",
|
|
58
77
|
"typescript": "^5.3.2"
|
|
59
78
|
},
|