or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-builders.mddecorators.mdframework-config.mdindex.mdportable-stories.mdstory-types.mdtemplate-utilities.md

decorators.mddocs/

0

# Angular Decorators

1

2

Angular-specific decorators for configuring module metadata, application configuration, and component wrapping in stories.

3

4

## Capabilities

5

6

### moduleMetadata Decorator

7

8

Decorator for providing Angular module metadata to stories, including imports, declarations, providers, and schemas.

9

10

```typescript { .api }

11

/**

12

* Decorator for Angular module metadata configuration

13

* @param metadata - Partial NgModuleMetadata configuration

14

* @returns Decorator function for stories

15

*/

16

declare function moduleMetadata<TArgs = any>(

17

metadata: Partial<NgModuleMetadata>

18

): DecoratorFunction<AngularRenderer, TArgs>;

19

20

interface NgModuleMetadata {

21

/** List of components, directives, and pipes that belong to your component */

22

declarations?: any[];

23

entryComponents?: any[];

24

/**

25

* List of modules that should be available to the root Storybook Component and all its children.

26

* For application providers or forRoot() patterns, use applicationConfig decorator instead.

27

*/

28

imports?: any[];

29

schemas?: any[];

30

/**

31

* List of providers that should be available on the root component and all its children.

32

* Use applicationConfig decorator for environment and application-wide providers.

33

*/

34

providers?: Provider[];

35

}

36

```

37

38

**Usage Examples:**

39

40

Basic module configuration:

41

42

```typescript

43

import { moduleMetadata } from "@storybook/angular";

44

import { CommonModule } from "@angular/common";

45

import { FormsModule } from "@angular/forms";

46

import { ButtonComponent } from "./button.component";

47

48

export default {

49

title: "Example/Button",

50

component: ButtonComponent,

51

decorators: [

52

moduleMetadata({

53

imports: [CommonModule, FormsModule],

54

declarations: [ButtonComponent],

55

}),

56

],

57

};

58

```

59

60

With providers:

61

62

```typescript

63

import { moduleMetadata } from "@storybook/angular";

64

import { HttpClientModule } from "@angular/common/http";

65

import { DataService } from "./data.service";

66

67

export default {

68

title: "Example/DataComponent",

69

component: DataComponent,

70

decorators: [

71

moduleMetadata({

72

imports: [HttpClientModule],

73

providers: [DataService],

74

}),

75

],

76

};

77

```

78

79

With schemas for custom elements:

80

81

```typescript

82

import { moduleMetadata } from "@storybook/angular";

83

import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";

84

85

export default {

86

title: "Example/CustomElement",

87

component: CustomElementComponent,

88

decorators: [

89

moduleMetadata({

90

schemas: [CUSTOM_ELEMENTS_SCHEMA],

91

}),

92

],

93

};

94

```

95

96

Multiple decorators (metadata merges):

97

98

```typescript

99

const baseDecorator = moduleMetadata({

100

imports: [CommonModule],

101

});

102

103

const extendedDecorator = moduleMetadata({

104

imports: [FormsModule],

105

providers: [MyService],

106

});

107

108

export const Enhanced: Story = {

109

decorators: [baseDecorator, extendedDecorator],

110

// Final metadata will include: CommonModule, FormsModule, and MyService

111

};

112

```

113

114

### applicationConfig Decorator

115

116

Decorator for setting application-level configuration options available during Angular bootstrap.

117

118

```typescript { .api }

119

/**

120

* Decorator to set the config options which are available during the application bootstrap operation

121

* @param config - Set of config options available during the application bootstrap operation

122

* @returns Decorator function for stories

123

*/

124

declare function applicationConfig<TArgs = any>(

125

config: ApplicationConfig

126

): DecoratorFunction<AngularRenderer, TArgs>;

127

128

interface ApplicationConfig {

129

providers?: Provider[];

130

}

131

```

132

133

**Usage Examples:**

134

135

With routing configuration:

136

137

```typescript

138

import { applicationConfig } from "@storybook/angular";

139

import { provideRouter } from "@angular/router";

140

import { routes } from "./app.routes";

141

142

export default {

143

title: "Example/RoutedComponent",

144

component: RoutedComponent,

145

decorators: [

146

applicationConfig({

147

providers: [provideRouter(routes)],

148

}),

149

],

150

};

151

```

152

153

With HTTP client:

154

155

```typescript

156

import { applicationConfig } from "@storybook/angular";

157

import { provideHttpClient } from "@angular/common/http";

158

159

export default {

160

title: "Example/ApiComponent",

161

component: ApiComponent,

162

decorators: [

163

applicationConfig({

164

providers: [provideHttpClient()],

165

}),

166

],

167

};

168

```

169

170

With animations:

171

172

```typescript

173

import { applicationConfig } from "@storybook/angular";

174

import { provideAnimations } from "@angular/platform-browser/animations";

175

176

export default {

177

title: "Example/AnimatedComponent",

178

component: AnimatedComponent,

179

decorators: [

180

applicationConfig({

181

providers: [provideAnimations()],

182

}),

183

],

184

};

185

```

186

187

Combined with moduleMetadata:

188

189

```typescript

190

import { applicationConfig, moduleMetadata } from "@storybook/angular";

191

import { provideRouter } from "@angular/router";

192

import { CommonModule } from "@angular/common";

193

194

export default {

195

title: "Example/ComplexComponent",

196

component: ComplexComponent,

197

decorators: [

198

// Application-level configuration

199

applicationConfig({

200

providers: [provideRouter([])],

201

}),

202

// Module-level configuration

203

moduleMetadata({

204

imports: [CommonModule],

205

}),

206

],

207

};

208

```

209

210

### componentWrapperDecorator

211

212

Decorator for wrapping stories with additional components or custom template wrappers.

213

214

```typescript { .api }

215

/**

216

* Decorator for wrapping components with additional elements or custom templates

217

* @param element - Angular component type or template function

218

* @param props - Static props object or function returning props based on story context

219

* @returns Decorator function for stories

220

*/

221

declare function componentWrapperDecorator<TArgs = any>(

222

element: Type<unknown> | ((story: string) => string),

223

props?: ICollection | ((storyContext: StoryContext<AngularRenderer, TArgs>) => ICollection)

224

): DecoratorFunction<AngularRenderer, TArgs>;

225

226

interface ICollection {

227

[p: string]: any;

228

}

229

```

230

231

**Usage Examples:**

232

233

Wrap with Angular component:

234

235

```typescript

236

import { componentWrapperDecorator } from "@storybook/angular";

237

import { CardComponent } from "./card.component";

238

239

export default {

240

title: "Example/Button",

241

component: ButtonComponent,

242

decorators: [

243

componentWrapperDecorator(CardComponent, {

244

title: "Button Demo",

245

padding: true,

246

}),

247

],

248

};

249

```

250

251

Wrap with custom template function:

252

253

```typescript

254

import { componentWrapperDecorator } from "@storybook/angular";

255

256

export default {

257

title: "Example/Icon",

258

component: IconComponent,

259

decorators: [

260

componentWrapperDecorator((story) => `

261

<div style="padding: 20px; background: #f5f5f5; border-radius: 8px;">

262

<h3>Icon Preview</h3>

263

${story}

264

</div>

265

`),

266

],

267

};

268

```

269

270

Dynamic props based on story context:

271

272

```typescript

273

import { componentWrapperDecorator } from "@storybook/angular";

274

import { ThemeWrapperComponent } from "./theme-wrapper.component";

275

276

export default {

277

title: "Example/ThemedComponent",

278

component: ThemedComponent,

279

decorators: [

280

componentWrapperDecorator(

281

ThemeWrapperComponent,

282

(storyContext) => ({

283

theme: storyContext.parameters.theme || "light",

284

showBorder: storyContext.args.bordered,

285

})

286

),

287

],

288

};

289

```

290

291

Multiple wrapper decorators:

292

293

```typescript

294

const cardWrapper = componentWrapperDecorator(CardComponent);

295

const containerWrapper = componentWrapperDecorator(

296

(story) => `<div class="container">${story}</div>`

297

);

298

299

export const Nested: Story = {

300

decorators: [containerWrapper, cardWrapper],

301

// Story will be wrapped: container > card > component

302

};

303

```

304

305

## Decorator Composition and Order

306

307

Decorators are applied in reverse order (last decorator wraps the innermost content):

308

309

```typescript

310

export default {

311

title: "Example/Component",

312

component: MyComponent,

313

decorators: [

314

// Applied third (outermost)

315

componentWrapperDecorator((story) => `<div class="outer">${story}</div>`),

316

// Applied second (middle)

317

moduleMetadata({ imports: [CommonModule] }),

318

// Applied first (innermost, around the component)

319

applicationConfig({ providers: [MyService] }),

320

],

321

};

322

```

323

324

## Best Practices

325

326

### Module Metadata

327

328

- Use `moduleMetadata` for Angular modules, pipes, directives, and component-level providers

329

- Place shared imports in global decorators (preview.ts) when used across many stories

330

- Keep module metadata close to the component requirements

331

332

### Application Config

333

334

- Use `applicationConfig` for application-wide providers like routing, HTTP client, animations

335

- Configure once at the story or meta level rather than per individual story

336

- Prefer standalone components and `applicationConfig` over `NgModule` patterns when possible

337

338

### Component Wrapper

339

340

- Use `componentWrapperDecorator` for layout, theming, or presentation concerns

341

- Keep wrapper logic simple and focused on presentation

342

- Consider performance implications of complex wrapper components