0
# Core UI Foundation
1
2
Essential building blocks for all Compose UI applications including the Modifier system, alignment, measurement units, and core interfaces.
3
4
## Capabilities
5
6
### Modifier System
7
8
The Modifier interface is the primary way to decorate or add behavior to Compose UI elements. Modifiers can be chained together to create complex styling and behavior combinations.
9
10
```kotlin { .api }
11
/**
12
* An ordered, immutable collection of modifier elements that decorate or add behavior to Compose UI elements.
13
*/
14
interface Modifier {
15
/**
16
* Accumulates a value starting with initial and applying operation to current result and each element.
17
*/
18
fun <R> foldIn(initial: R, operation: (R, Element) -> R): R
19
20
/**
21
* Accumulates a value starting with initial and applying operation from right to left.
22
*/
23
fun <R> foldOut(initial: R, operation: (Element, R) -> R): R
24
25
/**
26
* Returns true if any element matches the given predicate.
27
*/
28
fun any(predicate: (Element) -> Boolean): Boolean
29
30
/**
31
* Returns true if all elements match the given predicate.
32
*/
33
fun all(predicate: (Element) -> Boolean): Boolean
34
35
/**
36
* Concatenates this modifier with another modifier.
37
*/
38
infix fun then(other: Modifier): Modifier
39
40
/**
41
* A single Element contained within a Modifier chain.
42
*/
43
interface Element : Modifier {
44
override fun <R> foldIn(initial: R, operation: (R, Element) -> R): R
45
override fun <R> foldOut(initial: R, operation: (Element, R) -> R): R
46
override fun any(predicate: (Element) -> Boolean): Boolean
47
override fun all(predicate: (Element) -> Boolean): Boolean
48
}
49
50
/**
51
* The companion object Modifier is the empty, default, or starter Modifier that contains no elements.
52
*/
53
companion object : Modifier {
54
override fun <R> foldIn(initial: R, operation: (R, Element) -> R): R
55
override fun <R> foldOut(initial: R, operation: (Element, R) -> R): R
56
override fun any(predicate: (Element) -> Boolean): Boolean
57
override fun all(predicate: (Element) -> Boolean): Boolean
58
override infix fun then(other: Modifier): Modifier
59
}
60
}
61
```
62
63
**Usage Examples:**
64
65
```kotlin
66
// Basic modifier chaining
67
Modifier
68
.fillMaxWidth()
69
.padding(16.dp)
70
.background(Color.Blue)
71
.clickable { /* action */ }
72
73
// Conditional modifiers
74
val baseModifier = Modifier.fillMaxWidth()
75
val finalModifier = if (isEnabled) {
76
baseModifier.clickable { /* action */ }
77
} else {
78
baseModifier.alpha(0.5f)
79
}
80
```
81
82
### Alignment System
83
84
Provides alignment specifications for positioning elements within containers, supporting both absolute and relative positioning.
85
86
```kotlin { .api }
87
/**
88
* An interface to calculate the position of a sized box inside an available space.
89
*/
90
interface Alignment {
91
/**
92
* Calculates the position of a box with the given size in the available space.
93
*/
94
fun align(size: IntSize, space: IntSize, layoutDirection: LayoutDirection): IntOffset
95
96
/**
97
* 2D Alignments for absolute positioning
98
*/
99
interface Horizontal {
100
fun align(size: Int, space: Int, layoutDirection: LayoutDirection): Int
101
}
102
103
interface Vertical {
104
fun align(size: Int, space: Int): Int
105
}
106
107
companion object {
108
// 2D alignments
109
val TopStart: Alignment
110
val TopCenter: Alignment
111
val TopEnd: Alignment
112
val CenterStart: Alignment
113
val Center: Alignment
114
val CenterEnd: Alignment
115
val BottomStart: Alignment
116
val BottomCenter: Alignment
117
val BottomEnd: Alignment
118
119
// 1D vertical alignments
120
val Top: Vertical
121
val CenterVertically: Vertical
122
val Bottom: Vertical
123
124
// 1D horizontal alignments
125
val Start: Horizontal
126
val CenterHorizontally: Horizontal
127
val End: Horizontal
128
}
129
}
130
131
/**
132
* BiasAlignment allows positioning with a bias value from -1.0 to 1.0
133
*/
134
class BiasAlignment(
135
val horizontalBias: Float,
136
val verticalBias: Float
137
) : Alignment {
138
class Horizontal(val bias: Float) : Alignment.Horizontal
139
class Vertical(val bias: Float) : Alignment.Vertical
140
}
141
142
/**
143
* AbsoluteAlignment uses start/end positioning regardless of layout direction
144
*/
145
object AbsoluteAlignment {
146
val TopLeft: Alignment
147
val TopRight: Alignment
148
val CenterLeft: Alignment
149
val CenterRight: Alignment
150
val BottomLeft: Alignment
151
val BottomRight: Alignment
152
153
val Left: Alignment.Horizontal
154
val Right: Alignment.Horizontal
155
}
156
```
157
158
**Usage Examples:**
159
160
```kotlin
161
// In a Box composable
162
Box(
163
modifier = Modifier.size(200.dp),
164
contentAlignment = Alignment.Center
165
) {
166
Text("Centered content")
167
}
168
169
// Custom bias alignment
170
Box(
171
modifier = Modifier.fillMaxSize(),
172
contentAlignment = BiasAlignment(0.3f, -0.2f)
173
) {
174
Text("Custom positioned")
175
}
176
```
177
178
### Measurement Units
179
180
Density-independent and scalable measurement units for consistent layout across different screen densities and user preferences.
181
182
```kotlin { .api }
183
/**
184
* Dimension value representing device-independent pixels (dp).
185
*/
186
@JvmInline
187
value class Dp(val value: Float) : Comparable<Dp> {
188
override operator fun compareTo(other: Dp): Int
189
operator fun plus(other: Dp): Dp
190
operator fun minus(other: Dp): Dp
191
operator fun times(other: Float): Dp
192
operator fun times(other: Int): Dp
193
operator fun div(other: Float): Dp
194
operator fun div(other: Int): Dp
195
operator fun unaryMinus(): Dp
196
197
companion object {
198
val Hairline: Dp
199
val Infinity: Dp
200
val Unspecified: Dp
201
}
202
}
203
204
/**
205
* Create a Dp using an Int
206
*/
207
val Int.dp: Dp
208
209
/**
210
* Create a Dp using a Double
211
*/
212
val Double.dp: Dp
213
214
/**
215
* Create a Dp using a Float
216
*/
217
val Float.dp: Dp
218
219
/**
220
* Scalable dimension value representing scalable pixels (sp) for text.
221
*/
222
@JvmInline
223
value class Sp(val value: Float) : Comparable<Sp> {
224
override operator fun compareTo(other: Sp): Int
225
operator fun plus(other: Sp): Sp
226
operator fun minus(other: Sp): Sp
227
operator fun times(other: Float): Sp
228
operator fun times(other: Int): Sp
229
operator fun div(other: Float): Sp
230
operator fun div(other: Int): Sp
231
operator fun unaryMinus(): Sp
232
233
companion object {
234
val Unspecified: Sp
235
}
236
}
237
238
/**
239
* Create an Sp using an Int
240
*/
241
val Int.sp: Sp
242
243
/**
244
* Create an Sp using a Double
245
*/
246
val Double.sp: Sp
247
248
/**
249
* Create an Sp using a Float
250
*/
251
val Float.sp: Sp
252
253
/**
254
* Represents a unit of text measurement
255
*/
256
sealed class TextUnit {
257
object Unspecified : TextUnit()
258
259
companion object {
260
val Unspecified: TextUnit
261
}
262
}
263
```
264
265
**Usage Examples:**
266
267
```kotlin
268
// Using dp for layout dimensions
269
Modifier
270
.width(200.dp)
271
.height(100.dp)
272
.padding(16.dp)
273
274
// Using sp for text sizes
275
TextStyle(fontSize = 16.sp)
276
277
// Arithmetic operations
278
val largeSpacing = 16.dp + 8.dp // 24.dp
279
val halfWidth = 100.dp / 2 // 50.dp
280
```
281
282
### Layout Direction
283
284
Support for left-to-right (LTR) and right-to-left (RTL) layout directions for internationalization.
285
286
```kotlin { .api }
287
/**
288
* Layout direction of a UI, either Left to Right or Right to Left.
289
*/
290
enum class LayoutDirection {
291
Ltr, Rtl
292
}
293
294
/**
295
* CompositionLocal providing the current layout direction
296
*/
297
val LocalLayoutDirection: ProvidableCompositionLocal<LayoutDirection>
298
```
299
300
**Usage Examples:**
301
302
```kotlin
303
// Access current layout direction
304
val layoutDirection = LocalLayoutDirection.current
305
306
// Conditional behavior based on layout direction
307
val startPadding = if (layoutDirection == LayoutDirection.Ltr) 16.dp else 8.dp
308
val endPadding = if (layoutDirection == LayoutDirection.Ltr) 8.dp else 16.dp
309
```
310
311
### Core Geometry Types
312
313
Essential geometric types for positioning and sizing UI elements.
314
315
```kotlin { .api }
316
/**
317
* An immutable 2D integer offset.
318
*/
319
@Immutable
320
data class IntOffset(val x: Int, val y: Int) {
321
operator fun plus(other: IntOffset): IntOffset
322
operator fun minus(other: IntOffset): IntOffset
323
operator fun unaryMinus(): IntOffset
324
325
companion object {
326
val Zero: IntOffset
327
}
328
}
329
330
/**
331
* An immutable 2D integer size.
332
*/
333
@Immutable
334
data class IntSize(val width: Int, val height: Int) {
335
operator fun times(other: Int): IntSize
336
337
companion object {
338
val Zero: IntSize
339
}
340
}
341
342
/**
343
* An immutable 2D floating-point offset.
344
*/
345
@Immutable
346
data class Offset(val x: Float, val y: Float) {
347
operator fun plus(other: Offset): Offset
348
operator fun minus(other: Offset): Offset
349
operator fun times(operand: Float): Offset
350
operator fun div(operand: Float): Offset
351
operator fun unaryMinus(): Offset
352
fun getDistance(): Float
353
fun getDistanceSquared(): Float
354
355
companion object {
356
val Zero: Offset
357
val Infinite: Offset
358
val Unspecified: Offset
359
}
360
}
361
362
/**
363
* An immutable 2D floating-point size.
364
*/
365
@Immutable
366
data class Size(val width: Float, val height: Float) {
367
operator fun times(operand: Float): Size
368
operator fun div(operand: Float): Size
369
370
companion object {
371
val Zero: Size
372
val Unspecified: Size
373
}
374
}
375
376
/**
377
* An immutable rectangle.
378
*/
379
@Immutable
380
data class Rect(
381
val left: Float,
382
val top: Float,
383
val right: Float,
384
val bottom: Float
385
) {
386
constructor(offset: Offset, size: Size)
387
constructor(topLeft: Offset, bottomRight: Offset)
388
389
val width: Float
390
val height: Float
391
val size: Size
392
val center: Offset
393
val topLeft: Offset
394
val topCenter: Offset
395
val topRight: Offset
396
val centerLeft: Offset
397
val centerRight: Offset
398
val bottomLeft: Offset
399
val bottomCenter: Offset
400
val bottomRight: Offset
401
402
fun isEmpty(): Boolean
403
fun isFinite(): Boolean
404
fun contains(offset: Offset): Boolean
405
fun overlaps(other: Rect): Boolean
406
fun intersect(other: Rect): Rect
407
408
companion object {
409
val Zero: Rect
410
}
411
}
412
```
413
414
**Usage Examples:**
415
416
```kotlin
417
// Creating positions and sizes
418
val position = IntOffset(x = 100, y = 50)
419
val size = IntSize(width = 200, height = 100)
420
421
// Floating point geometry
422
val center = Offset(150.0f, 75.0f)
423
val bounds = Size(300.0f, 200.0f)
424
425
// Rectangle operations
426
val rect = Rect(
427
left = 0.0f,
428
top = 0.0f,
429
right = 100.0f,
430
bottom = 50.0f
431
)
432
val contains = rect.contains(Offset(25.0f, 25.0f)) // true
433
```
434
435
### Density Interface
436
437
Interface for converting between different measurement units based on screen density.
438
439
```kotlin { .api }
440
/**
441
* A density of the screen. Used for the conversions between [Dp] and pixels.
442
*/
443
interface Density {
444
/**
445
* The logical density of the display.
446
*/
447
val density: Float
448
449
/**
450
* Current user preference for the scaling factor for fonts.
451
*/
452
val fontScale: Float
453
454
/**
455
* Convert [Dp] to pixels.
456
*/
457
fun Dp.toPx(): Float
458
459
/**
460
* Convert [Sp] to pixels.
461
*/
462
fun Sp.toPx(): Float
463
464
/**
465
* Convert pixels to [Dp].
466
*/
467
fun Float.toDp(): Dp
468
469
/**
470
* Convert pixels to [Sp].
471
*/
472
fun Float.toSp(): Sp
473
474
/**
475
* Convert [Dp] to [Int] pixels.
476
*/
477
fun Dp.roundToPx(): Int
478
479
/**
480
* Convert [Sp] to [Int] pixels.
481
*/
482
fun Sp.roundToPx(): Int
483
}
484
485
/**
486
* CompositionLocal providing the current density
487
*/
488
val LocalDensity: ProvidableCompositionLocal<Density>
489
```
490
491
**Usage Examples:**
492
493
```kotlin
494
// Access current density
495
val density = LocalDensity.current
496
497
// Convert between units
498
with(density) {
499
val pixels = 16.dp.toPx() // Convert dp to pixels
500
val dp = 48.0f.toDp() // Convert pixels to dp
501
val textPixels = 14.sp.toPx() // Convert sp to pixels
502
}
503
```