-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#7670: Simplify creation of isolated widgets (IsolatedComponent
)
#8151
Changes from all commits
46d2207
708ba2b
0671574
386b02c
6a273f9
360f843
e3018e8
4760ee0
a2c75b9
9760393
df1ec00
a6dc0fe
652339a
c5aa5f6
3d139a2
123b53a
16542a2
fb4d8a4
a349a66
efb53fe
f195c5c
fee63aa
e29f974
82b3dd4
3313bc3
1334a91
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,16 +55,25 @@ const config = { | |
silent: true, | ||
testEnvironment: "./src/testUtils/FixJsdomEnvironment.js", | ||
modulePaths: ["/src"], | ||
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "yaml", "yml", "json"], | ||
moduleFileExtensions: [ | ||
"ts", | ||
"tsx", | ||
"js", | ||
"jsx", | ||
"mjs", | ||
"yaml", | ||
"yml", | ||
"json", | ||
], | ||
modulePathIgnorePatterns: ["<rootDir>/headers.json", "<rootDir>/dist/"], | ||
testPathIgnorePatterns: ["/end-to-end-tests"], | ||
transform: { | ||
"^.+\\.[jt]sx?$": "@swc/jest", | ||
"^.+\\.mjs$": "@swc/jest", | ||
"^.+\\.ya?ml$": "yaml-jest-transform", | ||
"^.+\\.ya?ml\\?loadAsText$": | ||
"<rootDir>/src/testUtils/rawJestTransformer.mjs", | ||
"^.+\\.txt$": "<rootDir>/src/testUtils/rawJestTransformer.mjs", | ||
"\\.[jt]sx?$": "@swc/jest", | ||
"\\.mjs$": "@swc/jest", | ||
"\\.ya?ml$": "yaml-jest-transform", | ||
"\\.txt$": "<rootDir>/src/testUtils/rawJestTransformer.mjs", | ||
// Note: `?param` URLs aren't supported here: https://github.com/jestjs/jest/pull/6282 | ||
// You can only use a mock via `moduleNameMapper` for these. | ||
}, | ||
transformIgnorePatterns: [`node_modules/(?!${esmPackages.join("|")})`], | ||
setupFiles: [ | ||
|
@@ -89,11 +98,15 @@ const config = { | |
"!**/vendor/**", | ||
], | ||
moduleNameMapper: { | ||
"^@contrib/([^?]+)": "<rootDir>/contrib/$1", | ||
"^@schemas/([^?]+)": "<rootDir>/schemas/$1", | ||
|
||
"\\.s?css$": "identity-obj-proxy", | ||
"\\.(gif|svg|png)$|\\?loadAsUrl$|\\?loadAsComponent$": | ||
"<rootDir>/src/__mocks__/stringMock.js", | ||
"^@contrib/(.*?)(\\?loadAsText)?$": "<rootDir>/contrib/$1", | ||
"^@schemas/(.*)": "<rootDir>/schemas/$1", | ||
"\\.(gif|svg|png)$": "<rootDir>/src/__mocks__/stringMock.js", | ||
|
||
"\\?loadAsUrl$": "<rootDir>/src/__mocks__/stringMock.js", | ||
"\\?loadAsText$": "<rootDir>/src/__mocks__/stringMock.js", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this conflict with the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given that tests and snapshots don't need to be updated, I'm guessing that it's not actually being applied nor needed. Anyway I think these 4 above should be moved below. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just wondered if it's related to the changes to imports in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sort of. I dropped it from that test file because:
Since I cleaned up line 109 as well: 1334a91 |
||
"\\?loadAsComponent$": "<rootDir>/src/__mocks__/stringMock.js", | ||
|
||
// Auto-mocks. See documentation in ./src/__mocks__/readme.md | ||
"^@/(.*)$": ["<rootDir>/src/__mocks__/@/$1", "<rootDir>/src/$1"], | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,25 +15,22 @@ | |
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
import "primereact/resources/themes/saga-blue/theme.css"; | ||
import "primereact/resources/primereact.min.css"; | ||
import "primeicons/primeicons.css"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can just load the stylesheets normally now 🎉 |
||
|
||
import { TreeTable } from "primereact/treetable"; | ||
import type TreeNode from "primereact/treenode"; | ||
import { Column } from "primereact/column"; | ||
import { Stylesheets } from "@/components/Stylesheets"; | ||
import React from "react"; | ||
|
||
import theme from "primereact/resources/themes/saga-blue/theme.css?loadAsUrl"; | ||
import primereact from "primereact/resources/primereact.min.css?loadAsUrl"; | ||
import primeicons from "primeicons/primeicons.css?loadAsUrl"; | ||
|
||
const PropertyTree: React.FunctionComponent<{ value: TreeNode[] }> = ({ | ||
value, | ||
}) => ( | ||
<Stylesheets href={[theme, primereact, primeicons]}> | ||
<TreeTable value={value}> | ||
<Column field="name" header="Property" expander /> | ||
<Column field="value" header="Value" /> | ||
</TreeTable> | ||
</Stylesheets> | ||
<TreeTable value={value}> | ||
<Column field="name" header="Property" expander /> | ||
<Column field="value" header="Value" /> | ||
</TreeTable> | ||
); | ||
|
||
export default PropertyTree; |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -21,6 +21,8 @@ import { sortBy, isPlainObject } from "lodash"; | |||||||||||||||||||||||||||||||
import { type BrickArgs, type BrickOptions } from "@/types/runtimeTypes"; | ||||||||||||||||||||||||||||||||
import { canParseUrl } from "@/utils/urlUtils"; | ||||||||||||||||||||||||||||||||
import { propertiesToSchema } from "@/utils/schemaUtils"; | ||||||||||||||||||||||||||||||||
import IsolatedComponent from "@/components/IsolatedComponent"; | ||||||||||||||||||||||||||||||||
import type TreeNode from "primereact/treenode"; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
interface Item { | ||||||||||||||||||||||||||||||||
key: string; | ||||||||||||||||||||||||||||||||
|
@@ -115,13 +117,21 @@ export class PropertyTableRenderer extends RendererABC { | |||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
async render({ data }: BrickArgs, { ctxt }: BrickOptions) { | ||||||||||||||||||||||||||||||||
const PropertyTree = await import( | ||||||||||||||||||||||||||||||||
/* webpackChunkName: "widgets" */ | ||||||||||||||||||||||||||||||||
"./PropertyTree" | ||||||||||||||||||||||||||||||||
const PropertyTree: React.FC<{ value: TreeNode[] }> = ({ value }) => ( | ||||||||||||||||||||||||||||||||
<IsolatedComponent | ||||||||||||||||||||||||||||||||
name="PropertyTree" | ||||||||||||||||||||||||||||||||
lazy={async () => | ||||||||||||||||||||||||||||||||
import( | ||||||||||||||||||||||||||||||||
/* webpackChunkName: "isolated/PropertyTree" */ | ||||||||||||||||||||||||||||||||
"./PropertyTree" | ||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
factory={(PropertyTree) => <PropertyTree value={value} />} | ||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||
Comment on lines
+121
to
+130
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the format I ended up with, I think it's compact and readable enough, which is important due to all the restrictions:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like to document some of these requirements all in one place somewhere (e.g. it's not clear just looking at IsolatedComponent.tsx that you'd need to add that component to isolatedComponentList). Either in the docstring directly or in a README that's referenced in the docstring. If I'm looking to add a new isolated component, what are the steps that need to be taken and out-of-the box behaviors or assumptions that are made? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes definitely it needs some documentation and a lint rule, but:
I can't think of anything that breaks that isn't already caught but the build.
Since "PropertyTree" is now loaded as an isolated component, it needs to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I just checked, each prop is already documented and it includes the requirement: pixiebrix-extension/src/components/IsolatedComponent.tsx Lines 61 to 70 in 1334a91
Also this: pixiebrix-extension/src/components/IsolatedComponent.tsx Lines 108 to 112 in 1334a91
|
||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||||
Component: PropertyTree.default, | ||||||||||||||||||||||||||||||||
Component: PropertyTree, | ||||||||||||||||||||||||||||||||
props: { | ||||||||||||||||||||||||||||||||
value: shapeData(data ?? ctxt), | ||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
/* | ||
eslint-disable @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unnecessary-type-assertion -- | ||
"Every property exists" (via Proxy), TypeScript doesn't offer such type | ||
Also strictNullChecks config mismatch */ | ||
/* | ||
* Copyright (C) 2024 PixieBrix, Inc. | ||
* | ||
|
@@ -19,10 +23,13 @@ | |
import EmotionShadowRoot from "react-shadow/emotion"; | ||
import { type CSSProperties } from "react"; | ||
|
||
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unnecessary-type-assertion -- | ||
"Every property exists" (via Proxy), TypeScript doesn't offer such type | ||
Also strictNullChecks config mismatch */ | ||
/** | ||
* Wrap components in a shadow DOM. This isolates them from styles inherited from | ||
* the host website. To support react-select and any future potential emotion | ||
* components we used the emotion variant of the react-shadow library. | ||
*/ | ||
const ShadowRoot = EmotionShadowRoot.div!; | ||
// TODO: Use EmotionShadowRoot["pixiebrix-widget"] to avoid any CSS conflicts. Requires snapshot/test updates | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried this in the POC PR, but it affected too many tests. I can try again later. |
||
|
||
export const styleReset: CSSProperties = { | ||
all: "initial", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated these to avoid confusion. See comment/link.