Skip to content

Commit

Permalink
Merge pull request #107 from josemarluedke/feat/overlay-close-button
Browse files Browse the repository at this point in the history
Migrate Modal & Drawer to use CloseButton component from core
  • Loading branch information
josemarluedke committed Oct 23, 2020
2 parents 3fcef9a + 4533fa5 commit 5a4a915
Show file tree
Hide file tree
Showing 14 changed files with 154 additions and 117 deletions.
2 changes: 1 addition & 1 deletion packages/core/addon/components/close-button.hbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<button
{{on "click" this.handleClick}}
type="button"
class="close-button {{this.sizeClass}}"
class="close-button {{this.sizeClass}} {{@class}}"
...attributes
>
{{#let (concat "close-button__icon " this.sizeClass "__icon") as |iconClassName|}}
Expand Down
17 changes: 14 additions & 3 deletions packages/core/addon/components/close-button.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';

interface CloseButtonArgs {
export interface CloseButtonArgs {
/*
* The icon size
*
* @defaultValue `lg`
*/
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';

/*
* The function to call when button is clicked
*/
onClick?: (event: Event) => void;
}

export default class CloseButton extends Component<CloseButtonArgs> {
@action handleClick(event: Event): void {
this.args.onClick?.(event);
if (typeof this.args.onClick === 'function') {
this.args.onClick(event);
}
}

get sizeClass(): string {
return `close-button--${this.args.size || 'sm'}`;
return `close-button--${this.args.size || 'md'}`;
}
}
11 changes: 8 additions & 3 deletions packages/core/tests/integration/components/close-button-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ module('Integration | Component | CloseButton', function (hooks) {
);
assert
.dom('.close-button .icon')
.hasText('close-button__icon close-button--sm__icon');
.hasText('close-button__icon close-button--md__icon');
});

test('it adds size classes', async function (assert) {
await render(hbs`<CloseButton @size={{this.size}} />`);

assert.dom('.close-button').hasClass('close-button--sm');
assert.dom('.close-button').hasClass('close-button--md');
assert
.dom('.close-button .close-button__icon')
.hasClass('close-button--sm__icon');
.hasClass('close-button--md__icon');

this.set('size', 'xm');
assert.dom('.close-button').hasClass('close-button--xm');
Expand Down Expand Up @@ -71,4 +71,9 @@ module('Integration | Component | CloseButton', function (hooks) {
.dom('.close-button .close-button__icon')
.hasClass('close-button--xl__icon');
});

test('it allows to pass @class for component curlying', async function (assert) {
await render(hbs`<CloseButton @class="some-class" />`);
assert.dom('.close-button').hasClass('some-class');
});
});
19 changes: 8 additions & 11 deletions packages/overlays/addon/components/drawer/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,16 @@
aria-labelledby={{this.headerId}}
...attributes
>
{{#unless this.preventClosing}}
<button
{{on "click" this.handleClose}}
type="button"
class="modal__close-btn"
data-test-id="drawer-close-btn"
>
<span class="modal__close-btn--icon"></span>
<VisuallyHidden>Close</VisuallyHidden>
</button>
{{/unless}}
{{#if this.showCloseButton}}
<CloseButton
@onClick={{this.handleClose}}
@size={{@closeButtonSize}}
class="drawer__close-btn"
/>
{{/if}}

{{yield (hash
CloseButton=(component "close-button" onClick=this.handleClose class="drawer__close-btn")
Header=(component "drawer/header" labelledById=this.headerId)
Body=(component "drawer/body")
Footer=(component "drawer/footer")
Expand Down
19 changes: 19 additions & 0 deletions packages/overlays/addon/components/drawer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Component from '@glimmer/component';
import { action } from '@ember/object';
import { guidFor } from '@ember/object/internals';
import { OverlayArgs } from '../overlay';
import type { CloseButtonArgs } from '@frontile/core/components/close-button';

interface DrawerArgs extends Omit<OverlayArgs, 'contentTransitionName'> {
/*
Expand All @@ -18,6 +19,18 @@ interface DrawerArgs extends Omit<OverlayArgs, 'contentTransitionName'> {
*/
allowClosing?: boolean;

/* If set to false, the close button will not be displayed.
*
*
* @defaultValue true
*/
allowCloseButton?: boolean;

/*
* The Close Button size.
*/
closeButtonSize?: CloseButtonArgs['size'];

/*
* The Drawer can appear from any side of the screen. The 'placement'
* option allows to choose where it appears from.
Expand All @@ -41,6 +54,12 @@ export default class Drawer extends Component<DrawerArgs> {
return this.args.allowClosing === false;
}

get showCloseButton(): boolean {
return (
this.args.allowClosing !== false && this.args.allowCloseButton !== false
);
}

@action handleClose(): void {
if (typeof this.args.onClose === 'function') {
this.args.onClose();
Expand Down
16 changes: 7 additions & 9 deletions packages/overlays/addon/components/modal/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,16 @@
aria-labelledby={{this.headerId}}
...attributes
>
{{#unless this.preventClosing}}
<button
{{on "click" this.handleClose}}
type="button"
{{#if this.showCloseButton}}
<CloseButton
@onClick={{this.handleClose}}
@size={{@closeButtonSize}}
class="modal__close-btn"
>
<span class="modal__close-btn--icon"></span>
<VisuallyHidden>Close</VisuallyHidden>
</button>
{{/unless}}
/>
{{/if}}

{{yield (hash
CloseButton=(component "close-button" onClick=this.handleClose class="modal__close-btn")
Header=(component "modal/header" labelledById=this.headerId)
Body=(component "modal/body")
Footer=(component "modal/footer")
Expand Down
19 changes: 19 additions & 0 deletions packages/overlays/addon/components/modal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Component from '@glimmer/component';
import { action } from '@ember/object';
import { guidFor } from '@ember/object/internals';
import { OverlayArgs } from '../overlay';
import type { CloseButtonArgs } from '@frontile/core/components/close-button';

interface ModalArgs extends Omit<OverlayArgs, 'contentTransitionName'> {
/*
Expand All @@ -18,6 +19,18 @@ interface ModalArgs extends Omit<OverlayArgs, 'contentTransitionName'> {
*/
allowClosing?: boolean;

/* If set to false, the close button will not be displayed.
*
*
* @defaultValue true
*/
allowCloseButton?: boolean;

/*
* The Close Button size.
*/
closeButtonSize?: CloseButtonArgs['size'];

/*
* If set to true, the modal will be vertically centered
* @defaultValue false
Expand All @@ -39,6 +52,12 @@ export default class Modal extends Component<ModalArgs> {
return this.args.allowClosing === false;
}

get showCloseButton(): boolean {
return (
this.args.allowClosing !== false && this.args.allowCloseButton !== false
);
}

@action handleClose(): void {
if (typeof this.args.onClose === 'function') {
this.args.onClose();
Expand Down
42 changes: 13 additions & 29 deletions packages/overlays/tailwind/default-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ const defaultTheme = require('tailwindcss/resolveConfig')(
const modalAndDrawerDefaultConfig = {
backgroundColor: defaultTheme.colors.white,
boxShadow: defaultTheme.boxShadow.default,

closeBtnHoverBgColor: defaultTheme.colors.gray[100],
iconColor: defaultTheme.colors.black,
closeBtnMargin: defaultTheme.spacing[2],

header: {
Expand Down Expand Up @@ -135,7 +132,8 @@ function defaultOptions({ config }) {
marginTop: defaultTheme.spacing[24],
width: defaultTheme.width.full,
outline: 'none',
overflow: 'hidden'
overflow: 'hidden',
zIndex: 0
},

centered: {
Expand All @@ -144,34 +142,12 @@ function defaultOptions({ config }) {
},

closeBtn: {
display: 'flex',
position: 'absolute',
fontSize: defaultTheme.fontSize.xl,
padding: defaultTheme.spacing[2],
top: config.modal.closeBtnMargin,
right: config.modal.closeBtnMargin,
transitionProperty: defaultTheme.transitionProperty.default,
transitionDuration: defaultTheme.transitionDuration[200],
borderRadius: defaultTheme.borderRadius.full,

'&:hover': {
backgroundColor: config.modal.closeBtnHoverBgColor
},

'&.focus-visible:focus': {
outline: 'none',
boxShadow: defaultTheme.boxShadow.outline
},

icon: {
height: '1em',
width: '1em',
backgroundRepeat: 'no-repeat',
iconColor: config.modal.iconColor,
icon: (iconColor) =>
`<svg fill="none" stroke="${iconColor}" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M6 18L18 6M6 6l12 12"></path></svg>`
}
zIndex: 1
},

header: {
fontWeight: defaultTheme.fontWeight.bold,
fontSize: defaultTheme.fontSize.xl,
Expand Down Expand Up @@ -225,7 +201,15 @@ function defaultOptions({ config }) {
backgroundColor: config.drawer.backgroundColor,
width: '100%',
height: '100%',
boxShadow: config.drawer.boxShadow.default
boxShadow: config.drawer.boxShadow.default,
zIndex: 0
},

closeBtn: {
position: 'absolute',
top: config.drawer.closeBtnMargin,
right: config.drawer.closeBtnMargin,
zIndex: 1
},

header: {
Expand Down
47 changes: 13 additions & 34 deletions packages/overlays/tailwind/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ const plugin = require('tailwindcss/plugin');
const {
resolve,
isEmpty,
svgToDataUri,
replaceIconDeclarations,
kebabCase
} = require('@frontile/tailwindcss-plugin-helpers');

Expand Down Expand Up @@ -86,57 +84,38 @@ module.exports = plugin.withOptions(function (userConfig) {
[`.modal--centered`]: centered,
[`.modal__header`]: header,
[`.modal__footer`]: footer,
[`.modal__body`]: body
[`.modal__body`]: body,
[`.modal__close-btn`]: closeBtn
});

Object.keys(sizes || {}).forEach((key) => {
addComponents({
[`.modal--${key}`]: sizes[key]
});
});

if (!isEmpty(closeBtn)) {
const { icon: btnIcon } = closeBtn;

if (btnIcon) {
delete closeBtn.icon;
}

addComponents({
[`.modal__close-btn`]: closeBtn
});

if (!isEmpty(btnIcon)) {
addComponents(
replaceIconDeclarations(
{
[`.modal__close-btn--icon`]: btnIcon
},
({ icon = btnIcon.icon, iconColor = btnIcon.iconColor }) => {
return {
backgroundImage: `url("${svgToDataUri(
typeof icon === 'function' ? icon(iconColor) : icon
)}")`
};
}
)
);
}
}
}

function addDrawer(options) {
if (isEmpty(options)) {
return;
}

const { header, body, footer, drawer, placements, sizes } = options;
const {
header,
body,
footer,
drawer,
placements,
sizes,
closeBtn
} = options;

addComponents({
['.drawer']: drawer,
['.drawer__header']: header,
['.drawer__footer']: footer,
['.drawer__body']: body
['.drawer__body']: body,
[`.drawer__close-btn`]: closeBtn
});

Object.keys(placements).forEach((key) => {
Expand Down
10 changes: 9 additions & 1 deletion packages/overlays/tests/dummy/app/components/demo-drawer.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,17 @@
@size={{this.size}}
@placement={{this.placement}}
@disableFocusTrap={{true}}
@allowCloseButton={{false}}
as |d|
>
<d.Header>Header</d.Header>
<d.Header>
Header

<d.CloseButton
@size="lg"
class="relative inset-auto ml-6 text-blue-500 bg-gray-200 rounded-md hover:bg-gray-500"
/>
</d.Header>
<d.Body>
In Place
</d.Body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = {
},
variants: {},
plugins: [
require('@frontile/core/tailwind'),
require('@frontile/overlays/tailwind'),
require('@frontile/buttons/tailwind'),
require('@frontile/forms/tailwind')
Expand Down
Loading

0 comments on commit 5a4a915

Please sign in to comment.