react-native-vroom-chart 0.4.0 → 0.6.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/lib/index.d.mts CHANGED
@@ -201,6 +201,31 @@ type DrawingStore = {
201
201
  */
202
202
  save: (marketId: string, data: string) => void | Promise<void>;
203
203
  };
204
+ /**
205
+ * Whether undo/redo are currently available for the chart's drawings — the
206
+ * payload of `onHistoryChange`, for binding toolbar button enabled-states.
207
+ */
208
+ type UndoRedoState = {
209
+ canUndo: boolean;
210
+ canRedo: boolean;
211
+ };
212
+ /**
213
+ * Programmatic undo/redo controls, published through the `historyRef` prop in
214
+ * managed mode — for toolbar buttons and other UI outside the chart. The
215
+ * keyboard shortcuts (⌘Z / ⇧⌘Z / Ctrl+Y) work without this.
216
+ */
217
+ type UndoRedoControls = {
218
+ /** Roll back the most recent committed drawing action. No-op when empty. */
219
+ undo: () => void;
220
+ /** Re-apply the most recently undone action. No-op when empty. */
221
+ redo: () => void;
222
+ /**
223
+ * Drop the undo/redo stacks without touching the drawings. Rarely needed —
224
+ * users find a cleared history surprising — but useful when reusing a mounted
225
+ * chart for what the user perceives as a brand-new context.
226
+ */
227
+ clearHistory: () => void;
228
+ };
204
229
  /** RSI indicator config. Rendered in a pane below the candles when enabled. */
205
230
  type RSIConfig = {
206
231
  enabled?: boolean;
@@ -246,6 +271,42 @@ type VWAPConfig = {
246
271
  /** Stroke width in px. Default 1.5. */
247
272
  width?: number;
248
273
  };
274
+ /**
275
+ * Bollinger Bands overlay config. A basis moving average of `source` over
276
+ * `period`, banded at ± `stdDev` × population standard deviation of the same
277
+ * window, drawn as three lines on the price pane with an optional translucent
278
+ * fill between the bands. No pane is reserved.
279
+ */
280
+ type BollingerBandsConfig = {
281
+ enabled?: boolean;
282
+ /** Lookback in candles. Default 20, clamped to >= 1. */
283
+ period?: number;
284
+ /** Standard-deviation multiplier. Default 2. */
285
+ stdDev?: number;
286
+ /** Price source. Default 'close'. */
287
+ source?: MASource;
288
+ /**
289
+ * Basis (middle) line type. Default 'sma'. The stdev always uses the
290
+ * window's arithmetic mean, even with an EMA basis (TradingView semantics).
291
+ */
292
+ basis?: 'sma' | 'ema';
293
+ /** Upper band color (hex string or packed ARGB number). Default blue. */
294
+ upperColor?: string | number;
295
+ /** Upper band stroke width in px. Default 1. */
296
+ upperWidth?: number;
297
+ /** Basis (middle) line color. Default orange. */
298
+ middleColor?: string | number;
299
+ /** Basis line stroke width in px. Default 1. */
300
+ middleWidth?: number;
301
+ /** Lower band color. Default blue. */
302
+ lowerColor?: string | number;
303
+ /** Lower band stroke width in px. Default 1. */
304
+ lowerWidth?: number;
305
+ /** Translucent fill between the bands. Default true. */
306
+ fill?: boolean;
307
+ /** Fill opacity 0..1, applied to the upper band color. Default 0.1. */
308
+ fillOpacity?: number;
309
+ };
249
310
  /**
250
311
  * A single resting-liquidity band: a price interval carrying a total order size
251
312
  * on one side of the book. Consolidate raw L2 levels into these buckets before
@@ -291,6 +352,78 @@ type LiquidityConfig = {
291
352
  * `widthPx` and `widthFrac * paneWidth` is used. */
292
353
  widthFrac?: number;
293
354
  };
355
+ /**
356
+ * A consumer-supplied horizontal status line at a fixed price — the primitive
357
+ * behind resting limit orders, take-profits, stop-losses and liquidation levels.
358
+ *
359
+ * Renders as a line across the price pane ending in a label group (a `text` pill
360
+ * plus an optional solid-filled `quantity` pill and an optional close button),
361
+ * with a price badge in the y-axis strip.
362
+ *
363
+ * Interaction is opt-in and callback-gated, mirroring TradingView: the line is
364
+ * only draggable when `draggable` is set, and the close button only renders when
365
+ * you pass `onPriceLineClose`. Dragging is a *preview* — the chart never mutates
366
+ * the price you gave it, so a move your backend rejects reverts on its own
367
+ * simply by leaving your `priceLines` state unchanged.
368
+ */
369
+ type PriceLine = {
370
+ /** Stable unique id, echoed back by every callback. */
371
+ id: string;
372
+ /** Where the line sits on the price scale. */
373
+ price: number;
374
+ /** Body label — render whatever you like (e.g. `'Limit Buy @ 13.79'`). */
375
+ text?: string;
376
+ /**
377
+ * Trailing segment, drawn as a solid-filled pill with white text so size reads
378
+ * at a glance (e.g. `'x 5.206'`). Omit to hide it.
379
+ */
380
+ quantity?: string;
381
+ /** Line, border, body text and close-icon color. Defaults to a soft red. */
382
+ color?: VroomColor;
383
+ /** Stroke width in px. Default 1. */
384
+ width?: number;
385
+ /** Line style. Default `'dotted'`, matching the current-price indicator. */
386
+ lineStyle?: 'solid' | 'dotted' | 'dashed';
387
+ /**
388
+ * Let the user drag this line vertically to a new price. Default false.
389
+ * Pair with `onPriceLineDragEnd` to commit the move.
390
+ */
391
+ draggable?: boolean;
392
+ /**
393
+ * Show the close button on this line. Defaults to true, but the button only
394
+ * ever renders if you also pass `onPriceLineClose` — set this to false to opt a
395
+ * single line out (e.g. a liquidation level the user can't dismiss).
396
+ */
397
+ closable?: boolean;
398
+ /** Extend the line to the pane's left edge. Default true. */
399
+ extendLeft?: boolean;
400
+ /** Show the price badge in the y-axis strip. Default true. */
401
+ axisLabel?: boolean;
402
+ };
403
+ /** Shared layout/style for every price line, passed via `priceLinesStyle`. */
404
+ type PriceLinesStyle = {
405
+ /**
406
+ * Translucent fill behind the body and close-button pills, so the label reads
407
+ * over candles without hiding them. Defaults to a dark translucent grey.
408
+ */
409
+ bodyBackground?: VroomColor;
410
+ /** Label font size in px. Defaults to the axis font size. */
411
+ fontSize?: number;
412
+ /**
413
+ * How far in from the price axis the label group sits, as a fraction of pane
414
+ * width (0 = flush against the axis, 0.5 = at the pane's midpoint). Only
415
+ * applies when `align` is `'right'`. Default 0.
416
+ */
417
+ inset?: number;
418
+ /** Where the label group sits horizontally. Default `'right'`. */
419
+ align?: 'left' | 'center' | 'right';
420
+ /**
421
+ * How much the hovered line or close button brightens, as a channel
422
+ * multiplier. 1 disables the highlight. Default 1.25. Web only — touch
423
+ * platforms have no hover state.
424
+ */
425
+ hoverBoost?: number;
426
+ };
294
427
  /** MACD indicator config. Rendered in its own pane below the candles. */
295
428
  type MACDConfig = {
296
429
  enabled?: boolean;
@@ -355,8 +488,41 @@ type VroomChartCoreProps = {
355
488
  movingAverages?: MovingAverageOverlay[];
356
489
  /** VWAP overlay (session anchor, configurable reset). */
357
490
  vwap?: VWAPConfig;
491
+ /** Bollinger Bands overlay (three lines + fill on the price pane). */
492
+ bollingerBands?: BollingerBandsConfig;
358
493
  /** Resting-order / order-book liquidity bands drawn behind the candles. */
359
494
  liquidity?: LiquidityConfig;
495
+ /**
496
+ * Horizontal status lines at consumer-supplied prices (resting orders, TP/SL,
497
+ * liquidation levels), each with a text label and an optional close button.
498
+ *
499
+ * This is a controlled prop: the chart renders exactly what you pass and never
500
+ * mutates it. A drag paints a live preview and reports the new price through
501
+ * `onPriceLineDragEnd`; the line only actually moves once you update this
502
+ * array, so a rejected move needs no explicit rollback.
503
+ */
504
+ priceLines?: PriceLine[];
505
+ /** Shared layout/style for every entry in `priceLines`. */
506
+ priceLinesStyle?: PriceLinesStyle;
507
+ /**
508
+ * Fired continuously while a draggable price line is being dragged, with the
509
+ * price under the pointer. Use it for a live readout (e.g. an order ticket);
510
+ * wait for `onPriceLineDragEnd` to commit.
511
+ */
512
+ onPriceLineDrag?: (id: string, price: number) => void;
513
+ /**
514
+ * Fired once when the user drops a dragged price line. Submit the new price to
515
+ * your backend here, then update `priceLines` on success — the line snaps back
516
+ * on its own if you don't. Dragging is cancelled (and this never fires) if the
517
+ * user presses Escape.
518
+ */
519
+ onPriceLineDragEnd?: (id: string, price: number) => void;
520
+ /**
521
+ * Fired when the user activates a price line's close button. Passing this
522
+ * handler is what makes the button render at all; individual lines opt out with
523
+ * `closable: false`.
524
+ */
525
+ onPriceLineClose?: (id: string) => void;
360
526
  /**
361
527
  * Pixels the crosshair dot / horizontal line sit *above* the touch point so
362
528
  * they aren't hidden under the thumb. The vertical line stays centered on the
@@ -417,6 +583,40 @@ type VroomChartCoreProps = {
417
583
  * host should apply the requested mode.
418
584
  */
419
585
  onModeChange?: (mode: ChartMode) => void;
586
+ /**
587
+ * Max drawing undo depth in managed mode (one step = one committed drawing
588
+ * action). Oldest steps are evicted beyond this. Default 100. History is
589
+ * in-memory and per-`seriesKey`: it resets on market switch and is never
590
+ * persisted — only the drawings themselves are saved. Web only.
591
+ */
592
+ historyLimit?: number;
593
+ /**
594
+ * Fired when drawing undo/redo availability changes in managed mode — bind
595
+ * toolbar undo/redo buttons' enabled-state to it. (In controlled mode you own
596
+ * the history, so track availability yourself.) Web only.
597
+ */
598
+ onHistoryChange?: (state: UndoRedoState) => void;
599
+ /**
600
+ * Receives programmatic `undo`/`redo`/`clearHistory` controls in managed mode
601
+ * (e.g. `useRef<UndoRedoControls | null>(null)` passed here, then
602
+ * `historyRef.current?.undo()` from a toolbar button). Set to `null` while
603
+ * unmounted or when no `drawingStore` is present. Web only.
604
+ */
605
+ historyRef?: {
606
+ current: UndoRedoControls | null;
607
+ };
608
+ /**
609
+ * Fired when the user presses the undo shortcut (⌘Z / Ctrl+Z) in controlled
610
+ * mode — apply the undo to your own drawings state. Ignored when
611
+ * `drawingStore` is set (managed mode undoes internally). Web only.
612
+ */
613
+ onUndo?: () => void;
614
+ /**
615
+ * Fired when the user presses the redo shortcut (⇧⌘Z / Ctrl+Shift+Z /
616
+ * Ctrl+Y) in controlled mode — apply the redo to your own drawings state.
617
+ * Ignored when `drawingStore` is set. Web only.
618
+ */
619
+ onRedo?: () => void;
420
620
  onCrosshair?: (e: CrosshairEvent) => void;
421
621
  onViewportChange?: (startMs: number, endMs: number) => void;
422
622
  };
@@ -450,4 +650,4 @@ declare global {
450
650
  */
451
651
  declare function VroomChart(props: VroomChartProps): React.JSX.Element;
452
652
 
453
- export { type Candle, type ChartType, type CrosshairEvent, type MACDConfig, type MASource, type MovingAverageOverlay, type RSIConfig, type VWAPConfig, type VisibleRange, VroomChart, type VroomChartProps, type VroomColor, type VroomTheme };
653
+ export { type BollingerBandsConfig, type Candle, type ChartType, type CrosshairEvent, type MACDConfig, type MASource, type MovingAverageOverlay, type PriceLine, type PriceLinesStyle, type RSIConfig, type VWAPConfig, type VisibleRange, VroomChart, type VroomChartProps, type VroomColor, type VroomTheme };
package/lib/index.d.ts CHANGED
@@ -201,6 +201,31 @@ type DrawingStore = {
201
201
  */
202
202
  save: (marketId: string, data: string) => void | Promise<void>;
203
203
  };
204
+ /**
205
+ * Whether undo/redo are currently available for the chart's drawings — the
206
+ * payload of `onHistoryChange`, for binding toolbar button enabled-states.
207
+ */
208
+ type UndoRedoState = {
209
+ canUndo: boolean;
210
+ canRedo: boolean;
211
+ };
212
+ /**
213
+ * Programmatic undo/redo controls, published through the `historyRef` prop in
214
+ * managed mode — for toolbar buttons and other UI outside the chart. The
215
+ * keyboard shortcuts (⌘Z / ⇧⌘Z / Ctrl+Y) work without this.
216
+ */
217
+ type UndoRedoControls = {
218
+ /** Roll back the most recent committed drawing action. No-op when empty. */
219
+ undo: () => void;
220
+ /** Re-apply the most recently undone action. No-op when empty. */
221
+ redo: () => void;
222
+ /**
223
+ * Drop the undo/redo stacks without touching the drawings. Rarely needed —
224
+ * users find a cleared history surprising — but useful when reusing a mounted
225
+ * chart for what the user perceives as a brand-new context.
226
+ */
227
+ clearHistory: () => void;
228
+ };
204
229
  /** RSI indicator config. Rendered in a pane below the candles when enabled. */
205
230
  type RSIConfig = {
206
231
  enabled?: boolean;
@@ -246,6 +271,42 @@ type VWAPConfig = {
246
271
  /** Stroke width in px. Default 1.5. */
247
272
  width?: number;
248
273
  };
274
+ /**
275
+ * Bollinger Bands overlay config. A basis moving average of `source` over
276
+ * `period`, banded at ± `stdDev` × population standard deviation of the same
277
+ * window, drawn as three lines on the price pane with an optional translucent
278
+ * fill between the bands. No pane is reserved.
279
+ */
280
+ type BollingerBandsConfig = {
281
+ enabled?: boolean;
282
+ /** Lookback in candles. Default 20, clamped to >= 1. */
283
+ period?: number;
284
+ /** Standard-deviation multiplier. Default 2. */
285
+ stdDev?: number;
286
+ /** Price source. Default 'close'. */
287
+ source?: MASource;
288
+ /**
289
+ * Basis (middle) line type. Default 'sma'. The stdev always uses the
290
+ * window's arithmetic mean, even with an EMA basis (TradingView semantics).
291
+ */
292
+ basis?: 'sma' | 'ema';
293
+ /** Upper band color (hex string or packed ARGB number). Default blue. */
294
+ upperColor?: string | number;
295
+ /** Upper band stroke width in px. Default 1. */
296
+ upperWidth?: number;
297
+ /** Basis (middle) line color. Default orange. */
298
+ middleColor?: string | number;
299
+ /** Basis line stroke width in px. Default 1. */
300
+ middleWidth?: number;
301
+ /** Lower band color. Default blue. */
302
+ lowerColor?: string | number;
303
+ /** Lower band stroke width in px. Default 1. */
304
+ lowerWidth?: number;
305
+ /** Translucent fill between the bands. Default true. */
306
+ fill?: boolean;
307
+ /** Fill opacity 0..1, applied to the upper band color. Default 0.1. */
308
+ fillOpacity?: number;
309
+ };
249
310
  /**
250
311
  * A single resting-liquidity band: a price interval carrying a total order size
251
312
  * on one side of the book. Consolidate raw L2 levels into these buckets before
@@ -291,6 +352,78 @@ type LiquidityConfig = {
291
352
  * `widthPx` and `widthFrac * paneWidth` is used. */
292
353
  widthFrac?: number;
293
354
  };
355
+ /**
356
+ * A consumer-supplied horizontal status line at a fixed price — the primitive
357
+ * behind resting limit orders, take-profits, stop-losses and liquidation levels.
358
+ *
359
+ * Renders as a line across the price pane ending in a label group (a `text` pill
360
+ * plus an optional solid-filled `quantity` pill and an optional close button),
361
+ * with a price badge in the y-axis strip.
362
+ *
363
+ * Interaction is opt-in and callback-gated, mirroring TradingView: the line is
364
+ * only draggable when `draggable` is set, and the close button only renders when
365
+ * you pass `onPriceLineClose`. Dragging is a *preview* — the chart never mutates
366
+ * the price you gave it, so a move your backend rejects reverts on its own
367
+ * simply by leaving your `priceLines` state unchanged.
368
+ */
369
+ type PriceLine = {
370
+ /** Stable unique id, echoed back by every callback. */
371
+ id: string;
372
+ /** Where the line sits on the price scale. */
373
+ price: number;
374
+ /** Body label — render whatever you like (e.g. `'Limit Buy @ 13.79'`). */
375
+ text?: string;
376
+ /**
377
+ * Trailing segment, drawn as a solid-filled pill with white text so size reads
378
+ * at a glance (e.g. `'x 5.206'`). Omit to hide it.
379
+ */
380
+ quantity?: string;
381
+ /** Line, border, body text and close-icon color. Defaults to a soft red. */
382
+ color?: VroomColor;
383
+ /** Stroke width in px. Default 1. */
384
+ width?: number;
385
+ /** Line style. Default `'dotted'`, matching the current-price indicator. */
386
+ lineStyle?: 'solid' | 'dotted' | 'dashed';
387
+ /**
388
+ * Let the user drag this line vertically to a new price. Default false.
389
+ * Pair with `onPriceLineDragEnd` to commit the move.
390
+ */
391
+ draggable?: boolean;
392
+ /**
393
+ * Show the close button on this line. Defaults to true, but the button only
394
+ * ever renders if you also pass `onPriceLineClose` — set this to false to opt a
395
+ * single line out (e.g. a liquidation level the user can't dismiss).
396
+ */
397
+ closable?: boolean;
398
+ /** Extend the line to the pane's left edge. Default true. */
399
+ extendLeft?: boolean;
400
+ /** Show the price badge in the y-axis strip. Default true. */
401
+ axisLabel?: boolean;
402
+ };
403
+ /** Shared layout/style for every price line, passed via `priceLinesStyle`. */
404
+ type PriceLinesStyle = {
405
+ /**
406
+ * Translucent fill behind the body and close-button pills, so the label reads
407
+ * over candles without hiding them. Defaults to a dark translucent grey.
408
+ */
409
+ bodyBackground?: VroomColor;
410
+ /** Label font size in px. Defaults to the axis font size. */
411
+ fontSize?: number;
412
+ /**
413
+ * How far in from the price axis the label group sits, as a fraction of pane
414
+ * width (0 = flush against the axis, 0.5 = at the pane's midpoint). Only
415
+ * applies when `align` is `'right'`. Default 0.
416
+ */
417
+ inset?: number;
418
+ /** Where the label group sits horizontally. Default `'right'`. */
419
+ align?: 'left' | 'center' | 'right';
420
+ /**
421
+ * How much the hovered line or close button brightens, as a channel
422
+ * multiplier. 1 disables the highlight. Default 1.25. Web only — touch
423
+ * platforms have no hover state.
424
+ */
425
+ hoverBoost?: number;
426
+ };
294
427
  /** MACD indicator config. Rendered in its own pane below the candles. */
295
428
  type MACDConfig = {
296
429
  enabled?: boolean;
@@ -355,8 +488,41 @@ type VroomChartCoreProps = {
355
488
  movingAverages?: MovingAverageOverlay[];
356
489
  /** VWAP overlay (session anchor, configurable reset). */
357
490
  vwap?: VWAPConfig;
491
+ /** Bollinger Bands overlay (three lines + fill on the price pane). */
492
+ bollingerBands?: BollingerBandsConfig;
358
493
  /** Resting-order / order-book liquidity bands drawn behind the candles. */
359
494
  liquidity?: LiquidityConfig;
495
+ /**
496
+ * Horizontal status lines at consumer-supplied prices (resting orders, TP/SL,
497
+ * liquidation levels), each with a text label and an optional close button.
498
+ *
499
+ * This is a controlled prop: the chart renders exactly what you pass and never
500
+ * mutates it. A drag paints a live preview and reports the new price through
501
+ * `onPriceLineDragEnd`; the line only actually moves once you update this
502
+ * array, so a rejected move needs no explicit rollback.
503
+ */
504
+ priceLines?: PriceLine[];
505
+ /** Shared layout/style for every entry in `priceLines`. */
506
+ priceLinesStyle?: PriceLinesStyle;
507
+ /**
508
+ * Fired continuously while a draggable price line is being dragged, with the
509
+ * price under the pointer. Use it for a live readout (e.g. an order ticket);
510
+ * wait for `onPriceLineDragEnd` to commit.
511
+ */
512
+ onPriceLineDrag?: (id: string, price: number) => void;
513
+ /**
514
+ * Fired once when the user drops a dragged price line. Submit the new price to
515
+ * your backend here, then update `priceLines` on success — the line snaps back
516
+ * on its own if you don't. Dragging is cancelled (and this never fires) if the
517
+ * user presses Escape.
518
+ */
519
+ onPriceLineDragEnd?: (id: string, price: number) => void;
520
+ /**
521
+ * Fired when the user activates a price line's close button. Passing this
522
+ * handler is what makes the button render at all; individual lines opt out with
523
+ * `closable: false`.
524
+ */
525
+ onPriceLineClose?: (id: string) => void;
360
526
  /**
361
527
  * Pixels the crosshair dot / horizontal line sit *above* the touch point so
362
528
  * they aren't hidden under the thumb. The vertical line stays centered on the
@@ -417,6 +583,40 @@ type VroomChartCoreProps = {
417
583
  * host should apply the requested mode.
418
584
  */
419
585
  onModeChange?: (mode: ChartMode) => void;
586
+ /**
587
+ * Max drawing undo depth in managed mode (one step = one committed drawing
588
+ * action). Oldest steps are evicted beyond this. Default 100. History is
589
+ * in-memory and per-`seriesKey`: it resets on market switch and is never
590
+ * persisted — only the drawings themselves are saved. Web only.
591
+ */
592
+ historyLimit?: number;
593
+ /**
594
+ * Fired when drawing undo/redo availability changes in managed mode — bind
595
+ * toolbar undo/redo buttons' enabled-state to it. (In controlled mode you own
596
+ * the history, so track availability yourself.) Web only.
597
+ */
598
+ onHistoryChange?: (state: UndoRedoState) => void;
599
+ /**
600
+ * Receives programmatic `undo`/`redo`/`clearHistory` controls in managed mode
601
+ * (e.g. `useRef<UndoRedoControls | null>(null)` passed here, then
602
+ * `historyRef.current?.undo()` from a toolbar button). Set to `null` while
603
+ * unmounted or when no `drawingStore` is present. Web only.
604
+ */
605
+ historyRef?: {
606
+ current: UndoRedoControls | null;
607
+ };
608
+ /**
609
+ * Fired when the user presses the undo shortcut (⌘Z / Ctrl+Z) in controlled
610
+ * mode — apply the undo to your own drawings state. Ignored when
611
+ * `drawingStore` is set (managed mode undoes internally). Web only.
612
+ */
613
+ onUndo?: () => void;
614
+ /**
615
+ * Fired when the user presses the redo shortcut (⇧⌘Z / Ctrl+Shift+Z /
616
+ * Ctrl+Y) in controlled mode — apply the redo to your own drawings state.
617
+ * Ignored when `drawingStore` is set. Web only.
618
+ */
619
+ onRedo?: () => void;
420
620
  onCrosshair?: (e: CrosshairEvent) => void;
421
621
  onViewportChange?: (startMs: number, endMs: number) => void;
422
622
  };
@@ -450,4 +650,4 @@ declare global {
450
650
  */
451
651
  declare function VroomChart(props: VroomChartProps): React.JSX.Element;
452
652
 
453
- export { type Candle, type ChartType, type CrosshairEvent, type MACDConfig, type MASource, type MovingAverageOverlay, type RSIConfig, type VWAPConfig, type VisibleRange, VroomChart, type VroomChartProps, type VroomColor, type VroomTheme };
653
+ export { type BollingerBandsConfig, type Candle, type ChartType, type CrosshairEvent, type MACDConfig, type MASource, type MovingAverageOverlay, type PriceLine, type PriceLinesStyle, type RSIConfig, type VWAPConfig, type VisibleRange, VroomChart, type VroomChartProps, type VroomColor, type VroomTheme };