or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

component-libraries.mdgradle-plugin.mdhtml-web.mdindex.md

html-web.mddocs/

0

# HTML/Web Libraries

1

2

Compose for Web provides a complete web development framework with type-safe DOM manipulation, CSS styling, SVG support, and testing utilities. It enables building modern web applications using Compose's declarative paradigm while maintaining direct access to web platform APIs.

3

4

## Capabilities

5

6

### DOM Elements

7

8

Type-safe HTML element creation with full attribute and event support.

9

10

```kotlin { .api }

11

/**

12

* Structural HTML elements

13

*/

14

@Composable fun Div(

15

attrs: AttrBuilderContext<HTMLDivElement>? = null,

16

content: ContentBuilder<HTMLDivElement>? = null

17

)

18

19

@Composable fun Header(

20

attrs: AttrBuilderContext<HTMLElement>? = null,

21

content: ContentBuilder<HTMLElement>? = null

22

)

23

24

@Composable fun Main(

25

attrs: AttrBuilderContext<HTMLElement>? = null,

26

content: ContentBuilder<HTMLElement>? = null

27

)

28

29

@Composable fun Section(

30

attrs: AttrBuilderContext<HTMLElement>? = null,

31

content: ContentBuilder<HTMLElement>? = null

32

)

33

34

@Composable fun Article(

35

attrs: AttrBuilderContext<HTMLElement>? = null,

36

content: ContentBuilder<HTMLElement>? = null

37

)

38

39

@Composable fun Nav(

40

attrs: AttrBuilderContext<HTMLElement>? = null,

41

content: ContentBuilder<HTMLElement>? = null

42

)

43

44

@Composable fun Footer(

45

attrs: AttrBuilderContext<HTMLElement>? = null,

46

content: ContentBuilder<HTMLElement>? = null

47

)

48

49

/**

50

* Text content elements

51

*/

52

@Composable fun H1(

53

attrs: AttrBuilderContext<HTMLHeadingElement>? = null,

54

content: ContentBuilder<HTMLHeadingElement>? = null

55

)

56

57

@Composable fun H2(

58

attrs: AttrBuilderContext<HTMLHeadingElement>? = null,

59

content: ContentBuilder<HTMLHeadingElement>? = null

60

)

61

62

@Composable fun H3(

63

attrs: AttrBuilderContext<HTMLHeadingElement>? = null,

64

content: ContentBuilder<HTMLHeadingElement>? = null

65

)

66

67

@Composable fun P(

68

attrs: AttrBuilderContext<HTMLParagraphElement>? = null,

69

content: ContentBuilder<HTMLParagraphElement>? = null

70

)

71

72

@Composable fun Span(

73

attrs: AttrBuilderContext<HTMLSpanElement>? = null,

74

content: ContentBuilder<HTMLSpanElement>? = null

75

)

76

77

@Composable fun Text(value: String)

78

79

/**

80

* Interactive elements

81

*/

82

@Composable fun Button(

83

attrs: AttrBuilderContext<HTMLButtonElement>? = null,

84

content: ContentBuilder<HTMLButtonElement>? = null

85

)

86

87

@Composable fun A(

88

href: String? = null,

89

attrs: AttrBuilderContext<HTMLAnchorElement>? = null,

90

content: ContentBuilder<HTMLAnchorElement>? = null

91

)

92

93

@Composable fun Label(

94

forId: String? = null,

95

attrs: AttrBuilderContext<HTMLLabelElement>? = null,

96

content: ContentBuilder<HTMLLabelElement>? = null

97

)

98

```

99

100

**Usage Example:**

101

102

```kotlin

103

@Composable

104

fun WebPage() {

105

Div({ style { padding(20.px) } }) {

106

Header {

107

H1 { Text("My Web Application") }

108

Nav {

109

A(href = "/home") { Text("Home") }

110

A(href = "/about") { Text("About") }

111

A(href = "/contact") { Text("Contact") }

112

}

113

}

114

115

Main {

116

Section {

117

H2 { Text("Welcome") }

118

P { Text("This is a Compose for Web application.") }

119

120

Button({

121

onClick { event ->

122

console.log("Button clicked!")

123

}

124

}) {

125

Text("Click me")

126

}

127

}

128

}

129

130

Footer {

131

P { Text("© 2024 My Company") }

132

}

133

}

134

}

135

```

136

137

### Form Elements

138

139

Comprehensive form controls with controlled and uncontrolled input support.

140

141

```kotlin { .api }

142

/**

143

* Form container

144

*/

145

@Composable fun Form(

146

action: String? = null,

147

attrs: AttrBuilderContext<HTMLFormElement>? = null,

148

content: ContentBuilder<HTMLFormElement>? = null

149

)

150

151

/**

152

* Generic input element

153

*/

154

@Composable fun <K : Any> Input(

155

type: InputType<K>,

156

attrs: AttrBuilderContext<HTMLInputElement>? = null

157

)

158

159

/**

160

* Controlled input elements

161

*/

162

@Composable fun TextInput(

163

value: String,

164

attrs: AttrBuilderContext<HTMLInputElement>? = null

165

)

166

167

@Composable fun NumberInput(

168

value: Number? = null,

169

attrs: AttrBuilderContext<HTMLInputElement>? = null

170

)

171

172

@Composable fun EmailInput(

173

value: String,

174

attrs: AttrBuilderContext<HTMLInputElement>? = null

175

)

176

177

@Composable fun PasswordInput(

178

value: String,

179

attrs: AttrBuilderContext<HTMLInputElement>? = null

180

)

181

182

@Composable fun CheckboxInput(

183

checked: Boolean,

184

attrs: AttrBuilderContext<HTMLInputElement>? = null

185

)

186

187

@Composable fun RadioInput(

188

checked: Boolean,

189

attrs: AttrBuilderContext<HTMLInputElement>? = null

190

)

191

192

@Composable fun DateInput(

193

value: String,

194

attrs: AttrBuilderContext<HTMLInputElement>? = null

195

)

196

197

@Composable fun DateTimeLocalInput(

198

value: String,

199

attrs: AttrBuilderContext<HTMLInputElement>? = null

200

)

201

202

@Composable fun TimeInput(

203

value: String,

204

attrs: AttrBuilderContext<HTMLInputElement>? = null

205

)

206

207

@Composable fun FileInput(

208

attrs: AttrBuilderContext<HTMLInputElement>? = null

209

)

210

211

@Composable fun RangeInput(

212

value: Number,

213

min: Number? = null,

214

max: Number? = null,

215

step: Number? = null,

216

attrs: AttrBuilderContext<HTMLInputElement>? = null

217

)

218

219

@Composable fun SearchInput(

220

value: String,

221

attrs: AttrBuilderContext<HTMLInputElement>? = null

222

)

223

224

@Composable fun TelInput(

225

value: String,

226

attrs: AttrBuilderContext<HTMLInputElement>? = null

227

)

228

229

@Composable fun UrlInput(

230

value: String,

231

attrs: AttrBuilderContext<HTMLInputElement>? = null

232

)

233

234

/**

235

* Text area for multi-line input

236

*/

237

@Composable fun TextArea(

238

value: String,

239

attrs: AttrBuilderContext<HTMLTextAreaElement>? = null

240

)

241

242

/**

243

* Select dropdown

244

*/

245

@Composable fun Select(

246

attrs: AttrBuilderContext<HTMLSelectElement>? = null,

247

multiple: Boolean = false,

248

content: ContentBuilder<HTMLSelectElement>? = null

249

)

250

251

@Composable fun Option(

252

value: String,

253

attrs: AttrBuilderContext<HTMLOptionElement>? = null,

254

content: ContentBuilder<HTMLOptionElement>? = null

255

)

256

257

@Composable fun OptGroup(

258

label: String,

259

attrs: AttrBuilderContext<HTMLOptGroupElement>? = null,

260

content: ContentBuilder<HTMLOptGroupElement>? = null

261

)

262

```

263

264

**Usage Example:**

265

266

```kotlin

267

@Composable

268

fun ContactForm() {

269

var name by remember { mutableStateOf("") }

270

var email by remember { mutableStateOf("") }

271

var message by remember { mutableStateOf("") }

272

var newsletter by remember { mutableStateOf(false) }

273

274

Form {

275

Div({ style { marginBottom(16.px) } }) {

276

Label(forId = "name") { Text("Name:") }

277

TextInput(

278

value = name,

279

attrs = {

280

id("name")

281

onInput { event ->

282

name = event.value

283

}

284

}

285

)

286

}

287

288

Div({ style { marginBottom(16.px) } }) {

289

Label(forId = "email") { Text("Email:") }

290

EmailInput(

291

value = email,

292

attrs = {

293

id("email")

294

onInput { event ->

295

email = event.value

296

}

297

}

298

)

299

}

300

301

Div({ style { marginBottom(16.px) } }) {

302

Label(forId = "message") { Text("Message:") }

303

TextArea(

304

value = message,

305

attrs = {

306

id("message")

307

rows(5)

308

onInput { event ->

309

message = event.value

310

}

311

}

312

)

313

}

314

315

Div({ style { marginBottom(16.px) } }) {

316

CheckboxInput(

317

checked = newsletter,

318

attrs = {

319

id("newsletter")

320

onInput { event ->

321

newsletter = event.value

322

}

323

}

324

)

325

Label(forId = "newsletter") { Text("Subscribe to newsletter") }

326

}

327

328

Button({

329

type("submit")

330

onClick { event ->

331

event.preventDefault()

332

submitForm(name, email, message, newsletter)

333

}

334

}) {

335

Text("Send Message")

336

}

337

}

338

}

339

```

340

341

### CSS Styling

342

343

Type-safe CSS styling with units, properties, and responsive design support.

344

345

```kotlin { .api }

346

/**

347

* Style scope for CSS properties

348

*/

349

interface StyleScope {

350

/** Add arbitrary CSS property */

351

fun property(propertyName: String, value: StylePropertyValue)

352

353

/** Set CSS custom property (variable) */

354

fun variable(variableName: String, value: StylePropertyValue)

355

}

356

357

/**

358

* Style scope builder implementation

359

*/

360

class StyleScopeBuilder : StyleScope, StyleHolder

361

362

/**

363

* Mount style tag with CSS rules

364

*/

365

@Composable fun Style(cssRules: CSSRuleDeclarationList)

366

367

/**

368

* Build and mount styles

369

*/

370

@Composable inline fun Style(rulesBuild: StyleSheetBuilder.() -> Unit)

371

372

/**

373

* CSS unit system

374

*/

375

interface CSSUnit

376

interface CSSUnitLength : CSSUnit

377

interface CSSUnitPercentage : CSSUnit

378

interface CSSUnitAngle : CSSUnit

379

interface CSSUnitTime : CSSUnit

380

381

/** Length units */

382

val Number.px: CSSLengthValue

383

val Number.em: CSSLengthValue

384

val Number.cssRem: CSSLengthValue

385

val Number.vw: CSSLengthValue

386

val Number.vh: CSSLengthValue

387

val Number.vmin: CSSLengthValue

388

val Number.vmax: CSSLengthValue

389

390

/** Percentage units */

391

val Number.percent: CSSPercentageValue

392

393

/** Angle units */

394

val Number.deg: CSSAngleValue

395

val Number.rad: CSSAngleValue

396

val Number.turn: CSSAngleValue

397

398

/** Time units */

399

val Number.s: CSSTimeValue

400

val Number.ms: CSSTimeValue

401

402

/**

403

* CSS variables

404

*/

405

class CSSStyleVariable<TValue : StylePropertyValue>

406

fun <TValue : StylePropertyValue> variable(): CSSStyleVariable<TValue>

407

```

408

409

**Usage Example:**

410

411

```kotlin

412

@Composable

413

fun StyledComponents() {

414

Style {

415

// Global styles

416

".card" style {

417

backgroundColor(Color.white)

418

borderRadius(8.px)

419

boxShadow(0.px, 2.px, 4.px, rgba(0, 0, 0, 0.1))

420

padding(16.px)

421

margin(8.px)

422

}

423

424

".button-primary" style {

425

backgroundColor(Color.blue)

426

color(Color.white)

427

border(0.px)

428

borderRadius(4.px)

429

padding(12.px, 24.px)

430

cursor("pointer")

431

432

hover style {

433

backgroundColor(Color.darkBlue)

434

}

435

}

436

}

437

438

Div({ classes("card") }) {

439

H3({ style { marginTop(0.px) } }) {

440

Text("Styled Card")

441

}

442

443

P { Text("This card has custom styling applied.") }

444

445

Button({ classes("button-primary") }) {

446

Text("Primary Action")

447

}

448

}

449

}

450

```

451

452

### Attributes API

453

454

Comprehensive attribute and event handling system.

455

456

```kotlin { .api }

457

/**

458

* Attributes scope for element configuration

459

*/

460

interface AttrsScope<out TElement : Element> : EventsListenerScope {

461

/** Set arbitrary HTML attribute */

462

fun attr(attr: String, value: String)

463

464

/** Add inline styles */

465

fun style(builder: StyleScope.() -> Unit)

466

467

/** Add CSS classes */

468

fun classes(classes: Collection<String>)

469

fun classes(vararg classes: String)

470

471

/** Set DOM properties directly */

472

fun <E : HTMLElement, V> prop(update: (E, V) -> Unit, value: V)

473

474

/** Get element reference for imperative operations */

475

fun ref(effect: DisposableEffectScope.(TElement) -> DisposableEffectResult)

476

}

477

478

/**

479

* Common HTML attributes

480

*/

481

fun AttrsScope<*>.id(value: String)

482

fun AttrsScope<*>.title(value: String)

483

fun AttrsScope<*>.hidden()

484

fun AttrsScope<*>.tabIndex(value: Int)

485

fun AttrsScope<*>.contentEditable(value: Boolean)

486

fun AttrsScope<*>.draggable(value: Draggable)

487

488

/**

489

* Type aliases for attribute and content builders

490

*/

491

typealias AttrBuilderContext<T> = AttrsScope<T>.() -> Unit

492

typealias ContentBuilder<T> = @Composable ElementScope<T>.() -> Unit

493

```

494

495

### Event Handling

496

497

Type-safe event handling with synthetic event wrappers.

498

499

```kotlin { .api }

500

/**

501

* Base synthetic event wrapper

502

*/

503

open class SyntheticEvent<Element : EventTarget>

504

505

/**

506

* Specific event types

507

*/

508

class SyntheticMouseEvent<Element : EventTarget> : SyntheticEvent<Element>

509

class SyntheticKeyboardEvent<Element : EventTarget> : SyntheticEvent<Element>

510

class SyntheticFocusEvent<Element : EventTarget> : SyntheticEvent<Element>

511

class SyntheticInputEvent<Element : EventTarget> : SyntheticEvent<Element>

512

class SyntheticChangeEvent<Element : EventTarget> : SyntheticEvent<Element>

513

class SyntheticSubmitEvent<Element : EventTarget> : SyntheticEvent<Element>

514

class SyntheticClipboardEvent<Element : EventTarget> : SyntheticEvent<Element>

515

class SyntheticTouchEvent<Element : EventTarget> : SyntheticEvent<Element>

516

517

/**

518

* Event listener scope

519

*/

520

interface EventsListenerScope

521

```

522

523

### SVG Support

524

525

Complete SVG creation and manipulation API for vector graphics.

526

527

```kotlin { .api }

528

/**

529

* SVG container element

530

*/

531

@ExperimentalComposeWebSvgApi

532

@Composable fun Svg(

533

viewBox: String? = null,

534

attrs: AttrBuilderContext<SVGSVGElement>? = null,

535

content: ContentBuilder<SVGSVGElement>? = null

536

)

537

538

/**

539

* SVG shape elements

540

*/

541

@ExperimentalComposeWebSvgApi

542

@Composable fun ElementScope<SVGElement>.Circle(

543

cx: CSSLengthOrPercentageValue? = null,

544

cy: CSSLengthOrPercentageValue? = null,

545

r: CSSLengthOrPercentageValue? = null,

546

attrs: AttrBuilderContext<SVGCircleElement>? = null,

547

content: ContentBuilder<SVGCircleElement>? = null

548

)

549

550

@ExperimentalComposeWebSvgApi

551

@Composable fun ElementScope<SVGElement>.Rect(

552

x: CSSLengthOrPercentageValue? = null,

553

y: CSSLengthOrPercentageValue? = null,

554

width: CSSLengthOrPercentageValue? = null,

555

height: CSSLengthOrPercentageValue? = null,

556

attrs: AttrBuilderContext<SVGRectElement>? = null,

557

content: ContentBuilder<SVGRectElement>? = null

558

)

559

560

@ExperimentalComposeWebSvgApi

561

@Composable fun ElementScope<SVGElement>.Path(

562

d: String,

563

attrs: AttrBuilderContext<SVGPathElement>? = null,

564

content: ContentBuilder<SVGPathElement>? = null

565

)

566

567

@ExperimentalComposeWebSvgApi

568

@Composable fun ElementScope<SVGElement>.Line(

569

x1: CSSLengthOrPercentageValue? = null,

570

y1: CSSLengthOrPercentageValue? = null,

571

x2: CSSLengthOrPercentageValue? = null,

572

y2: CSSLengthOrPercentageValue? = null,

573

attrs: AttrBuilderContext<SVGLineElement>? = null,

574

content: ContentBuilder<SVGLineElement>? = null

575

)

576

577

@ExperimentalComposeWebSvgApi

578

@Composable fun ElementScope<SVGElement>.Ellipse(

579

cx: CSSLengthOrPercentageValue? = null,

580

cy: CSSLengthOrPercentageValue? = null,

581

rx: CSSLengthOrPercentageValue? = null,

582

ry: CSSLengthOrPercentageValue? = null,

583

attrs: AttrBuilderContext<SVGEllipseElement>? = null,

584

content: ContentBuilder<SVGEllipseElement>? = null

585

)

586

587

@ExperimentalComposeWebSvgApi

588

@Composable fun ElementScope<SVGElement>.Polygon(

589

points: String,

590

attrs: AttrBuilderContext<SVGPolygonElement>? = null,

591

content: ContentBuilder<SVGPolygonElement>? = null

592

)

593

594

@ExperimentalComposeWebSvgApi

595

@Composable fun ElementScope<SVGElement>.Polyline(

596

points: String,

597

attrs: AttrBuilderContext<SVGPolylineElement>? = null,

598

content: ContentBuilder<SVGPolylineElement>? = null

599

)

600

601

/**

602

* SVG text elements

603

*/

604

@ExperimentalComposeWebSvgApi

605

@Composable fun ElementScope<SVGElement>.SvgText(

606

text: String,

607

x: CSSLengthOrPercentageValue? = null,

608

y: CSSLengthOrPercentageValue? = null,

609

attrs: AttrBuilderContext<SVGTextElement>? = null

610

)

611

612

/**

613

* SVG gradient elements

614

*/

615

@ExperimentalComposeWebSvgApi

616

@Composable fun ElementScope<SVGElement>.LinearGradient(

617

id: String,

618

attrs: AttrBuilderContext<SVGLinearGradientElement>? = null,

619

content: ContentBuilder<SVGLinearGradientElement>? = null

620

)

621

622

@ExperimentalComposeWebSvgApi

623

@Composable fun ElementScope<SVGElement>.RadialGradient(

624

id: String,

625

attrs: AttrBuilderContext<SVGRadialGradientElement>? = null,

626

content: ContentBuilder<SVGRadialGradientElement>? = null

627

)

628

629

@ExperimentalComposeWebSvgApi

630

@Composable fun ElementScope<SVGElement>.Stop(

631

attrs: AttrBuilderContext<SVGStopElement>? = null,

632

content: ContentBuilder<SVGStopElement>? = null

633

)

634

```

635

636

**Usage Example:**

637

638

```kotlin

639

@OptIn(ExperimentalComposeWebSvgApi::class)

640

@Composable

641

fun SvgExample() {

642

Svg(

643

viewBox = "0 0 200 200",

644

attrs = {

645

style {

646

width(200.px)

647

height(200.px)

648

border(1.px, LineStyle.Solid, Color.black)

649

}

650

}

651

) {

652

// Define gradient

653

LinearGradient(id = "myGradient") {

654

Stop {

655

attr("offset", "0%")

656

attr("stop-color", "red")

657

}

658

Stop {

659

attr("offset", "100%")

660

attr("stop-color", "blue")

661

}

662

}

663

664

// Draw shapes

665

Circle(

666

cx = 100.px,

667

cy = 100.px,

668

r = 50.px,

669

attrs = {

670

fill("url(#myGradient)")

671

attr("stroke", "black")

672

attr("stroke-width", "2")

673

}

674

)

675

676

Path(

677

d = "M 50 150 Q 100 100 150 150",

678

attrs = {

679

fill("none")

680

attr("stroke", "green")

681

attr("stroke-width", "3")

682

}

683

)

684

685

SvgText(

686

text = "SVG Text",

687

x = 100.px,

688

y = 180.px,

689

attrs = {

690

attr("text-anchor", "middle")

691

attr("font-family", "Arial")

692

attr("font-size", "16")

693

}

694

)

695

}

696

}

697

```

698

699

### Testing Utilities

700

701

Testing framework for web Compose applications with composition and DOM testing support.

702

703

```kotlin { .api }

704

/**

705

* Main test scope with coroutine support

706

*/

707

@ComposeWebExperimentalTestsApi

708

class TestScope : CoroutineScope

709

710

/**

711

* Execute test block with test scope

712

*/

713

@ComposeWebExperimentalTestsApi

714

fun runTest(block: suspend TestScope.() -> Unit)

715

716

/**

717

* Test scope API

718

*/

719

interface TestScope {

720

/** Root test element */

721

val root: HTMLElement

722

723

/** Create test composition */

724

fun composition(content: @Composable () -> Unit)

725

726

/** Get next child element */

727

fun nextChild(): HTMLElement

728

fun <T> nextChild(): T

729

730

/** Wait for recomposition to complete */

731

suspend fun waitForRecompositionComplete()

732

733

/** Wait for DOM changes */

734

suspend fun waitForChanges(elementId: String)

735

suspend fun waitForChanges(element: HTMLElement)

736

}

737

738

/**

739

* Test utilities

740

*/

741

val HTMLElement.computedStyle: CSSStyleDeclaration

742

```

743

744

**Usage Example:**

745

746

```kotlin

747

@OptIn(ComposeWebExperimentalTestsApi::class)

748

fun testMyComponent() = runTest {

749

var clicked by mutableStateOf(false)

750

751

composition {

752

Button({

753

id("test-button")

754

onClick { clicked = true }

755

}) {

756

Text(if (clicked) "Clicked!" else "Click me")

757

}

758

}

759

760

val button = nextChild<HTMLButtonElement>()

761

assertEquals("Click me", button.textContent)

762

763

button.click()

764

waitForRecompositionComplete()

765

766

assertEquals("Clicked!", button.textContent)

767

assertTrue(clicked)

768

}

769

```

770

771

## Experimental APIs

772

773

```kotlin { .api }

774

/**

775

* Marks experimental web APIs

776

*/

777

@RequiresOptIn

778

annotation class ExperimentalComposeWebApi

779

780

/**

781

* Marks experimental style APIs

782

*/

783

@RequiresOptIn

784

annotation class ExperimentalComposeWebStyleApi

785

786

/**

787

* Marks experimental SVG APIs

788

*/

789

@RequiresOptIn

790

annotation class ExperimentalComposeWebSvgApi

791

792

/**

793

* Marks experimental test APIs

794

*/

795

@RequiresOptIn

796

annotation class ComposeWebExperimentalTestsApi

797

```