Button case study
Button implementation
The Button source code includes the TypeScript file (Button.tsx) and the CSS stylesheet (Button.module.css).
HTML default structure (simplified)
- the root is a
<button>. - inner, section, label and loader are
<span>elements:- loader contains a loader, if any
- inner contains the label and sections
- the label contains the button's text.
- a section is a container for an icon, if applicable:
<button {/* root */}>
<span {/* 1.0 loader */} />
<span {/* 2.0 inner */}>
<span {/* 2.1 section (icons..) */}/>
<span {/* 2.2 label (button text) */}/>
</span>
</span>
</button>
Mantine adds its internal classes (e.g. m-77c9d27d) along with unimplemented empty classes (e.g. mantine-Button-root) to the inner-elements:
<button class="m-77c9d27d mantine-Button-root">
<span class="m-80f1301b mantine-Button-inner">
<span class="m-811560b9 mantine-Button-label">Save</span>
</span>
</button>
the stylesheet: a CSS module
The Button's CSS module stylesheet targets inner-elements with classes of the same name:
.loader {
position: absolute;
left: 50%;
top: 50%;
}
The .tsx file imports the classes object and plugs it to Button.classes.
(advanced) component-agnostic internal classes and data attributes
Mantine also adds component-agnostic internal classes, such as mantine-active and mantine-focus-auto. They are placed preemptively, and their style triggers on specific states. For example, mantine-active activates its style on the active state:
mantine-active:active {
transform: translateY(calc(0.0625rem));
}
Mantine can also add internal data-attributes such as data-centered="true" to set a specific style:
.m_a3c6e060[data-centered] {
display: flex;
justify-content: center;
align-items: center;
}