diff --git a/examples/ui-demo/src/app/AuthModal.tsx b/examples/ui-demo/src/app/AuthModal.tsx new file mode 100644 index 000000000..6dd0f31fd --- /dev/null +++ b/examples/ui-demo/src/app/AuthModal.tsx @@ -0,0 +1,62 @@ +import { ReactNode, useCallback, useRef } from "react"; + +type AuthType = + | { + type: "email"; + showButton: boolean; + } + | { type: "passkey" }; + +type AuthModalProps = { + header?: ReactNode; + // Each section can contain multiple auth types which will be grouped together + // and separated by an OR divider + sections?: AuthType[][]; +}; + +// TODO: move this into aa-alchemy +export const useAuthModal = ({ header = "Sign in" }: AuthModalProps) => { + const ref = useRef(null); + const openAuthModal = () => ref.current?.showModal(); + const closeAuthModal = () => ref.current?.close(); + + // TODO: use the sections prop to render the auth types + const AuthModal = useCallback(() => { + return ( + +
+

{header}

+
+ + +
+ {/* divider */} +
+
+

Or

+
+
+
+ +
+
+ + By signing in, you agree to the following{" "} + + End User Terms + + + powered by INSERT_LOGO +
+
+
closeAuthModal()}>
+
+ ); + }, [header]); + + return { openAuthModal, closeAuthModal, AuthModal }; +}; diff --git a/examples/ui-demo/src/app/page.tsx b/examples/ui-demo/src/app/page.tsx index 371702954..4565f992e 100644 --- a/examples/ui-demo/src/app/page.tsx +++ b/examples/ui-demo/src/app/page.tsx @@ -2,9 +2,14 @@ import { DemoSet } from "@alchemy/aa-alchemy/react"; import { JSX, SVGProps } from "react"; +// eslint-disable-next-line import/extensions +import { useAuthModal } from "./AuthModal"; // TODO: move this into the aa-alchemy package -const MailIcon = ({fill = "#475569", ...props}: JSX.IntrinsicAttributes & SVGProps) => ( +const MailIcon = ({ + fill = "#475569", + ...props +}: JSX.IntrinsicAttributes & SVGProps) => ( ); -const ChevronRight = ({ fill = "#475569", ...props }: JSX.IntrinsicAttributes & SVGProps) => ( - - - -) +const ChevronRight = ({ + fill = "#475569", + ...props +}: JSX.IntrinsicAttributes & SVGProps) => ( + + + +); export default function Home() { + const { openAuthModal, AuthModal } = useAuthModal({}); + return ( -
- Primary - Secondary - Google -
-
+ + + + + ); } diff --git a/examples/ui-demo/tailwind.config.ts b/examples/ui-demo/tailwind.config.ts index 80f1b6156..5d44fd24c 100644 --- a/examples/ui-demo/tailwind.config.ts +++ b/examples/ui-demo/tailwind.config.ts @@ -6,14 +6,15 @@ const config: Config = withAccountKitUi({ content: [ "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", "./src/components/**/*.{js,ts,jsx,tsx,mdx}", - "./src/app/**/*.{js,ts,jsx,tsx,mdx}" + "./src/app/**/*.{js,ts,jsx,tsx,mdx}", ], theme: {}, - plugins: [plugin(({ addComponents }) => { - // use this as a playground to test out new styles and components before moving them - addComponents({ - }); - })], + plugins: [ + plugin(({ addComponents }) => { + // use this as a playground to test out new styles and components before moving them + addComponents({}); + }), + ], }); export default config; diff --git a/packages/alchemy/src/tailwind/components/buttons.ts b/packages/alchemy/src/tailwind/components/buttons.ts index 3fb761a33..fe9691835 100644 --- a/packages/alchemy/src/tailwind/components/buttons.ts +++ b/packages/alchemy/src/tailwind/components/buttons.ts @@ -4,7 +4,7 @@ export const buttonComponents: ComponentDef = { ".btn": { "@apply p-3 inline-flex h-10 font-semibold": {}, "@apply gap-2": {}, - "@apply items-center": {}, + "@apply items-center justify-center": {}, "@apply shrink-0": {}, "@apply cursor-pointer": {}, // for w/e reason, using @apply rounded-[8px] doesn't work @@ -18,13 +18,13 @@ export const buttonComponents: ComponentDef = { "@apply active:shadow-none": {}, }, ".btn-primary": { - "@apply btn-bg-primary": {}, + "@apply bg-btn-primary text-fg-invert": {}, }, ".btn-secondary": { - "@apply btn-bg-secondary": {}, + "@apply bg-btn-secondary text-fg-primary": {}, }, ".btn-auth": { - "@apply btn-bg-social": {}, + "@apply bg-btn-social text-fg-primary": {}, "@apply static-border": {}, }, }; diff --git a/packages/alchemy/src/tailwind/components/form-controls.ts b/packages/alchemy/src/tailwind/components/form-controls.ts index 1ba47a7d6..1f62f3e3f 100644 --- a/packages/alchemy/src/tailwind/components/form-controls.ts +++ b/packages/alchemy/src/tailwind/components/form-controls.ts @@ -1,10 +1,9 @@ import type { ComponentDef } from "../types.js"; -import { getColorVariableName } from "../utils.js"; export const formControlComponents: ComponentDef = { ".form-controls": { "@apply flex flex-col gap-2": {}, - [`@apply text-[var(${getColorVariableName("fg-secondary")})]`]: {}, + "@apply text-fg-secondary": {}, ".form-label": { "@apply text-sm font-medium": {}, }, @@ -12,7 +11,7 @@ export const formControlComponents: ComponentDef = { "@apply text-xs font-normal": {}, }, ".input-error + .form-hint, .input[error] + .form-hint": { - [`@apply text-[var(${getColorVariableName("critical")})]`]: {}, + "@apply text-critical": {}, }, }, }; diff --git a/packages/alchemy/src/tailwind/components/input.ts b/packages/alchemy/src/tailwind/components/input.ts index b68a48ad3..3698c73db 100644 --- a/packages/alchemy/src/tailwind/components/input.ts +++ b/packages/alchemy/src/tailwind/components/input.ts @@ -1,28 +1,26 @@ import type { ComponentDef } from "../types"; -import { getColorVariableName } from "../utils.js"; export const inputComponents: ComponentDef = { ".input": { // container styling "@apply p-3 inline-flex gap-2 h-10 items-center": {}, "@apply static-border": {}, - [`@apply text-[var(${getColorVariableName("fg-primary")})]`]: {}, + "@apply text-fg-primary": {}, "&-disabled, &:disabled, &[disabled]": { "@apply static-border pointer-events-none": {}, - [`@apply bg-[var(${getColorVariableName("bg-surface-inset")})]`]: {}, + [`@apply bg-bg-surface-inset`]: {}, input: { - [`@apply bg-[var(${getColorVariableName( - "bg-surface-inset" - )})] cursor-not-allowed`]: {}, - [`@apply placeholder-[var(${getColorVariableName("fg-disabled")})]`]: - {}, + "@apply bg-bg-surface-inset cursor-not-allowed": {}, + "@apply placeholder-fg-disabled": {}, }, "svg > *": { - fill: `var(${getColorVariableName("fg-disabled")}) !important`, + "@apply !fill-fg-disabled": {}, + // fill: `var(${getColorVariableName("fg-disabled")}) !important`, }, }, "svg > *": { - fill: `var(${getColorVariableName("fg-primary")})`, + "@apply fill-fg-primary": {}, + // fill: `var(${getColorVariableName("fg-primary")})`, }, "&:focus, &:focus-visible, &:focus-within, &:active": { "@apply active-border": {}, @@ -34,7 +32,7 @@ export const inputComponents: ComponentDef = { // input field styling input: { - "@apply appearance-none": {}, + "@apply appearance-none grow": {}, "&:focus, &:focus-visible, &:focus-within, &:active": { "@apply outline-none": {}, }, @@ -48,9 +46,9 @@ export const inputComponents: ComponentDef = { // this makes a lot of assumptions about how our svgs are structured // pretty brittle so fix this later "> *": { - fill: `var(${getColorVariableName("fg-disabled")}) !important`, + "@apply fill-fg-disabled": {}, }, - [`@apply text-[var(${getColorVariableName("fg-disabled")})]`]: {}, + "@apply text-fg-disabled": {}, }, }, }; diff --git a/packages/alchemy/src/tailwind/components/modal.ts b/packages/alchemy/src/tailwind/components/modal.ts new file mode 100644 index 000000000..6dcd9577e --- /dev/null +++ b/packages/alchemy/src/tailwind/components/modal.ts @@ -0,0 +1,23 @@ +import type { ComponentDef } from "../types"; + +export const modalComponents: ComponentDef = { + ".modal": { + "@apply rounded-2xl": {}, + "@apply bg-bg-surface-default": {}, + "&::backdrop": { + "@apply bg-black bg-opacity-[0.8]": {}, + }, + ".modal-box": { + "@apply z-[1] p-8": {}, + }, + ".modal-backdrop": { + "@apply fixed w-screen h-screen top-0 left-0": {}, + "@apply -z-[1] col-start-1 row-start-1 grid self-stretch justify-self-stretch text-transparent": + {}, + button: { + opacity: "0", + "@apply h-screen w-screen cursor-default": {}, + }, + }, + }, +}; diff --git a/packages/alchemy/src/tailwind/plugin.ts b/packages/alchemy/src/tailwind/plugin.ts index 24b896d2c..9fea2d521 100644 --- a/packages/alchemy/src/tailwind/plugin.ts +++ b/packages/alchemy/src/tailwind/plugin.ts @@ -4,11 +4,11 @@ import { buttonComponents } from "./components/buttons.js"; import { colorVariables } from "./components/colorsvars.js"; import { formControlComponents } from "./components/form-controls.js"; import { inputComponents } from "./components/input.js"; +import { modalComponents } from "./components/modal.js"; import { createDefaultTheme } from "./theme.js"; -import type { AccountKitThemeOverride } from "./types"; +import type { AccountKitThemeColor, AccountKitThemeOverride } from "./types"; import { borderUtilities } from "./utilities/borders.js"; -import { buttonUtilities } from "./utilities/buttons.js"; -import { apply } from "./utils.js"; +import { apply, getColorVariableName } from "./utils.js"; type TailWindPlugin = ReturnType; @@ -74,11 +74,11 @@ export const accountKitUi: ( ) => TailWindPlugin = (themeOverride) => { const defaultTheme = createDefaultTheme(); const accountKitTheme = apply(defaultTheme, themeOverride); + const { colors, ...rest } = accountKitTheme; return plugin( ({ addComponents, addUtilities }) => { // utilities - addUtilities(buttonUtilities); addUtilities(borderUtilities); // components @@ -86,11 +86,21 @@ export const accountKitUi: ( addComponents(buttonComponents); addComponents(inputComponents); addComponents(formControlComponents); + addComponents(modalComponents); }, { theme: { extend: { - ...accountKitTheme, + ...rest, + colors: Object.keys(colors).reduce( + (acc, key) => ({ + ...acc, + [key]: `var(${getColorVariableName( + key as AccountKitThemeColor + )})`, + }), + {} as Record + ), }, }, } @@ -115,5 +125,6 @@ export const withAccountKitUi = ( ...config.content, files: [...config.content.files, getAccountKitContentPath()], }, + // TODO: this isn't good. it means if someone is already using daisy then we'll end up destroying their config plugins: [...(config.plugins ?? []), accountKitUi(themeOverride)], }); diff --git a/packages/alchemy/src/tailwind/theme.ts b/packages/alchemy/src/tailwind/theme.ts index 7f3689feb..8d3156ec3 100644 --- a/packages/alchemy/src/tailwind/theme.ts +++ b/packages/alchemy/src/tailwind/theme.ts @@ -24,6 +24,7 @@ export function createDefaultTheme(): AccountKitTheme { "fg-tertiary": createColorSet("#94A3B8", "#94A3B8"), "fg-invert": createColorSet("#FFF", "#000"), "fg-disabled": createColorSet("#CBD5E1", "#475569"), + "fg-accent-brand": createColorSet("#000", "#fff"), // surface colors "bg-surface-default": createColorSet("#fff", "#020617"), diff --git a/packages/alchemy/src/tailwind/types.ts b/packages/alchemy/src/tailwind/types.ts index 557b5729b..7a106fffc 100644 --- a/packages/alchemy/src/tailwind/types.ts +++ b/packages/alchemy/src/tailwind/types.ts @@ -20,6 +20,7 @@ export interface AccountKitTheme { "fg-tertiary": ColorVariantRecord; "fg-invert": ColorVariantRecord; "fg-disabled": ColorVariantRecord; + "fg-accent-brand": ColorVariantRecord; // surface colors "bg-surface-default": ColorVariantRecord; diff --git a/packages/alchemy/src/tailwind/utilities/buttons.ts b/packages/alchemy/src/tailwind/utilities/buttons.ts deleted file mode 100644 index dca3572e0..000000000 --- a/packages/alchemy/src/tailwind/utilities/buttons.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { UtilityDef } from "../types.js"; -import { getColorVariableName } from "../utils.js"; - -/** - * A utility function for generating the account kit button utilities - * - * @returns a utility definition object - */ -export const buttonUtilities: UtilityDef = { - ".btn-bg-primary": { - backgroundColor: `var(${getColorVariableName("btn-primary")})`, - color: `var(${getColorVariableName("fg-invert")})`, - }, - ".btn-bg-secondary": { - backgroundColor: `var(${getColorVariableName("btn-secondary")})`, - color: `var(${getColorVariableName("fg-primary")})`, - }, - ".btn-bg-social": { - backgroundColor: `var(${getColorVariableName("btn-social")})`, - color: `var(${getColorVariableName("fg-primary")})`, - }, -}; diff --git a/packages/alchemy/src/tailwind/utils.test.ts b/packages/alchemy/src/tailwind/utils.test.ts index 153d216e0..f3bda2754 100644 --- a/packages/alchemy/src/tailwind/utils.test.ts +++ b/packages/alchemy/src/tailwind/utils.test.ts @@ -50,6 +50,10 @@ describe("tailwind utils test", () => { "dark": "#DC2626", "light": "#F87171", }, + "fg-accent-brand": { + "dark": "#fff", + "light": "#000", + }, "fg-disabled": { "dark": "#475569", "light": "#CBD5E1",