Skip to content

Commit

Permalink
feat: add option to use scope data in providers easily
Browse files Browse the repository at this point in the history
  • Loading branch information
rangoo94 committed Oct 17, 2023
1 parent 80d36e3 commit 2ff8a0b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
6 changes: 6 additions & 0 deletions packages/plugins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ export default createPlugin('some-name')

// You may use alternative JSX syntax too, the children will be added automatically anyway.
.provider(<SomeContext.Provider value={{foo: 'bar'}} />)

// Additionally

.init();
```
Expand All @@ -262,6 +264,10 @@ export default createPlugin('some-name')
// Inject the store
.provider(<StoreProvider store={initializeSomeStore} />)

// Such store may be reset by some data too
.needs(data<string>()('environmentId'))
.provider(tk => <StoreProvider store={initializeSomeStore} dependencies={[tk.data.environmentId]} />)

// Expose public interface for other plugins
.data({useSomeStorePick})

Expand Down
18 changes: 18 additions & 0 deletions packages/plugins/src/PluginResolver.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -560,4 +560,22 @@ describe('plugins', () => {
'dynamic4',
]);
});

it('should allow reading the scope in the provider definition', () => {
const Context = createContext<any>(null);
const Reader: FC = () => <div data-testid={useContext(Context)} />;
const plugin = createPlugin('plugin')
.data({value: 'some1'})
.provider(tk => <Context.Provider value={tk.data.value} />)
.init();
const [Provider, {initialize}] = new PluginResolver().register(plugin).resolve();
const scope = initialize();
const result = render(
<Provider root={scope}>
<Reader />
</Provider>
);

expect(result.queryByTestId('some1')).toBeTruthy();
});
});
19 changes: 18 additions & 1 deletion packages/plugins/src/internal/PluginBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type {ReactElement} from 'react';
import {createElement} from 'react';

import {usePluginScope} from '../hooks';

import {Plugin} from './Plugin';
import {PluginScope} from './PluginScope';
Expand Down Expand Up @@ -59,7 +62,21 @@ export class PluginBuilder<T extends PluginState> {
* It may have condition,
* but conditional providers are included after those without condition.
*/
public provider<U>(provider: PluginProvider<U>, metadata: PluginProviderMetadata<T> = {}): PluginBuilder<T> {
public provider<U>(
rawProvider: PluginProvider<U> | ((tk: PluginScope<PluginScopeStateFor<T>>) => PluginProvider<U>),
metadata: PluginProviderMetadata<T> = {}
): PluginBuilder<T> {
const provider =
typeof rawProvider === 'function'
? ({
type: (props: any) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const {type: Provider, props: innerProps} = rawProvider(usePluginScope());
return createElement(Provider as any, {...innerProps, ...props});
},
props: {},
} as unknown as PluginProvider<U>)
: rawProvider;
return new PluginBuilder({
...this.plugin,
providers: [...this.plugin.providers, {provider, metadata}],
Expand Down

0 comments on commit 2ff8a0b

Please sign in to comment.