@tinacms/app 0.0.0-e0ddb8c-20241004065742 → 0.0.0-e1b6d05-20251114052813
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/CHANGELOG.md +265 -11
- package/index.html +1 -1
- package/package.json +12 -8
- package/src/App.tsx +24 -24
- package/src/Playground.tsx +56 -58
- package/src/dummy-client.ts +1 -1
- package/src/fields/rich-text/index.tsx +2 -2
- package/src/fields/rich-text/monaco/error-message.tsx +59 -59
- package/src/fields/rich-text/monaco/index.tsx +68 -74
- package/src/fields/rich-text/monaco/use-debounce.ts +8 -8
- package/src/global.css +3 -3
- package/src/index.css +24 -15
- package/src/lib/build-form.ts +24 -24
- package/src/lib/errors.tsx +7 -7
- package/src/lib/expand-query.ts +74 -69
- package/src/lib/graphql-reducer.ts +303 -276
- package/src/lib/types.ts +35 -33
- package/src/lib/util.ts +48 -53
- package/src/main.tsx +7 -7
- package/src/preflight.css +10 -10
- package/src/preview.tsx +12 -12
- package/src/vite-env.d.ts +3 -3
package/src/dummy-client.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const queries = false
|
|
1
|
+
export const queries = false;
|
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*/
|
|
6
|
-
import React from 'react'
|
|
7
|
-
import { XCircleIcon } from '@heroicons/react/solid'
|
|
8
1
|
import {
|
|
9
2
|
Popover,
|
|
10
3
|
PopoverButton,
|
|
11
4
|
PopoverPanel,
|
|
12
5
|
Transition,
|
|
13
|
-
} from '@headlessui/react'
|
|
14
|
-
import {
|
|
6
|
+
} from '@headlessui/react';
|
|
7
|
+
import { XCircleIcon } from '@heroicons/react/solid';
|
|
8
|
+
/**
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
*/
|
|
13
|
+
import React from 'react';
|
|
14
|
+
import { Fragment } from 'react';
|
|
15
15
|
// import { InvalidMarkdownElement } from '@tinacms/mdx/src/parse/plate'
|
|
16
|
-
export type EmptyTextElement = { type: 'text'; text: '' }
|
|
16
|
+
export type EmptyTextElement = { type: 'text'; text: '' };
|
|
17
17
|
export type PositionItem = {
|
|
18
|
-
line?: number | null
|
|
19
|
-
column?: number | null
|
|
20
|
-
offset?: number | null
|
|
21
|
-
_index?: number | null
|
|
22
|
-
_bufferIndex?: number | null
|
|
23
|
-
}
|
|
18
|
+
line?: number | null;
|
|
19
|
+
column?: number | null;
|
|
20
|
+
offset?: number | null;
|
|
21
|
+
_index?: number | null;
|
|
22
|
+
_bufferIndex?: number | null;
|
|
23
|
+
};
|
|
24
24
|
export type Position = {
|
|
25
|
-
start: PositionItem
|
|
26
|
-
end: PositionItem
|
|
27
|
-
}
|
|
25
|
+
start: PositionItem;
|
|
26
|
+
end: PositionItem;
|
|
27
|
+
};
|
|
28
28
|
export type InvalidMarkdownElement = {
|
|
29
|
-
type: 'invalid_markdown'
|
|
30
|
-
value: string
|
|
31
|
-
message: string
|
|
32
|
-
position?: Position
|
|
33
|
-
children: [EmptyTextElement]
|
|
34
|
-
}
|
|
29
|
+
type: 'invalid_markdown';
|
|
30
|
+
value: string;
|
|
31
|
+
message: string;
|
|
32
|
+
position?: Position;
|
|
33
|
+
children: [EmptyTextElement];
|
|
34
|
+
};
|
|
35
35
|
|
|
36
36
|
type ErrorType = {
|
|
37
|
-
message: string
|
|
37
|
+
message: string;
|
|
38
38
|
position?: {
|
|
39
|
-
startColumn: number
|
|
40
|
-
endColumn: number
|
|
41
|
-
startLineNumber: number
|
|
42
|
-
endLineNumber: number
|
|
43
|
-
}
|
|
44
|
-
}
|
|
39
|
+
startColumn: number;
|
|
40
|
+
endColumn: number;
|
|
41
|
+
startLineNumber: number;
|
|
42
|
+
endLineNumber: number;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
45
|
export const buildError = (element: InvalidMarkdownElement): ErrorType => {
|
|
46
46
|
return {
|
|
47
47
|
message: element.message,
|
|
@@ -51,28 +51,28 @@ export const buildError = (element: InvalidMarkdownElement): ErrorType => {
|
|
|
51
51
|
startLineNumber: element.position.start.line,
|
|
52
52
|
endLineNumber: element.position.end.line,
|
|
53
53
|
},
|
|
54
|
-
}
|
|
55
|
-
}
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
56
|
export const buildErrorMessage = (element: InvalidMarkdownElement): string => {
|
|
57
57
|
if (!element) {
|
|
58
|
-
return ''
|
|
58
|
+
return '';
|
|
59
59
|
}
|
|
60
|
-
const errorMessage = buildError(element)
|
|
60
|
+
const errorMessage = buildError(element);
|
|
61
61
|
const message = errorMessage
|
|
62
62
|
? `${errorMessage.message}${
|
|
63
63
|
errorMessage.position
|
|
64
64
|
? ` at line: ${errorMessage.position.startLineNumber}, column: ${errorMessage.position.startColumn}`
|
|
65
65
|
: ''
|
|
66
66
|
}`
|
|
67
|
-
: null
|
|
68
|
-
return message
|
|
69
|
-
}
|
|
67
|
+
: null;
|
|
68
|
+
return message;
|
|
69
|
+
};
|
|
70
70
|
|
|
71
71
|
export function ErrorMessage({ error }: { error: InvalidMarkdownElement }) {
|
|
72
|
-
const message = buildErrorMessage(error)
|
|
72
|
+
const message = buildErrorMessage(error);
|
|
73
73
|
|
|
74
74
|
return (
|
|
75
|
-
<Popover className=
|
|
75
|
+
<Popover className='relative'>
|
|
76
76
|
{() => (
|
|
77
77
|
<>
|
|
78
78
|
<PopoverButton
|
|
@@ -80,29 +80,29 @@ export function ErrorMessage({ error }: { error: InvalidMarkdownElement }) {
|
|
|
80
80
|
error ? '' : ' opacity-0 hidden '
|
|
81
81
|
}`}
|
|
82
82
|
>
|
|
83
|
-
<span className=
|
|
84
|
-
<XCircleIcon className=
|
|
83
|
+
<span className='sr-only'>Errors</span>
|
|
84
|
+
<XCircleIcon className='h-5 w-5 text-red-400' aria-hidden='true' />
|
|
85
85
|
</PopoverButton>
|
|
86
86
|
<Transition
|
|
87
|
-
enter=
|
|
88
|
-
enterFrom=
|
|
89
|
-
enterTo=
|
|
90
|
-
leave=
|
|
91
|
-
leaveFrom=
|
|
92
|
-
leaveTo=
|
|
87
|
+
enter='transition ease-out duration-200'
|
|
88
|
+
enterFrom='opacity-0 translate-y-1'
|
|
89
|
+
enterTo='opacity-100 translate-y-0'
|
|
90
|
+
leave='transition ease-in duration-150'
|
|
91
|
+
leaveFrom='opacity-100 translate-y-0'
|
|
92
|
+
leaveTo='opacity-0 translate-y-1'
|
|
93
93
|
>
|
|
94
|
-
<PopoverPanel className=
|
|
95
|
-
<div className=
|
|
96
|
-
<div className=
|
|
97
|
-
<div className=
|
|
98
|
-
<div className=
|
|
94
|
+
<PopoverPanel className='absolute top-8 w-[300px] -right-3 z-10 mt-3 px-4 sm:px-0'>
|
|
95
|
+
<div className='overflow-hidden rounded-lg shadow-lg ring-1 ring-black ring-opacity-5'>
|
|
96
|
+
<div className='rounded bg-red-50 p-4 overflow-scroll'>
|
|
97
|
+
<div className='flex'>
|
|
98
|
+
<div className='flex-shrink-0'>
|
|
99
99
|
<XCircleIcon
|
|
100
|
-
className=
|
|
101
|
-
aria-hidden=
|
|
100
|
+
className='h-5 w-5 text-red-400'
|
|
101
|
+
aria-hidden='true'
|
|
102
102
|
/>
|
|
103
103
|
</div>
|
|
104
|
-
<div className=
|
|
105
|
-
<h3 className=
|
|
104
|
+
<div className='ml-3'>
|
|
105
|
+
<h3 className='text-sm font-medium text-red-800 whitespace-pre-wrap'>
|
|
106
106
|
{message}
|
|
107
107
|
</h3>
|
|
108
108
|
</div>
|
|
@@ -114,5 +114,5 @@ export function ErrorMessage({ error }: { error: InvalidMarkdownElement }) {
|
|
|
114
114
|
</>
|
|
115
115
|
)}
|
|
116
116
|
</Popover>
|
|
117
|
-
)
|
|
117
|
+
);
|
|
118
118
|
}
|
|
@@ -1,26 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React from 'react'
|
|
8
|
-
import MonacoEditor, { useMonaco, loader } from '@monaco-editor/react'
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import MonacoEditor, { useMonaco, loader } from '@monaco-editor/react';
|
|
9
3
|
/**
|
|
10
4
|
* MDX is built directly to the app because of how we load dependencies.
|
|
11
5
|
* Since we drop the package.json in to the end users folder, we can't
|
|
12
6
|
* easily install the current version of the mdx package in all scenarios
|
|
13
7
|
* (when we're working in the monorepo, or working with a tagged npm version)
|
|
14
8
|
*/
|
|
15
|
-
import { parseMDX,
|
|
16
|
-
import
|
|
17
|
-
import
|
|
9
|
+
import { parseMDX, serializeMDX } from '@tinacms/mdx';
|
|
10
|
+
import type * as monaco from 'monaco-editor';
|
|
11
|
+
import { RichTextType } from 'tinacms';
|
|
18
12
|
import {
|
|
19
|
-
buildError,
|
|
20
13
|
ErrorMessage,
|
|
21
14
|
InvalidMarkdownElement,
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
buildError,
|
|
16
|
+
} from './error-message';
|
|
17
|
+
import { useDebounce } from './use-debounce';
|
|
24
18
|
|
|
25
19
|
export const uuid = () => {
|
|
26
20
|
// @ts-ignore
|
|
@@ -29,15 +23,10 @@ export const uuid = () => {
|
|
|
29
23
|
c ^
|
|
30
24
|
(crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
|
|
31
25
|
).toString(16)
|
|
32
|
-
)
|
|
33
|
-
}
|
|
26
|
+
);
|
|
27
|
+
};
|
|
34
28
|
|
|
35
|
-
type Monaco = typeof monaco
|
|
36
|
-
|
|
37
|
-
// 0.33.0 has a bug https://github.com/microsoft/monaco-editor/issues/2947
|
|
38
|
-
loader.config({
|
|
39
|
-
paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.31.1/min/vs' },
|
|
40
|
-
})
|
|
29
|
+
type Monaco = typeof monaco;
|
|
41
30
|
|
|
42
31
|
/**
|
|
43
32
|
* Since monaco lazy-loads we may have a delay from when the block is inserted
|
|
@@ -45,81 +34,81 @@ loader.config({
|
|
|
45
34
|
*
|
|
46
35
|
* Will try for 3 seconds before moving on
|
|
47
36
|
*/
|
|
48
|
-
let retryCount = 0
|
|
37
|
+
let retryCount = 0;
|
|
49
38
|
const retryFocus = (ref) => {
|
|
50
39
|
if (ref.current) {
|
|
51
|
-
ref.current.focus()
|
|
40
|
+
ref.current.focus();
|
|
52
41
|
} else {
|
|
53
42
|
if (retryCount < 30) {
|
|
54
43
|
setTimeout(() => {
|
|
55
|
-
retryCount = retryCount + 1
|
|
56
|
-
retryFocus(ref)
|
|
57
|
-
}, 100)
|
|
44
|
+
retryCount = retryCount + 1;
|
|
45
|
+
retryFocus(ref);
|
|
46
|
+
}, 100);
|
|
58
47
|
}
|
|
59
48
|
}
|
|
60
|
-
}
|
|
49
|
+
};
|
|
61
50
|
|
|
62
51
|
export const RawEditor = (props: RichTextType) => {
|
|
63
|
-
const monaco = useMonaco() as Monaco
|
|
52
|
+
const monaco = useMonaco() as Monaco;
|
|
64
53
|
const monacoEditorRef =
|
|
65
|
-
React.useRef<monaco.editor.IStandaloneCodeEditor>(null)
|
|
66
|
-
const [height, setHeight] = React.useState(100)
|
|
67
|
-
const id = React.useMemo(() => uuid(), [])
|
|
68
|
-
const field = props.field
|
|
54
|
+
React.useRef<monaco.editor.IStandaloneCodeEditor>(null);
|
|
55
|
+
const [height, setHeight] = React.useState(100);
|
|
56
|
+
const id = React.useMemo(() => uuid(), []);
|
|
57
|
+
const field = props.field;
|
|
69
58
|
const inputValue = React.useMemo(() => {
|
|
70
59
|
// @ts-ignore no access to the rich-text type from this package
|
|
71
|
-
const res =
|
|
72
|
-
return typeof props.input.value === 'string' ? props.input.value : res
|
|
73
|
-
}, [])
|
|
74
|
-
const [value, setValue] = React.useState(inputValue)
|
|
75
|
-
const [error, setError] = React.useState<InvalidMarkdownElement>(null)
|
|
60
|
+
const res = serializeMDX(props.input.value, field, (value) => value);
|
|
61
|
+
return typeof props.input.value === 'string' ? props.input.value : res;
|
|
62
|
+
}, []);
|
|
63
|
+
const [value, setValue] = React.useState(inputValue);
|
|
64
|
+
const [error, setError] = React.useState<InvalidMarkdownElement>(null);
|
|
76
65
|
|
|
77
|
-
const debouncedValue = useDebounce(value, 500)
|
|
66
|
+
const debouncedValue = useDebounce(value, 500);
|
|
78
67
|
|
|
79
68
|
React.useEffect(() => {
|
|
80
69
|
// @ts-ignore no access to the rich-text type from this package
|
|
81
|
-
const parsedValue = parseMDX(value, field, (value) => value)
|
|
70
|
+
const parsedValue = parseMDX(value, field, (value) => value);
|
|
82
71
|
if (
|
|
83
72
|
parsedValue.children[0] &&
|
|
84
73
|
parsedValue.children[0].type === 'invalid_markdown'
|
|
85
74
|
) {
|
|
86
|
-
const invalidMarkdown = parsedValue.children[0]
|
|
87
|
-
setError(invalidMarkdown)
|
|
75
|
+
const invalidMarkdown = parsedValue.children[0];
|
|
76
|
+
setError(invalidMarkdown);
|
|
88
77
|
} else {
|
|
89
|
-
setError(null)
|
|
78
|
+
setError(null);
|
|
90
79
|
}
|
|
91
|
-
props.input.onChange(parsedValue)
|
|
92
|
-
}, [JSON.stringify(debouncedValue)])
|
|
80
|
+
props.input.onChange(parsedValue);
|
|
81
|
+
}, [JSON.stringify(debouncedValue)]);
|
|
93
82
|
|
|
94
83
|
React.useEffect(() => {
|
|
95
84
|
if (monacoEditorRef.current) {
|
|
96
85
|
if (error) {
|
|
97
|
-
const errorMessage = buildError(error)
|
|
86
|
+
const errorMessage = buildError(error);
|
|
98
87
|
monaco.editor.setModelMarkers(monacoEditorRef.current.getModel(), id, [
|
|
99
88
|
{
|
|
100
89
|
...errorMessage.position,
|
|
101
90
|
message: errorMessage.message,
|
|
102
91
|
severity: 8,
|
|
103
92
|
},
|
|
104
|
-
])
|
|
93
|
+
]);
|
|
105
94
|
} else {
|
|
106
95
|
monaco.editor.setModelMarkers(
|
|
107
96
|
monacoEditorRef.current.getModel(),
|
|
108
97
|
id,
|
|
109
98
|
[]
|
|
110
|
-
)
|
|
99
|
+
);
|
|
111
100
|
}
|
|
112
101
|
}
|
|
113
|
-
}, [JSON.stringify(error), monacoEditorRef.current])
|
|
102
|
+
}, [JSON.stringify(error), monacoEditorRef.current]);
|
|
114
103
|
|
|
115
104
|
React.useEffect(() => {
|
|
116
105
|
if (monaco) {
|
|
117
|
-
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true)
|
|
106
|
+
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);
|
|
118
107
|
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
|
|
119
108
|
// disable errors
|
|
120
109
|
noSemanticValidation: true,
|
|
121
110
|
noSyntaxValidation: true,
|
|
122
|
-
})
|
|
111
|
+
});
|
|
123
112
|
// TODO: autocomplete suggestions
|
|
124
113
|
// monaco.languages.registerCompletionItemProvider('markdown', {
|
|
125
114
|
// provideCompletionItems: function (model, position) {
|
|
@@ -143,24 +132,28 @@ export const RawEditor = (props: RichTextType) => {
|
|
|
143
132
|
// },
|
|
144
133
|
// })
|
|
145
134
|
}
|
|
146
|
-
}, [monaco])
|
|
135
|
+
}, [monaco]);
|
|
147
136
|
|
|
148
137
|
function handleEditorDidMount(
|
|
149
138
|
monacoEditor: monaco.editor.IStandaloneCodeEditor,
|
|
150
139
|
monaco: Monaco
|
|
151
140
|
) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
141
|
+
if (monacoEditor) {
|
|
142
|
+
monacoEditorRef.current = monacoEditor;
|
|
143
|
+
monacoEditor.onDidContentSizeChange(() => {
|
|
144
|
+
// FIXME: if the window is too tall the performance degrades, come up with a nice
|
|
145
|
+
// balance between the two
|
|
146
|
+
setHeight(
|
|
147
|
+
Math.min(Math.max(100, monacoEditor.getContentHeight()), 1000)
|
|
148
|
+
);
|
|
149
|
+
monacoEditor.layout();
|
|
150
|
+
});
|
|
151
|
+
}
|
|
159
152
|
}
|
|
160
153
|
|
|
161
154
|
return (
|
|
162
|
-
<div className=
|
|
163
|
-
<div className=
|
|
155
|
+
<div className='relative'>
|
|
156
|
+
<div className='sticky top-1 w-full flex justify-between mb-2 z-50 max-w-full bg-white'>
|
|
164
157
|
<Button onClick={() => props.setRawMode(false)}>
|
|
165
158
|
View in rich-text editor 📝
|
|
166
159
|
</Button>
|
|
@@ -168,6 +161,9 @@ export const RawEditor = (props: RichTextType) => {
|
|
|
168
161
|
</div>
|
|
169
162
|
<div style={{ height: `${height}px` }}>
|
|
170
163
|
<MonacoEditor
|
|
164
|
+
beforeMount={() => {}}
|
|
165
|
+
height='100%'
|
|
166
|
+
width='100%'
|
|
171
167
|
path={id}
|
|
172
168
|
onMount={handleEditorDidMount}
|
|
173
169
|
// Setting a custom theme is kind of buggy because it doesn't get defined until monaco has mounted.
|
|
@@ -204,33 +200,31 @@ export const RawEditor = (props: RichTextType) => {
|
|
|
204
200
|
value={value}
|
|
205
201
|
onChange={(value) => {
|
|
206
202
|
try {
|
|
207
|
-
setValue(value)
|
|
203
|
+
setValue(value);
|
|
208
204
|
} catch (e) {
|
|
209
|
-
console.log('error', e)
|
|
205
|
+
console.log('error', e);
|
|
210
206
|
}
|
|
211
207
|
}}
|
|
212
208
|
/>
|
|
213
209
|
</div>
|
|
214
210
|
</div>
|
|
215
|
-
)
|
|
216
|
-
}
|
|
211
|
+
);
|
|
212
|
+
};
|
|
217
213
|
|
|
218
214
|
const Button = (props) => {
|
|
219
215
|
return (
|
|
220
216
|
<button
|
|
221
217
|
className={`${
|
|
222
|
-
props.align === 'left'
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
} flex justify-center w-full shadow rounded-md bg-white cursor-pointer relative inline-flex items-center px-2 py-2 border border-gray-200 hover:text-white text-sm font-medium transition-all ease-out duration-150 hover:bg-blue-500 focus:z-10 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500`}
|
|
226
|
-
type="button"
|
|
218
|
+
props.align === 'left' ? 'rounded-l border-r-0' : 'rounded-r border-l-0'
|
|
219
|
+
} flex justify-center w-full shadow rounded bg-white cursor-pointer relative inline-flex items-center px-2 py-2 border border-gray-200 hover:text-white text-sm font-medium transition-all ease-out duration-150 hover:bg-blue-500 focus:z-10 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500`}
|
|
220
|
+
type='button'
|
|
227
221
|
onClick={props.onClick}
|
|
228
222
|
>
|
|
229
|
-
<span className=
|
|
223
|
+
<span className='text-sm font-semibold tracking-wide align-baseline mr-1'>
|
|
230
224
|
{props.children}
|
|
231
225
|
</span>
|
|
232
226
|
</button>
|
|
233
|
-
)
|
|
234
|
-
}
|
|
227
|
+
);
|
|
228
|
+
};
|
|
235
229
|
|
|
236
|
-
export default RawEditor
|
|
230
|
+
export default RawEditor;
|
|
@@ -3,23 +3,23 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
*/
|
|
6
|
-
import { useState, useEffect } from 'react'
|
|
6
|
+
import { useState, useEffect } from 'react';
|
|
7
7
|
export function useDebounce(value, delay) {
|
|
8
|
-
const [debouncedValue, setDebouncedValue] = useState(value)
|
|
8
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
9
9
|
useEffect(
|
|
10
10
|
() => {
|
|
11
11
|
// Update debounced value after delay
|
|
12
12
|
const handler = setTimeout(() => {
|
|
13
|
-
setDebouncedValue(value)
|
|
14
|
-
}, delay)
|
|
13
|
+
setDebouncedValue(value);
|
|
14
|
+
}, delay);
|
|
15
15
|
// Cancel the timeout if value changes (also on delay change or unmount)
|
|
16
16
|
// This is how we prevent debounced value from updating if value is changed ...
|
|
17
17
|
// .. within the delay period. Timeout gets cleared and restarted.
|
|
18
18
|
return () => {
|
|
19
|
-
clearTimeout(handler)
|
|
20
|
-
}
|
|
19
|
+
clearTimeout(handler);
|
|
20
|
+
};
|
|
21
21
|
},
|
|
22
22
|
[value, delay] // Only re-call effect if value or delay changes
|
|
23
|
-
)
|
|
24
|
-
return debouncedValue
|
|
23
|
+
);
|
|
24
|
+
return debouncedValue;
|
|
25
25
|
}
|
package/src/global.css
CHANGED
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
--tina-font-size-7: 26px;
|
|
41
41
|
--tina-font-size-8: 32px;
|
|
42
42
|
|
|
43
|
-
--tina-font-family:
|
|
43
|
+
--tina-font-family: "Inter", sans-serif;
|
|
44
44
|
|
|
45
45
|
--tina-font-weight-regular: 400;
|
|
46
46
|
--tina-font-weight-bold: 600;
|
|
47
47
|
|
|
48
|
-
--tina-shadow-big: 0px 2px 3px rgba(0, 0, 0, 0.05),
|
|
49
|
-
|
|
48
|
+
--tina-shadow-big: 0px 2px 3px rgba(0, 0, 0, 0.05), 0 4px 12px
|
|
49
|
+
rgba(0, 0, 0, 0.1);
|
|
50
50
|
--tina-shadow-small: 0px 2px 3px rgba(0, 0, 0, 0.12);
|
|
51
51
|
|
|
52
52
|
--tina-timing-short: 85ms;
|
package/src/index.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
@import
|
|
2
|
-
@import
|
|
1
|
+
@import "global.css";
|
|
2
|
+
@import "preflight.css";
|
|
3
3
|
@tailwind base;
|
|
4
4
|
@tailwind components;
|
|
5
5
|
@tailwind utilities;
|
|
@@ -13,18 +13,22 @@
|
|
|
13
13
|
fill: currentColor;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
.font-libre-baskerville {
|
|
17
|
+
font-family: "Libre Baskerville", serif;
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
body {
|
|
17
21
|
margin: 0;
|
|
18
22
|
padding: 0;
|
|
19
|
-
font-family: -apple-system, BlinkMacSystemFont,
|
|
20
|
-
|
|
23
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
|
24
|
+
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
|
21
25
|
sans-serif;
|
|
22
26
|
-webkit-font-smoothing: antialiased;
|
|
23
27
|
-moz-osx-font-smoothing: grayscale;
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
code {
|
|
27
|
-
font-family: source-code-pro, Menlo, Monaco, Consolas,
|
|
31
|
+
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
|
28
32
|
monospace;
|
|
29
33
|
}
|
|
30
34
|
|
|
@@ -38,32 +42,32 @@ div.graphiql-explorer-root > div:last-child {
|
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
/* if the last block has margin-bottom it makes the text box larger but some of it isn't clickable */
|
|
41
|
-
.tina-prose [data-slate-editor=
|
|
45
|
+
.tina-prose [data-slate-editor="true"] {
|
|
42
46
|
padding-bottom: 0.5em;
|
|
43
47
|
/* Outline is placed on the parent element for styling consistency with other elements */
|
|
44
48
|
outline: none;
|
|
45
49
|
}
|
|
46
50
|
/* prose adds backticks, which look like they should be editable */
|
|
47
|
-
.tina-prose [data-slate-editor=
|
|
48
|
-
content:
|
|
51
|
+
.tina-prose [data-slate-editor="true"] .slate-code::before {
|
|
52
|
+
content: "";
|
|
49
53
|
}
|
|
50
|
-
.tina-prose [data-slate-editor=
|
|
51
|
-
content:
|
|
54
|
+
.tina-prose [data-slate-editor="true"] .slate-code::after {
|
|
55
|
+
content: "";
|
|
52
56
|
}
|
|
53
|
-
.tina-prose [data-slate-editor=
|
|
57
|
+
.tina-prose [data-slate-editor="true"] .slate-code_block {
|
|
54
58
|
margin: 0;
|
|
55
59
|
}
|
|
56
60
|
/* code lines as part of a block don't need the same background formatting */
|
|
57
|
-
.tina-prose [data-slate-editor=
|
|
61
|
+
.tina-prose [data-slate-editor="true"] .slate-code_block .slate-code {
|
|
58
62
|
background: none;
|
|
59
63
|
}
|
|
60
64
|
/* prose makes the first p in a block slightly larger */
|
|
61
|
-
.tina-prose [data-slate-editor=
|
|
65
|
+
.tina-prose [data-slate-editor="true"] p:first-of-type {
|
|
62
66
|
font-size: 1em;
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
/* experimental floating toolbar doesn't need a large text area */
|
|
66
|
-
.with-toolbar [data-slate-editor=
|
|
70
|
+
.with-toolbar [data-slate-editor="true"] {
|
|
67
71
|
min-height: 72px;
|
|
68
72
|
}
|
|
69
73
|
|
|
@@ -190,7 +194,7 @@ div.graphiql-explorer-root > div:last-child {
|
|
|
190
194
|
}
|
|
191
195
|
|
|
192
196
|
.tina-date-field .rdtPicker td.rdtToday:before {
|
|
193
|
-
content:
|
|
197
|
+
content: "";
|
|
194
198
|
display: inline-block;
|
|
195
199
|
border-left: 7px solid transparent;
|
|
196
200
|
border-bottom: 7px solid var(--tina-color-primary);
|
|
@@ -382,3 +386,8 @@ td.rdtYear:hover {
|
|
|
382
386
|
.tina-date-field .rdtTime td {
|
|
383
387
|
cursor: default;
|
|
384
388
|
}
|
|
389
|
+
|
|
390
|
+
/* Override Radix UI Portal wrapper z-index for dropdown menus */
|
|
391
|
+
[data-radix-popper-content-wrapper] {
|
|
392
|
+
z-index: 10800 !important;
|
|
393
|
+
}
|
package/src/lib/build-form.ts
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import { Field, Form, FormOptions, TinaCMS, TinaField } from 'tinacms'
|
|
1
|
+
import { Field, Form, FormOptions, TinaCMS, TinaField } from 'tinacms';
|
|
2
2
|
|
|
3
|
-
export type FieldType = Field & TinaField
|
|
4
|
-
export type FormValues = Record<string, unknown
|
|
5
|
-
export type FormType = Form<FormValues, FieldType
|
|
3
|
+
export type FieldType = Field & TinaField;
|
|
4
|
+
export type FormValues = Record<string, unknown>;
|
|
5
|
+
export type FormType = Form<FormValues, FieldType>;
|
|
6
6
|
|
|
7
|
-
type FormCreator = (formConfig: FormOptions<any>) => Form
|
|
7
|
+
type FormCreator = (formConfig: FormOptions<any>) => Form;
|
|
8
8
|
interface GlobalFormOptions {
|
|
9
|
-
icon?: any
|
|
10
|
-
layout: 'fullscreen' | 'popup'
|
|
9
|
+
icon?: any;
|
|
10
|
+
layout: 'fullscreen' | 'popup';
|
|
11
11
|
}
|
|
12
12
|
type GlobalFormCreator = (
|
|
13
13
|
formConfig: FormOptions<any>,
|
|
14
14
|
options?: GlobalFormOptions
|
|
15
|
-
) => Form
|
|
15
|
+
) => Form;
|
|
16
16
|
interface GlobalFormOptions {
|
|
17
|
-
icon?: any
|
|
18
|
-
layout: 'fullscreen' | 'popup'
|
|
17
|
+
icon?: any;
|
|
18
|
+
layout: 'fullscreen' | 'popup';
|
|
19
19
|
}
|
|
20
20
|
export interface FormifyArgs {
|
|
21
|
-
formConfig: FormOptions<any
|
|
22
|
-
createForm: FormCreator
|
|
23
|
-
createGlobalForm: FormCreator
|
|
24
|
-
skip?: () => void
|
|
21
|
+
formConfig: FormOptions<any>;
|
|
22
|
+
createForm: FormCreator;
|
|
23
|
+
createGlobalForm: FormCreator;
|
|
24
|
+
skip?: () => void;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export type FormifyCallback = (args: FormifyArgs, cms: TinaCMS) => Form | void
|
|
27
|
+
export type FormifyCallback = (args: FormifyArgs, cms: TinaCMS) => Form | void;
|
|
28
28
|
export type onSubmitArgs = {
|
|
29
29
|
/**
|
|
30
30
|
* @deprecated queryString is actually a mutation string, use `mutationString` instead
|
|
31
31
|
*/
|
|
32
|
-
queryString: string
|
|
33
|
-
mutationString: string
|
|
34
|
-
variables: object
|
|
35
|
-
}
|
|
32
|
+
queryString: string;
|
|
33
|
+
mutationString: string;
|
|
34
|
+
variables: object;
|
|
35
|
+
};
|
|
36
36
|
|
|
37
37
|
export const createForm = (formConfig: FormOptions<any, any>) => {
|
|
38
|
-
return new Form(formConfig)
|
|
39
|
-
}
|
|
38
|
+
return new Form(formConfig);
|
|
39
|
+
};
|
|
40
40
|
export const createGlobalForm: GlobalFormCreator = (
|
|
41
41
|
formConfig,
|
|
42
42
|
options?: { icon?: any; layout: 'fullscreen' | 'popup' }
|
|
@@ -44,6 +44,6 @@ export const createGlobalForm: GlobalFormCreator = (
|
|
|
44
44
|
const form = new Form({
|
|
45
45
|
...formConfig,
|
|
46
46
|
global: { global: true, ...options },
|
|
47
|
-
})
|
|
48
|
-
return form
|
|
49
|
-
}
|
|
47
|
+
});
|
|
48
|
+
return form;
|
|
49
|
+
};
|