or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdcomponent-events.mdcomponent-props.mdindex.md

advanced-features.mddocs/

0

# Advanced Features

1

2

Advanced functionality including aspect ratio locking, handle customization, programmatic control methods, and specialized configuration options.

3

4

## Capabilities

5

6

### Aspect Ratio Control

7

8

Lock aspect ratio during resize operations to maintain proportional dimensions.

9

10

```javascript { .api }

11

/**

12

* Aspect ratio locking configuration

13

*/

14

interface AspectRatioControl {

15

/** Enable aspect ratio locking (default: false) */

16

lockAspectRatio: boolean;

17

}

18

```

19

20

**Usage Examples:**

21

22

```vue

23

<template>

24

<!-- Image with locked aspect ratio -->

25

<vue-draggable-resizable

26

:lock-aspect-ratio="true"

27

:w="300"

28

:h="200"

29

>

30

<img src="photo.jpg" style="width: 100%; height: 100%; object-fit: cover;" />

31

</vue-draggable-resizable>

32

33

<!-- Video player with 16:9 ratio -->

34

<vue-draggable-resizable

35

:lock-aspect-ratio="true"

36

:w="480"

37

:h="270"

38

:min-width="320"

39

:min-height="180"

40

>

41

<video controls style="width: 100%; height: 100%;">

42

<source src="video.mp4" type="video/mp4">

43

</video>

44

</vue-draggable-resizable>

45

</template>

46

```

47

48

### Handle Customization

49

50

Configure which resize handles are available and customize their appearance and behavior.

51

52

```javascript { .api }

53

/**

54

* Resize handle configuration and types

55

*/

56

interface HandleCustomization {

57

/** Array of enabled resize handles (default: all 8 handles) */

58

handles: HandleType[];

59

60

/** Base CSS class for handles, used to create handle-specific classes */

61

classNameHandle: string;

62

}

63

64

/** Available resize handle positions */

65

type HandleType = 'tl' | 'tm' | 'tr' | 'mr' | 'br' | 'bm' | 'bl' | 'ml';

66

67

/** Handle position meanings */

68

interface HandlePositions {

69

'tl': 'top-left'; // Corner: top-left

70

'tm': 'top-middle'; // Edge: top-middle

71

'tr': 'top-right'; // Corner: top-right

72

'mr': 'middle-right'; // Edge: middle-right

73

'br': 'bottom-right'; // Corner: bottom-right

74

'bm': 'bottom-middle';// Edge: bottom-middle

75

'bl': 'bottom-left'; // Corner: bottom-left

76

'ml': 'middle-left'; // Edge: middle-left

77

}

78

```

79

80

**Usage Examples:**

81

82

```vue

83

<template>

84

<!-- Only corner handles -->

85

<vue-draggable-resizable

86

:handles="['tl', 'tr', 'br', 'bl']"

87

class-name-handle="corner-handle"

88

>

89

Corner resize only

90

</vue-draggable-resizable>

91

92

<!-- Only right and bottom handles -->

93

<vue-draggable-resizable

94

:handles="['mr', 'br', 'bm']"

95

>

96

Expand right and down only

97

</vue-draggable-resizable>

98

99

<!-- Custom handle slots -->

100

<vue-draggable-resizable :handles="['br']">

101

<template #br>

102

<div class="custom-handle">

103

<svg width="10" height="10">

104

<path d="M0,0 L10,10 M0,10 L10,0" stroke="black" />

105

</svg>

106

</div>

107

</template>

108

Custom handle appearance

109

</vue-draggable-resizable>

110

</template>

111

112

<style>

113

.corner-handle {

114

border-radius: 50%;

115

background: #ff6b6b;

116

}

117

118

.custom-handle {

119

display: flex;

120

align-items: center;

121

justify-content: center;

122

background: rgba(0, 0, 0, 0.7);

123

border-radius: 3px;

124

}

125

</style>

126

```

127

128

### Scale Factor Support

129

130

Handle parent element scaling transformations correctly.

131

132

```javascript { .api }

133

/**

134

* Scale factor configuration for transformed parent elements

135

*/

136

interface ScaleSupport {

137

/** Scale factor - single number or [scaleX, scaleY] array (default: 1) */

138

scale: number | [number, number];

139

}

140

```

141

142

**Usage Examples:**

143

144

```vue

145

<template>

146

<!-- Parent container with CSS transform scale -->

147

<div class="scaled-container">

148

<vue-draggable-resizable

149

:scale="0.75"

150

:w="200"

151

:h="150"

152

>

153

Handles parent scaling

154

</vue-draggable-resizable>

155

</div>

156

157

<!-- Different X and Y scale factors -->

158

<div class="stretched-container">

159

<vue-draggable-resizable

160

:scale="[0.8, 1.2]"

161

>

162

Different X/Y scaling

163

</vue-draggable-resizable>

164

</div>

165

</template>

166

167

<style>

168

.scaled-container {

169

transform: scale(0.75);

170

transform-origin: top left;

171

}

172

173

.stretched-container {

174

transform: scaleX(0.8) scaleY(1.2);

175

transform-origin: top left;

176

}

177

</style>

178

```

179

180

### Custom Drag Handles

181

182

Specify custom elements within the component that act as drag handles or prevent dragging.

183

184

```javascript { .api }

185

/**

186

* Custom drag handle configuration

187

*/

188

interface CustomDragHandles {

189

/** CSS selector for elements that act as drag handles */

190

dragHandle?: string;

191

192

/** CSS selector for elements that prevent dragging when clicked */

193

dragCancel?: string;

194

}

195

```

196

197

**Usage Examples:**

198

199

```vue

200

<template>

201

<!-- Custom drag handle -->

202

<vue-draggable-resizable

203

drag-handle=".drag-handle"

204

drag-cancel=".no-drag"

205

>

206

<div class="drag-handle" style="background: #eee; padding: 10px; cursor: move;">

207

πŸ“ Drag me here

208

</div>

209

<div style="padding: 10px;">

210

<p>Main content area</p>

211

<button class="no-drag">Don't drag when clicking this button</button>

212

</div>

213

</vue-draggable-resizable>

214

215

<!-- Multiple drag handles -->

216

<vue-draggable-resizable drag-handle=".handle">

217

<div class="handle title-bar">Title Bar (drag here)</div>

218

<div>Content area</div>

219

<div class="handle status-bar">Status Bar (or here)</div>

220

</vue-draggable-resizable>

221

</template>

222

223

<style>

224

.drag-handle {

225

cursor: move;

226

user-select: none;

227

}

228

229

.title-bar {

230

background: #333;

231

color: white;

232

padding: 8px;

233

}

234

235

.status-bar {

236

background: #f0f0f0;

237

padding: 4px 8px;

238

font-size: 0.9em;

239

}

240

241

.no-drag {

242

cursor: pointer;

243

}

244

</style>

245

```

246

247

### Programmatic Control Methods

248

249

Methods for controlling component position and size programmatically.

250

251

```javascript { .api }

252

/**

253

* Programmatic control methods available on component instance

254

*/

255

interface ProgrammaticMethods {

256

/**

257

* Set horizontal position programmatically

258

* @param val - New X position in pixels

259

*/

260

moveHorizontally(val: number): void;

261

262

/**

263

* Set vertical position programmatically

264

* @param val - New Y position in pixels

265

*/

266

moveVertically(val: number): void;

267

268

/**

269

* Set width programmatically

270

* @param val - New width in pixels

271

*/

272

changeWidth(val: number): void;

273

274

/**

275

* Set height programmatically

276

* @param val - New height in pixels

277

*/

278

changeHeight(val: number): void;

279

}

280

```

281

282

**Usage Examples:**

283

284

```vue

285

<template>

286

<div>

287

<vue-draggable-resizable

288

ref="draggableElement"

289

:w="200"

290

:h="150"

291

>

292

Programmable element

293

</vue-draggable-resizable>

294

295

<div class="controls">

296

<button @click="moveToCenter">Center</button>

297

<button @click="resetSize">Reset Size</button>

298

<button @click="animateToCorner">Animate to Corner</button>

299

</div>

300

</div>

301

</template>

302

303

<script>

304

export default {

305

methods: {

306

moveToCenter() {

307

const container = this.$el;

308

const element = this.$refs.draggableElement;

309

310

const centerX = (container.offsetWidth - 200) / 2;

311

const centerY = (container.offsetHeight - 150) / 2;

312

313

element.moveHorizontally(centerX);

314

element.moveVertically(centerY);

315

},

316

317

resetSize() {

318

const element = this.$refs.draggableElement;

319

element.changeWidth(200);

320

element.changeHeight(150);

321

},

322

323

async animateToCorner() {

324

const element = this.$refs.draggableElement;

325

const steps = 20;

326

const targetX = 0;

327

const targetY = 0;

328

329

// Simple animation by stepping through positions

330

for (let i = 0; i <= steps; i++) {

331

const progress = i / steps;

332

const currentX = element.left * (1 - progress) + targetX * progress;

333

const currentY = element.top * (1 - progress) + targetY * progress;

334

335

element.moveHorizontally(currentX);

336

element.moveVertically(currentY);

337

338

await new Promise(resolve => setTimeout(resolve, 20));

339

}

340

}

341

}

342

}

343

</script>

344

```

345

346

### Grid Snapping

347

348

Configure grid-based snapping for precise positioning and sizing.

349

350

```javascript { .api }

351

/**

352

* Grid snapping configuration

353

*/

354

interface GridSnapping {

355

/** Grid intervals [x, y] in pixels (default: [1, 1]) */

356

grid: [number, number];

357

}

358

```

359

360

**Usage Examples:**

361

362

```vue

363

<template>

364

<!-- 20x20 pixel grid -->

365

<vue-draggable-resizable

366

:grid="[20, 20]"

367

:w="200"

368

:h="160"

369

>

370

Snaps to 20px grid

371

</vue-draggable-resizable>

372

373

<!-- Different X and Y grid sizes -->

374

<vue-draggable-resizable

375

:grid="[25, 15]"

376

>

377

25px horizontal, 15px vertical grid

378

</vue-draggable-resizable>

379

380

<!-- Fine grid for precision -->

381

<vue-draggable-resizable

382

:grid="[5, 5]"

383

>

384

Fine 5px grid

385

</vue-draggable-resizable>

386

</template>

387

```

388

389

### Slot System

390

391

Comprehensive slot system allowing content customization and custom handle designs.

392

393

```javascript { .api }

394

/**

395

* Available slots for content and handle customization

396

*/

397

interface SlotSystem {

398

/** Default slot for main component content */

399

default: Slot;

400

401

/** Named slots for each resize handle position */

402

'tl': Slot; // Top-left handle slot

403

'tm': Slot; // Top-middle handle slot

404

'tr': Slot; // Top-right handle slot

405

'mr': Slot; // Middle-right handle slot

406

'br': Slot; // Bottom-right handle slot

407

'bm': Slot; // Bottom-middle handle slot

408

'bl': Slot; // Bottom-left handle slot

409

'ml': Slot; // Middle-left handle slot

410

}

411

```

412

413

**Usage Examples:**

414

415

```vue

416

<template>

417

<!-- Custom handle designs -->

418

<vue-draggable-resizable :handles="['tl', 'br', 'mr']">

419

<!-- Default slot content -->

420

<div class="content">

421

<h3>Resizable Card</h3>

422

<p>Content goes here</p>

423

</div>

424

425

<!-- Custom corner handle -->

426

<template #tl>

427

<div class="corner-handle top-left">

428

<svg width="12" height="12">

429

<path d="M2,2 L10,2 L10,10" stroke="currentColor" fill="none" stroke-width="2"/>

430

</svg>

431

</div>

432

</template>

433

434

<!-- Custom corner handle -->

435

<template #br>

436

<div class="corner-handle bottom-right">

437

<svg width="12" height="12">

438

<path d="M2,10 L10,10 L10,2" stroke="currentColor" fill="none" stroke-width="2"/>

439

</svg>

440

</div>

441

</template>

442

443

<!-- Custom edge handle -->

444

<template #mr>

445

<div class="edge-handle">

446

<div class="handle-dots">

447

<span></span>

448

<span></span>

449

<span></span>

450

</div>

451

</div>

452

</template>

453

</vue-draggable-resizable>

454

</template>

455

456

<style>

457

.content {

458

padding: 16px;

459

background: white;

460

border: 1px solid #ddd;

461

border-radius: 4px;

462

height: 100%;

463

box-sizing: border-box;

464

}

465

466

.corner-handle {

467

display: flex;

468

align-items: center;

469

justify-content: center;

470

background: rgba(0, 123, 255, 0.1);

471

border: 2px solid #007bff;

472

border-radius: 6px;

473

color: #007bff;

474

cursor: nw-resize;

475

}

476

477

.corner-handle.bottom-right {

478

cursor: se-resize;

479

}

480

481

.edge-handle {

482

display: flex;

483

align-items: center;

484

justify-content: center;

485

background: #f8f9fa;

486

border: 1px solid #dee2e6;

487

border-radius: 4px;

488

cursor: ew-resize;

489

}

490

491

.handle-dots {

492

display: flex;

493

flex-direction: column;

494

gap: 2px;

495

}

496

497

.handle-dots span {

498

width: 3px;

499

height: 3px;

500

background: #6c757d;

501

border-radius: 50%;

502

}

503

</style>

504

```

505

506

**Themed Handle Examples:**

507

508

```vue

509

<template>

510

<!-- Dark theme handles -->

511

<vue-draggable-resizable class="dark-theme">

512

<div class="dark-content">Dark themed content</div>

513

514

<template #tl>

515

<div class="dark-handle corner">β†–</div>

516

</template>

517

<template #tr>

518

<div class="dark-handle corner">β†—</div>

519

</template>

520

<template #bl>

521

<div class="dark-handle corner">↙</div>

522

</template>

523

<template #br>

524

<div class="dark-handle corner">β†˜</div>

525

</template>

526

</vue-draggable-resizable>

527

528

<!-- Minimal handles -->

529

<vue-draggable-resizable :handles="['br']">

530

<div class="minimal-content">Minimal resize</div>

531

532

<template #br>

533

<div class="minimal-handle">

534

<div class="resize-icon">β€’</div>

535

</div>

536

</template>

537

</vue-draggable-resizable>

538

</template>

539

540

<style>

541

.dark-theme {

542

background: #343a40;

543

border: 1px solid #495057;

544

}

545

546

.dark-content {

547

color: white;

548

padding: 16px;

549

}

550

551

.dark-handle {

552

background: #495057;

553

color: #adb5bd;

554

border: 1px solid #6c757d;

555

border-radius: 3px;

556

font-size: 12px;

557

display: flex;

558

align-items: center;

559

justify-content: center;

560

}

561

562

.minimal-handle {

563

background: transparent;

564

color: #6c757d;

565

display: flex;

566

align-items: flex-end;

567

justify-content: flex-end;

568

cursor: se-resize;

569

}

570

571

.resize-icon {

572

font-size: 14px;

573

line-height: 1;

574

}

575

</style>

576

```

577

578

### Touch Device Support

579

580

Built-in support for touch devices with optimized touch event handling.

581

582

```javascript { .api }

583

/**

584

* Touch device support is automatically enabled

585

* Component handles both mouse and touch events seamlessly

586

*/

587

interface TouchSupport {

588

/** Touch events are automatically detected and handled */

589

touchEnabled: true;

590

591

/** Enhanced touch targets on mobile devices via CSS media queries */

592

mobileFriendly: true;

593

}

594

```

595

596

**Usage Examples:**

597

598

```vue

599

<template>

600

<!-- Works automatically on touch devices -->

601

<vue-draggable-resizable

602

:w="250"

603

:h="200"

604

class="touch-optimized"

605

>

606

Touch and drag on mobile

607

608

<!-- Larger handles for better touch experience -->

609

<template #br>

610

<div class="touch-handle">

611

<div class="touch-indicator"></div>

612

</div>

613

</template>

614

</vue-draggable-resizable>

615

</template>

616

617

<style>

618

.touch-optimized {

619

/* Component automatically includes mobile-friendly handle sizing */

620

}

621

622

.touch-handle {

623

width: 20px;

624

height: 20px;

625

background: rgba(0, 123, 255, 0.2);

626

border: 2px solid #007bff;

627

border-radius: 4px;

628

display: flex;

629

align-items: center;

630

justify-content: center;

631

}

632

633

.touch-indicator {

634

width: 8px;

635

height: 8px;

636

background: #007bff;

637

border-radius: 2px;

638

}

639

640

/* Additional mobile optimizations */

641

@media (max-width: 768px) {

642

.touch-optimized {

643

min-width: 100px;

644

min-height: 80px;

645

}

646

647

.touch-handle {

648

width: 24px;

649

height: 24px;

650

}

651

}

652

</style>

653

```