or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-management.mdindex.mdinstance-control.mdmomentum-control.mdplugin-system.md

plugin-system.mddocs/

0

# Plugin System

1

2

Extensible plugin architecture for adding custom behaviors like overscroll effects, custom easing, or specialized scrolling modes. The plugin system provides lifecycle hooks and delta transformation capabilities.

3

4

## Capabilities

5

6

### ScrollbarPlugin Base Class

7

8

Base class for creating custom scrollbar plugins with lifecycle management and event transformation.

9

10

```typescript { .api }

11

/**

12

* Base class for scrollbar plugins

13

*/

14

class ScrollbarPlugin {

15

/** Plugin identifier - must be set by subclasses */

16

static pluginName: string;

17

18

/** Default options for the plugin */

19

static defaultOptions: any;

20

21

/** Reference to the scrollbar instance */

22

readonly scrollbar: Scrollbar;

23

24

/** Plugin configuration options */

25

readonly options: any;

26

27

/** Plugin name (same as pluginName) */

28

readonly name: string;

29

30

constructor(scrollbar: Scrollbar, options?: any);

31

}

32

```

33

34

### Plugin Lifecycle Hooks

35

36

Methods called during various phases of the scrollbar lifecycle.

37

38

```typescript { .api }

39

/**

40

* Called when the plugin is initialized

41

*/

42

onInit(): void;

43

44

/**

45

* Called when the plugin is being destroyed

46

*/

47

onDestroy(): void;

48

49

/**

50

* Called when the scrollbar updates (e.g., after resize)

51

*/

52

onUpdate(): void;

53

54

/**

55

* Called during each render frame with remaining momentum

56

* @param remainMomentum - Remaining scroll momentum after frame

57

*/

58

onRender(remainMomentum: Data2d): void;

59

```

60

61

### Delta Transformation

62

63

Method for intercepting and modifying scroll events before they're processed.

64

65

```typescript { .api }

66

/**

67

* Transforms scroll delta values from input events

68

* @param delta - Original scroll delta from input event

69

* @param evt - The original input event (wheel, touch, etc.)

70

* @returns Modified delta to be used for scrolling

71

*/

72

transformDelta(delta: Data2d, evt: Event): Data2d;

73

```

74

75

## Built-in Plugins

76

77

### OverscrollPlugin

78

79

Built-in plugin providing overscroll effects with bounce and glow animations.

80

81

```typescript { .api }

82

class OverscrollPlugin extends ScrollbarPlugin {

83

static pluginName: "overscroll";

84

static defaultOptions: {

85

effect: "bounce";

86

damping: 0.2;

87

maxOverscroll: 150;

88

glowColor: "#87ceeb";

89

onScroll: null;

90

};

91

92

readonly options: OverscrollOptions;

93

}

94

95

interface OverscrollOptions {

96

/** Effect type: 'bounce' or 'glow' */

97

effect?: OverscrollEffect;

98

99

/** Callback function called during overscroll */

100

onScroll?: OnScrollCallback;

101

102

/** Overscroll damping factor (0-1) */

103

damping: number;

104

105

/** Maximum overscroll distance in pixels */

106

maxOverscroll: number;

107

108

/** Color for glow effect */

109

glowColor: string;

110

}

111

112

enum OverscrollEffect {

113

BOUNCE = "bounce",

114

GLOW = "glow"

115

}

116

117

interface OnScrollCallback {

118

(this: OverscrollPlugin, position: Data2d): void;

119

}

120

121

type Position = Data2d;

122

```

123

124

**Usage Examples:**

125

126

```typescript

127

import Scrollbar from "smooth-scrollbar";

128

import OverscrollPlugin from "smooth-scrollbar/plugins/overscroll";

129

130

// Register the plugin

131

Scrollbar.use(OverscrollPlugin);

132

133

// Use with bounce effect

134

const scrollbar = Scrollbar.init(container, {

135

plugins: {

136

overscroll: {

137

effect: "bounce",

138

damping: 0.2,

139

maxOverscroll: 150

140

}

141

}

142

});

143

144

// Use with glow effect

145

const scrollbar2 = Scrollbar.init(container2, {

146

plugins: {

147

overscroll: {

148

effect: "glow",

149

glowColor: "#ff6b6b",

150

maxOverscroll: 100,

151

onScroll(position) {

152

console.log(`Overscroll: x=${position.x}, y=${position.y}`);

153

}

154

}

155

}

156

});

157

```

158

159

## Creating Custom Plugins

160

161

### Basic Plugin Structure

162

163

Template for creating custom plugins with proper lifecycle implementation.

164

165

```typescript

166

import { ScrollbarPlugin } from "smooth-scrollbar";

167

168

class CustomPlugin extends ScrollbarPlugin {

169

static pluginName = "custom-plugin";

170

static defaultOptions = {

171

customOption: true,

172

threshold: 100

173

};

174

175

onInit() {

176

// Setup plugin resources

177

console.log("Custom plugin initialized");

178

}

179

180

onDestroy() {

181

// Clean up plugin resources

182

console.log("Custom plugin destroyed");

183

}

184

185

onUpdate() {

186

// Handle scrollbar updates

187

this.adjustToNewSize();

188

}

189

190

onRender(remainMomentum) {

191

// Custom rendering logic

192

if (Math.abs(remainMomentum.y) > this.options.threshold) {

193

this.triggerCustomEffect();

194

}

195

}

196

197

transformDelta(delta, fromEvent) {

198

// Modify scroll behavior

199

if (fromEvent.type === "wheel") {

200

return {

201

x: delta.x * 0.8, // Reduce horizontal scroll speed

202

y: delta.y * 1.2 // Increase vertical scroll speed

203

};

204

}

205

return delta;

206

}

207

208

private adjustToNewSize() {

209

// Custom logic for size changes

210

}

211

212

private triggerCustomEffect() {

213

// Custom effect implementation

214

}

215

}

216

217

// Register and use the plugin

218

Scrollbar.use(CustomPlugin);

219

220

const scrollbar = Scrollbar.init(container, {

221

plugins: {

222

"custom-plugin": {

223

customOption: false,

224

threshold: 50

225

}

226

}

227

});

228

```

229

230

### Advanced Plugin Example

231

232

Example of a more complex plugin that adds momentum-based effects.

233

234

```typescript

235

import { ScrollbarPlugin } from "smooth-scrollbar";

236

237

class MomentumEffectsPlugin extends ScrollbarPlugin {

238

static pluginName = "momentum-effects";

239

static defaultOptions = {

240

fadeOnScroll: true,

241

blurOnScroll: false,

242

scaleOnScroll: false,

243

maxEffect: 1.0

244

};

245

246

private lastMomentum = { x: 0, y: 0 };

247

248

onInit() {

249

// Initialize effect elements if needed

250

this.setupEffectElements();

251

}

252

253

onRender(remainMomentum) {

254

const { fadeOnScroll, blurOnScroll, scaleOnScroll, maxEffect } = this.options;

255

const intensity = Math.min(

256

Math.sqrt(remainMomentum.x ** 2 + remainMomentum.y ** 2) / 100,

257

maxEffect

258

);

259

260

if (fadeOnScroll) {

261

this.scrollbar.contentEl.style.opacity = (1 - intensity * 0.3).toString();

262

}

263

264

if (blurOnScroll) {

265

this.scrollbar.contentEl.style.filter = `blur(${intensity * 2}px)`;

266

}

267

268

if (scaleOnScroll) {

269

const scale = 1 - intensity * 0.05;

270

this.scrollbar.contentEl.style.transform = `scale(${scale})`;

271

}

272

273

this.lastMomentum = remainMomentum;

274

}

275

276

transformDelta(delta, fromEvent) {

277

// Add momentum-based resistance

278

const resistance = this.calculateResistance();

279

return {

280

x: delta.x * resistance,

281

y: delta.y * resistance

282

};

283

}

284

285

private setupEffectElements() {

286

// Setup any DOM elements needed for effects

287

}

288

289

private calculateResistance() {

290

// Calculate scroll resistance based on current momentum

291

const momentum = Math.abs(this.lastMomentum.x) + Math.abs(this.lastMomentum.y);

292

return Math.max(0.3, 1 - momentum / 1000);

293

}

294

}

295

```

296

297

## Plugin Registration and Management

298

299

```typescript { .api }

300

/**

301

* Global plugin management functions

302

*/

303

304

/** Register plugins globally for all scrollbar instances */

305

function addPlugins(...Plugins: (typeof ScrollbarPlugin)[]): void;

306

307

/** Initialize plugins for a specific scrollbar instance */

308

function initPlugins(scrollbar: Scrollbar, options: any): ScrollbarPlugin[];

309

310

/** Global plugin registry */

311

interface PluginMap {

312

order: Set<string>;

313

constructors: {

314

[name: string]: typeof ScrollbarPlugin;

315

};

316

}

317

```