-
Notifications
You must be signed in to change notification settings - Fork 394
feat(ui): Initial AppearanceProvider support #3976
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
Conversation
🦋 Changeset detectedLatest commit: 1ecaaed The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
<AppearanceProvider appearance={{ layout: { unsafe_disableDevelopmentModeWarnings: devMode === 'off' } }}> | ||
<style | ||
dangerouslySetInnerHTML={{ | ||
__html: css, |
Check warning
Code scanning / CodeQL
DOM text reinterpreted as HTML Medium
DOM text
DOM text
DOM text
/** | ||
* Union of all valid descriptors used throughout the components. | ||
*/ | ||
export type DescriptorIdentifier = 'alert' | 'alert__error' | 'alert__warning' | 'alertRoot' | 'alertIcon'; |
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.
Will definitely want to work out an approach for naming here. I think this was just for testing to start. But ideally we have a convention for underscore vs camelcase etc.
export const layoutStyle = { | ||
alert: { | ||
className: 'border px-4 py-3', | ||
}, | ||
alert__warning: {}, | ||
alert__error: {}, | ||
alertRoot: { | ||
className: 'flex gap-x-2', | ||
}, | ||
alertIcon: { | ||
className: 'mt-px shrink-0 *:size-4', | ||
}, | ||
} satisfies ParsedElementsFragment; | ||
|
||
export const visualStyle = { | ||
alert: { | ||
className: 'leading-small rounded-md text-base', | ||
}, | ||
alert__warning: { | ||
className: 'text-warning bg-warning/[0.06] border-warning/[0.12]', | ||
}, | ||
alert__error: { | ||
className: 'text-danger bg-danger/[0.06] border-danger/[0.12]', | ||
}, | ||
alertRoot: {}, | ||
alertIcon: {}, | ||
} satisfies ParsedElementsFragment; |
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.
Since both the layout and visual styles are needed for each component (I think), have you considered a helper function that'd solve some of the need to have empty objects defined here?
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.
Will also have a good amount of these objects for files like the card component which has a good amount of nested components https://github.com/clerk/javascript/blob/main/packages/ui/src/primitives/card.tsx
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.
The empty objects are a type checking requirement, but after talking with Bryce we decided to move to a runtime validation approach instead. In a future PR, we'll be able to remove these empty objects, and our useAppearance
hook will automatically create the empty objects without us needing to specify them.
} from '~/contexts/AppearanceContext'; | ||
import * as Icon from './icon'; | ||
|
||
export const layoutStyle = { |
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 am still not super sold on the layout naming for the based styles. But we can start with it and iterate if we want to change.
function FirstFactorConnections({ | ||
isGlobalLoading, | ||
hasConnection, | ||
}: { | ||
isGlobalLoading: boolean; | ||
hasConnection: boolean; | ||
}) { | ||
const { t } = useLocalizations(); |
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.
Are these changes meant to be here? 👀
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.
Ah, I see yes! Alex had a few PRs targeting this branch 👍
|
||
export { AppearanceProvider, useAppearance }; | ||
|
||
if (import.meta.vitest) { |
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.
love that you can test local functions without having to export them!
return result; | ||
} | ||
|
||
function mergeAppearance(a: Appearance | null | undefined, b: Appearance | null | undefined): Appearance | null { |
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.
Might be helpful to outline the merging heuristic in prose in a JSDoc. 👀
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.
This is a solid foundation to build from. I am interested in getting this in sooner than later, and continue iterating on it.
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.
👏 great start!
Co-authored-by: Alex Carpenter <im.alexcarpenter@gmail.com>
Description
This PR contains a complete implementation of the
appearance
prop for the new AIO components. Notable changes from the existingappearance
prop include the dropping of arbitrary CSS (such as pseudo elements) and the removal of component-specific styles likeappearance={{ elements: { signIn: { ... } } }}
.This PR also contains the following sub-PRs:
Checklist
npm test
runs as expected.npm run build
runs as expected.Type of change