or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

hook-based-control.mdindex.mdref-based-control.mdstate-based-control.md

state-based-control.mddocs/

0

# State-based Control

1

2

The state-based approach uses the controlled component pattern, where you manage the progress state in your component and pass it to the LoadingBar as a prop. This provides React-style declarative control over the loading bar.

3

4

## Basic Setup

5

6

Control the loading bar by managing progress state:

7

8

```typescript

9

import React, { useState } from "react";

10

import LoadingBar from "react-top-loading-bar";

11

12

const App = () => {

13

const [progress, setProgress] = useState(0);

14

15

return (

16

<div>

17

<LoadingBar

18

color="#f11946"

19

progress={progress}

20

onLoaderFinished={() => setProgress(0)}

21

/>

22

<button onClick={() => setProgress(100)}>Complete</button>

23

</div>

24

);

25

};

26

```

27

28

## LoadingBar Props for State Control

29

30

```typescript { .api }

31

interface IProps {

32

// State Control

33

progress?: number;

34

onLoaderFinished?: () => void;

35

36

// Visual Properties

37

color?: string;

38

background?: string;

39

height?: number;

40

shadow?: boolean;

41

className?: string;

42

containerClassName?: string;

43

style?: CSSProperties;

44

containerStyle?: CSSProperties;

45

shadowStyle?: CSSProperties;

46

47

// Animation Timing

48

loaderSpeed?: number;

49

transitionTime?: number;

50

waitingTime?: number;

51

}

52

```

53

54

## Key Props

55

56

```typescript { .api }

57

/**

58

* Current progress value (0-100)

59

*/

60

progress?: number;

61

62

/**

63

* Callback fired when loading animation completes

64

* Called after the bar reaches 100% and fade animation finishes

65

*/

66

onLoaderFinished?: () => void;

67

```

68

69

## Usage Examples

70

71

### Simple Progress Control

72

73

```typescript

74

const SimpleProgress = () => {

75

const [progress, setProgress] = useState(0);

76

77

const handleStart = () => setProgress(20);

78

const handleIncrease = () => setProgress(prev => Math.min(prev + 20, 100));

79

const handleComplete = () => setProgress(100);

80

81

return (

82

<div>

83

<LoadingBar

84

color="blue"

85

progress={progress}

86

onLoaderFinished={() => setProgress(0)}

87

/>

88

<button onClick={handleStart}>Start (20%)</button>

89

<button onClick={handleIncrease}>+20%</button>

90

<button onClick={handleComplete}>Complete</button>

91

</div>

92

);

93

};

94

```

95

96

### API Loading State

97

98

```typescript

99

const ApiExample = () => {

100

const [progress, setProgress] = useState(0);

101

const [loading, setLoading] = useState(false);

102

103

const fetchData = async () => {

104

setLoading(true);

105

setProgress(10);

106

107

try {

108

// Start request

109

setProgress(30);

110

const response = await fetch("/api/data");

111

112

// Processing

113

setProgress(70);

114

const data = await response.json();

115

116

// Complete

117

setProgress(100);

118

} catch (error) {

119

setProgress(100); // Complete on error too

120

} finally {

121

setLoading(false);

122

}

123

};

124

125

return (

126

<div>

127

<LoadingBar

128

color="green"

129

progress={progress}

130

onLoaderFinished={() => setProgress(0)}

131

/>

132

<button onClick={fetchData} disabled={loading}>

133

{loading ? "Loading..." : "Fetch Data"}

134

</button>

135

</div>

136

);

137

};

138

```

139

140

### Form Submission Progress

141

142

```typescript

143

const FormSubmission = () => {

144

const [progress, setProgress] = useState(0);

145

const [formData, setFormData] = useState({ name: "", email: "" });

146

147

const handleSubmit = async (e: React.FormEvent) => {

148

e.preventDefault();

149

150

// Validation

151

setProgress(20);

152

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

153

154

// Submit

155

setProgress(50);

156

await fetch("/api/submit", {

157

method: "POST",

158

body: JSON.stringify(formData),

159

});

160

161

// Processing

162

setProgress(80);

163

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

164

165

// Complete

166

setProgress(100);

167

};

168

169

return (

170

<div>

171

<LoadingBar

172

color="purple"

173

progress={progress}

174

onLoaderFinished={() => {

175

setProgress(0);

176

alert("Form submitted successfully!");

177

}}

178

/>

179

<form onSubmit={handleSubmit}>

180

<input

181

value={formData.name}

182

onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))}

183

placeholder="Name"

184

/>

185

<input

186

value={formData.email}

187

onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))}

188

placeholder="Email"

189

/>

190

<button type="submit">Submit</button>

191

</form>

192

</div>

193

);

194

};

195

```

196

197

### Multi-step Process

198

199

```typescript

200

const MultiStepProcess = () => {

201

const [progress, setProgress] = useState(0);

202

const [currentStep, setCurrentStep] = useState(0);

203

204

const steps = [

205

{ name: "Initialize", progress: 10 },

206

{ name: "Validate", progress: 30 },

207

{ name: "Process", progress: 60 },

208

{ name: "Finalize", progress: 90 },

209

{ name: "Complete", progress: 100 },

210

];

211

212

const executeStep = async (stepIndex: number) => {

213

setCurrentStep(stepIndex);

214

setProgress(steps[stepIndex].progress);

215

216

// Simulate step execution

217

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

218

219

if (stepIndex < steps.length - 1) {

220

executeStep(stepIndex + 1);

221

}

222

};

223

224

return (

225

<div>

226

<LoadingBar

227

color="orange"

228

progress={progress}

229

onLoaderFinished={() => {

230

setProgress(0);

231

setCurrentStep(0);

232

}}

233

/>

234

<p>Current Step: {steps[currentStep]?.name}</p>

235

<button onClick={() => executeStep(0)}>Start Process</button>

236

</div>

237

);

238

};

239

```

240

241

### File Upload with Progress

242

243

```typescript

244

const FileUpload = () => {

245

const [progress, setProgress] = useState(0);

246

247

const uploadFile = (file: File) => {

248

const formData = new FormData();

249

formData.append("file", file);

250

251

const xhr = new XMLHttpRequest();

252

253

// Track upload progress

254

xhr.upload.addEventListener("progress", (e) => {

255

if (e.lengthComputable) {

256

const percentComplete = (e.loaded / e.total) * 100;

257

setProgress(percentComplete);

258

}

259

});

260

261

xhr.onload = () => {

262

setProgress(100);

263

};

264

265

xhr.open("POST", "/upload");

266

xhr.send(formData);

267

};

268

269

return (

270

<div>

271

<LoadingBar

272

color="red"

273

progress={progress}

274

onLoaderFinished={() => setProgress(0)}

275

/>

276

<input

277

type="file"

278

onChange={(e) => e.target.files?.[0] && uploadFile(e.target.files[0])}

279

/>

280

</div>

281

);

282

};

283

```

284

285

## Visual Customization

286

287

Customize appearance through props:

288

289

```typescript

290

<LoadingBar

291

progress={progress}

292

color="#ff6b6b"

293

height={4}

294

shadow={true}

295

background="rgba(255,255,255,0.1)"

296

loaderSpeed={300}

297

transitionTime={200}

298

waitingTime={500}

299

className="custom-loader"

300

containerClassName="custom-container"

301

style={{ borderRadius: "2px" }}

302

onLoaderFinished={() => console.log("Done!")}

303

/>

304

```

305

306

## Important Notes

307

308

- **Progress Range**: Progress values should be between 0 and 100

309

- **Auto Reset**: Use `onLoaderFinished` callback to reset progress to 0 after completion

310

- **Smooth Transitions**: The loading bar automatically animates between progress values

311

- **Complete State**: Setting progress to 100 triggers the completion animation

312

- **No Conflicts**: Do not use progress prop with ref methods simultaneously