-
Notifications
You must be signed in to change notification settings - Fork 16
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
feat: support merging base component props, custom props, and pluginProps
via slotOptions.mergeProps
#84
feat: support merging base component props, custom props, and pluginProps
via slotOptions.mergeProps
#84
Conversation
f8aca45
to
e068ebd
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #84 +/- ##
==========================================
+ Coverage 96.79% 97.80% +1.01%
==========================================
Files 10 10
Lines 187 228 +41
Branches 41 58 +17
==========================================
+ Hits 181 223 +42
+ Misses 5 4 -1
Partials 1 1 ☔ View full report in Codecov by Sentry. |
716ba3e
to
3702c58
Compare
@@ -18,12 +17,28 @@ const modifyWidget = (widget) => { | |||
return modifiedWidget; | |||
}; | |||
|
|||
const wrapWidget = ({ component, idx }) => ( | |||
<div className="bg-warning" data-testid={`wrapper${idx + 1}`} key={idx}> |
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.
[inform/context] Passing the key
here does not resolve the React console warning; The key
needs to be applied to the parent wrapWidget
function as opposed to a node within wrapWidget
, given its acting as a component (e.g., wrapWidget
is the display name of the rendered component).
import PluginSlotWithInsert from './pluginSlots/PluginSlotWithInsert'; | ||
import PluginSlotWithModifyWrapHide from './pluginSlots/PluginSlotWithModifyWrapHide'; | ||
import PluginSlotWithModularPlugins from './pluginSlots/PluginSlotWithModularPlugins'; | ||
import PluginSlotWithoutDefault from './pluginSlots/PluginSlotWithoutDefault'; | ||
|
||
const pluginExamples = [ |
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.
[inform/context] Refactored ExamplePage
to iterate through pluginExamples
to ensure the generated Table of Content links (below) are created in the same order as the plugin examples themselves.
<ul> | ||
{pluginExamples.map(({ id, label }) => ( | ||
<li key={id}> | ||
<a href={`#${id}`}>{label}</a> | ||
</li> | ||
))} | ||
</ul> |
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.
[inform/context] Includes a small list of skip links to navigate to specific example(s), without necessarily needing to scroll to find a specific example.
@@ -16,9 +16,10 @@ | |||
"lint": "fedx-scripts eslint --ext .js --ext .jsx .", | |||
"lint:fix": "fedx-scripts eslint --fix --ext .js --ext .jsx .", | |||
"snapshot": "fedx-scripts jest --updateSnapshot", | |||
"start": "./node_modules/.bin/fedx-scripts babel src --watch --out-dir dist --source-maps --ignore **/*.test.jsx,**/*.test.js,**/setupTest.js --copy-files", | |||
"start": "fedx-scripts babel src --watch --out-dir dist --source-maps --ignore **/*.test.jsx,**/*.test.js,**/setupTest.js", |
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.
./node_modules/.bin/
isn't needed to callfedx-scripts
(per other NPM scripts above).--copy-files
seems to copy test files intodist
, even though they are ignored through--ignore
. When running tests, it runs tests against thedist
andsrc
directories, instead of justsrc
. Without--copy-files
,npm run test
will only work againstsrc
as intended.
"start:example": "npm --prefix example start & npm --prefix example-plugin-app start", | ||
"test": "fedx-scripts jest --coverage --passWithNoTests" | ||
"test": "fedx-scripts jest --coverage --passWithNoTests", | ||
"test:watch": "npm run test -- --watch" |
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.
[inform/context] Exposes a "test:watch" command; same behavior as npm run test
, but uses a watcher to re-run tests on file saves.
5cb8851
to
e1a762b
Compare
PluginOperations.Modify
6b5dde7
to
208a3a4
Compare
PluginOperations.Modify
pluginProps
via slotOptions.mergeProps
1931be1
to
1886404
Compare
1886404
to
aff65a1
Compare
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.
Overall this is looking great! Awesome cleanup and the new feature works beautifully (as I've found out by using it in openedx/frontend-component-header#528)
I left a couple small comments about naming, and a couple questions about default slotOptions
. From what I can tell existing PluginSlot
s used without setting slotOptions
should still be fine and there are just a couple places where comments aren't making that clear, but if I'm mistaken about that then I'd like to discuss what can be done to make sure that is the case and this can land as a non-breaking change!
example/src/pluginSlots/PluginSlotWithModifyDefaultContents.jsx
Outdated
Show resolved
Hide resolved
example/src/pluginSlots/PluginSlotWithModifyDefaultContentsLink.jsx
Outdated
Show resolved
Hide resolved
e04659a
to
49df398
Compare
49df398
to
be17231
Compare
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.
Super exciting to see this all come together!
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.
Just one nit pick on a comment. Feel free to disregard if you think it's unnecessary.
Thanks for adding this feature as well as cleaning up the areas around it! 😄
Oof, I'm going to have to figure out how to merge this into frontend-base, where I've been Typescript-ifying the frontend-plugin-framework code. 😬 |
🎉 This PR is included in version 1.3.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
CHANGELOG
This PR introduces several key improvements, bug fixes, and new features to the frontend-plugin-framework. The following changes have been made:
Slot Options for
PluginSlot
slotOptions
prop to thePluginSlot
component.slotOptions
allow opting into merging props, rather than exposing prop modifications solely withincontent
to the widget.default_contents
widget, and handles special cases such asclassName
,style
, and event handlers (i.e., functions).Validation of
PluginSlot
Childrendefault_contents
widget now only works whenPluginSlot
contains a single React element as itschildren
, but you may still pass all types of children, including plain text (strings), multiple elements, etc.Parity in Widget Prop Handling
pluginProps
are passed to thedefault_contents
widget, achieving consistency across all widgets.PluginSlot
to pass some widget props both inpluginProps
and directly to the defaultchildren
element, as is done in a few existing usages.React Key Warning Fix
key
warning was triggered when a widget was wrapped via a plugin.Default Value Adjustment for
className
className
prop has been changed toundefined
. This ensures that an emptyclass
attribute isn't rendered in the DOM.Automated TOC and PluginSlot Examples in Example App
ExamplePage
in the example app now automates the generation of a Table of Contents (TOC) andPluginSlot
examples.New
PluginOperations.Modify
ExamplePluginOperations.Modify
applied to the "default_contents" widget in the example app'sExamplePage
.NPM Script Updates
start
NPM script to exclude test files by removing the--copy-files
flag.test:watch
NPM script to streamline the testing process.Test Enhancements
Minor Syntax Cleanup
These changes improve the overall robustness of the framework, provide better customization options for consumers, and address some existing issues with the current implementation.
Examples
Enabling merged props within
PluginSlot
viaslotOptions