Skip to content

Commit

Permalink
feat: 🎸 DeckBuilder can accept a predefined shapes\animations
Browse files Browse the repository at this point in the history
DeckBuilder.start() method can accept a predefined set of shapes and
animations created before. Moreover, it infers the names of the shapes
and animations and can suggest autocompletion for slide builders inside
of deck builder chaining.

BREAKING CHANGE: 🧨 DeckBuilder has no longer methods withShape(), withAnimation(). If you
want to add a "global" shape, you can create a predefined set of
shapes\animations and pass them into DeckBuilder.start(shapes,
animations).
  • Loading branch information
ghaiklor committed May 10, 2020
1 parent 999f82e commit 64988f6
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 30 deletions.
50 changes: 36 additions & 14 deletions packages/kittik-deck/spec/DeckBuilder.spec.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,56 @@
import { AnimationBuilder, ShapeBuilder, SlideBuilder } from '../src/Deck';
import { AnimationBuilder, ShapeBuilder } from '../src/Deck';
import { Canvas } from 'terminal-canvas';
import { DeckBuilder } from '../src/DeckBuilder';

describe('deck builder', () => {
it('should properly create deck using DeckBuilder', () => {
expect.hasAssertions();

const PREDEFINED_SHAPES = { 'Test Shape': ShapeBuilder.start('Text').end() };
const PREDEFINED_ANIMATIONS = { 'Test Animation': AnimationBuilder.start('Focus').end() };
const deck = DeckBuilder
.start()
.start(PREDEFINED_SHAPES, PREDEFINED_ANIMATIONS)
.withCanvas(Canvas.create())
.withAnimation(
'Test Animation',
AnimationBuilder
.start('Focus')
.end()
)
.withShape(
'Test Shape',
ShapeBuilder
.start('Text')
.withSlide(
(builder) => builder
.withName('Slide #1')
.withOrder('Test Shape', ['Test Animation'])
.end()
)
.withSlide(
SlideBuilder
.start()
(builder) => builder
.withName('Slide #2')
.withAnimation('Local Animation', AnimationBuilder.start('Focus').end())
.withOrder('Test Shape', ['Test Animation', 'Local Animation'])
.end()
)
.end();

expect(deck.canvas).toBeInstanceOf(Canvas);

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
const [firstSlide, secondSlide] = deck.slides;

expect(firstSlide.shapes.size).toBe(1);
expect(firstSlide.shapes.has('Test Shape')).toBe(true);
expect(firstSlide.animations.size).toBe(1);
expect(firstSlide.animations.has('Test Animation')).toBe(true);
expect(firstSlide.order).toStrictEqual([{
shape: 'Test Shape',
animations: ['Test Animation']
}]);

expect(secondSlide.shapes.size).toBe(1);
expect(secondSlide.shapes.has('Test Shape')).toBe(true);
expect(secondSlide.animations.size).toBe(2);
expect(secondSlide.animations.has('Test Animation')).toBe(true);
expect(secondSlide.animations.has('Local Animation')).toBe(true);
expect(secondSlide.order).toStrictEqual([{
shape: 'Test Shape',
animations: ['Test Animation', 'Local Animation']
}]);

deck.exit();
});
});
33 changes: 17 additions & 16 deletions packages/kittik-deck/src/DeckBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
import { Slide, SlideBuilder } from 'kittik-slide';
import { Animationable } from 'kittik-animation-basic';
import { Canvas } from 'terminal-canvas';
import { Deck } from './Deck';
import { ShapeRenderable } from 'kittik-shape-basic';
import { Slide } from 'kittik-slide';

export class DeckBuilder {
export class DeckBuilder<TShape extends string, TAnimation extends string> {
private readonly deck: Deck = new Deck();
private readonly shapes: Record<TShape, ShapeRenderable>;
private readonly animations: Record<TAnimation, Animationable>;

public static start (): DeckBuilder {
return new this();
public constructor (shapes: Record<string, ShapeRenderable> = {}, animations: Record<string, Animationable> = {}) {
this.shapes = shapes;
this.animations = animations;
}

public withCanvas (canvas: Canvas): this {
this.deck.canvas = canvas;

return this;
public static start <TShape extends string = never, TAnimation extends string = never>(
shapes?: Record<TShape, ShapeRenderable>,
animations?: Record<TAnimation, Animationable>
): DeckBuilder<TShape, TAnimation> {
return new this(shapes, animations);
}

public withShape (name: string, shape: ShapeRenderable): this {
this.deck.addShape(name, shape);
public withCanvas (canvas: Canvas): this {
this.deck.canvas = canvas;

return this;
}

public withAnimation (name: string, animation: Animationable): this {
this.deck.addAnimation(name, animation);

return this;
}
public withSlide (fn: (builder: SlideBuilder<TShape, TAnimation>) => Slide): this {
const builder = SlideBuilder.start(this.shapes, this.animations);
const slide = fn(builder);

public withSlide (slide: Slide): this {
this.deck.addSlide(slide);

return this;
Expand Down

0 comments on commit 64988f6

Please sign in to comment.