Theming
Styling examples
This page shows the main ways to style the component. Use
classNames for slot-level classes, styles for
inline styles, or keep the bundled stylesheet and override CSS
variables.
Start with your framework or library
Start with the section for your framework, then use the references later on this page.
Example: Angular with Angular Material
The component does not become a Material form field, but you can make it match Material spacing and surfaces.
import { Component } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { MatCardModule } from '@angular/material/card'
import { CountriesFlagsComponent } from '@drobinetm/angular-countries-flags'
@Component({
standalone: true,
imports: [FormsModule, MatCardModule, CountriesFlagsComponent],
template: `
<mat-card appearance="outlined">
<mat-card-content>
<drm-countries-flags
[(ngModel)]="selectedCode"
[unstyled]="true"
[classNames]="{
trigger: 'mat-mdc-button-base w-full d-flex align-items-center justify-content-between px-3 py-3 rounded-4 border',
triggerContent: 'd-flex align-items-center gap-2 text-truncate',
placeholder: 'mat-body-medium text-medium-emphasis',
list: 'mt-2 rounded-4 border bg-surface p-1 mat-elevation-z8',
option: 'd-flex align-items-center gap-2 rounded-3 px-3 py-2',
optionSelected: 'bg-primary text-white'
}"
[styles]="{ flag: { borderRadius: "9999px" } }"
></drm-countries-flags>
</mat-card-content>
</mat-card>
`,
})
export class DemoComponent {
selectedCode: string | null = null
} Example: React with Tailwind or shadcn/ui
In React, Tailwind and shadcn/ui fit well because the component lets you pass classes to each slot.
import { CountriesFlags } from '@drobinetm/react-countries-flags'
<CountriesFlags
value={code}
onChange={(event) => setCode(event.code)}
unstyled
classNames={{
root: 'w-full',
trigger: 'flex h-11 w-full items-center justify-between rounded-xl border border-slate-300 bg-white px-3 shadow-sm dark:border-slate-700 dark:bg-slate-950',
triggerContent: 'flex min-w-0 items-center gap-2',
placeholder: 'text-slate-400 dark:text-slate-500',
label: 'truncate',
list: 'mt-2 max-h-64 overflow-auto rounded-xl border border-slate-200 bg-white p-1 shadow-2xl dark:border-slate-800 dark:bg-slate-950',
option: 'flex cursor-pointer items-center gap-2 rounded-lg px-3 py-2 text-sm',
optionActive: 'bg-slate-100 dark:bg-slate-900',
optionSelected: 'bg-sky-600 text-white',
}}
styles={{
flag: { borderRadius: '9999px' },
}}
/> Example: Vue with Vuetify
Use Vuetify utility classes on the exposed slots to align spacing, elevation, and colors.
<CountriesFlags
v-model="selectedCode"
:unstyled="true"
:class-names="{
root: 'w-100',
trigger: 'd-flex align-center justify-space-between w-100 px-4 py-3 rounded-lg border',
triggerContent: 'd-flex align-center ga-2 min-w-0',
placeholder: 'text-medium-emphasis',
list: 'mt-2 pa-2 rounded-lg border bg-surface elevation-8',
option: 'd-flex align-center ga-2 rounded-lg px-3 py-2',
optionActive: 'bg-grey-lighten-4',
optionSelected: 'bg-primary text-white',
}"
:styles="{
flag: { borderRadius: '9999px' },
}"
/> Inline styles
Use inline styles when your theme is computed at runtime or comes from JavaScript tokens. The same object shape is used in React, Vue, and Angular.
styles={{
root: { width: '100%', minWidth: 280 },
trigger: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
width: '100%',
minHeight: 44,
padding: '0 14px',
border: '1px solid #d4d4d8',
borderRadius: 16,
backgroundColor: '#ffffff',
color: '#111827',
},
triggerContent: { display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 },
placeholder: { color: '#6b7280' },
list: {
marginTop: 8,
padding: 6,
listStyle: 'none',
border: '1px solid #e5e7eb',
borderRadius: 16,
backgroundColor: '#ffffff',
boxShadow: '0 24px 48px rgba(15, 23, 42, 0.18)',
},
option: { display: 'flex', alignItems: 'center', gap: 8, padding: '10px 12px', borderRadius: 12 },
optionActive: { backgroundColor: '#f3f4f6' },
optionSelected: { backgroundColor: '#2563eb', color: '#ffffff' },
flag: { borderRadius: '9999px' },
}} Compatibility matrix
Use this matrix to compare which design systems make sense for each framework package.
| System | Angular | React | Vue | Recommended API |
|---|---|---|---|---|
| Tailwind CSS | Yes | Yes | Yes | unstyled + classNames |
| Bootstrap | Yes | Yes | Yes | unstyled + classNames |
| Inline styles | Yes | Yes | Yes | unstyled + styles |
| shadcn/ui | No | Yes | No | unstyled + classNames |
| Angular Material | Yes | No | No | unstyled + host layout classes |
| Vuetify | No | No | Yes | unstyled + classNames |
Available slots
All framework packages expose the same slot names. In most cases, only the syntax changes between frameworks.
type CountriesFlagsClassNames = {
root?: string
trigger?: string
triggerContent?: string
placeholder?: string
label?: string
chevron?: string
backdrop?: string
list?: string
empty?: string
option?: string
optionSelected?: string
optionActive?: string
flag?: string
optionName?: string
} CSS variables
If you want to keep the default layout and just change colors or radii, CSS variables are the simplest option.
.drm-cf {
--drm-cf-bg: #ffffff;
--drm-cf-border: #d4d4d8;
--drm-cf-border-hover: #93c5fd;
--drm-cf-focus: #2563eb;
--drm-cf-radius: 16px;
--drm-cf-text: #111827;
--drm-cf-placeholder: #6b7280;
--drm-cf-dropdown-bg: #ffffff;
--drm-cf-accent: #2563eb;
} Slot mapping reference
Use this table when translating a design system into component slots.
| Slot | What it styles | Typical design-system mapping |
|---|---|---|
root | Outer wrapper | Width, layout, spacing container |
trigger | Closed field button | Field chrome, border, padding, radius |
triggerContent | Inner trigger row | Horizontal alignment and spacing |
placeholder | Empty-state text | Muted text color |
label | Selected country label | Text truncation and typography |
chevron | Open/close icon | Icon color and transitions |
list | Dropdown panel | Surface, border, shadow, radius |
option | Every option row | Spacing, cursor, typography |
optionActive | Hovered or active row | Hover background |
optionSelected | Selected row | Brand background and foreground |
flag | Flag icon | Rounded shape or fixed size |
optionName | Country text in list | Typography and truncation |