@rulab/adminjs-components 0.1.0-beta.1 → 0.1.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 CHANGED
@@ -1 +1,162 @@
1
- # adminjs-components
1
+ # adminjs-components
2
+
3
+ Prebuilt AdminJS components and features for common UI needs: colored status
4
+ badges, slug generation, Editor.js content, sortable string lists, tabs layout,
5
+ and record preview.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @rulab/adminjs-components
11
+ # or
12
+ npm install @rulab/adminjs-components
13
+ ```
14
+
15
+ ## Quick start
16
+
17
+ ```ts
18
+ import AdminJS from "adminjs";
19
+ import { ComponentLoader } from "adminjs";
20
+ import { setComponentLoader, ColorStatusFeature } from "@rulab/adminjs-components";
21
+
22
+ const componentLoader = new ComponentLoader();
23
+ setComponentLoader(componentLoader);
24
+
25
+ const admin = new AdminJS({
26
+ componentLoader,
27
+ resources: [
28
+ {
29
+ resource: YourResource,
30
+ features: [
31
+ ColorStatusFeature({
32
+ key: "status",
33
+ availableValues: [
34
+ { value: "draft", label: "Draft", color: "#64748b" },
35
+ { value: "published", label: "Published", color: "#16a34a" },
36
+ ],
37
+ }),
38
+ ],
39
+ },
40
+ ],
41
+ });
42
+ ```
43
+
44
+ You can also pass `componentLoader` into every feature instead of calling
45
+ `setComponentLoader`.
46
+
47
+ ## Components and features
48
+
49
+ ### ColorStatus
50
+
51
+ Renders a colored badge in edit/list/show based on a list of available values.
52
+
53
+ ```ts
54
+ import { ColorStatusFeature } from "@rulab/adminjs-components";
55
+
56
+ features: [
57
+ ColorStatusFeature({
58
+ key: "status",
59
+ availableValues: [
60
+ { value: "draft", label: "Draft", color: "#64748b" },
61
+ { value: "review", label: "In review", color: "#f59e0b" },
62
+ { value: "published", label: "Published", color: "#16a34a" },
63
+ ],
64
+ }),
65
+ ]
66
+ ```
67
+
68
+ ### Slug
69
+
70
+ Generates a slug from another field and stores it in the target property.
71
+
72
+ ```ts
73
+ import { SlugFeature } from "@rulab/adminjs-components";
74
+
75
+ features: [
76
+ SlugFeature({
77
+ key: "slug",
78
+ source: "title",
79
+ }),
80
+ ]
81
+ ```
82
+
83
+ ### Editor
84
+
85
+ Editor.js field for rich content. Supports optional image upload via
86
+ `@adminjs/upload` provider.
87
+
88
+ ```ts
89
+ import { EditorFeature } from "@rulab/adminjs-components";
90
+ import { BaseProvider } from "@adminjs/upload";
91
+
92
+ const uploadProvider = new BaseProvider({
93
+ bucket: "my-bucket",
94
+ baseUrl: "https://cdn.example.com",
95
+ });
96
+
97
+ features: [
98
+ EditorFeature({
99
+ key: "content",
100
+ uploadProvider, // optional
101
+ }),
102
+ ]
103
+ ```
104
+
105
+ ### StringList
106
+
107
+ Sortable list stored as a single string (comma-separated by default).
108
+
109
+ ```ts
110
+ import { StringListFeature } from "@rulab/adminjs-components";
111
+
112
+ features: [
113
+ StringListFeature({
114
+ key: "facts",
115
+ }),
116
+ ]
117
+ ```
118
+
119
+ ### Tabs
120
+
121
+ Groups edit/show fields into tabs based on property `props.tab` or
122
+ `custom.tab`. Fields without a tab go to a common group.
123
+
124
+ ```ts
125
+ import { TabsFeature } from "@rulab/adminjs-components";
126
+
127
+ features: [
128
+ TabsFeature({
129
+ commonTabLabel: "Common",
130
+ }),
131
+ ]
132
+
133
+ // resource options example
134
+ properties: {
135
+ title: { props: { tab: "Main" } },
136
+ description: { props: { tab: "Main" } },
137
+ seoTitle: { props: { tab: "SEO" } },
138
+ seoDescription: { props: { tab: "SEO" } },
139
+ },
140
+ ```
141
+
142
+ ### Preview
143
+
144
+ Adds a record action that renders an iframe preview. The `url` can include
145
+ template variables like `$id` or `$slug`.
146
+
147
+ ```ts
148
+ import { PreviewFeature } from "@rulab/adminjs-components";
149
+
150
+ features: [
151
+ PreviewFeature({
152
+ url: "https://example.com/posts/$id",
153
+ actionName: "preview", // optional
154
+ }),
155
+ ]
156
+ ```
157
+
158
+ ## Utilities
159
+
160
+ - `setComponentLoader(loader)` and `getComponentLoader()` to reuse a single
161
+ AdminJS `ComponentLoader`.
162
+ - `parseHtml(html)` helper to transform stored Editor.js output into HTML.
@@ -37,7 +37,7 @@ export const EditorFeature = (config) => {
37
37
  size: buffer.length,
38
38
  path: tempPath,
39
39
  };
40
- await fs.writeFile(tempPath, buffer);
40
+ await fs.writeFile(tempPath, new Uint8Array(buffer));
41
41
  try {
42
42
  await uploadProvider.upload(uploadedFile, key, context);
43
43
  }
@@ -5,7 +5,6 @@ import { theme } from "@adminjs/design-system";
5
5
  import { slugifyTitle } from "../../utils/index.js";
6
6
  import { StyledCustomInput, StyledGenerateButton, StyledInputWrapper, StyledLabel, } from "./styles.js";
7
7
  export const SlugEdit = ({ property, record, resource, onChange, }) => {
8
- console.log("✅ SlugEdit loaded", { property });
9
8
  const { params } = record;
10
9
  const { custom } = property;
11
10
  const source = flat.get(params, custom.source);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulab/adminjs-components",
3
- "version": "0.1.0-beta.1",
3
+ "version": "0.1.0",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -18,8 +18,6 @@
18
18
  "lint": "tsc"
19
19
  },
20
20
  "dependencies": {
21
- "@adminjs/design-system": "^4.1.1",
22
- "@adminjs/upload": "^4.0.2",
23
21
  "@dnd-kit/core": "^6.1.0",
24
22
  "@dnd-kit/sortable": "^8.0.0",
25
23
  "@editorjs/editorjs": "2.30.2",
@@ -29,22 +27,34 @@
29
27
  "@editorjs/paragraph": "^2.11.6",
30
28
  "@editorjs/quote": "^2.7.2",
31
29
  "@editorjs/table": "^2.4.1",
32
- "adminjs": "^7.8.1",
33
30
  "chroma-js": "^3.0.0",
34
31
  "editorjs-audio-player": "^0.0.3",
35
32
  "editorjs-html": "^3.4.3",
36
- "react": "^18.2.0",
37
33
  "react-select": "^5.8.0",
38
- "slugify": "^1.6.6",
34
+ "slugify": "^1.6.6"
35
+ },
36
+ "peerDependencies": {
37
+ "@adminjs/design-system": "^4.1.1",
38
+ "@adminjs/upload": "^4.0.2",
39
+ "adminjs": "^7.8.1",
40
+ "react": "^18.2.0",
39
41
  "styled-components": "^6.1.11"
40
42
  },
43
+ "peerDependenciesMeta": {
44
+ "@adminjs/upload": {
45
+ "optional": true
46
+ }
47
+ },
41
48
  "devDependencies": {
49
+ "@adminjs/design-system": "^4.1.1",
50
+ "@adminjs/upload": "^4.0.2",
51
+ "adminjs": "^7.8.1",
42
52
  "@types/chroma-js": "^2.4.4",
43
53
  "@types/node": "^20.11.24",
44
54
  "@types/react": "^18.2.61",
45
- "eslint": "^8.57.0",
46
- "tsc-alias": "^1.8.16",
55
+ "react": "^18.2.0",
47
56
  "tsup": "^8.1.0",
57
+ "styled-components": "^6.1.11",
48
58
  "typescript": "^5.3.2"
49
59
  },
50
60
  "engines": {