Skip to content

Commit

Permalink
[refactor] rewrite BG Icon, Input Group, Collapse, Accordion & Month …
Browse files Browse the repository at this point in the history
…Calendar components (#20)
  • Loading branch information
TechQuery authored Jan 21, 2024
1 parent e2af9e9 commit 78e31ce
Show file tree
Hide file tree
Showing 12 changed files with 386 additions and 260 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "boot-cell",
"version": "2.0.0-beta.7",
"version": "2.0.0-beta.9",
"license": "LGPL-3.0",
"author": "[email protected]",
"description": "Web Components UI library based on WebCell v3, BootStrap v5, BootStrap Icon v1 & FontAwesome v6",
Expand Down Expand Up @@ -29,7 +29,7 @@
"dom-renderer": "^2.0.6",
"mobx": "^6.12.0",
"regenerator-runtime": "^0.14.1",
"web-cell": "^3.0.0-rc.7",
"web-cell": "^3.0.0-rc.8",
"web-utility": "^4.1.3"
},
"peerDependencies": {
Expand Down Expand Up @@ -70,7 +70,7 @@
"ts-jest": "^29.1.1",
"ts-node": "^10.9.2",
"typedoc": "^0.25.7",
"typedoc-plugin-mdn-links": "^3.1.12",
"typedoc-plugin-mdn-links": "^3.1.13",
"typescript": "~5.3.3"
},
"scripts": {
Expand Down
16 changes: 8 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

102 changes: 102 additions & 0 deletions source/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { observable } from 'mobx';
import {
FC,
WebCell,
WebCellProps,
attribute,
component,
observer,
on,
reaction
} from 'web-cell';

import { CollapseProps, Collapse } from './Collapse';

export const AccordionItem: FC<WebCellProps<HTMLDivElement>> = ({
className = '',
children,
...props
}) => (
<div className={`accordion-item ${className}`} {...props}>
{children}
</div>
);

export const AccordionHeader: FC<WebCellProps<HTMLHeadingElement>> = ({
className = '',
children,
onClick,
...props
}) => (
<h2 className={`accordion-header ${className}`} {...props}>
<button className="accordion-button" type="button" onClick={onClick}>
{children}
</button>
</h2>
);

export const AccordionBody: FC<CollapseProps> = ({
className = '',
children,
...props
}) => (
<Collapse className={`accordion-collapse ${className}`} {...props}>
<div className="accordion-body">{children}</div>
</Collapse>
);

export interface AccordionProps {
flush?: boolean;
alwaysOpen?: boolean;
}

export interface Accordion extends WebCell<AccordionProps> {}

@component({
tagName: 'accordion-box',
mode: 'open'
})
@observer
export class Accordion extends HTMLElement implements WebCell<AccordionProps> {
@attribute
@observable
accessor flush = false;

@attribute
@observable
accessor alwaysOpen = false;

connectedCallback() {
this.classList.add('accordion');
}

@reaction(({ flush }) => flush)
handleFlush(flush: boolean) {
this.classList.toggle('accordion-flush', flush);
}

@on('click', '.accordion-header')
handleClick(
_,
{ nextElementSibling: currentCollapse }: HTMLHeadingElement
) {
if (!this.alwaysOpen)
for (const collapse of this.querySelectorAll<HTMLDivElement>(
'.accordion-collapse'
))
if (collapse !== currentCollapse) {
collapse.classList.remove('show');
collapse.previousElementSibling.querySelector(
'button'
).ariaExpanded = 'false';
}
currentCollapse.classList.toggle('show');
currentCollapse.previousElementSibling.querySelector(
'button'
).ariaExpanded = 'false';
}

render() {
return <slot />;
}
}
8 changes: 7 additions & 1 deletion source/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,18 @@ export const Button: FC<ButtonProps> = ({
className,
href,
variant,
size,
active,
children,
...props
}) => {
const { disabled, tabIndex } = props,
Class = classNames('btn', variant && `btn-${variant}`, className);
Class = classNames(
'btn',
variant && `btn-${variant}`,
size && `btn-${size}`,
className
);

return href ? (
<a
Expand Down
26 changes: 26 additions & 0 deletions source/Collapse.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import classNames from 'classnames';
import { FC, WebCellProps } from 'web-cell';

export interface CollapseProps extends WebCellProps<HTMLElement> {
dimension?: 'width' | 'height';
in?: boolean;
}

export const Collapse: FC<CollapseProps> = ({
className,
dimension = 'width',
in: show,
children,
...props
}) => (
<div
className={classNames(
'collapse',
{ 'collapse-horizontal': dimension === 'height', show },
className
)}
{...props}
>
{children}
</div>
);
32 changes: 32 additions & 0 deletions source/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,38 @@ export const FloatingLabel: FC<FloatingLabelProps> = ({
</div>
);

export interface InputGroupProps extends WebCellProps<HTMLDivElement> {
size?: 'sm' | 'lg';
}

export const InputGroup: FC<InputGroupProps> = ({
className = '',
size,
children,
...props
}) => (
<div
className={classNames(
'input-group',
size && `input-group-${size}`,
className
)}
{...props}
>
{children}
</div>
);

export const InputGroupText: FC<WebCellProps<HTMLSpanElement>> = ({
className = '',
children,
...props
}) => (
<span className={`input-group-text ${className}`} {...props}>
{children}
</span>
);

export type FormControlTag = 'input' | 'textarea' | 'select';

export type FormControlProps<T extends FormControlTag> = WebCellProps &
Expand Down
57 changes: 40 additions & 17 deletions source/Icon.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from 'classnames';
import { WebCellProps } from 'web-cell';
import { FC, WebCellProps } from 'web-cell';

import { Color } from './type';

Expand All @@ -9,27 +9,50 @@ export interface IconProps extends WebCellProps {
size?: number;
}

export function Icon({
export const Icon: FC<IconProps> = ({
className,
style,
color,
name,
size,
children,
...rest
}: IconProps) {
return (
<i
className={classNames(
`bi-${name}`,
color && `text-${color}`,
className
)}
style={{
...style,
fontSize: size ? `${size}rem` : undefined
}}
{...rest}
/>
);
}) => (
<i
className={classNames(
`bi-${name}`,
color && `text-${color}`,
className
)}
style={{
...style,
fontSize: size ? `${size}rem` : undefined
}}
{...rest}
/>
);

export interface BGIconProps extends IconProps {
type?: 'square' | 'circle';
}

export const BGIcon: FC<BGIconProps> = ({
className = '',
type = 'square',
color = 'primary',
children,
...props
}) => (
<span
className={classNames(
'd-inline-block',
'p-3',
`bg-${color}`,
`rounded${type === 'square' ? '' : '-circle'}`,
className
)}
{...props}
>
<Icon color={color === 'light' ? 'dark' : 'light'} {...props} />
</span>
);
Loading

0 comments on commit 78e31ce

Please sign in to comment.