Skip to content

Commit

Permalink
feat(hdom-components): merge button & button group attribs
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Dec 14, 2018
1 parent 6b04e16 commit da441c1
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 85 deletions.
65 changes: 36 additions & 29 deletions packages/hdom-components/src/button-group.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IObjectOf } from "@thi.ng/api/api";

import { ButtonArgs, Button } from "./button";
import { mergeAttribs } from "./utils/merge-attribs";

/**
* Button group component config options.
Expand Down Expand Up @@ -52,7 +53,8 @@ export interface ButtonGroupItem extends Array<any> {
[id: number]: any;
}

export type ButtonGroup = (_, args: ButtonGroupArgs, ...buttons: ButtonGroupItem[]) => any;
export type ButtonGroup =
(_, args: ButtonGroupArgs, ...buttons: ButtonGroupItem[]) => any;

/**
* Higher order function to create a new stateless button group
Expand All @@ -71,35 +73,40 @@ export type ButtonGroup = (_, args: ButtonGroupArgs, ...buttons: ButtonGroupItem
*
* @param opts
*/
export const buttonGroup = (opts: ButtonGroupOpts): ButtonGroup =>
(_, args: ButtonGroupArgs, ...buttons: ButtonGroupItem[]) =>
["div", { ...opts.attribs, ...args.attribs }, ...groupBody(opts, args.disabled, buttons)];
export const buttonGroup =
(opts: ButtonGroupOpts): ButtonGroup =>
(_, args: ButtonGroupArgs, ...buttons: ButtonGroupItem[]) =>
["div",
mergeAttribs(opts.attribs, args.attribs),
...groupBody(opts, args.disabled, buttons)];

const groupBody = (opts: ButtonGroupOpts, disabled: boolean, buttons: ButtonGroupItem[]) => {
switch (buttons.length) {
case 0:
return;
case 1:
return [bt(opts.inner || opts.first, disabled, buttons[0])];
case 2:
return [
bt(opts.first, disabled, buttons[0]),
bt(opts.last || opts.first, disabled, buttons[1])
];
default: {
const res = [bt(opts.first, disabled, buttons[0])];
const el = opts.inner || opts.first
const n = buttons.length - 1;
for (let i = 1; i < n; i++) {
res[i] = bt(el, disabled, buttons[i]);
const groupBody =
(opts: ButtonGroupOpts, disabled: boolean, buttons: ButtonGroupItem[]) => {
switch (buttons.length) {
case 0:
return;
case 1:
return [bt(opts.inner || opts.first, disabled, buttons[0])];
case 2:
return [
bt(opts.first, disabled, buttons[0]),
bt(opts.last || opts.first, disabled, buttons[1])
];
default: {
const res = [bt(opts.first, disabled, buttons[0])];
const el = opts.inner || opts.first
const n = buttons.length - 1;
for (let i = 1; i < n; i++) {
res[i] = bt(el, disabled, buttons[i]);
}
res[n] = bt(opts.last || opts.first, disabled, buttons[n]);
return res;
}
res[n] = bt(opts.last || opts.first, disabled, buttons[n]);
return res;
}
}
};
};

const bt = (el: Button, disabled: boolean, bt: ButtonGroupItem) =>
disabled ?
[el, { ...bt[0], disabled: true }, ...bt.slice(1)] :
[el, ...bt];
const bt =
(el: Button, disabled: boolean, bt: ButtonGroupItem) =>
disabled ?
[el, { ...bt[0], disabled: true }, ...bt.slice(1)] :
[el, ...bt];
51 changes: 26 additions & 25 deletions packages/hdom-components/src/button.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IObjectOf } from "@thi.ng/api/api";
import { mergeAttribs } from "./utils/merge-attribs";

export interface ButtonOpts {
/**
Expand Down Expand Up @@ -36,7 +37,8 @@ export interface ButtonArgs {
disabled: boolean;
}

export type Button = (_: any, args: Partial<ButtonArgs>, ...body: any[]) => any;
export type Button =
(_: any, args: Partial<ButtonArgs>, ...body: any[]) => any;

/**
* Higher order function to create a new stateless button component,
Expand All @@ -52,28 +54,27 @@ export type Button = (_: any, args: Partial<ButtonArgs>, ...body: any[]) => any;
* button version to create. The button can have any number of body
* elements (e.g. icon and label), given as varargs.
*/
export const button = (opts?: Partial<ButtonOpts>): Button => {
// init with defaults
opts = {
tag: "a",
tagDisabled: "span",
preventDefault: true,
attribs: {},
...opts
export const button =
(opts?: Partial<ButtonOpts>): Button => {
// init with defaults
opts = {
tag: "a",
tagDisabled: "span",
preventDefault: true,
attribs: {},
...opts
};
!opts.attribs.role && (opts.attribs.role = "button");
return (_: any, args: Partial<ButtonArgs>, ...body: any[]) =>
args.disabled ?
[opts.tagDisabled, {
...mergeAttribs(opts.attribsDisabled, args.attribs),
disabled: true,
}, ...body] :
[opts.tag, {
...mergeAttribs(opts.attribs, args.attribs),
onclick: opts.preventDefault ?
(e) => (e.preventDefault(), args.onclick(e)) :
args.onclick
}, ...body];
};
!opts.attribs.role && (opts.attribs.role = "button");
return (_: any, args: Partial<ButtonArgs>, ...body: any[]) =>
args.disabled ?
[opts.tagDisabled, {
...opts.attribsDisabled,
...args.attribs,
disabled: true,
}, ...body] :
[opts.tag, {
...opts.attribs,
...args.attribs,
onclick: opts.preventDefault ?
(e) => (e.preventDefault(), args.onclick(e)) :
args.onclick
}, ...body];
};
64 changes: 33 additions & 31 deletions packages/hdom-components/src/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,29 @@ export interface CanvasHandlers<T extends CanvasContext> {
* @param handlers user handlers
* @param opts canvas context creation options
*/
const _canvas = (type, { init, update, release }: Partial<CanvasHandlers<any>>, opts) => {
let el, ctx;
let frame = 0;
let time = 0;
return {
init(_el: HTMLCanvasElement, hctx: any, ...args: any[]) {
el = _el;
adaptDPI(el, el.width, el.height);
ctx = el.getContext(type, opts);
time = Date.now();
init && init(el, ctx, hctx, ...args);
update && update(el, ctx, hctx, time, frame++, ...args);
},
render(hctx: any, ...args: any[]) {
ctx && update && update(el, ctx, hctx, Date.now() - time, frame++, ...args);
return ["canvas", args[0]];
},
release(hctx: any, ...args: any[]) {
release && release(el, ctx, hctx, ...args);
}
const _canvas =
(type, { init, update, release }: Partial<CanvasHandlers<any>>, opts) => {
let el, ctx;
let frame = 0;
let time = 0;
return {
init(_el: HTMLCanvasElement, hctx: any, ...args: any[]) {
el = _el;
adaptDPI(el, el.width, el.height);
ctx = el.getContext(type, opts);
time = Date.now();
init && init(el, ctx, hctx, ...args);
update && update(el, ctx, hctx, time, frame++, ...args);
},
render(hctx: any, ...args: any[]) {
ctx && update && update(el, ctx, hctx, Date.now() - time, frame++, ...args);
return ["canvas", args[0]];
},
release(hctx: any, ...args: any[]) {
release && release(el, ctx, hctx, ...args);
}
};
};
};

/**
* Higher order WebGL canvas component delegating to user provided
Expand Down Expand Up @@ -122,13 +123,14 @@ export const canvas2D = (
* @param width uncompensated pixel width
* @param height uncompensated pixel height
*/
export const adaptDPI = (canvas: HTMLCanvasElement, width: number, height: number) => {
const dpr = window.devicePixelRatio || 1;
if (dpr != 1) {
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
}
canvas.width = width * dpr;
canvas.height = height * dpr;
return dpr;
};
export const adaptDPI =
(canvas: HTMLCanvasElement, width: number, height: number) => {
const dpr = window.devicePixelRatio || 1;
if (dpr != 1) {
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
}
canvas.width = width * dpr;
canvas.height = height * dpr;
return dpr;
};

0 comments on commit da441c1

Please sign in to comment.