There are two ways to implement a component. One is to implement a class deriving from the AbstractComponent class. The other is to implement it by use of other components.
The former one is more flexible. It requires deeper understanding of ZK, so it is usually done by component developers. It is discussed in the ZK Component Reference.
On the other hand, implementing a new component by use of other components is straightforward. It works like composition, macro expansion, or inline replacement. For sake of convenience, we call this kind of components as macro components., while the others are called primitive components.
Tip: a macro component is no different from a primitive component from application developer's viewpoint, except how it is implemented.