@knapsack/renderer-react-components 4.79.2 → 4.79.3--canary.6036.f7fab19.0

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/.lintstagedrc.mjs CHANGED
@@ -6,6 +6,6 @@ import defaultConfig from '../../../../.lintstagedrc.mjs';
6
6
  const __dirname = dirname(fileURLToPath(import.meta.url));
7
7
 
8
8
  export default {
9
- '*.{ts,tsx,js,jsx,cjs,mjs,mts,cts}': `cd ${__dirname} && ./node_modules/.bin/eslint`,
9
+ '*.{ts,tsx,js,jsx,cjs,mjs}': `cd ${__dirname} && ./node_modules/.bin/eslint`,
10
10
  ...defaultConfig,
11
11
  };
@@ -0,0 +1,4 @@
1
+
2
+ > @knapsack/renderer-react-components@4.78.14 build /home/runner/work/app-monorepo/app-monorepo/apps/client/libs/renderer-react-components
3
+ > tsc
4
+
@@ -0,0 +1,13 @@
1
+
2
+ > @knapsack/renderer-react-components@4.78.14 lint /home/runner/work/app-monorepo/app-monorepo/apps/client/libs/renderer-react-components
3
+ > eslint ./
4
+
5
+
6
+ /home/runner/work/app-monorepo/app-monorepo/apps/client/libs/renderer-react-components/src/test-fixtures/complex-props.tsx
7
+ 18:3 warning 'config' is defined but never used. Allowed unused args must match /^_/u unused-imports/no-unused-vars
8
+
9
+ /home/runner/work/app-monorepo/app-monorepo/apps/client/libs/renderer-react-components/src/test-fixtures/generic-component-type.tsx
10
+ 16:23 warning 'index' is defined but never used. Allowed unused args must match /^_/u unused-imports/no-unused-vars
11
+
12
+ ✖ 2 problems (0 errors, 2 warnings)
13
+
package/CHANGELOG.md CHANGED
@@ -1,30 +1,3 @@
1
- # v4.79.2 (Tue Apr 29 2025)
2
-
3
- #### 🏠 Internal
4
-
5
- - update logic for editable spec [#6077](https://github.com/knapsack-labs/app-monorepo/pull/6077) ([@mabry1985](https://github.com/mabry1985))
6
- - Add .mts and .cts file extensions to ESLint configuration in lint-staged [#6079](https://github.com/knapsack-labs/app-monorepo/pull/6079) ([@EvanLovely](https://github.com/EvanLovely))
7
-
8
- #### Authors: 2
9
-
10
- - Evan Lovely ([@EvanLovely](https://github.com/EvanLovely))
11
- - Josh Mabry ([@mabry1985](https://github.com/mabry1985))
12
-
13
- ---
14
-
15
- # v4.79.0 (Mon Apr 28 2025)
16
-
17
- #### 🚀 Enhancement
18
-
19
- - setup better testing on App Client [#6072](https://github.com/knapsack-labs/app-monorepo/pull/6072) ([@EvanLovely](https://github.com/EvanLovely))
20
- - setup new Demo type that is App Client Data agnostic [#6072](https://github.com/knapsack-labs/app-monorepo/pull/6072) ([@EvanLovely](https://github.com/EvanLovely))
21
-
22
- #### Authors: 1
23
-
24
- - Evan Lovely ([@EvanLovely](https://github.com/EvanLovely))
25
-
26
- ---
27
-
28
1
  # v4.78.13 (Fri Apr 25 2025)
29
2
 
30
3
  #### 🏠 Internal
@@ -2,6 +2,8 @@ import type { Demo } from '@knapsack/types';
2
2
  export type DemoWrapperProps = {
3
3
  children: React.ReactNode;
4
4
  demo: Demo;
5
+ patternId: string;
6
+ templateId: string;
5
7
  };
6
8
  declare const DemoWrapper: ({ children }: DemoWrapperProps) => import("react/jsx-runtime").JSX.Element;
7
9
  export default DemoWrapper;
@@ -1 +1 @@
1
- {"version":3,"file":"demo-wrapper.d.ts","sourceRoot":"","sources":["../src/demo-wrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF,QAAA,MAAM,WAAW,GAAI,cAAc,gBAAgB,4CAElD,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"demo-wrapper.d.ts","sourceRoot":"","sources":["../src/demo-wrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,WAAW,GAAI,cAAc,gBAAgB,4CAElD,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"demo-wrapper.js","sourceRoot":"","sources":["../src/demo-wrapper.tsx"],"names":[],"mappings":";AAOA,MAAM,WAAW,GAAG,CAAC,EAAE,QAAQ,EAAoB,EAAE,EAAE,CAAC,CACtD,cAAK,SAAS,EAAC,cAAc,YAAE,QAAQ,GAAO,CAC/C,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"demo-wrapper.js","sourceRoot":"","sources":["../src/demo-wrapper.tsx"],"names":[],"mappings":";AASA,MAAM,WAAW,GAAG,CAAC,EAAE,QAAQ,EAAoB,EAAE,EAAE,CAAC,CACtD,cAAK,SAAS,EAAC,cAAc,YAAE,QAAQ,GAAO,CAC/C,CAAC;AAEF,eAAe,WAAW,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@knapsack/renderer-react-components",
3
3
  "description": "",
4
- "version": "4.79.2",
4
+ "version": "4.79.3--canary.6036.f7fab19.0",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  "./demo-wrapper": {
@@ -35,10 +35,10 @@
35
35
  "lint": "eslint ./"
36
36
  },
37
37
  "devDependencies": {
38
- "@knapsack/eslint-config-starter": "4.79.2",
39
- "@knapsack/prettier-config": "4.79.2",
40
- "@knapsack/types": "4.79.2",
41
- "@knapsack/typescript-config-starter": "4.79.2",
38
+ "@knapsack/eslint-config-starter": "4.79.3--canary.6036.f7fab19.0",
39
+ "@knapsack/prettier-config": "4.79.3--canary.6036.f7fab19.0",
40
+ "@knapsack/types": "4.79.3--canary.6036.f7fab19.0",
41
+ "@knapsack/typescript-config-starter": "4.79.3--canary.6036.f7fab19.0",
42
42
  "@types/node": "^20.17.24",
43
43
  "@types/prop-types": "^15.7.14",
44
44
  "@types/react": "^18.3.20",
@@ -56,5 +56,5 @@
56
56
  "directory": "apps/client/libs/renderer-react-components",
57
57
  "type": "git"
58
58
  },
59
- "gitHead": "a97f048e259c07f4887a675bd339dea5d736721e"
59
+ "gitHead": "f7fab193b76725d99a7f77f334c13776477f1378"
60
60
  }
@@ -0,0 +1,14 @@
1
+ import type { Demo } from '@knapsack/types';
2
+
3
+ export type DemoWrapperProps = {
4
+ children: React.ReactNode;
5
+ demo: Demo;
6
+ patternId: string;
7
+ templateId: string;
8
+ };
9
+
10
+ const DemoWrapper = ({ children }: DemoWrapperProps) => (
11
+ <div className="demo-wrapper">{children}</div>
12
+ );
13
+
14
+ export default DemoWrapper;
@@ -0,0 +1,79 @@
1
+ import * as React from 'react';
2
+
3
+ type State = {
4
+ hasError: boolean;
5
+ componentStack?: string;
6
+ error?: Error;
7
+ };
8
+
9
+ export default class ErrorCatcher extends React.Component<
10
+ { children: React.ReactNode },
11
+ State
12
+ > {
13
+ constructor(props: { children: React.ReactNode }) {
14
+ super(props);
15
+ this.state = {
16
+ hasError: false,
17
+ componentStack: '',
18
+ };
19
+ }
20
+
21
+ static getDerivedStateFromError(_error: Error) {
22
+ // Update state so the next render will show the fallback UI.
23
+ return {
24
+ hasError: true,
25
+ };
26
+ }
27
+
28
+ override componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {
29
+ const { componentStack } = errorInfo;
30
+ this.setState({
31
+ error,
32
+ componentStack: componentStack ?? '',
33
+ });
34
+ }
35
+
36
+ override render() {
37
+ if (this.state.hasError) {
38
+ return (
39
+ <div
40
+ style={{
41
+ padding: '5px',
42
+ }}
43
+ >
44
+ <h5>Error caught in React Components</h5>
45
+ {this.state.error?.name && (
46
+ <h5>
47
+ Error Name: <code>{this.state.error?.name}</code>
48
+ </h5>
49
+ )}
50
+ {this.state.error?.message && (
51
+ <h5>
52
+ Message:
53
+ {this.state.error?.message}
54
+ </h5>
55
+ )}
56
+ {this.state.componentStack && (
57
+ <>
58
+ <h6>Component Stack:</h6>
59
+ <pre>
60
+ <code>{this.state.componentStack}</code>
61
+ </pre>
62
+ <br />
63
+ </>
64
+ )}
65
+ {this.state.error?.stack && (
66
+ <>
67
+ <h6>Error Stack:</h6>
68
+ <pre>
69
+ <code>{this.state.error?.stack}</code>
70
+ </pre>
71
+ </>
72
+ )}
73
+ </div>
74
+ );
75
+ }
76
+
77
+ return this.props.children;
78
+ }
79
+ }
@@ -0,0 +1,5 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ const PrototypeWrapper = ({ children }: { children: ReactNode }) => children;
4
+
5
+ export default PrototypeWrapper;
@@ -0,0 +1,26 @@
1
+ import { StrictMode, type ComponentType } from 'react';
2
+ import type { Except } from '@knapsack/types';
3
+ import ErrorCatcher from './error-catcher.js';
4
+ import type { DemoWrapperProps } from './demo-wrapper.js';
5
+
6
+ export const ReactRendererClientApp = ({
7
+ DemoApp,
8
+ DemoWrapper,
9
+ disableReactStrictMode,
10
+ demoWrapperProps,
11
+ }: {
12
+ DemoApp: ComponentType<Record<string, unknown>>;
13
+ DemoWrapper: ComponentType<Record<string, unknown>>;
14
+ demoWrapperProps: Except<DemoWrapperProps, 'children'>;
15
+ disableReactStrictMode?: boolean;
16
+ }) => {
17
+ const app = (
18
+ <ErrorCatcher>
19
+ <DemoWrapper {...demoWrapperProps}>
20
+ <DemoApp />
21
+ </DemoWrapper>
22
+ </ErrorCatcher>
23
+ );
24
+
25
+ return disableReactStrictMode ? app : <StrictMode>{app}</StrictMode>;
26
+ };
@@ -0,0 +1,7 @@
1
+ export const Button = (props: {
2
+ text: string;
3
+ size?: 'small' | 'medium' | 'large';
4
+ children: React.ReactNode;
5
+ }) => {
6
+ return <button type="button">{props.text}</button>;
7
+ };
@@ -0,0 +1,79 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ export class CardPropTypes extends React.Component {
5
+ constructor(props: any) {
6
+ super(props);
7
+ this.state = {
8
+ count: 0,
9
+ };
10
+ this.handleButtonClick = this.handleButtonClick.bind(this);
11
+ }
12
+
13
+ handleButtonClick() {
14
+ this.setState((prevState) => {
15
+ // @ts-expect-error purposely not typed
16
+ const newCount = prevState.count + 1;
17
+ // @ts-expect-error purposely not typed
18
+ this.props.handleClick(newCount);
19
+ return { count: newCount };
20
+ });
21
+ }
22
+
23
+ override render() {
24
+ return (
25
+ <aside
26
+ // @ts-expect-error purposely not typed
27
+ className={`card card--align-${this.props.align}${
28
+ // @ts-expect-error purposely not typed
29
+ this.props.isDark ? ' card--dark' : ''
30
+ }`}
31
+ >
32
+ {/* @ts-expect-error purposely not typed */}
33
+ {this.props.headerSlot}
34
+ <div
35
+ className="card__img"
36
+ // @ts-expect-error purposely not typed
37
+ style={{ backgroundImage: `url("${this.props.img}")` }}
38
+ />
39
+ <div className="card__contents">
40
+ {/* @ts-expect-error purposely not typed */}
41
+ <h3 className="card__title">{this.props.title}</h3>
42
+ <p>
43
+ Count:
44
+ {/* @ts-expect-error purposely not typed */}
45
+ {this.state.count}
46
+ </p>
47
+ <button onClick={this.handleButtonClick} type="button">
48
+ Add
49
+ </button>
50
+ {/* @ts-expect-error purposely not typed */}
51
+ <p className="card__body">{this.props.body}</p>
52
+ </div>
53
+ {/* @ts-expect-error purposely not typed */}
54
+ <footer className="card__footer">{this.props.children}</footer>
55
+ </aside>
56
+ );
57
+ }
58
+ }
59
+
60
+ // @ts-expect-error purposely not typed
61
+ CardPropTypes.defaultProps = {
62
+ align: 'left',
63
+ children: null,
64
+ handleClick: () => {},
65
+ isDark: false,
66
+ };
67
+
68
+ // @ts-expect-error purposely not typed
69
+ CardPropTypes.propTypes = {
70
+ /**
71
+ * The card title
72
+ */
73
+ title: PropTypes.string.isRequired,
74
+ align: PropTypes.oneOf(['left', 'right']),
75
+ children: PropTypes.node,
76
+ headerSlot: PropTypes.node.isRequired,
77
+ handleClick: PropTypes.func,
78
+ isDark: PropTypes.bool,
79
+ };
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+
3
+ // export const CardButton = ({ disabled = false, text }) => (
4
+ // <button>{text}</button>
5
+ // );
6
+
7
+ type Props = {
8
+ textAlign?: 'left' | 'center' | 'right';
9
+ // cardHeader?: string;
10
+ imgSrc?: string;
11
+ isDark?: boolean;
12
+ cardTitle?: string;
13
+ cardSubTitle?: string;
14
+ cardBody: string;
15
+ handleIt?: (x: string) => boolean;
16
+ header?: React.ReactNode;
17
+ /**
18
+ * Goes in footer
19
+ */
20
+ children?: React.ReactNode;
21
+ items: {
22
+ id: string;
23
+ title: string;
24
+ description?: string;
25
+ }[];
26
+ };
27
+
28
+ export const Card: React.FC<Props> = ({
29
+ textAlign = 'left',
30
+ children,
31
+ cardBody,
32
+ // cardHeader,
33
+ cardSubTitle,
34
+ cardTitle,
35
+ imgSrc,
36
+ isDark = true,
37
+ }: Props) => {
38
+ const classes = `card text-${textAlign} ${isDark ? 'bg-dark' : ''}`;
39
+ return (
40
+ <div className={classes}>
41
+ {imgSrc && <img src={imgSrc} className="card-img-top" alt="hi" />}
42
+ <div className="card-body">
43
+ <h5 className="card-title">{cardTitle}</h5>
44
+ {cardSubTitle && (
45
+ <h6 className="card-subtitle mb-2 text-muted">{cardSubTitle}</h6>
46
+ )}
47
+ <p className="card-text">{cardBody}</p>
48
+ {children}
49
+ </div>
50
+ </div>
51
+ );
52
+ };
53
+
54
+ export default Card;
@@ -0,0 +1,25 @@
1
+ // Example with complex TypeScript types
2
+ interface ComplexProps {
3
+ /** Array of user objects */
4
+ users: Array<{
5
+ id: number;
6
+ name: string;
7
+ role: 'admin' | 'user';
8
+ }>;
9
+ /** Configuration object */
10
+ config: {
11
+ theme: 'light' | 'dark';
12
+ showHeader: boolean;
13
+ };
14
+ }
15
+
16
+ export const ComplexComponent = ({
17
+ users,
18
+ config,
19
+ }: ComplexProps): JSX.Element => (
20
+ <div>
21
+ {users.map((user) => (
22
+ <div key={user.id}>{user.name}</div>
23
+ ))}
24
+ </div>
25
+ );
@@ -0,0 +1,20 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ // // Example with generic types
4
+ interface ListProps<T> {
5
+ /** List of items */
6
+ items: T[];
7
+ /** Render function for each item */
8
+ renderItem: (item: T) => ReactNode;
9
+ }
10
+
11
+ export const GenericComponentType = <T,>({
12
+ items,
13
+ renderItem,
14
+ }: ListProps<T>): JSX.Element => (
15
+ <ul>
16
+ {items.map((item, index) => (
17
+ <li key={JSON.stringify(item)}>{renderItem(item)}</li>
18
+ ))}
19
+ </ul>
20
+ );
@@ -0,0 +1,6 @@
1
+ export * from './button.js';
2
+ export * from './card.js';
3
+ export * from './card-prop-types.js';
4
+ export * from './complex-props.js';
5
+ export * from './generic-component-type.js';
6
+ export * from './render-node-props.js';
@@ -0,0 +1,23 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ // Example with render props using TypeScript
4
+ interface RenderPropsComponentProps {
5
+ /** Header render function */
6
+ renderHeader: () => ReactNode;
7
+ /** Content render function */
8
+ renderContent: (data: { count: number }) => ReactNode;
9
+ /** Optional footer */
10
+ footer?: ReactNode;
11
+ }
12
+
13
+ export const RenderPropsComponent = ({
14
+ renderHeader,
15
+ renderContent,
16
+ footer,
17
+ }: RenderPropsComponentProps): JSX.Element => (
18
+ <div>
19
+ {renderHeader()}
20
+ {renderContent({ count: 0 })}
21
+ {footer}
22
+ </div>
23
+ );