Skip to content

Commit

Permalink
Rudimentary text bubbles and background colors
Browse files Browse the repository at this point in the history
TextBubbles can now be added to any of the
existing components (Comic, Scene, Stick) though
it only renders within Stick for now.

Background Color (`bgColor`) can now be passed to
all components (including TextBubble) and will
render.
  • Loading branch information
MaximeIJ committed Aug 27, 2022
1 parent 2f1d1e4 commit 4e1f3bc
Show file tree
Hide file tree
Showing 18 changed files with 415 additions and 372 deletions.
570 changes: 230 additions & 340 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 0 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@
"main": "./lib/cjs/index.js",
"module": "./lib/esm/index.js",
"types": "./lib/index.d.ts",
"babel": {
"presets": [
"@babel/preset-react",
"@babel/preset-typescript"
]
},
"files": [
"lib",
"LICENSE",
Expand Down
3 changes: 2 additions & 1 deletion src/components/Comic/Comic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import {baseCSSProps, divCss, multCss} from '@/util/css';
import {ComicProps} from '@/util/types';
import {chainClickable} from 'hooks/chainClickable';

const Comic: FC<ComicProps> = ({color, dimensions, layout, onClick, scenes}) => {
const Comic: FC<ComicProps> = ({bgColor, color, dimensions, layout, onClick, scenes}) => {
const {width, height, thickness} = dimensions ?? Default.dimensions;

const comicStyle = baseCSSProps({
width,
height,
thickness,
bgColor,
color,
});

Expand Down
7 changes: 7 additions & 0 deletions src/components/Comic/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import {ComicProps} from '@/util/types';
const DEFAULT_COMIC_SIZE = '50vmin';

export const Default: Required<ComicProps> = {
children: [],
color: StickPresets.Default.color,
type: 'comic',
bgColor: 'transparent',
coord: {
x: '0',
y: '0',
},
dimensions: {
width: DEFAULT_COMIC_SIZE,
height: DEFAULT_COMIC_SIZE,
Expand Down
1 change: 1 addition & 0 deletions src/components/Comic/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
outline: var(--t, 2px) solid var(--c, #888888);
margin: 3rem auto;
overflow: hidden;
background-color: var(--bgc, transparent);
}

.row {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Scene/Scene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import {baseCSSProps} from '@/util/css';
import {SceneProps} from '@/util/types';
import {chainClickable} from 'hooks/chainClickable';

const Scene: FC<SceneProps> = ({color, dimensions, sticks, onClick}) => {
const Scene: FC<SceneProps> = ({bgColor, color, dimensions, sticks, onClick}) => {
const {width, height, thickness} = dimensions ?? Default.dimensions;

const sceneStyle = baseCSSProps({
width,
height,
thickness,
bgColor,
color,
});

Expand Down
7 changes: 7 additions & 0 deletions src/components/Scene/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import {Coordinates, SceneProps} from '@/util/types';
const DEFAULT_SCENE_SIZE = '100%';

export const Default: Required<SceneProps> = {
children: [],
type: 'scene',
bgColor: 'transparent',
coord: {
x: '0',
y: '0',
},
color: StickPresets.Default.color,
dimensions: {
width: DEFAULT_SCENE_SIZE,
Expand Down
21 changes: 18 additions & 3 deletions src/components/Stick/Stick.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {FC} from 'react';

import {chainCall, chainClickable} from '../../hooks/chainClickable';
import TextBubble from '../TextBubble';

import {Default, Positions} from './presets';

Expand All @@ -9,7 +10,7 @@ import {rotateTransformCSSProp, stickCSSProps} from '@/util/css';
import {LimbAngleProps, StickProps} from '@/util/types';

const Stick: FC<StickProps> = (props = Default) => {
const {color, posId, customPos, dimensions, coord, onClick} = props;
const {bgColor, color, posId, customPos, dimensions, coord, children, onClick} = props;
const hasCustomPose = posId === 'custom' && customPos;
const {limbs, offsets} = !hasCustomPose ? Positions[posId ?? 'custom'] : customPos;
const {width, height, thickness} = {...Default.dimensions, ...dimensions};
Expand All @@ -19,6 +20,7 @@ const Stick: FC<StickProps> = (props = Default) => {
width,
height,
thickness,
bgColor,
color,
base,
offsets,
Expand All @@ -43,10 +45,23 @@ const Stick: FC<StickProps> = (props = Default) => {
{renderLimb(legs?.right)}
</div>
</div>
{children?.map((child, idx) => {
const {type} = child;
let ChildComponent = null;
switch (type) {
case 'stick':
ChildComponent = Stick;
break;
case 'text':
ChildComponent = TextBubble;
break;
default:
break;
}
return ChildComponent && <ChildComponent {...child} key={`stickchild-${idx}`} />;
})}
</div>
);
};

// export const ClickableStick = makeClickable(Stick);

export default chainClickable(Stick);
16 changes: 15 additions & 1 deletion src/components/Stick/presets.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
import {PosType, StickPosition, StickProps} from '@/util/types';
import { offsetVar } from '@/util/css';
import {PosType, StickPosition, StickProps, TextBubbleProps} from '@/util/types';

const DEFAULT_STICK_SIZE = '12rem';

export const Default: Required<StickProps> = {
children: [{
type: 'text',
id: 'test',
text: 'Hello World!',
coord: {
x: offsetVar('w'),
y: '0%',
},


} as TextBubbleProps],
bgColor: 'transparent',
color: '#888888',
coord: {
x: '0',
Expand All @@ -21,6 +34,7 @@ export const Default: Required<StickProps> = {
id: 'stick',
onClick: () => null,
posId: 'default',
type: 'stick',
};

export const Positions: Record<PosType, StickPosition> = {
Expand Down
1 change: 1 addition & 0 deletions src/components/Stick/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
border: var(--t) solid var(--c);
border-radius: 50%;
font-size: smaller;
background-color: var(--bgc, transparent);
}

.body {
Expand Down
41 changes: 41 additions & 0 deletions src/components/TextBubble/TextBubble.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, {FC} from 'react';

import {chainCall, chainClickable} from '../../hooks/chainClickable';

import {Default} from './presets';

import './style.css';
import {stickCSSProps, textCSSProps} from '@/util/css';
import {TextBubbleProps} from '@/util/types';

const TextBubble: FC<TextBubbleProps> = (props = Default) => {
const {font, fontSize, fontWeight, borderColor, borderRadius, color, dimensions, coord, text, onClick} = props;
const {width, height, thickness} = {...Default.dimensions, ...dimensions};

const stickStyle = stickCSSProps({
width,
height,
thickness,
color,
coord,
});
const textStyle = textCSSProps({
font,
fontSize,
fontWeight,
borderColor,
borderRadius,
});
const bubbleStyle = {
...stickStyle,
...textStyle,
};

return (
<div className="bubble" style={bubbleStyle} onClick={chainCall(onClick)}>
<div className="text">{text ?? ''}</div>
</div>
);
};

export default chainClickable(TextBubble);
2 changes: 2 additions & 0 deletions src/components/TextBubble/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export {default} from './TextBubble';
export * as TextBubblePresets from './presets';
27 changes: 27 additions & 0 deletions src/components/TextBubble/presets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {TextBubbleProps} from '@/util/types';

const DEFAULT_SIZE = 'fit-content';

export const Default: Required<TextBubbleProps> = {
children: [],
type: 'text',
bgColor: 'transparent',
color: '#888888',
coord: {
x: '0',
y: '0',
},
dimensions: {
width: DEFAULT_SIZE,
height: DEFAULT_SIZE,
thickness: '2px',
},
id: 'text bubble',
onClick: () => null,
text: '',
font: 'comic sans',
fontSize: '2rem',
fontWeight: 'normal',
borderColor: 'transparent',
borderRadius: '40%',
};
18 changes: 18 additions & 0 deletions src/components/TextBubble/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
div.bubble {
border-radius: var(--br);
background-color: var(--bc);
border: var(--t) solid var(--c, transparent);
position: absolute !important;
width: var(--w);
height: var(--h);
background-color: var(--bgc, transparent);
padding: calc(var(--t, 1px) * 2);
}

.text {
text-align: center;
font-family: var(--f, Comic Sans MS, Comic Sans, cursive);
font-size: var(--fs, auto);
font-weight: var(--fw, normal);
color: var(--c, #888);
}
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export {default as Comic, ComicPresets} from './Comic';
export {default as Scene, ScenePresets} from './Scene';
export {default as Stick, StickPresets} from './Stick';
export {default as TextBubble, TextBubblePresets} from './TextBubble';
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './components';
export * from './util/types';
export * from './util/types';
27 changes: 22 additions & 5 deletions src/util/css.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {CSSProperties} from 'react';

import {BaseCSSPropsInput, StickCSSPropsInput} from './types';
import {BaseCSSPropsInput, StickCSSPropsInput, TextProps} from './types';

/**
* Generate CSS strings
Expand Down Expand Up @@ -59,12 +59,13 @@ export const rotateTransformCSSProp = (angle?: number) =>
* @returns CSSProperties object with the inputs process where needed
*/
export const baseCSSProps = (input: BaseCSSPropsInput): CSSProperties => {
const {color, width, height, thickness} = input;
const {bgColor, color, width, height, thickness} = input;
return {
['--w']: width,
['--h']: height,
['--t']: thickness,
['--c']: color,
['--bgc']: bgColor,
} as CSSProperties;
};

Expand All @@ -73,12 +74,28 @@ export const baseCSSProps = (input: BaseCSSPropsInput): CSSProperties => {
* @param input Subset of StickProps needed for dynamic CSS props
* @returns CSSProperties object with the inputs process where needed
*/
export const stickCSSProps = (input: StickCSSPropsInput): CSSProperties => {
const {color, width, height, thickness, base, coord, offsets} = input;
export const stickCSSProps = (input: StickCSSPropsInput): CSSProperties => {
const {bgColor, color, width, height, thickness, base, coord, offsets} = input;
return {
...baseCSSProps({color, width, height, thickness}),
...baseCSSProps({bgColor, color, width, height, thickness}),
['--angle']: deg(base ?? 0),
top: `calc(${coord?.y ?? 0} - ${offsets?.y ?? '0%'})`,
left: `calc(${coord?.x ?? 0} - ${offsets?.x ?? '0%'})`,
} as CSSProperties;
};

/**
*
* @param input Subset of StickProps needed for dynamic CSS props
* @returns CSSProperties object with the inputs process where needed
*/
export const textCSSProps = (input: TextProps): CSSProperties => {
const {font, fontSize, fontWeight, borderColor, borderRadius} = input;
return {
['--f']: font,
['--fs']: fontSize,
['--fw']: fontWeight,
['--bc']: borderColor,
['--br']: borderRadius,
} as CSSProperties;
};
34 changes: 20 additions & 14 deletions src/util/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,48 @@ export type StickPosition = {limbs?: LimbAngles; offsets?: Coordinates};

export type Clickable = {
onClick: (id?: string) => void;
}
};

export type CommonProps = Clickable & {
export type CommonProps<T = unknown> = Clickable & {
id: string;
type: 'common' | 'stick' | 'text' | 'scene' | 'comic';
bgColor?: string;
color?: string;
coord?: Coordinates;
dimensions?: Partial<Dimensions>;
children?: Array<T extends CommonProps ? T : CommonProps>;
};

export type StickProps = CommonProps & {
posId?: PosType;
coord?: Coordinates;
customPos?: StickPosition;
};


export type BaseCSSPropsInput = {
export type BaseCSSPropsInput = {
color?: string;
coord?: Coordinates;
width?: string;
height?: string;
thickness?: string;
bgColor?: string;
};

export type StickCSSPropsInput = BaseCSSPropsInput & {
base?: number;
coord?: Coordinates;
offsets?: Coordinates;
};

export type TextProps = {
text?: string;
font?: string;
fontSize?: string;
fontWeight?: string;
borderColor?: string;
borderRadius?: string;
};

export type TextBubbleProps = CommonProps & TextProps;

export type SceneProps = CommonProps & {
sticks?: Array<StickProps>;
};
Expand All @@ -63,11 +77,3 @@ export type ComicProps = CommonProps & {
scenes: Array<SceneProps>;
layout: Array<Array<number>>;
};

export type EditorProps<T> = {
onChange: (newProps: T) => void;
starter?: T;
selection?: string;
setSelection?: (s: string) => void;
showPreview?: boolean;
};

0 comments on commit 4e1f3bc

Please sign in to comment.