datocms-react-ui 1.1.1 → 2.0.1

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.
@@ -1,10 +1,10 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import React, { useEffect, useState } from 'react';
1
+ import React, { useState } from 'react';
3
2
  import { Button, useCtx } from '..';
4
3
  import s from './styles.module.css.json';
4
+ import { manifest } from 'datocms-plugin-sdk';
5
5
 
6
6
  const baseUrl =
7
- 'https://github.com/datocms/plugins-sdk/blob/master/packages/sdk/src/types.ts';
7
+ 'https://github.com/datocms/plugins-sdk/blob/master/packages/sdk/';
8
8
 
9
9
  function copyTextToClipboard(text: string) {
10
10
  const textArea = document.createElement('textarea');
@@ -32,138 +32,12 @@ function copyTextToClipboard(text: string) {
32
32
  document.body.removeChild(textArea);
33
33
  }
34
34
 
35
- function addFinalPeriod(text: string) {
36
- if (['!', '.'].includes(text[text.length - 1])) {
37
- return text;
38
- }
39
-
40
- return `${text}.`;
41
- }
42
-
43
- function findChildrenById(manifest: any, id: string) {
44
- return manifest.children.find((child: any) => child.id === id);
45
- }
46
-
47
- function findShortText(signature: any) {
48
- return (
49
- (signature.comment &&
50
- addFinalPeriod(
51
- signature.comment.summary.map((chunk: any) => chunk.text).join(''),
52
- )) ||
53
- null
54
- );
55
- }
56
-
57
- function findFirstTag(signature: any, tagName: string): string | null {
58
- if (!signature.comment || !signature.comment.blockTags) {
59
- return null;
60
- }
61
-
62
- const tagNode = signature.comment.blockTags.find(
63
- (tag: any) => tag.tag === tagName,
64
- );
65
-
66
- if (!tagNode) {
67
- return null;
68
- }
69
-
70
- return tagNode.content.map((chunk: any) => chunk.text).join('');
71
- }
72
-
73
- function findExample(signature: any) {
74
- const example = findFirstTag(signature, '@example');
75
-
76
- if (!example) {
77
- return null;
78
- }
79
-
80
- const lines = example
81
- .split(/\n/)
82
- .filter((l, i, all) => l.length !== 0 || (i !== 0 && i !== all.length - 1));
83
-
84
- const spacesPerLine = lines.map((line) => {
85
- const spaces = line.match(/^\s*/);
86
- return spaces ? spaces[0].length : 0;
87
- });
88
-
89
- const commonIndentation = Math.min(...spacesPerLine);
90
-
91
- const result = lines
92
- .map((line) => line.substring(commonIndentation))
93
- .join('\n');
94
-
95
- return result.match(/```[a-z]*\n([\s\S]*?)\n```/)?.[1].trim();
96
- }
97
-
98
- function buildCtx(manifest: any, definition: any): any {
99
- if (definition.type.type === 'intersection') {
100
- let result: any[] = [];
101
-
102
- for (const elementInIntersection of definition.type.types) {
103
- if (elementInIntersection.type === 'reference') {
104
- const innerDefinition = findChildrenById(
105
- manifest,
106
- elementInIntersection.id,
107
- );
108
- result = [...result, buildCtx(manifest, innerDefinition)];
109
- }
110
- }
111
-
112
- return result.flat().filter((x) => x);
113
- }
114
-
115
- if (definition.type.type === 'reflection') {
116
- const properties = definition.type.declaration.children.filter(
117
- (child: any) =>
118
- !['mode', 'getSettings', 'setHeight', 'bodyPadding'].includes(
119
- child.name,
120
- ),
121
- );
122
-
123
- if (properties.length === 0) {
124
- return null;
125
- }
126
-
127
- return {
128
- name: definition.name,
129
- description: findShortText(definition),
130
- properties: properties.map((child: any) => {
131
- if (child.type?.declaration?.signatures) {
132
- child.signatures = child.type.declaration.signatures;
133
- }
134
-
135
- if (child.signatures) {
136
- const signature = child.signatures[0];
137
- return {
138
- name: child.name,
139
- type: 'function',
140
- description: findShortText(signature),
141
- example: findExample(signature),
142
- group: definition.name,
143
- lineNumber: child.sources[0].line,
144
- };
145
- }
146
-
147
- return {
148
- name: child.name,
149
- type: 'property',
150
- description: findShortText(child),
151
- example: findExample(child),
152
- groupDescription: findShortText(definition),
153
- group: definition.name,
154
- lineNumber: child.sources[0].line,
155
- };
156
- }),
157
- };
158
- }
159
-
160
- if (definition.type.type === 'reference') {
161
- const innerDefinition = findChildrenById(manifest, definition.type.id);
162
-
163
- return buildCtx(manifest, innerDefinition);
164
- }
165
-
166
- throw new Error(`Don\t know how to handle ${definition}`);
35
+ function capitalize(input: string): string {
36
+ const transformed = input
37
+ .replace(/([A-Z])/g, ' $1')
38
+ .trim()
39
+ .toLowerCase();
40
+ return transformed.charAt(0).toUpperCase() + transformed.slice(1);
167
41
  }
168
42
 
169
43
  const ExpandablePane = ({ children, label }: any) => {
@@ -183,43 +57,10 @@ const ExpandablePane = ({ children, label }: any) => {
183
57
  );
184
58
  };
185
59
 
186
- export function ContextInspector(): JSX.Element {
60
+ export function ContextInspector(): JSX.Element | null {
187
61
  const ctx = useCtx();
188
- const [groups, setGroups] = useState<any[] | null>(null);
189
-
190
- useEffect(() => {
191
- const runner = async () => {
192
- const response = await fetch(
193
- 'https://unpkg.com/datocms-plugin-sdk/types.json',
194
- );
195
- const manifest = await response.json();
196
-
197
- const connectParameters = manifest.children.find(
198
- (child: any) => child.name === 'FullConnectParameters',
199
- );
200
-
201
- const hook = connectParameters.type.declaration.children.find(
202
- (hook: any) => hook.name === (ctx as any).mode,
203
- );
204
-
205
- const signature = hook.signatures
206
- ? hook.signatures[0]
207
- : hook.type.declaration.signatures[0];
208
-
209
- const ctxParameter = signature.parameters.find(
210
- (p: any) => p.name === 'ctx',
211
- );
212
62
 
213
- setGroups(
214
- buildCtx(
215
- manifest,
216
- findChildrenById(manifest, ctxParameter.type.id),
217
- ) as any[],
218
- );
219
- };
220
-
221
- runner();
222
- }, [setGroups]);
63
+ const hook = manifest.hooks[ctx.mode];
223
64
 
224
65
  const handleCopy = (text: string) => {
225
66
  copyTextToClipboard(text);
@@ -244,47 +85,56 @@ export function ContextInspector(): JSX.Element {
244
85
  )()(ctx);
245
86
  };
246
87
 
88
+ if (!hook.ctxArgument) {
89
+ return null;
90
+ }
91
+
92
+ const groups = [
93
+ ...manifest.baseCtx.properties,
94
+ ...(hook.ctxArgument.additionalProperties || []),
95
+ ...manifest.baseCtx.methods,
96
+ ...(hook.ctxArgument.additionalMethods || []),
97
+ ];
98
+
247
99
  return (
248
100
  <div className={s.inspector}>
249
- {groups?.map((group) => {
250
- const name = group.name
251
- .replace('AdditionalMethods', 'Methods')
252
- .replace('AdditionalProperties', 'Properties')
253
- .replace('Methods', ' methods')
254
- .replace('Properties', ' properties')
255
- .replace('Utilities', ' utilities');
256
-
101
+ {groups.map((group) => {
257
102
  return (
258
- <ExpandablePane label={`${name}`} key={name}>
259
- <div className={s.groupDescription}>{group.description}</div>
103
+ <ExpandablePane
104
+ label={group.name ? capitalize(group.name) : 'Other'}
105
+ key={group.name}
106
+ >
260
107
  <div className={s.propertyGroup}>
261
- {(group.properties || []).map((item: any) => (
262
- <div key={item.name} className={s.propertyOrMethod}>
108
+ {group.comment?.comment && (
109
+ <div className={s.groupDescription}>
110
+ {group.comment?.comment}
111
+ </div>
112
+ )}
113
+ {Object.entries(group.items).map(([name, info]) => (
114
+ <div key={name} className={s.propertyOrMethod}>
263
115
  <div className={s.propertyOrMethodBody}>
264
116
  <a
265
117
  className={s.propertyOrMethodName}
266
- href={`${baseUrl}#L${item.lineNumber}`}
118
+ href={`${baseUrl}${info.location.filePath}#L${info.location.lineNumber}`}
267
119
  target="_blank"
268
120
  rel="noreferrer"
269
121
  >
270
- {item.name}
271
- {item.type === 'function' ? '()' : ''}
122
+ {name}
123
+ {info.type.startsWith('(') ? info.type : `: ${info.type}`}
272
124
  </a>
273
125
 
274
- <div>{item.description}</div>
126
+ <div>{info.comment?.comment}</div>
275
127
  </div>
276
- {item.type === 'property' && (
128
+ {!info.type.startsWith('(') && (
277
129
  <div className={s.propertyOrMethodExample}>
278
- <pre>
279
- {JSON.stringify((ctx as any)[item.name], null, 2)}
280
- </pre>
130
+ <pre>{JSON.stringify((ctx as any)[name], null, 2)}</pre>
281
131
  <div className={s.propertyOrMethodExampleActions}>
282
132
  <Button
283
133
  type="button"
284
134
  buttonSize="xxs"
285
135
  onClick={handleCopy.bind(
286
136
  null,
287
- JSON.stringify((ctx as any)[item.name], null, 2),
137
+ JSON.stringify((ctx as any)[name], null, 2),
288
138
  )}
289
139
  >
290
140
  Copy value
@@ -292,22 +142,22 @@ export function ContextInspector(): JSX.Element {
292
142
  </div>
293
143
  </div>
294
144
  )}
295
- {item.example && (
145
+ {info.comment?.example && (
296
146
  <div className={s.propertyOrMethodExample}>
297
- <pre>{item.example}</pre>
147
+ <pre>{info.comment.example}</pre>
298
148
  <div className={s.propertyOrMethodExampleActions}>
299
149
  <Button
300
150
  type="button"
301
151
  buttonSize="xxs"
302
152
  buttonType="primary"
303
- onClick={handleRun.bind(null, item.example)}
153
+ onClick={handleRun.bind(null, info.comment.example)}
304
154
  >
305
155
  Run example
306
156
  </Button>
307
157
  <Button
308
158
  type="button"
309
159
  buttonSize="xxs"
310
- onClick={handleCopy.bind(null, item.example)}
160
+ onClick={handleCopy.bind(null, info.comment.example)}
311
161
  >
312
162
  Copy example
313
163
  </Button>
@@ -1,5 +1,5 @@
1
- import type { RenderProperties } from 'datocms-plugin-sdk';
2
1
  import type { CSSProperties } from 'react';
2
+ import { BaseCtx } from '../Canvas';
3
3
 
4
4
  function camelToDash(str: string) {
5
5
  if (str === str.toLowerCase()) {
@@ -9,7 +9,7 @@ function camelToDash(str: string) {
9
9
  }
10
10
 
11
11
  export function generateStyleFromCtx(
12
- ctx: RenderProperties,
12
+ ctx: BaseCtx,
13
13
  noBodyPadding = false,
14
14
  ): CSSProperties {
15
15
  return {