Theming

Theming

Using CSS Variables or Tailwind CSS for theming.

Utility Classes

To use the utility classes in some components, an additional component must be used in order to style a button, for example.

In some cases, the class associated with the component must be invoked in order to add more styling. For example if you want a big Avatar you need:

1.- Import avatarClassname from the component.

const { Avatar, AvatarImage, AvatarFallback, avatarClassname } = VM.require(
  "uiisnear.near/widget/avatar"
);

2.- Import ClassnameConf from the utils component and wait until is loaded

const { ClassnameConf } = VM.require("uiisnear.near/widget/utils");
 
if (ClassnameConf == undefined) return "";

3.- Add a state variable to the component (the name is up to you).

const [avatar, setAvatar] = useState("");

3.- Here is where the magic happens. Create a variable called classname to which you assign the value of the variable imported in step 1 and add the Tailwind classes to the string. Then you must invoke ClassnameConf passing to the output attribute the setAvatar (in the case of this example) and to the classname attribute the content of the variable just created. With this the state variable will be assigned with the correctly formed string for your styles to be applied.

if (avatar === "") {
  let className = `${avatarClassname} h-24 w-24`;
  return <ClassnameConf output={setAvatar} className={className} />;
}

Finally, the state variable must be passed to the component so that it can use the required classes. And this is the complete code:

const { Tailwind } = VM.require("uiisnear.near/widget/tailwind");
 
const { Avatar, AvatarImage, AvatarFallback, avatarClassname } = VM.require(
  "uiisnear.near/widget/avatar"
);
const { ClassnameConf } = VM.require("uiisnear.near/widget/utils");
 
if (Tailwind === undefined) return <></>;
if (ClassnameConf == undefined) return "";
 
const [avatar, setAvatar] = useState("");
 
if (avatar === "") {
  let className = `${avatarClassname} h-24 w-24`;
  return <ClassnameConf output={setAvatar} className={className} />;
}
 
return (
  <Tailwind>
    <div className="flex mx-auto w-max pt-10">
      <Avatar className={avatar}>
        <AvatarImage
          src="https://pages.near.org/wp-content/uploads/2023/11/NEAR_token.png"
          alt="@uiisnear"
        />
        <AvatarFallback>UI</AvatarFallback>
      </Avatar>
    </div>
  </Tailwind>
);

Variants (+ Utility Classes)

There are components that have variants (Alert, AlertDialog, Badge, Toast and Toggle), which should be used as follows:

If you want to use a destructive Badge, here is how to do it

1.- Import BadgeConf from the component and wait until is loaded

const { Badge, BadgeConf } = VM.require("uiisnear.near/widget/badge");
 
if (BadgeConf == undefined) return "";

2.- Add a state variable to the component (the name is up to you).

const [badgeDestructive, setBadgeDestructive] = useState("");

3.- Here is where the magic happens. You must invoke BadgeConf passing to the output attribute the setBadgeDestructive (in the case of this example) and to the variant attribute available in the component, in this case destructive. With this the state variable will be assigned with the correctly formed string for your styles to be applied.

if (badgeDestructive === "")
  return <BadgeConf output={setBadgeDestructive} variant="destructive" />;

4.- (Optional) If you also want to add any special Tailwind, you must add the classname attribute and add the text with the desired classes.

if (badgeDestructive === "")
  return <BadgeConf output={setBadgeDestructive} variant="destructive" className="bg-red-900" />;

Finally, the state variable must be passed to the component so that it can use the required classes. And this is the complete code:

const { Tailwind } = VM.require("uiisnear.near/widget/tailwind");
const { Badge, BadgeConf } = VM.require("uiisnear.near/widget/badge");
 
if (Tailwind == undefined) return "";
if (BadgeConf == undefined) return "";
 
const [badgeDestructive, setBadgeDestructive] = useState("");
 
if (badgeDestructive === "")
  return <BadgeConf output={setBadgeDestructive} variant="destructive" />;
 
return (
  <Tailwind>
    <div className="flex w-full justify-center pt-10">
      <Badge className={badgeDestructive}>Destructive</Badge>
    </div>
  </Tailwind>
);

CSS Variables

List of variables

Here's the list of variables available for customization:

Default background color of <body />...etc

--background: 0 0% 100%;
--foreground: 222.2 47.4% 11.2%;

Muted backgrounds such as <TabsList />, <Skeleton /> and <Switch />}

--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;

Background color for <Card />

--card: 0 0% 100%;
--card-foreground: 222.2 47.4% 11.2%;

Background color for popovers such as <DropdownMenu />, <HoverCard />, <Popover />

--popover: 0 0% 100%;
--popover-foreground: 222.2 47.4% 11.2%;

Default border color

--border: 214.3 31.8% 91.4%;

Border color for inputs such as <Input />, <Select />, <Textarea />

--input: 214.3 31.8% 91.4%;

Primary colors for <Button />

--uin-primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;

Secondary colors for <Button />

--uin-secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;

Used for accents such as hover effects on <DropdownMenuItem>, <SelectItem>...etc

--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;

Used for destructive actions such as <Button className={destructiveClassname}>

--destructive: 0 100% 50%;
--destructive-foreground: 210 40% 98%;

Used for focus ring

--ring: 215 20.2% 65.1%;

Border radius for card, input and buttons

--radius: 0.5rem;

Make your own Theme

If you wish, you can configure the variables with the color of your choice. To do this, create a JSON variable with the colors that suit you (only the colors you want to modify are necessary, the other colors will remain).

const myTheme = {
  background: "0 0% 100%",
  foreground: "240 10% 3.9%",
  card: "0 0% 100%",
  "card-foreground": "240 10% 3.9%",
  popover: "0 0% 100%",
  "popover-foreground": "240 10% 3.9%",
  "uin-primary": "142.1 76.2% 36.3%",
  "primary-foreground": "355.7 100% 97.3%",
  "uin-secondary": "240 4.8% 95.9%",
  "secondary-foreground": "240 5.9% 10%",
  muted: "240 4.8% 95.9%",
  "muted-foreground": "240 3.8% 46.1%",
  accent: "240 4.8% 95.9%",
  "accent-foreground": "240 5.9% 10%",
  destructive: "0 84.2% 60.2%",
  "destructive-foreground": "0 0% 98%",
  border: "240 5.9% 90%",
  input: "240 5.9% 90%",
  ring: "142.1 76.2% 36.3%",
  radius: "0.5rem",
};

Then add the theme attribute in the Tailwind component with the name of the variable created earlier. With this, all the components inside the Tailwind component will be ruled under these colors.

<Tailwind theme={myTheme}>
 {/* content */}
</Tailwind>