parent
6e9e5c53ef
commit
13d30beba0
@ -15,10 +15,6 @@
|
|||||||
content:
|
content:
|
||||||
'{\n"title": "This is a JSON front matter post",\n"image": "/nf-logo.png",\n"date": "2015-02-15T00:00:00.000Z"\n}\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n',
|
'{\n"title": "This is a JSON front matter post",\n"image": "/nf-logo.png",\n"date": "2015-02-15T00:00:00.000Z"\n}\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n',
|
||||||
},
|
},
|
||||||
'2015-02-16-this-is-a-toml-frontmatter-post.md': {
|
|
||||||
content:
|
|
||||||
'+++\ntitle = "This is a TOML front matter post"\nimage = "/nf-logo.png"\n"date" = "2015-02-16T00:00:00.000Z"\n+++\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n',
|
|
||||||
},
|
|
||||||
'2015-02-14-this-is-a-post-with-a-different-extension.other': {
|
'2015-02-14-this-is-a-post-with-a-different-extension.other': {
|
||||||
content:
|
content:
|
||||||
'---\ntitle: This post should not appear because the extension is different\nimage: /nf-logo.png\ndate: 2015-02-14T00:00:00.000Z\n---\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n',
|
'---\ntitle: This post should not appear because the extension is different\nimage: /nf-logo.png\ndate: 2015-02-14T00:00:00.000Z\n---\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@staticcms/core",
|
"name": "@staticcms/core",
|
||||||
"version": "1.0.0-alpha33",
|
"version": "1.0.0-alpha34",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "Static CMS core application.",
|
"description": "Static CMS core application.",
|
||||||
"repository": "https://github.com/StaticJsCMS/static-cms",
|
"repository": "https://github.com/StaticJsCMS/static-cms",
|
||||||
@ -27,12 +27,10 @@
|
|||||||
"type-check": "tsc --watch"
|
"type-check": "tsc --watch"
|
||||||
},
|
},
|
||||||
"main": "dist/static-cms-core.js",
|
"main": "dist/static-cms-core.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
"files": [
|
"files": [
|
||||||
"src/",
|
"dist/**/*"
|
||||||
"dist/",
|
|
||||||
"index.d.ts"
|
|
||||||
],
|
],
|
||||||
"types": "index.d.ts",
|
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"last 2 Chrome versions",
|
"last 2 Chrome versions",
|
||||||
"last 2 ChromeAndroid versions",
|
"last 2 ChromeAndroid versions",
|
||||||
@ -47,7 +45,6 @@
|
|||||||
"@emotion/css": "11.10.0",
|
"@emotion/css": "11.10.0",
|
||||||
"@emotion/react": "11.10.4",
|
"@emotion/react": "11.10.4",
|
||||||
"@emotion/styled": "11.10.4",
|
"@emotion/styled": "11.10.4",
|
||||||
"@iarna/toml": "2.2.5",
|
|
||||||
"@mui/icons-material": "5.10.6",
|
"@mui/icons-material": "5.10.6",
|
||||||
"@mui/material": "5.10.10",
|
"@mui/material": "5.10.10",
|
||||||
"@mui/system": "5.4.1",
|
"@mui/system": "5.4.1",
|
||||||
@ -111,7 +108,6 @@
|
|||||||
"semaphore": "1.1.0",
|
"semaphore": "1.1.0",
|
||||||
"stream-browserify": "3.0.0",
|
"stream-browserify": "3.0.0",
|
||||||
"symbol-observable": "4.0.0",
|
"symbol-observable": "4.0.0",
|
||||||
"tomlify-j0.4": "3.0.0",
|
|
||||||
"ts-loader": "9.4.1",
|
"ts-loader": "9.4.1",
|
||||||
"uploadcare-widget": "3.19.0",
|
"uploadcare-widget": "3.19.0",
|
||||||
"uploadcare-widget-tab-effects": "1.5.0",
|
"uploadcare-widget-tab-effects": "1.5.0",
|
||||||
|
@ -96,54 +96,56 @@ const Sidebar = ({
|
|||||||
const additionalLinks = useMemo(() => getAdditionalLinks(), []);
|
const additionalLinks = useMemo(() => getAdditionalLinks(), []);
|
||||||
const links = useMemo(
|
const links = useMemo(
|
||||||
() =>
|
() =>
|
||||||
Object.values(additionalLinks).map(({ id, title, data, options: { iconName } = {} }) => {
|
Object.values(additionalLinks).map(
|
||||||
let icon: ReactNode = <ArticleIcon />;
|
({ id, title, data, options: { icon: iconName } = {} }) => {
|
||||||
if (iconName) {
|
let icon: ReactNode = <ArticleIcon />;
|
||||||
const StoredIcon = getIcon(iconName);
|
if (iconName) {
|
||||||
if (StoredIcon) {
|
const StoredIcon = getIcon(iconName);
|
||||||
icon = <StoredIcon />;
|
if (StoredIcon) {
|
||||||
|
icon = <StoredIcon />;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
<>
|
<>
|
||||||
<StyledListItemIcon>{icon}</StyledListItemIcon>
|
<StyledListItemIcon>{icon}</StyledListItemIcon>
|
||||||
<ListItemText primary={title} />
|
<ListItemText primary={title} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
return typeof data === 'string' ? (
|
return typeof data === 'string' ? (
|
||||||
<ListItem
|
<ListItem
|
||||||
key={title}
|
key={title}
|
||||||
href={data}
|
href={data}
|
||||||
component="a"
|
component="a"
|
||||||
disablePadding
|
disablePadding
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
sx={{
|
sx={{
|
||||||
color: colors.inactive,
|
color: colors.inactive,
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
color: colors.active,
|
|
||||||
'.MuiListItemIcon-root': {
|
|
||||||
color: colors.active,
|
color: colors.active,
|
||||||
|
'.MuiListItemIcon-root': {
|
||||||
|
color: colors.active,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<ListItemButton>{content}</ListItemButton>
|
||||||
<ListItemButton>{content}</ListItemButton>
|
</ListItem>
|
||||||
</ListItem>
|
) : (
|
||||||
) : (
|
<ListItem
|
||||||
<ListItem
|
key={title}
|
||||||
key={title}
|
to={`/page/${id}`}
|
||||||
to={`/page/${id}`}
|
component={NavLink}
|
||||||
component={NavLink}
|
disablePadding
|
||||||
disablePadding
|
activeClassName="sidebar-active"
|
||||||
activeClassName="sidebar-active"
|
>
|
||||||
>
|
<ListItemButton>{content}</ListItemButton>
|
||||||
<ListItemButton>{content}</ListItemButton>
|
</ListItem>
|
||||||
</ListItem>
|
);
|
||||||
);
|
},
|
||||||
}),
|
),
|
||||||
[additionalLinks],
|
[additionalLinks],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -13,8 +13,6 @@ const EditorPreviewContent = ({ previewComponent, previewProps }: EditorPreviewC
|
|||||||
let children: ReactNode;
|
let children: ReactNode;
|
||||||
if (!previewComponent) {
|
if (!previewComponent) {
|
||||||
children = null;
|
children = null;
|
||||||
} else if (React.isValidElement(previewComponent)) {
|
|
||||||
children = React.cloneElement(previewComponent, previewProps);
|
|
||||||
} else {
|
} else {
|
||||||
children = React.createElement(previewComponent, previewProps);
|
children = React.createElement(previewComponent, previewProps);
|
||||||
}
|
}
|
||||||
|
@ -429,13 +429,14 @@ const PreviewPane = (props: TranslatedProps<EditorPreviewPaneProps>) => {
|
|||||||
|
|
||||||
const element = useMemo(() => document.getElementById('cms-root'), []);
|
const element = useMemo(() => document.getElementById('cms-root'), []);
|
||||||
|
|
||||||
const previewProps: Omit<TemplatePreviewProps, 'document' | 'window'> = useMemo(
|
const previewProps = useMemo(
|
||||||
() => ({
|
() =>
|
||||||
...props,
|
({
|
||||||
getAsset: handleGetAsset,
|
...props,
|
||||||
widgetFor,
|
getAsset: handleGetAsset,
|
||||||
widgetsFor,
|
widgetFor,
|
||||||
}),
|
widgetsFor,
|
||||||
|
} as Omit<TemplatePreviewProps, 'document' | 'window'>),
|
||||||
[handleGetAsset, props, widgetFor, widgetsFor],
|
[handleGetAsset, props, widgetFor, widgetsFor],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
import toml from '@iarna/toml';
|
|
||||||
import moment from 'moment';
|
|
||||||
import tomlify from 'tomlify-j0.4';
|
|
||||||
|
|
||||||
import AssetProxy from '../valueObjects/AssetProxy';
|
|
||||||
import { sortKeys } from './helpers';
|
|
||||||
import { FileFormatter } from './FileFormatter';
|
|
||||||
|
|
||||||
function outputReplacer(_key: string, value: unknown) {
|
|
||||||
if (moment.isMoment(value)) {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
return value.format(value._f);
|
|
||||||
}
|
|
||||||
if (value instanceof AssetProxy) {
|
|
||||||
return `${value.path}`;
|
|
||||||
}
|
|
||||||
if (typeof value === 'number' && Number.isInteger(value)) {
|
|
||||||
// Return the string representation of integers so tomlify won't render with tenths (".0")
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
// Return `false` to use default (`undefined` would delete key).
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
class TomlFormatter extends FileFormatter {
|
|
||||||
fromFile(content: string) {
|
|
||||||
return toml.parse(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
toFile(data: object, sortedKeys: string[] = []): string {
|
|
||||||
return tomlify.toToml(data as object, { replace: outputReplacer, sort: sortKeys(sortedKeys) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default new TomlFormatter();
|
|
@ -1,29 +1,25 @@
|
|||||||
import YamlFormatter from './YamlFormatter';
|
import YamlFormatter from './YamlFormatter';
|
||||||
import TomlFormatter from './TomlFormatter';
|
|
||||||
import JsonFormatter from './JsonFormatter';
|
import JsonFormatter from './JsonFormatter';
|
||||||
import { FrontmatterInfer, frontmatterJSON, frontmatterTOML, frontmatterYAML } from './frontmatter';
|
import { FrontmatterInfer, frontmatterJSON, frontmatterYAML } from './frontmatter';
|
||||||
|
|
||||||
import type { Delimiter } from './frontmatter';
|
import type { Delimiter } from './frontmatter';
|
||||||
import type { Collection, Entry, Format } from '../interface';
|
import type { Collection, Entry, Format } from '../interface';
|
||||||
import type { FileFormatter } from './FileFormatter';
|
import type { FileFormatter } from './FileFormatter';
|
||||||
|
|
||||||
export const frontmatterFormats = ['yaml-frontmatter', 'toml-frontmatter', 'json-frontmatter'];
|
export const frontmatterFormats = ['yaml-frontmatter', 'json-frontmatter'];
|
||||||
|
|
||||||
export const formatExtensions = {
|
export const formatExtensions = {
|
||||||
yml: 'yml',
|
yml: 'yml',
|
||||||
yaml: 'yml',
|
yaml: 'yml',
|
||||||
toml: 'toml',
|
|
||||||
json: 'json',
|
json: 'json',
|
||||||
frontmatter: 'md',
|
frontmatter: 'md',
|
||||||
'json-frontmatter': 'md',
|
'json-frontmatter': 'md',
|
||||||
'toml-frontmatter': 'md',
|
|
||||||
'yaml-frontmatter': 'md',
|
'yaml-frontmatter': 'md',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const extensionFormatters: Record<string, FileFormatter> = {
|
export const extensionFormatters: Record<string, FileFormatter> = {
|
||||||
yml: YamlFormatter,
|
yml: YamlFormatter,
|
||||||
yaml: YamlFormatter,
|
yaml: YamlFormatter,
|
||||||
toml: TomlFormatter,
|
|
||||||
json: JsonFormatter,
|
json: JsonFormatter,
|
||||||
md: FrontmatterInfer,
|
md: FrontmatterInfer,
|
||||||
markdown: FrontmatterInfer,
|
markdown: FrontmatterInfer,
|
||||||
@ -34,11 +30,9 @@ function formatByName(name: Format, customDelimiter?: Delimiter): FileFormatter
|
|||||||
const fileFormatter: Record<string, FileFormatter> = {
|
const fileFormatter: Record<string, FileFormatter> = {
|
||||||
yml: YamlFormatter,
|
yml: YamlFormatter,
|
||||||
yaml: YamlFormatter,
|
yaml: YamlFormatter,
|
||||||
toml: TomlFormatter,
|
|
||||||
json: JsonFormatter,
|
json: JsonFormatter,
|
||||||
frontmatter: FrontmatterInfer,
|
frontmatter: FrontmatterInfer,
|
||||||
'json-frontmatter': frontmatterJSON(customDelimiter),
|
'json-frontmatter': frontmatterJSON(customDelimiter),
|
||||||
'toml-frontmatter': frontmatterTOML(customDelimiter),
|
|
||||||
'yaml-frontmatter': frontmatterYAML(customDelimiter),
|
'yaml-frontmatter': frontmatterYAML(customDelimiter),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
import matter from 'gray-matter';
|
import matter from 'gray-matter';
|
||||||
|
|
||||||
import TomlFormatter from './TomlFormatter';
|
|
||||||
import YamlFormatter from './YamlFormatter';
|
import YamlFormatter from './YamlFormatter';
|
||||||
import JsonFormatter from './JsonFormatter';
|
import JsonFormatter from './JsonFormatter';
|
||||||
import { FileFormatter } from './FileFormatter';
|
import { FileFormatter } from './FileFormatter';
|
||||||
|
|
||||||
const Languages = {
|
const Languages = {
|
||||||
YAML: 'yaml',
|
YAML: 'yaml',
|
||||||
TOML: 'toml',
|
|
||||||
JSON: 'json',
|
JSON: 'json',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
@ -17,13 +15,6 @@ export type Delimiter = string | [string, string];
|
|||||||
type Format = { language: Language; delimiters: Delimiter };
|
type Format = { language: Language; delimiters: Delimiter };
|
||||||
|
|
||||||
const parsers = {
|
const parsers = {
|
||||||
toml: {
|
|
||||||
parse: (input: string) => TomlFormatter.fromFile(input),
|
|
||||||
stringify: (metadata: object, opts?: { sortedKeys?: string[] }) => {
|
|
||||||
const { sortedKeys } = opts || {};
|
|
||||||
return TomlFormatter.toFile(metadata, sortedKeys);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
json: {
|
json: {
|
||||||
parse: (input: string) => {
|
parse: (input: string) => {
|
||||||
let JSONinput = input.trim();
|
let JSONinput = input.trim();
|
||||||
@ -58,14 +49,11 @@ function inferFrontmatterFormat(str: string) {
|
|||||||
const lineEnd = str.indexOf('\n');
|
const lineEnd = str.indexOf('\n');
|
||||||
const firstLine = str.slice(0, lineEnd !== -1 ? lineEnd : 0).trim();
|
const firstLine = str.slice(0, lineEnd !== -1 ? lineEnd : 0).trim();
|
||||||
if (firstLine.length > 3 && firstLine.slice(0, 3) === '---') {
|
if (firstLine.length > 3 && firstLine.slice(0, 3) === '---') {
|
||||||
// No need to infer, `gray-matter` will handle things like `---toml` for us.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (firstLine) {
|
switch (firstLine) {
|
||||||
case '---':
|
case '---':
|
||||||
return getFormatOpts(Languages.YAML);
|
return getFormatOpts(Languages.YAML);
|
||||||
case '+++':
|
|
||||||
return getFormatOpts(Languages.TOML);
|
|
||||||
case '{':
|
case '{':
|
||||||
return getFormatOpts(Languages.JSON);
|
return getFormatOpts(Languages.JSON);
|
||||||
default:
|
default:
|
||||||
@ -80,7 +68,6 @@ export function getFormatOpts(format?: Language, customDelimiter?: Delimiter) {
|
|||||||
|
|
||||||
const formats: { [key in Language]: Format } = {
|
const formats: { [key in Language]: Format } = {
|
||||||
yaml: { language: Languages.YAML, delimiters: '---' },
|
yaml: { language: Languages.YAML, delimiters: '---' },
|
||||||
toml: { language: Languages.TOML, delimiters: '+++' },
|
|
||||||
json: { language: Languages.JSON, delimiters: ['{', '}'] },
|
json: { language: Languages.JSON, delimiters: ['{', '}'] },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -143,10 +130,6 @@ export function frontmatterYAML(customDelimiter?: Delimiter) {
|
|||||||
return new FrontmatterFormatter(Languages.YAML, customDelimiter);
|
return new FrontmatterFormatter(Languages.YAML, customDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function frontmatterTOML(customDelimiter?: Delimiter) {
|
|
||||||
return new FrontmatterFormatter(Languages.TOML, customDelimiter);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function frontmatterJSON(customDelimiter?: Delimiter) {
|
export function frontmatterJSON(customDelimiter?: Delimiter) {
|
||||||
return new FrontmatterFormatter(Languages.JSON, customDelimiter);
|
return new FrontmatterFormatter(Languages.JSON, customDelimiter);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ export * from './media-libraries';
|
|||||||
export * from './locales';
|
export * from './locales';
|
||||||
export * from './lib';
|
export * from './lib';
|
||||||
|
|
||||||
export const CMS = {
|
const CMS = {
|
||||||
...Registry,
|
...Registry,
|
||||||
init: bootstrap,
|
init: bootstrap,
|
||||||
};
|
};
|
||||||
|
@ -263,29 +263,30 @@ export type WidgetPreviewComponent<T = unknown, F extends Field = Field> =
|
|||||||
| React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
|
| React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
|
||||||
| ComponentType<WidgetPreviewProps<T, F>>;
|
| ComponentType<WidgetPreviewProps<T, F>>;
|
||||||
|
|
||||||
export interface TemplatePreviewProps<T = unknown> {
|
export type WidgetsFor<P = EntryData> = <K extends keyof P>(
|
||||||
|
name: K,
|
||||||
|
) => P[K] extends Array<infer U>
|
||||||
|
? {
|
||||||
|
data: U | null;
|
||||||
|
widgets: Record<keyof U, React.ReactNode>;
|
||||||
|
}[]
|
||||||
|
: {
|
||||||
|
data: P[K] | null;
|
||||||
|
widgets: Record<keyof P[K], React.ReactNode>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface TemplatePreviewProps<T = EntryData> {
|
||||||
collection: Collection;
|
collection: Collection;
|
||||||
fields: Field[];
|
fields: Field[];
|
||||||
entry: Entry<T>;
|
entry: Entry<T>;
|
||||||
document: Document | undefined | null;
|
document: Document | undefined | null;
|
||||||
window: Window | undefined | null;
|
window: Window | undefined | null;
|
||||||
getAsset: GetAssetFunction;
|
getAsset: GetAssetFunction;
|
||||||
widgetFor: (name: string) => ReactNode;
|
widgetFor: (name: T extends EntryData ? string : keyof T) => ReactNode;
|
||||||
widgetsFor: (name: string) =>
|
widgetsFor: WidgetsFor<T>;
|
||||||
| {
|
|
||||||
data: EntryData | null;
|
|
||||||
widgets: Record<string, React.ReactNode>;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
data: EntryData | null;
|
|
||||||
widgets: Record<string, React.ReactNode>;
|
|
||||||
}[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TemplatePreviewComponent =
|
export type TemplatePreviewComponent<T = EntryData> = ComponentType<TemplatePreviewProps<T>>;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
| React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
|
|
||||||
| ComponentType<TemplatePreviewProps>;
|
|
||||||
|
|
||||||
export interface WidgetOptions<T = unknown, F extends Field = Field> {
|
export interface WidgetOptions<T = unknown, F extends Field = Field> {
|
||||||
validator?: Widget<T, F>['validator'];
|
validator?: Widget<T, F>['validator'];
|
||||||
@ -752,7 +753,7 @@ export interface EventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AdditionalLinkOptions {
|
export interface AdditionalLinkOptions {
|
||||||
iconName?: string;
|
icon?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AdditionalLink {
|
export interface AdditionalLink {
|
||||||
|
@ -8,6 +8,7 @@ import type {
|
|||||||
Config,
|
Config,
|
||||||
CustomIcon,
|
CustomIcon,
|
||||||
Entry,
|
Entry,
|
||||||
|
EntryData,
|
||||||
EventData,
|
EventData,
|
||||||
EventListener,
|
EventListener,
|
||||||
Field,
|
Field,
|
||||||
@ -34,7 +35,7 @@ const eventHandlers = allowedEvents.reduce((acc, e) => {
|
|||||||
|
|
||||||
interface Registry {
|
interface Registry {
|
||||||
backends: Record<string, BackendInitializer>;
|
backends: Record<string, BackendInitializer>;
|
||||||
templates: Record<string, TemplatePreviewComponent>;
|
templates: Record<string, TemplatePreviewComponent<EntryData>>;
|
||||||
widgets: Record<string, Widget>;
|
widgets: Record<string, Widget>;
|
||||||
icons: Record<string, CustomIcon>;
|
icons: Record<string, CustomIcon>;
|
||||||
additionalLinks: Record<string, AdditionalLink>;
|
additionalLinks: Record<string, AdditionalLink>;
|
||||||
@ -109,11 +110,11 @@ export function getPreviewStyles() {
|
|||||||
/**
|
/**
|
||||||
* Preview Templates
|
* Preview Templates
|
||||||
*/
|
*/
|
||||||
export function registerPreviewTemplate(name: string, component: TemplatePreviewComponent) {
|
export function registerPreviewTemplate<T>(name: string, component: TemplatePreviewComponent<T>) {
|
||||||
registry.templates[name] = component;
|
registry.templates[name] = component as TemplatePreviewComponent<EntryData>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPreviewTemplate(name: string): TemplatePreviewComponent {
|
export function getPreviewTemplate(name: string): TemplatePreviewComponent<EntryData> {
|
||||||
return registry.templates[name];
|
return registry.templates[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +127,7 @@ export function registerWidget(widget: WidgetParam): void;
|
|||||||
export function registerWidget<T = unknown>(
|
export function registerWidget<T = unknown>(
|
||||||
name: string,
|
name: string,
|
||||||
control: string | Widget<T>['control'],
|
control: string | Widget<T>['control'],
|
||||||
preview: Widget<T>['preview'],
|
preview?: Widget<T>['preview'],
|
||||||
options?: WidgetOptions,
|
options?: WidgetOptions,
|
||||||
): void;
|
): void;
|
||||||
export function registerWidget<T = unknown>(
|
export function registerWidget<T = unknown>(
|
||||||
@ -358,7 +359,6 @@ export function getAdditionalLinks(): Record<string, AdditionalLink> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getAdditionalLink(id: string): AdditionalLink | undefined {
|
export function getAdditionalLink(id: string): AdditionalLink | undefined {
|
||||||
console.log('additionalLinks', registry.additionalLinks);
|
|
||||||
return registry.additionalLinks[id];
|
return registry.additionalLinks[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,14 +85,33 @@ const DateTimeControl = ({
|
|||||||
[timezoneOffset],
|
[timezoneOffset],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const inputFormat = useMemo(() => {
|
||||||
|
if (typeof dateFormat === 'string' || typeof timeFormat === 'string') {
|
||||||
|
const formatParts: string[] = [];
|
||||||
|
if (typeof dateFormat === 'string' && isNotEmpty(dateFormat)) {
|
||||||
|
formatParts.push(dateFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof timeFormat === 'string' && isNotEmpty(timeFormat)) {
|
||||||
|
formatParts.push(timeFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formatParts.length > 0) {
|
||||||
|
return formatParts.join(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
|
||||||
|
}, [dateFormat, timeFormat]);
|
||||||
|
|
||||||
const defaultValue = useMemo(() => {
|
const defaultValue = useMemo(() => {
|
||||||
const today = field.picker_utc ? localToUTC(new Date()) : new Date();
|
const today = field.picker_utc ? localToUTC(new Date()) : new Date();
|
||||||
return field.default === undefined
|
return field.default === undefined
|
||||||
? format
|
? format
|
||||||
? formatDate(today, format)
|
? formatDate(today, format)
|
||||||
: formatISO(today)
|
: formatDate(today, inputFormat)
|
||||||
: field.default;
|
: field.default;
|
||||||
}, [field.default, field.picker_utc, format, localToUTC]);
|
}, [field.default, field.picker_utc, format, inputFormat, localToUTC]);
|
||||||
|
|
||||||
const [internalValue, setInternalValue] = useState(value ?? defaultValue);
|
const [internalValue, setInternalValue] = useState(value ?? defaultValue);
|
||||||
|
|
||||||
@ -132,14 +151,12 @@ const DateTimeControl = ({
|
|||||||
|
|
||||||
const dateTimePicker = useMemo(() => {
|
const dateTimePicker = useMemo(() => {
|
||||||
if (dateFormat && !timeFormat) {
|
if (dateFormat && !timeFormat) {
|
||||||
const inputDateFormat = typeof dateFormat === 'string' ? dateFormat : 'MMM d, yyyy';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MobileDatePicker
|
<MobileDatePicker
|
||||||
key="mobile-date-picker"
|
key="mobile-date-picker"
|
||||||
inputFormat={inputDateFormat}
|
inputFormat={inputFormat}
|
||||||
label={label}
|
label={label}
|
||||||
value={formatDate(field.picker_utc ? utcDate : dateValue, inputDateFormat)}
|
value={formatDate(field.picker_utc ? utcDate : dateValue, inputFormat)}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
renderInput={params => (
|
renderInput={params => (
|
||||||
<TextField
|
<TextField
|
||||||
@ -164,14 +181,12 @@ const DateTimeControl = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!dateFormat && timeFormat) {
|
if (!dateFormat && timeFormat) {
|
||||||
const inputTimeFormat = typeof timeFormat === 'string' ? timeFormat : 'H:mm';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TimePicker
|
<TimePicker
|
||||||
key="time-picker"
|
key="time-picker"
|
||||||
label={label}
|
label={label}
|
||||||
inputFormat={inputTimeFormat}
|
inputFormat={inputFormat}
|
||||||
value={formatDate(field.picker_utc ? utcDate : dateValue, inputTimeFormat)}
|
value={formatDate(field.picker_utc ? utcDate : dateValue, inputFormat)}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
renderInput={params => (
|
renderInput={params => (
|
||||||
<TextField
|
<TextField
|
||||||
@ -195,22 +210,6 @@ const DateTimeControl = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let inputFormat = 'MMM d, yyyy H:mm';
|
|
||||||
if (typeof dateFormat === 'string' || typeof timeFormat === 'string') {
|
|
||||||
const formatParts: string[] = [];
|
|
||||||
if (typeof dateFormat === 'string' && isNotEmpty(dateFormat)) {
|
|
||||||
formatParts.push(dateFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof timeFormat === 'string' && isNotEmpty(timeFormat)) {
|
|
||||||
formatParts.push(timeFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formatParts.length > 0) {
|
|
||||||
inputFormat = formatParts.join(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MobileDateTimePicker
|
<MobileDateTimePicker
|
||||||
key="mobile-date-time-picker"
|
key="mobile-date-time-picker"
|
||||||
@ -244,6 +243,8 @@ const DateTimeControl = ({
|
|||||||
field.picker_utc,
|
field.picker_utc,
|
||||||
handleChange,
|
handleChange,
|
||||||
hasErrors,
|
hasErrors,
|
||||||
|
inputFormat,
|
||||||
|
internalValue,
|
||||||
isDisabled,
|
isDisabled,
|
||||||
label,
|
label,
|
||||||
t,
|
t,
|
||||||
|
705
core/yarn.lock
705
core/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user