Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions packages/ui/src/components/sign-in/sign-in.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { SignInGetHelp } from '~/components/sign-in/steps/get-help';
import { SignInResetPassword } from '~/components/sign-in/steps/reset-password';
import { SignInStart } from '~/components/sign-in/steps/start';
import { SignInVerifications } from '~/components/sign-in/steps/verifications';
import { type Appearance, AppearanceProvider, useAppearance } from '~/contexts';
import { type Appearance, AppearanceProvider } from '~/contexts';

import { SignInChooseSession } from './steps/choose-session';

Expand All @@ -25,13 +25,9 @@ import { SignInChooseSession } from './steps/choose-session';
*/
export function SignIn({ appearance }: { appearance?: Appearance }) {
const [showHelp, setShowHelp] = React.useState(false);
const { appearance: globalAppearance } = useAppearance();

return (
<AppearanceProvider
globalAppearance={globalAppearance}
appearance={appearance}
>
<AppearanceProvider appearance={appearance}>
<GetHelpContext.Provider value={{ showHelp, setShowHelp }}>
<SignInRoot>
{showHelp ? (
Expand Down
41 changes: 15 additions & 26 deletions packages/ui/src/contexts/AppearanceContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,6 @@ export type ParsedAppearance = {
};

type AppearanceContextValue = {
/**
* The appearance value provided to the AppearanceProvider. Should be passed to children `AppearanceProvider`s as the
* `globalAppearance` prop.
*
* Example:
* ```tsx
* function SignIn({ children }) {
* const { appearance } = useAppearance();
* return (<AppearanceProvider globalAppearance={appearance} appearance={{}}>{children}</AppearanceProvider>)
* }
* ```
*/
appearance?: Appearance;

// TODO: This can probably be removed
globalAppearance?: Appearance;

/**
* The calculated appearance value based on the provided `appearance` and `globalAppearance`.
*
Expand Down Expand Up @@ -81,24 +64,30 @@ function parseAppearance(props: AppearanceCascade): ParsedAppearance {
return appearance;
}

const [AppearanceContext, useAppearance] = createContextAndHook<AppearanceContextValue>('AppearanceContext');
const [AppearanceContext, useAppearance, usePartialAppearance] =
createContextAndHook<AppearanceContextValue>('AppearanceContext');

type AppearanceProviderProps = React.PropsWithChildren<AppearanceCascade>;
type AppearanceProviderProps = React.PropsWithChildren<{ appearance?: Appearance }>;

/**
* Used to provide appearance values throughout an application. In typical usage, the entire application will be
* wrapped in an `AppearanceProvider` to provide global configuration. Each top-level AIO component that accepts an
* `appearance` prop will wrap its children in `AppearanceProvider`, and provide the `appearance` value from
* `useAppearance` as `globalAppearance` (which ensures that global configuration is able to be accounted for as well
* as component-level configuration). The provider handles the merging of attributes, and makes them available via the
* `useAppearance` hook.
* `appearance` prop will wrap its children in `AppearanceProvider`. The provider handles the merging of attributes,
* and makes them available via the `useAppearance` hook.
*/
const AppearanceProvider = (props: AppearanceProviderProps) => {
// Access the parsedAppearance of the parent context provider. `undefined` if this is the top-most
// AppearanceProvider.
const { parsedAppearance: globalAppearance } = usePartialAppearance();

const ctxValue = useDeepEqualMemo(() => {
const parsedAppearance = parseAppearance(props);
const parsedAppearance = parseAppearance({
appearance: props.appearance,
globalAppearance: globalAppearance,
});

return { value: { appearance: props.appearance, globalAppearance: props.globalAppearance, parsedAppearance } };
}, [props.appearance, props.globalAppearance]);
return { value: { parsedAppearance } };
}, [props.appearance, globalAppearance]);

return <AppearanceContext.Provider value={ctxValue}>{props.children}</AppearanceContext.Provider>;
};
Expand Down