ng-hub-ui-stepper 22.8.2 → 22.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  A flexible, customizable, and accessible stepper component for Angular 21+. Perfect for multi-step forms, wizards, and guided user experiences with a focus on developer experience and modern standards.
9
9
 
10
10
  > [!IMPORTANT]
11
- > Version `22.8.2` targets **Angular 21** and uses the **Signals** architecture shared across `ng-hub-ui`.
11
+ > Version `22.10.0` targets **Angular 21** and uses the **Signals** architecture shared across `ng-hub-ui`.
12
12
 
13
13
  ## Documentation and Live Examples
14
14
 
@@ -59,6 +59,7 @@ This library is part of the **ng-hub-ui** ecosystem:
59
59
  - [Directives](#directives)
60
60
  - [Host classes](#host-classes)
61
61
  - [Services](#services)
62
+ - [Providers](#providers)
62
63
  - [Interfaces](#interfaces)
63
64
  - [Internationalization](#internationalization)
64
65
  - [Styling](#styling)
@@ -107,9 +108,20 @@ The rest of the surface — `StepTriggerDirective`, `StepperNavDirective`, `Prev
107
108
  `NextButtonDirective` and `SubmitButtonDirective` — is imported the same way, one by one, as each
108
109
  template needs it.
109
110
 
111
+ Then register the library once, so the built-in Back / Continue / Submit controls have text:
112
+
113
+ ```typescript
114
+ import { provideHubStepper } from 'ng-hub-ui-stepper';
115
+
116
+ bootstrapApplication(AppComponent, {
117
+ providers: [provideHubStepper({ language: 'en' })]
118
+ });
119
+ ```
120
+
110
121
  > **`StepperModule` is deprecated and will be removed in 23.0.0.** It only re-exports the seven
111
- > building blocks above, so importing them directly is the whole migration. `StepperModule.forRoot()`
112
- > goes with it — see [Internationalization](#internationalization).
122
+ > building blocks above, so importing them directly is the whole migration, and
123
+ > `StepperModule.forRoot()` becomes `provideHubStepper()` — same providers, no module. See
124
+ > [Providers](#providers) and [Internationalization](#internationalization).
113
125
 
114
126
  In your template:
115
127
 
@@ -199,13 +211,14 @@ button disabled while the move is unavailable.
199
211
 
200
212
  ### Step transitions
201
213
 
202
- Transitions are plain CSS and opt-in: add `stepper--animated` to the host, then pick the flavour with
203
- `stepper--anim-slide` (the default when neither is set) or `stepper--anim-fade`. Duration comes from
204
- `--hub-stepper-animation-duration`.
214
+ Transitions are plain CSS and opt-in: add `hub-stepper--animated` to the host, then pick the flavour
215
+ with `hub-stepper--anim-slide` (the default when neither is set) or `hub-stepper--anim-fade`. Duration
216
+ comes from `--hub-stepper-animation-duration`. The unprefixed `stepper--animated`,
217
+ `stepper--anim-slide` and `stepper--anim-fade` are still read, and go in 23.0.0.
205
218
 
206
219
  ```html
207
220
  <hub-stepper
208
- class="stepper--animated stepper--anim-fade"
221
+ class="hub-stepper--animated hub-stepper--anim-fade"
209
222
  [style.--hub-stepper-animation-duration.ms]="240"
210
223
  >
211
224
  <hub-step title="Profile">...</hub-step>
@@ -213,6 +226,39 @@ Transitions are plain CSS and opt-in: add `stepper--animated` to the host, then
213
226
  </hub-stepper>
214
227
  ```
215
228
 
229
+ ### Custom rail triggers
230
+
231
+ `hubStepperNav` replaces the whole rail. When all you want is a different control inside each rail
232
+ item — a numbered circle, an icon, a check on the steps already done — `hubStepTrigger` is one level
233
+ down: the rail keeps its list, its `role="tablist"`, its orientation and its label, and only the
234
+ button inside each item is yours.
235
+
236
+ ```html
237
+ <hub-stepper #wizard>
238
+ <ng-template hubStepTrigger let-title="title" let-index="index" let-isCurrent="isCurrent" let-disabled="disabled">
239
+ <button
240
+ type="button"
241
+ role="tab"
242
+ [attr.aria-selected]="isCurrent"
243
+ [disabled]="disabled"
244
+ (click)="wizard.goTo(index)"
245
+ >
246
+ <span class="badge">{{ index + 1 }}</span> {{ title }}
247
+ </button>
248
+ </ng-template>
249
+
250
+ <hub-step title="Account">...</hub-step>
251
+ <hub-step title="Payment">...</hub-step>
252
+ </hub-stepper>
253
+ ```
254
+
255
+ The context carries the step as `$implicit` and as `step`, plus `title`, `index`, `isCurrent`,
256
+ `isCompleted` and `disabled`. Activating a step stays with you, through a template reference on the
257
+ host — which is why the example names the stepper `#wizard`. Give the trigger `role="tab"` if you
258
+ want the rail's arrow-key navigation to keep finding it.
259
+
260
+ A stepper that declares both templates uses `hubStepperNav` and ignores this one.
261
+
216
262
  ## API Reference
217
263
 
218
264
  ### StepperComponent (`hub-stepper`)
@@ -262,7 +308,7 @@ Public members you can reach through a template reference (`<hub-stepper #steppe
262
308
  | `PreviousButtonDirective` | `button[previousButton]`, `button[backButton]` | `<button>` | Calls `goToPrevious()` and disables the button when there is no enabled previous step. |
263
309
  | `SubmitButtonDirective` | `button[submitButton]` | `<button>` | Calls `complete()` and disables the button while the current step is `disabled`. |
264
310
  | `StepperNavDirective` | `[hubStepperNav]`, `[stepperNav]` | `<ng-template>` | Replaces the built-in rail. Context: `steps`, `currentIndex`. |
265
- | `StepTriggerDirective` | `[hubStepTrigger]`, `[stepTrigger]` | `<ng-template>` | Captures a per-step trigger template. **Exported but not yet rendered** — the stepper draws its own triggers; this is groundwork, and applying it changes nothing today. |
311
+ | `StepTriggerDirective` | `[hubStepTrigger]`, `[stepTrigger]` | `<ng-template>` | Replaces the rail trigger the default rail draws, once per step. Context: `$implicit` / `step`, `title`, `index`, `isCurrent`, `isCompleted`, `disabled`. Ignored when a `hubStepperNav` template is present, since a custom rail draws its own triggers. |
266
312
 
267
313
  ### Host classes
268
314
 
@@ -270,9 +316,16 @@ Set these on `<hub-stepper>` itself; they are read by the stylesheet, not by inp
270
316
 
271
317
  | Class | Effect |
272
318
  |---|---|
273
- | `stepper--animated` | Enables the CSS transition between step panels. Without it, panels swap instantly. |
274
- | `stepper--anim-slide` | Slide transition (also the default when only `stepper--animated` is set). |
275
- | `stepper--anim-fade` | Fade transition instead of the slide. |
319
+ | `hub-stepper--animated` | Enables the CSS transition between step panels. Without it, panels swap instantly. |
320
+ | `hub-stepper--anim-slide` | Slide transition (also the default when only `hub-stepper--animated` is set). |
321
+ | `hub-stepper--anim-fade` | Fade transition instead of the slide. |
322
+
323
+ > **Renamed in 22.10.0.** These were `stepper--animated`, `stepper--anim-slide` and
324
+ > `stepper--anim-fade`, and the component itself wore a bare `stepper` class. `stepper` is a word in
325
+ > the application's namespace, not the library's, so a host application with a `.stepper` rule of its
326
+ > own restyled the component from the outside. The whole block is now `hub-stepper`, in line with
327
+ > every other library of the family. **The old spellings still work and are still written to the
328
+ > DOM**; both go in **23.0.0**. See [`BREAKING_CHANGES.md`](./BREAKING_CHANGES.md).
276
329
 
277
330
  ### Services
278
331
 
@@ -293,6 +346,46 @@ inject(StepperThemeService).setTheme({
293
346
  For a theme known at build time, prefer the [`hub-stepper-theme()` mixin](#sass-mixin): it scopes to a
294
347
  selector instead of the document root.
295
348
 
349
+ ### Providers
350
+
351
+ #### `provideHubStepper(config?: StepperConfig)`
352
+
353
+ The standalone entry point. Registers the ten bundled dictionaries and the `HubTranslationService`
354
+ that `TranslatePipe` injects to resolve the built-in control labels — the service is not
355
+ `providedIn: 'root'`, so without this (or another provider of it) the first render throws
356
+ `NullInjectorError`.
357
+
358
+ ```typescript
359
+ bootstrapApplication(AppComponent, {
360
+ providers: [provideHubStepper({ language: 'en', fallbackLanguage: 'en' })]
361
+ });
362
+ ```
363
+
364
+ It can also be scoped to the route that owns the wizard, which is what an application already
365
+ configuring `provideHubTranslation()` at the root should do — see
366
+ [Internationalization](#internationalization) for why.
367
+
368
+ #### `STEPPER_DICTIONARIES`
369
+
370
+ The bundled dictionaries as a plain record, keyed by language code, so you can register only the
371
+ languages you ship or merge the labels into a dictionary of your own:
372
+
373
+ ```typescript
374
+ import { STEPPER_DICTIONARIES } from 'ng-hub-ui-stepper';
375
+
376
+ provideHubTranslation({
377
+ language: 'ca',
378
+ fallbackLanguage: 'en',
379
+ dictionaries: {
380
+ ca: { ...STEPPER_DICTIONARIES['ca'], ...myCatalanStrings },
381
+ en: { ...STEPPER_DICTIONARIES['en'], ...myEnglishStrings }
382
+ }
383
+ });
384
+ ```
385
+
386
+ The keys are flat — `BACK`, `CONTINUE`, `SUBMIT` — which is what the component resolves once its
387
+ `HUBUI.STEPPER` namespace misses.
388
+
296
389
  ### Interfaces
297
390
 
298
391
  #### `StepperOptions`
@@ -305,7 +398,7 @@ interface StepperOptions {
305
398
 
306
399
  #### `StepperConfig`
307
400
 
308
- Accepted by the deprecated `StepperModule.forRoot()`, which registers the bundled dictionaries:
401
+ Accepted by `provideHubStepper()` and by the deprecated `StepperModule.forRoot()`:
309
402
 
310
403
  ```typescript
311
404
  interface StepperConfig {
@@ -319,19 +412,22 @@ interface StepperConfig {
319
412
  The built-in back, continue and submit labels go through `TranslatePipe` from `ng-hub-ui-utils`. There are
320
413
  two ways to feed them, and they can be combined.
321
414
 
322
- **The bundled dictionaries — deprecated.** `StepperModule.forRoot()` registers translations for `en`,
323
- `es`, `ca`, `eu`, `gl`, `ast`, `an`, `de`, `zh` and `ar`:
415
+ **The bundled dictionaries.** `provideHubStepper()` registers translations for `en`, `es`, `ca`, `eu`,
416
+ `gl`, `ast`, `an`, `de`, `zh` and `ar`, and the `HubTranslationService` that `TranslatePipe` injects:
324
417
 
325
418
  ```typescript
326
- imports: [StepperModule.forRoot({ language: 'en', fallbackLanguage: 'en' })];
419
+ providers: [provideHubStepper({ language: 'en', fallbackLanguage: 'en' })];
327
420
  ```
328
421
 
329
- It is the only way to reach those dictionaries, and it is **removed in 23.0.0** along with the module.
330
- The dictionaries themselves are not exported, so they cannot be handed to a provider function: use the
331
- application dictionary below, or name the three controls through the `backLabel` / `continueLabel` /
332
- `submitLabel` inputs. Note that `forRoot()` is also what provides `HubTranslationService`, which
333
- `TranslatePipe` injects — an application that drops it must provide the service another way, which
334
- both `provideHubTranslation()` and `provideHubTranslationAdapter()` do.
422
+ `StepperModule.forRoot({ language: 'en', fallbackLanguage: 'en' })` does the same and is **removed in
423
+ 23.0.0** along with the module; it now delegates to `provideHubStepper()`, so the swap changes nothing
424
+ at runtime.
425
+
426
+ One caveat: `provideHubStepper()` writes `HUB_TRANSLATION_CONFIG`, and that is a single
427
+ application-wide token. If your application already calls `provideHubTranslation()` at the root, do
428
+ not register both — whichever comes last wins and the other loses its dictionaries. Merge the stepper
429
+ labels into your own call with [`STEPPER_DICTIONARIES`](#stepper_dictionaries), or scope
430
+ `provideHubStepper()` to the route that owns the wizard.
335
431
 
336
432
  **Your application dictionary.** Configure `provideHubTranslationAdapter()` once in `app.config.ts`; its
337
433
  reactive dictionary updates the rendered navigation automatically. The component provides