-
Notifications
You must be signed in to change notification settings - Fork 318
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
AmplifyProvider accepts partial list of primitives as
components
(#582
- Loading branch information
1 parent
3985283
commit 3143def
Showing
4 changed files
with
92 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
--- | ||
"@aws-amplify/ui-react": patch | ||
--- | ||
|
||
AmplifyProvider accepts a partial list of primitives as `components`: | ||
|
||
```js | ||
const App = () => { | ||
const { | ||
components: { Heading }, | ||
} = useAmplify(); | ||
|
||
return <Heading>Howdy</Heading>; | ||
}; | ||
|
||
|
||
<AmplifyProvider | ||
components={{ | ||
Heading({ children }) { | ||
return <h1>{children}</h1>; | ||
}, | ||
}} | ||
> | ||
<App /> | ||
</AmplifyProvider> | ||
``` |
54 changes: 54 additions & 0 deletions
54
packages/react/src/components/AmplifyProvider/__tests__/AmplifyProvider.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { render, screen } from '@testing-library/react'; | ||
import { useAmplify } from '../../../hooks'; | ||
|
||
import { AmplifyProvider } from '..'; | ||
|
||
const App = () => { | ||
const { | ||
components: { Heading }, | ||
} = useAmplify(); | ||
|
||
return <Heading>Howdy</Heading>; | ||
}; | ||
|
||
describe('AmplifyProvider', () => { | ||
it('does not require props', async () => { | ||
render( | ||
<AmplifyProvider> | ||
<App /> | ||
</AmplifyProvider> | ||
); | ||
|
||
const heading = await screen.getByText('Howdy'); | ||
expect(heading.nodeName).toBe('H6'); | ||
}); | ||
|
||
it('wraps the App in [data-amplify-theme="default-theme"]', () => { | ||
const { container } = render( | ||
<AmplifyProvider> | ||
<App /> | ||
</AmplifyProvider> | ||
); | ||
|
||
const wrapper = container.querySelector('[data-amplify-theme]'); | ||
expect(wrapper).toBeInTheDocument(); | ||
expect(wrapper).toHaveAttribute('data-amplify-theme', 'default-theme'); | ||
}); | ||
|
||
it('accepts custom primitives as components', async () => { | ||
render( | ||
<AmplifyProvider | ||
components={{ | ||
Heading({ children }) { | ||
return <h1>Custom {children}</h1>; | ||
}, | ||
}} | ||
> | ||
<App /> | ||
</AmplifyProvider> | ||
); | ||
|
||
const heading = await screen.getByText('Custom Howdy'); | ||
expect(heading.nodeName).toBe('H1'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,18 @@ | ||
import { useContext } from 'react'; | ||
import * as React from 'react'; | ||
|
||
import { AmplifyContext } from '../components/AmplifyProvider/AmplifyContext'; | ||
import * as primitives from '../primitives'; | ||
|
||
export function useAmplify(namespace) { | ||
const { components = {}, theme } = useContext(AmplifyContext); | ||
|
||
const customComponents = Object.entries(components).reduce( | ||
(acc, [namespaced, Component]) => { | ||
// `Authenticator.SignIn.Button` => `Button` | ||
const name = namespaced.split('.').pop(); | ||
|
||
// TODO `Authenticator.Button` should also override `Authenticator.SignIn.Button`? Maybe not... | ||
// But wait, `Input` should override `Authenticator.Input`! | ||
// if (namespaced === `${namespace}.${name}`) { | ||
// TODO Support decorator pattern (e.g. `acc[name] = Component(InputPrimitive)`) | ||
// TODO Pass in the previous component, not necessarily a primitive (e.g. SignIn?) | ||
acc[name] = Component; | ||
// } | ||
|
||
return acc; | ||
}, | ||
{} | ||
); | ||
|
||
// TODO `theme` should override `style` or `className`? | ||
|
||
// const styledComponents = Object.entries(components).reduce( | ||
// (acc, [name, Component]) => { | ||
// // e.g. `Authenticator.Input` || `Input` | ||
// // TODO Is this needed anymore? Maybe so for custom tailwind overrides! | ||
// const className = | ||
// custom.theme?.[`${namespace}.${name}`] || custom.theme?.[name]; | ||
// const namespaced = `${namespace}.${name}`; | ||
|
||
// acc[name] = | ||
// custom.components?.[namespaced] || | ||
// custom.components?.[name] || | ||
// Component; | ||
|
||
// return acc; | ||
// }, | ||
// {} | ||
// ); | ||
|
||
return { | ||
components: { | ||
export function useAmplify() { | ||
const context = React.useContext(AmplifyContext); | ||
const { components: customComponents, theme } = context; | ||
const components = React.useMemo( | ||
() => ({ | ||
...primitives, | ||
...customComponents, | ||
}, | ||
}), | ||
[customComponents] | ||
); | ||
|
||
theme, | ||
}; | ||
return { components, theme }; | ||
} |