Skip to content

Commit

Permalink
fix types and attend comments
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMightyPenguin committed Nov 14, 2023
1 parent f56df8d commit a41c296
Show file tree
Hide file tree
Showing 21 changed files with 113 additions and 64 deletions.
21 changes: 20 additions & 1 deletion .changeset/fluffy-spies-remain.md
Expand Up @@ -2,4 +2,23 @@
'playroom': minor
---

Add support for vite
Adds support for vite. This allows user to configure a bundler, by specifying a `bundler` option in their Playroom config.

```js
// playroom.config.js

/**
* @type {import('../../../src/types').PlayroomConfig}
*/
module.exports = {
components: './components.ts',
snippets: './snippets.ts',
outputPath: './dist',
scope: './useScope.ts',
themes: './themes.ts',
frameComponent: './FrameComponent.tsx',
outputPath: './dist',
openBrowser: false,
bundler: 'vite',
};
```
@@ -1,13 +1,22 @@
import type { ReactNode } from 'react';
import type { Theme } from './themes';

const parent = {
border: '1px solid currentColor',
padding: '10px 10px 10px 15px',
};

const FrameComponent = ({ theme, children }) => (
const FrameComponent = ({
theme,
children,
}: {
theme: Theme;
children: ReactNode;
}) => (
<div>
FrameComponent (theme: &quot;{theme.name}&quot;)
{children ? <div style={parent}>{children}</div> : null}
</div>
);

export default FrameComponent
export default FrameComponent;
1 change: 1 addition & 0 deletions cypress/projects/vite/playroom.config.js
Expand Up @@ -5,6 +5,7 @@ module.exports = {
components: './components.ts',
snippets: './snippets.ts',
outputPath: './dist',
scope: './useScope.ts',
themes: './themes.ts',
frameComponent: './FrameComponent.tsx',
outputPath: './dist',
Expand Down
8 changes: 6 additions & 2 deletions cypress/projects/vite/themes.ts
@@ -1,2 +1,6 @@
export const themeOne = { name: 'one' };
export const themeTwo = { name: 'two' };
export type Theme = {
name: string;
};

export const themeOne = { name: 'one' } satisfies Theme;
export const themeTwo = { name: 'two' } satisfies Theme;
File renamed without changes.
2 changes: 1 addition & 1 deletion lib/build.js
Expand Up @@ -6,7 +6,7 @@ const noop = () => {};

/**
*
* @param {import('../src/types').InternalPlayroomConfig} config
* @param {import('../src/internalTypes').InternalPlayroomConfig} config
* @param {(...args: any[]) => void} callback
*/
module.exports = async (config, callback = noop) => {
Expand Down
2 changes: 1 addition & 1 deletion lib/makeDefaultWebpackConfig.js
@@ -1,5 +1,5 @@
/**
* @param {import('../src/types').InternalPlayroomConfig} playroomConfig
* @param {import('../src/internalTypes').InternalPlayroomConfig} playroomConfig
*/
module.exports = (playroomConfig) => ({
module: {
Expand Down
6 changes: 2 additions & 4 deletions lib/makeViteConfig.js
Expand Up @@ -5,7 +5,7 @@ const vite = require('vite');
const getStaticTypes = require('./getStaticTypes');

/**
* @param {import('../src/types').InternalPlayroomConfig} playroomConfig
* @param {import('../src/internalTypes').InternalPlayroomConfig} playroomConfig
* @param {{ production?: boolean }} options
* @returns {import('vite').InlineConfig}
*/
Expand Down Expand Up @@ -72,9 +72,7 @@ module.exports = async (playroomConfig, options) => {
},
};

const theirConfig = playroomConfig.webpackConfig
? await playroomConfig.viteConfig()
: {};
const theirConfig = await playroomConfig.viteConfig?.();

return vite.mergeConfig(ourConfig, theirConfig);
};
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -122,6 +122,7 @@
"@changesets/cli": "^2.25.2",
"@octokit/rest": "^19.0.5",
"@types/jest": "^29.2.4",
"@types/webpack-env": "^1.18.4",
"concurrently": "^7.6.0",
"cypress": "^12.0.2",
"eslint": "^8.44.0",
Expand Down
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/Playroom/Frame.tsx
@@ -1,4 +1,4 @@
import { ComponentType, ReactNode } from 'react';
import type { ComponentType, ReactNode } from 'react';
import { useParams } from '../utils/params';
import CatchErrors from './CatchErrors/CatchErrors';
import RenderCode from './RenderCode/RenderCode';
Expand All @@ -12,6 +12,7 @@ interface FrameProps {
children?: ReactNode;
}>;
}

export default function Frame({
themes,
components,
Expand Down
2 changes: 1 addition & 1 deletion src/Playroom/Frames/frameSrc.ts
@@ -1,4 +1,4 @@
import type { FrameSrcHandler } from '../../types';
import type { FrameSrcHandler } from '../../internalTypes';

import frameConfig from '__PLAYROOM_ALIAS__FRAME_COMPONENT__';

Expand Down
4 changes: 2 additions & 2 deletions src/Playroom/Playroom.tsx
Expand Up @@ -5,7 +5,7 @@ import { useDebouncedCallback } from 'use-debounce';
import { Resizable } from 're-resizable';
import Frames from './Frames/Frames';
import { WindowPortal } from './WindowPortal';
import type { Snippets } from '../utils/url';
import type { Snippet } from '../types';
import componentsToHints from '../utils/componentsToHints';
import Toolbar, { toolbarItemCount } from './Toolbar/Toolbar';
import ChevronIcon from './icons/ChevronIcon';
Expand Down Expand Up @@ -50,7 +50,7 @@ export interface PlayroomProps {
components: Record<string, ComponentType>;
themes: string[];
widths: number[];
snippets: Snippets;
snippets: Snippet[];
}

export default ({ components, themes, widths, snippets }: PlayroomProps) => {
Expand Down
2 changes: 1 addition & 1 deletion src/Playroom/Snippets/Snippets.tsx
Expand Up @@ -4,7 +4,7 @@ import fuzzy from 'fuzzy';
// @ts-expect-error no types
import { useDebouncedCallback } from 'use-debounce';
import type { PlayroomProps } from '../Playroom';
import type { Snippet } from '../../utils/url';
import type { Snippet } from '../../types';
import SearchField from './SearchField/SearchField';
import { Strong } from '../Strong/Strong';
import { Text } from '../Text/Text';
Expand Down
3 changes: 2 additions & 1 deletion src/StoreContext/StoreContext.tsx
Expand Up @@ -12,7 +12,8 @@ import dedent from 'dedent';
// @ts-expect-error no types
import { useDebouncedCallback } from 'use-debounce';

import { type Snippet, compressParams } from '../utils/url';
import type { Snippet } from '../types';
import { compressParams } from '../utils/url';
import { formatForInsertion, formatAndInsert } from '../utils/formatting';
import { getParamsFromQuery, updateUrlCode } from '../utils/params';
import type { PlayroomProps } from '../Playroom/Playroom';
Expand Down
36 changes: 36 additions & 0 deletions src/internalTypes.d.ts
@@ -0,0 +1,36 @@
// file with types that are not meant to be exposed as part of the public API

import type { PlayroomConfig } from './types';

export interface InternalPlayroomConfig extends PlayroomConfig {
cwd: string;
storageKey: string;
port: number;
openBrowser: boolean;
}

declare global {
declare const __PLAYROOM_GLOBAL__CONFIG__: InternalPlayroomConfig;
declare const __PLAYROOM_GLOBAL__STATIC_TYPES__: any;

interface Window {
__playroomConfig__: InternalPlayroomConfig;
}
}

export interface InternalPlayroomConfig extends PlayroomConfig {
cwd: string;
storageKey: string;
port: number;
openBrowser: boolean;
}

export interface FrameParams {
code: string;
themeName: string;
}

export type FrameSrcHandler = (
frameParams: FrameParams,
config: InternalPlayroomConfig
) => string;
8 changes: 5 additions & 3 deletions src/render.ts
@@ -1,3 +1,4 @@
import type { ReactElement, ReactNode } from 'react';
import ReactDOM, { version as reactDomVersion } from 'react-dom';

// Uses the correct render API based on the available version of
Expand All @@ -7,9 +8,9 @@ const canUseNewReactRootApi =
reactDomVersion &&
(reactDomVersion.startsWith('18') || reactDomVersion.startsWith('0.0.0'));

declare let __webpack_public_path__: string | undefined;
let __webpack_public_path__: string | undefined;

export const renderElement = async (node: any, outlet: HTMLElement) => {
export const renderElement = async (node: ReactNode, outlet: HTMLElement) => {
if (canUseNewReactRootApi) {
// webpack needs to know the public path when doing dynamic imports,
// otherwise the HTML chunk for the preview page, will end up importing
Expand All @@ -21,6 +22,7 @@ export const renderElement = async (node: any, outlet: HTMLElement) => {
const root = createRoot(outlet);
root.render(node);
} else {
ReactDOM.render(node, outlet);
// casting as ReactDOM.render requires a different type
ReactDOM.render(node as ReactElement, outlet);
}
};
40 changes: 11 additions & 29 deletions src/types.d.ts
@@ -1,4 +1,12 @@
import { type Snippet } from './utils/url';
import type { ParamType } from './utils/url';

// all of the types in here get exposed as part of the public API

export interface Snippet {
group: string;
name: string;
code: string;
}

export interface PlayroomConfig {
components: string;
Expand All @@ -12,37 +20,11 @@ export interface PlayroomConfig {
cwd?: string;
storageKey?: string;
bundler: 'webpack' | 'vite';
viteConfig: () => Promise<any>;
viteConfig?: () => Promise<any>;
webpackConfig?: () => Promise<any>;
baseUrl?: string;
paramType: 'hash' | 'search';
paramType: ParamType;
iframeSandbox?: string;
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
reactDocgenTypescriptConfig?: import('react-docgen-typescript').ParserOptions;
}

export interface InternalPlayroomConfig extends PlayroomConfig {
cwd: string;
storageKey: string;
port: number;
openBrowser: boolean;
}

export interface FrameParams {
code: string;
themeName: string;
}

export type FrameSrcHandler = (
frameParams: FrameParams,
config: InternalPlayroomConfig
) => string;

declare global {
declare const __PLAYROOM_GLOBAL__CONFIG__: InternalPlayroomConfig;
declare const __PLAYROOM_GLOBAL__STATIC_TYPES__: any;

interface Window {
__playroomConfig__: InternalPlayroomConfig;
}
}
9 changes: 2 additions & 7 deletions src/utils/hmr.ts
@@ -1,17 +1,12 @@
type AcceptHandler = (relativePath: string, handler: () => void) => void;

export function hmrAccept(handler: (accept: AcceptHandler) => void) {
// @ts-ignore
const viteAccept = import.meta.hot?.accept;

if (
typeof module !== 'undefined' &&
// @ts-ignore
typeof module?.hot?.accept === 'function'
) {
// @ts-ignore
handler(module.hot.accept);
} else if (typeof viteAccept === 'function') {
handler(viteAccept);
} else if (typeof import.meta.hot?.accept === 'function') {
handler(import.meta.hot?.accept);
}
}
8 changes: 0 additions & 8 deletions src/utils/url.ts
@@ -1,13 +1,5 @@
import lzString from 'lz-string';

export interface Snippet {
group: string;
name: string;
code: string;
}

export type Snippets = Snippet[];

export type ParamType = 'hash' | 'search';

export interface CompressParamsOptions {
Expand Down
2 changes: 2 additions & 0 deletions src/vite.d.ts
@@ -0,0 +1,2 @@
/* eslint-disable spaced-comment */
/// <reference types="vite/client" />

0 comments on commit a41c296

Please sign in to comment.