Closed MildTomato closed 2 years ago
So the variables will be used like this after defined, right?
module.exports = { theme: { extend: { colors: { primary-color: "var(--primary-color)", secondary-color: "var(--secondary-color)" }, }, }, };
My question is, how can the user, after is installing @supabase/ui, customise the styling?
I guess it will work if those variables are overwritten at project level. Maybe we can have the default ones which are currently defined now, move them in css variables and when the user is defining others at project level, those will be used. That means the change will not be a breaking change.
I don't if is the best way, but I was watching the way that @windmill/react-ui
handles the theming, they have a themes/default.ts
file that store an object with all of the names of the components and their styles (defaults, danger, info, etc). Then, they define a ThemeContext
that will export the object globally in the application. After that, the components will extract their corresponding styles.
theme/default.ts
export default {
alert: {
base: 'text-4xl px-4 py-2',
},
};
context/ThemeContext.tsx
import React from 'react';
import defaultTheme from '../themes/default';
interface ThemeContextInterface {
theme: any;
mode?: Mode;
toggleMode?: any;
}
export const ThemeContext = React.createContext<ThemeContextInterface>({
theme: defaultTheme,
});
interface ThemeProviderProps {
children: React.ReactNode;
value?: any;
}
export const ThemeProvider: React.FC<ThemeProviderProps> = ({
children,
value,
}) => {
return (
<ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
);
};
components/Alert.tsx
const Alert = () => {
const { theme: { alert } } = useContext(ThemeContext)
// ...
}
Maybe we don't need to handle all of the styles here (because we have a *.module.css
) but we can use this approach to handle the background
, text-color
, border-color
of the components.
@angelmtztrc yep, i think that's a good suggestion.
I think the only caveat of using a theme provider is you end up with a lot of consumers around every component - but it's also how AntDesign seem to apply theming as well and it looks convenient if someone wanted to swap the theme on the fly in the app.
I'm not against moving away from css modules either (or changing how they work), they're actually causing a problem on nextjs sites that are sever side rendered. Although that's a separate issue really.
I hadn't seen @windmill/react-ui
before 🙈 i love the concept though.
I think, this solution does mean whoever uses SupabaseUI will need to have tailwind installed, as the css needs to get purged in the target app - I'm also not apposed to this, as everyone likes tailwind and this library is becoming more of a conveniently ready styled Radix/HeadlessUI components collection.
@angelmtztrc maybe one of us can try this out, we could try a POC with just 1 or 2 of the components ?
We could also use the same config setup windmill uses, by wrapping the tailwind config with a supabaseui config. https://windmillui.com/react-ui/installation#add-to-tailwind config file it imports -> https://github.com/estevanmaito/windmill-react-ui/blob/master/config.js
If anyone else has any suggestions, ideas or concerns please add them on here 👍
I would be a fan of the custom properties approach. Re browser support, we're already using tailwind which uses them so the risk is already present. A concern I might have around the context approach is centralising all the styles in one place, I like to have them as close to the related code as possible.
@MildTomato I can start by creating the custom wrapper for the tailwind.config.js
file if you have no problem with that
@angelmtztrc go for it!
I think @jonthomp has a point, in this library, we should possibly still try and keep styles locally to each component, but the custom wrapper just allows for those styles to be overwritten. (Did i understand that correctly?). Although I would still like to see global variables, like brand color etc.
I do also like the idea of just using custom properties, which also means whoever is using this library doesn't need to have tailwind installed, so one less dependency / tool to learn.
The counter argument though is if we rely on tailwind for everything, we could eliminate css being exported from the library and all the css is neatly purged in the target app instead (this is probably a really great fit for the Supabase dashboard), this also possibly reduces some duplicated css. For example, if 'flex' is used in the Supabase UI or the dashboard app, we'll just have one .flex class - as apposed to today, we have quite a few css classes that just add the same functionality as flex.
This is quite a large deviation for this library though, but I could see this being useful even though it essentially forces you to use tailwind.
I think the first decision here for us is, would people like to see a tailwind based library, that requires tailwind to use, or would you rather have/work on a ui library that has pre baked styles, that has no dependency, that can be customised with a theme file (or something like that).
Feel free to keep this thread going, would be great to hear what everyone thinks.
I've started a POC for this based on @angelmtztrc's suggestion https://github.com/supabase/ui/pull/241
Is there currently a temporary fix for this?
I'm afraid not, will try and get this done this week though
How have things progressed on theming? @MildTomato thank you for all you're doing 🙏
As you can see, it was not 1 week. 😬
I am working on this right now though.
I'm currently refactoring some more components away from CSS modules but I'm getting there.
In short, though, a lot of components are using Radix primitives, and there is a react theme provider that inserts either default tailwind CSS classes, or you can override the theme with your own one. (You could even just use non-tailwind classes I guess, or use stitches in this custom theme).
There is a tailwind config wrapper that you wrap around your own tailwind config that will add any necessary plugins/extends needed for the default theme.
We're using Radix colors rather than Tailwind colors for the default theme.
We're also using a standard color scale of gray across almost everything, but the idea is that you could replace this scale with whatever color scale you like. So it could be a warm gray, cool gray, slate.. etc. These can be used as CSS variables which are pretty handy as you could swap out the scale easily for light/dark/multiple themes.
One of the major headaches is that the Brand color is also based on a scale, which is annoying since someone would have to make the scale of their brand color for this to be useful.
I tried just using 1 hex color for the brand, and an accent, but it was just always really hard and always restrictive; it made a lot more sense to just have a brand color scale - made it a lot easier to work with.
I'm also going to drop a few components as they are a pain to work with, don't really solve anything, and add bloat to the library. It's also just a lot easier to just use tailwind in your app for these. The following will be deprecated.
@supabase/ui/Radio added new layouts, improved spacing
@supabase/ui/Toggle New left/right align, improved spacing
@supabase/ui/Button Overhauled styles, added focus styles
@supabase/ui/Input, @supabase/ui/Select, @supabase/ui/InputNumber, @supabase/ui/Checkbox Improved layout, improved error state
@supabase/ui/Menu Overhauled styles, added focus styles
@supabase/ui/Dropdown Overhauled styles, added focus styles.
@supabase/ui/Tabs Moved to Radix component. Overhauled styles, added focus styles.
Wow, awesome! Thanks for the reply. I'd offer to help, but Radix is new to me so I'd likely just slow things down.
For now, we're doing this:
/* override supabase ui */
.sbui-formlayout__label,
.sbui-typography-text {
color: unset !important; /* to be replaced with branded color */
}
That along with the style
prop inside of <Auth/>
gives us all we need to customize manually.
Quite honestly, an unstyled
prop would be pretty nice to be able to use Auth
and the parent wrapper without any styles.
@jchekanoff are you just using <Auth/>
?
Quite honestly, an unstyled prop would be pretty nice to be able to use Auth and the parent wrapper without any styles.
Sounds like a good idea.
@MildTomato Sorry I missed this -- Yes! Just using <Auth/>
.
@jchekanoff ok! - I'm starting a new repo for the Auth component. I think we're going to drop support for it in this library as it will need its own theming/customization solution and I don't want to force anyone to install a whole UI library just to use the Auth component.
I'll make sure that the new package (probably called @supabase/auth-elements-react) will be working before I remove it from here.
Awesome! I won't work on a PR for this repo, then :smile:
Tag me in on supabse/auth-elements#4 if I can contribute there.
Is there a way to create your theme? At this point, I just want to update the button colors to our branding.
We released this last week. https://github.com/supabase-community/auth-ui
Some docs on customizing. https://supabase.com/docs/guides/auth/auth-helpers/auth-ui#customization for overriding the button color, do something like this
Thanks @MildTomato, that worked!
We are moving the components to the main mono repo at github.com/supabase/supabase.
I encourage anyone who would like to see theming implemented in the supabase dashboard/studio to make a new discussion in the main mono repo.
https://github.com/supabase/supabase/discussions/new?category=ideas
Feature request
Ability to customize / style each component
How it works now
it doesn't work at all, all the color variables are stuck in the ui lib and cannot be changed externally. all colors are set as rgb() values, also resulting in overriding externally as a tedious job.
If someone wanted to implement a 'brand color' change, they would need to target with CSS every class name that would contain the brand color, and then overwrite it, and for every shade color. This isn't practical.
Proposal
! this would be a breaking change !
All color variables are stored in css variables (CSS custom properties).
With css variables, we can set the variable names inside tailwind config file, rather than hex color values.
All of our components, when exported, would have colors set like this:
in the target app, using the ui library, you would need a stylesheet, that's imported into all pages, that contains all the variables, like:
This will then show the correct colors in your app, which can be modified and changed to whatever you like.
it would (maybe) then be possible to just load up the correct variables file, depending on which 'theme' you wanted to show. (think slack themes)
downsides
css variables still isn't fully supported by all browsers
there is no support for ie
this presents a problem, because if the css variables do not work, there is no fallback style -unless, we implement a fall back color for every variable, in every place it is used, in every component - this isn't a realistic solution really, and it would add a lot of redundant css.