Customize skin
Let's start to create a skin from scratch. to create a skin just you need to know the props available. Check the offcicial documentation to know about the required element prop.
Skin folder struncture
you can store your skin as your needs. here is a way to store the skins in a proper way. set the skin folder in your src src/skins/...
Project file
├── src
│ └── skins
│ ├── default skins
│ │ └──element skins folder
│ │ └──element skins
│ └── optional skin
│ └──element skins folder
│ └──other skins for the element
│ └──other skins for the element
UI designing
For the styling you can use the tailwind
or bootstrap
or dispaly it with an svg
npm install -D tailwindcss postcss autoprefixer
pnpm add -D tailwindcss postcss autoprefixer
npm install bootstrap
pnpm add bootstrap
Let's Start to Create the Skin
To create a skin, define a React functional component that takes the appropriate props. Refer to the documentation for the property definitions (type definition interface name) to pass the correct props.
Example: Tab Item Element Skin
const TabItemSkin: com.qbit.Skin<TabItemProps> = (props) => {
const { name, onClick, disabled, active,className } = props;
return (
<button
className={`${className} ${active ? 'border-b-2 border-blue-500 text-blue-500' : 'text-gray-500 hover:text-blue-500'} ${disabled ? 'cursor-not-allowed opacity-50' : ''}`}
onClick={(e) => {
if (!disabled) {
onClick?.(e);
}
}}
>
{name}
</button>
);
};
export default TabItemSkin;
For instance, if you're creating a skin for a tab item, you can use TabItemProps
as shown below:
const TabItemSkin: com.qbit.Skin<TabItemProps> = (props) => {
- The component uses the TypeScript generic type
com.qbit.Skin<TabItemProps>
, which enforces that the props (TabItemProps
) adhere to the provided type definition. TabItemProps
defines the properties that can be passed to this component. (The exact definition ofTabItemProps
is not included here, but its usage is demonstrated below.)
Destructuring Props
You can destructure the props for easier access:
const { name, onClick, disabled, active, className } = props;
- Props Explanation:
name
: The label or text displayed inside the button.onClick
: An optional function executed when the button is clicked.disabled
: A boolean indicating whether the button is disabled.active
: A boolean indicating whether this tab is currently active.className
: A custom class name string for additional CSS styling.
Rendering the Button
The skin renders a <button>
element, styled dynamically using Tailwind CSS classes.
Dynamic Styling
-
The
className
combines custom classes and conditional classes based on theactive
anddisabled
props. -
Styling Behavior:
- If
active
istrue
:- Adds styles:
border-b-2 border-blue-500 text-blue-500
(active tab appearance with a blue underline and blue text).
- Adds styles:
- If
active
isfalse
:- Adds styles:
text-gray-500 hover:text-blue-500
(gray text by default, turning blue on hover).
- Adds styles:
- If
disabled
istrue
:- Adds styles:
cursor-not-allowed opacity-50
(disables pointer events and makes the button semi-transparent).
- Adds styles:
- If
Click Handler
- The button’s click event is handled via the
onClick
function passed as a prop. - If
disabled
istrue
, theonClick
function is not executed. - Optional chaining (
onClick?.(e)
) ensures the function is only called if it exists.
Button Content
- The
{name}
prop displays the name inside the button.
Skin usage
here is how to use your skin in the required page. for render your desired skin pass it into your element's parent element's renderers prop
-
For an example
Use the tabskin in a page<Tab
keyExtractor={(value: string, i: number) => `${value}-${i}`}
renderers={{ renderer: TabSkin, childRenderer: TabItemSkin }}
>
<TabItem active={true} name="Tasks" content={<SampleContent />} />
<TabItem active={false} name="Removed task" content={<Element />} />
<TabItem active={false} name="Sign in/up" content={<Login />} />
</Tab> -
Here into the renderers prop you can pass the parent element skin into the renderer prop and children's skin into the childRendrer prop
-
You should pass the
childRenderer
is a required one