@sensinum/astro-strapi-blocks
Version:
Astro components for Strapi Block Field
119 lines (107 loc) • 4.48 kB
text/typescript
import type { StrapiBlock, StrapiBlockTheme, StrapiBlockThemeCode, StrapiBlockThemeHeading, StrapiBlockThemeList, StrapiBlockThemeParagraph, StrapiBlockThemeQuote, StrapiBlockUserTheme, StrapiBlockThemeImage, StrapiRenderClassesType, StrapiRenderClassesPropretyType, DeepPartial } from '../types';
export const StrapiBlockThemeDefault: StrapiBlockTheme = {
block: ['astro-strapi-block'],
heading: {
block: ['astro-strapi-block-heading'],
h1: ['text-6xl', 'font-bold', 'mb-4'],
h2: ['text-5xl', 'font-bold', 'mb-4'],
h3: ['text-4xl', 'font-bold', 'mb-4'],
h4: ['text-3xl', 'font-bold', 'mb-4'],
h5: ['text-2xl', 'font-bold', 'mb-4'],
h6: ['text-xl', 'font-bold', 'mb-4'],
},
paragraph: {
block: ['astro-strapi-block-paragraph', 'mb-4'],
span: [],
strong: ['font-bold'],
italic: ['italic'],
underline: ['underline'],
strikethrough: ['line-through'],
link: ['text-blue-500', 'underline', 'hover:text-blue-800'],
},
quote: {
block: ['astro-strapi-block-quote', 'border-l-4', 'border-gray-300', 'pl-4', 'mb-4'],
span: [],
strong: ['font-bold'],
italic: ['italic'],
underline: ['underline'],
strikethrough: ['line-through'],
link: ['text-blue-500', 'underline', 'hover:text-blue-800'],
},
list: {
block: ['astro-strapi-block-list', 'my-4'],
ordered: ['list-decimal', 'pl-6'],
unordered: ['list-disc', 'pl-6'],
item: ['mb-2', 'last:mb-0'],
},
code: {
block: [
'astro-strapi-block-code',
'mb-4',
'bg-gray-200',
'p-4',
'rounded-md',
'text-sm',
'font-mono',
'last:mb-0',
],
language: ['astro-strapi-block-code-language', 'inline-block', 'text-xs', 'font-sans', 'font-medium', 'bg-gray-300', 'py-1', 'px-4', 'mb-2', 'rounded-full', 'text-gray-700'],
},
image: {
block: [
'mb-4',
'w-full',
'h-auto',
'flex',
'items-center',
'justify-center',
'last:mb-0',
],
image: ['rounded-md'],
caption: ['text-sm', 'mb-2', 'text-gray-900', 'text-center', 'italic']
},
};
const modifyThemeProperty = <T extends Record<string, any>>(
data: T,
modify: DeepPartial<T>,
overwrite: boolean = false
): T => {
const result = { ...data };
const modifyProps = Object.keys(modify) as Array<keyof T>;
modifyProps.forEach((prop) => {
const modifyValue = modify[prop as keyof typeof modify];
if (modifyValue !== undefined && modifyValue !== null) {
if (Array.isArray(modifyValue)) {
result[prop] = (overwrite
? [...(modifyValue as Array<string>)]
: [...(data[prop] as Array<string>), ...(modifyValue as Array<string>)]) as T[keyof T];
} else if (typeof modifyValue === 'object') {
result[prop] = modifyThemeProperty<T[keyof T]>(data[prop], modifyValue as DeepPartial<T[keyof T]>, overwrite);
}
}
});
return result;
};
export const buildThemeObject = (theme: StrapiBlockUserTheme, defaultTheme: StrapiBlockTheme): StrapiBlockTheme => {
let result = { ...defaultTheme };
if (theme.overwrite) {
result = modifyThemeProperty<StrapiBlockTheme>(result, theme.overwrite, true);
}
if (theme.extend) {
result = modifyThemeProperty<StrapiBlockTheme>(result, theme.extend);
}
return result;
};
export const getPropertyClass = <T extends keyof StrapiBlockTheme>(theme: StrapiBlockTheme, path: T | [T, keyof StrapiBlockTheme[T]]): Array<string> => {
const [rootLevel, subLevel] = Array.isArray(path) ? path : [path];
if (rootLevel && subLevel && theme[rootLevel] && typeof theme[rootLevel] === 'object') {
const nestedValue = (theme[rootLevel] as Record<string, string[]>)[subLevel as string];
return Array.isArray(nestedValue) ? nestedValue : [];
} else if (rootLevel && theme[rootLevel]) {
const value = theme[rootLevel];
return Array.isArray(value) ? value : [];
}
return [];
};
export const renderPropertyClasses = <T extends keyof StrapiBlockTheme>(theme: StrapiBlockTheme, path: T | [T, keyof StrapiBlockTheme[T]]): string =>
getPropertyClass(theme, path).join(' ');