Skip to content

Commit

Permalink
Add vanilla design system
Browse files Browse the repository at this point in the history
  • Loading branch information
dabbott committed Dec 14, 2023
1 parent 2b8075b commit 8bcb2fb
Show file tree
Hide file tree
Showing 12 changed files with 369 additions and 87 deletions.
160 changes: 92 additions & 68 deletions packages/noya-compiler/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ export interface CompilerConfiguration {
name: string;
ds: DS;
designSystemDefinition: DesignSystemDefinition;
target: 'standalone' | 'codesandbox';
}

function findElementNameAndSource(
Expand Down Expand Up @@ -208,7 +207,7 @@ export function createSimpleElement(

export function createReactComponentDeclaration(
name: string,
resolvedElement: SimpleElement,
returnValue: ts.Expression,
params: ts.ParameterDeclaration[] = [],
) {
return ts.factory.createFunctionDeclaration(
Expand All @@ -221,9 +220,7 @@ export function createReactComponentDeclaration(
undefined,
params,
undefined,
ts.factory.createBlock([
ts.factory.createReturnStatement(createElementCode(resolvedElement)),
]),
ts.factory.createBlock([ts.factory.createReturnStatement(returnValue)]),
);
}

Expand Down Expand Up @@ -325,6 +322,80 @@ function extractImports(
});
}

function createLayoutSource(DesignSystem: DesignSystemDefinition) {
const providerElement = DesignSystem.components[component.id.Provider]
? DesignSystem.createElement(
DesignSystem.components[component.id.Provider],
{
theme: createPassthrough(ts.factory.createIdentifier('theme')),
},
createPassthrough(
ts.factory.createJsxExpression(
undefined,
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier('props'),
ts.factory.createIdentifier('children'),
),
),
),
)
: null;

const nextProviderElement = DesignSystem.components[component.id.NextProvider]
? DesignSystem.createElement(
DesignSystem.components[component.id.NextProvider],
{},
providerElement,
)
: providerElement;

if (!nextProviderElement) return;

const layoutElement = createSimpleElement(nextProviderElement, DesignSystem);

if (!layoutElement) return;

const layoutComponentFunc = createReactComponentDeclaration(
'NextProvider',
createElementCode(layoutElement),
[
ts.factory.createParameterDeclaration(
undefined,
undefined,
ts.factory.createIdentifier('props'),
undefined,
// Type React.PropsWithChildren<{}>
ts.factory.createTypeReferenceNode(
ts.factory.createIdentifier('React.PropsWithChildren'),
[
// Empty object type
ts.factory.createTypeLiteralNode([]),
],
),
undefined,
),
],
);

const layoutImports = extractImports(layoutElement, DesignSystem);

const layoutSource = [
"'use client'",
[
"import React from 'react'",
print(layoutImports),
'import { theme } from "./theme"',
].join('\n'),
print(layoutComponentFunc),
]
.map(clean)
.join('\n');

return {
source: layoutSource,
};
}

export function compile(configuration: CompilerConfiguration) {
const DesignSystem = configuration.designSystemDefinition;

Expand Down Expand Up @@ -368,7 +439,7 @@ export function compile(configuration: CompilerConfiguration) {

const func = createReactComponentDeclaration(
getComponentNameIdentifier(component.name),
simpleElement,
createElementCode(simpleElement),
);

const dependencies = (DesignSystem.imports ?? []).reduce(
Expand Down Expand Up @@ -412,63 +483,7 @@ export function compile(configuration: CompilerConfiguration) {
{},
);

const layoutElement = createSimpleElement(
DesignSystem.createElement(
DesignSystem.components[component.id.NextProvider],
{},
DesignSystem.createElement(
DesignSystem.components[component.id.Provider],
{
theme: createPassthrough(ts.factory.createIdentifier('theme')),
},
createPassthrough(
ts.factory.createJsxExpression(
undefined,
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier('props'),
ts.factory.createIdentifier('children'),
),
),
),
),
),
DesignSystem,
);
const layoutComponentFunc = createReactComponentDeclaration(
'NextProvider',
layoutElement!,
[
ts.factory.createParameterDeclaration(
undefined,
undefined,
ts.factory.createIdentifier('props'),
undefined,
// Type React.PropsWithChildren<{}>
ts.factory.createTypeReferenceNode(
ts.factory.createIdentifier('React.PropsWithChildren'),
[
// Empty object type
ts.factory.createTypeLiteralNode([]),
],
),
undefined,
),
],
);

const layoutImports = extractImports(layoutElement!, DesignSystem);

const layoutSource = [
"'use client'",
[
"import React from 'react'",
print(layoutImports),
'import { theme } from "./theme"',
].join('\n'),
print(layoutComponentFunc),
]
.map(clean)
.join('\n');
const layoutSource = createLayoutSource(DesignSystem);

const theme: Theme = {
colorMode: configuration.ds.config.colorMode ?? 'light',
Expand All @@ -480,6 +495,14 @@ export function compile(configuration: CompilerConfiguration) {

const themeFile = generateThemeFile(DesignSystem, { theme });

const includeTailwindBase = configuration.ds.source.name === 'vanilla';

const tailwindLayers = [
...(includeTailwindBase ? ['base'] : []),
'components',
'utilities',
];

const files = {
'src/app/layout.tsx': `import './globals.css'
Expand All @@ -495,10 +518,9 @@ export default function RootLayout({
)
}
`,
'src/app/globals.css': `@tailwind base;
@tailwind components;
@tailwind utilities;
`,
'src/app/globals.css': tailwindLayers
.map((layer) => `@tailwind ${layer};`)
.join('\n'),
...Object.fromEntries(
componentPageItems.map(({ name, source }) => [
`src/app/components/${getComponentNameIdentifier(
Expand All @@ -509,7 +531,9 @@ export default function RootLayout({
]),
),
'src/app/components/theme.ts': themeFile,
'src/app/components/layout.tsx': layoutSource,
...(layoutSource
? { 'src/app/components/layout.tsx': layoutSource.source }
: {}),
'package.json': JSON.stringify(
{
name: sanitizePackageName(configuration.name),
Expand Down
6 changes: 3 additions & 3 deletions packages/noya-component/src/renderResolvedNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function renderResolvedNode({
dsConfig,
system,
stylingMode = 'inline',
theme,
noya,
}: {
containerWidth?: number;
contentEditable: boolean;
Expand All @@ -73,7 +73,7 @@ export function renderResolvedNode({
dsConfig: DSConfig;
system: DesignSystemDefinition;
stylingMode?: StylingMode;
theme?: any; // Passed into components as _theme
noya?: any; // Passed into components as _noya
}) {
return ResolvedHierarchy.map<ReactNode>(
resolvedNode,
Expand Down Expand Up @@ -266,7 +266,7 @@ export function renderResolvedNode({
element.componentID === component.id.Radio) && {
label: transformedChildren,
})}
{...(theme && { _theme: theme })}
{...(noya && { _noya: noya })}
/>
);
},
Expand Down
2 changes: 1 addition & 1 deletion packages/noya-module-loader/src/ThumbnailDesignSystem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const handler = {
};

function getTheme(props: any) {
if (props._theme) return props._theme as Theme;
if (props._noya && props._noya.theme) return props._noya.theme as Theme;

return undefined;
}
Expand Down
Loading

0 comments on commit 8bcb2fb

Please sign in to comment.