Skip to content

Commit

Permalink
Merge pull request #106 from josemarluedke/feat/core-close-button
Browse files Browse the repository at this point in the history
[core] Create CloseButton component
  • Loading branch information
josemarluedke committed Oct 23, 2020
2 parents a312036 + c1dae1b commit 3fcef9a
Show file tree
Hide file tree
Showing 11 changed files with 299 additions and 1 deletion.
27 changes: 27 additions & 0 deletions packages/core/addon/components/close-button.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<button
{{on "click" this.handleClick}}
type="button"
class="close-button {{this.sizeClass}}"
...attributes
>
{{#let (concat "close-button__icon " this.sizeClass "__icon") as |iconClassName|}}
{{#if hasBlock}}
{{yield iconClassName}}
{{else}}
<svg
class={{iconClassName}}
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
{{/if}}
{{/let}}

<VisuallyHidden>
{{if @title @title "Close"}}
</VisuallyHidden>
</button>
17 changes: 17 additions & 0 deletions packages/core/addon/components/close-button.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';

interface CloseButtonArgs {
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
onClick?: (event: Event) => void;
}

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

get sizeClass(): string {
return `close-button--${this.args.size || 'sm'}`;
}
}
1 change: 1 addition & 0 deletions packages/core/app/components/close-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@frontile/core/components/close-button';
15 changes: 14 additions & 1 deletion packages/core/ember-cli-build.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
'use strict';

const EmberAddon = require('ember-cli/lib/broccoli/ember-addon');
const path = require('path');

module.exports = function (defaults) {
const app = new EmberAddon(defaults, {
// Add options here
postcssOptions: {
compile: {
enabled: true,
cacheExclude: [],
cacheInclude: [/.*\.css$/, /(.*?)tailwind(.*)?\.js$/],
plugins: [
require('tailwindcss')(
path.join('tests', 'dummy', 'config', 'tailwind.config.js')
),
require('autoprefixer')
]
}
}
});

/*
Expand Down
4 changes: 4 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"postpack": "ember ts:clean"
},
"dependencies": {
"@frontile/tailwindcss-plugin-helpers": "^0.4.0",
"ember-cli-babel": "^7.23.0",
"ember-cli-htmlbars": "^5.2.0",
"ember-cli-typescript": "^4.0.0",
Expand All @@ -42,11 +43,13 @@
"@types/ember__test-helpers": "^1.7.3",
"@types/qunit": "^2.9.5",
"@types/rsvp": "^4.0.3",
"autoprefixer": "^9.8.0",
"broccoli-asset-rev": "^3.0.0",
"ember-auto-import": "^1.6.0",
"ember-cli": "3.22.0",
"ember-cli-dependency-checker": "^3.1.0",
"ember-cli-inject-live-reload": "^2.0.1",
"ember-cli-postcss": "^6.0.1",
"ember-cli-typescript-blueprints": "^3.0.0",
"ember-cli-uglify": "^3.0.0",
"ember-disable-prototype-extensions": "^1.1.3",
Expand All @@ -58,6 +61,7 @@
"ember-try": "^1.2.1",
"loader.js": "^4.7.0",
"qunit-dom": "^1.5.0",
"tailwindcss": "^1.9.5",
"typescript": "^4.0.3"
},
"engines": {
Expand Down
86 changes: 86 additions & 0 deletions packages/core/tailwind/default-options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
const defaultTheme = require('tailwindcss/resolveConfig')(
require('tailwindcss/defaultConfig')
).theme;

const defaultConfig = {
closeButton: {
backgroundColor: undefined,
hoverBackgroundColor: defaultTheme.colors.gray[100],
borderRadius: defaultTheme.borderRadius.full,
color: 'inherit',

sizes: {
xs: defaultTheme.fontSize.sm,
sm: defaultTheme.fontSize.base,
md: defaultTheme.fontSize.xl,
lg: defaultTheme.fontSize['2xl'],
xl: defaultTheme.fontSize['4xl']
}
}
};

function defaultOptions({ config }) {
return {
closeButton: {
baseStyle: {
backgroundColor: config.closeButton.backgroundColor,
borderRadius: config.closeButton.borderRadius,
transitionProperty: defaultTheme.transitionProperty.default,
transitionDuration: defaultTheme.transitionDuration[200],

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

'&:hover': {
backgroundColor: config.closeButton.hoverBackgroundColor
}
},
variants: {
xs: {
baseStyle: {
fontSize: config.closeButton.sizes.xs,
padding: defaultTheme.spacing[2]
}
},
sm: {
baseStyle: {
fontSize: config.closeButton.sizes.sm,
padding: defaultTheme.spacing[1]
}
},
md: {
baseStyle: {
fontSize: config.closeButton.sizes.md,
padding: defaultTheme.spacing[2]
}
},
lg: {
baseStyle: {
fontSize: config.closeButton.sizes.lg,
padding: defaultTheme.spacing[3]
}
},
xl: {
baseStyle: {
fontSize: config.closeButton.sizes.xl,
padding: defaultTheme.spacing[3]
}
}
},

parts: {
icon: {
height: '1em',
width: '1em'
}
}
}
};
}

module.exports = {
defaultConfig,
defaultOptions
};
49 changes: 49 additions & 0 deletions packages/core/tailwind/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const plugin = require('tailwindcss/plugin');
const {
resolve,
isEmpty,
kebabCase
} = require('@frontile/tailwindcss-plugin-helpers');

module.exports = plugin.withOptions(function (userConfig) {
return function ({ addComponents, theme }) {
const { options } = resolve(
'@frontile/core',
require('./default-options'),
userConfig,
theme
);

function addStylesFor(base, options, modifier = '') {
if (isEmpty(options)) {
return;
}

if (modifier !== '') {
base += `--${modifier}`;
}

const { baseStyle, variants, parts } = options;

addComponents({
[base]: baseStyle
});

if (!isEmpty(parts)) {
Object.keys(parts).forEach((key) => {
addComponents({
[`${base}__${kebabCase(key)}`]: parts[key]
});
});
}

if (!isEmpty(variants)) {
Object.keys(variants).forEach((key) => {
addStylesFor(base, variants[key], kebabCase(key));
});
}
}

addStylesFor('.close-button', options.closeButton);
};
});
5 changes: 5 additions & 0 deletions packages/core/tests/dummy/app/styles/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@tailwind base;

@tailwind components;

@tailwind utilities;
8 changes: 8 additions & 0 deletions packages/core/tests/dummy/app/templates/application.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,12 @@

<VisuallyHidden>This should not be shown</VisuallyHidden>

<div class="flex items-center mt-10 space-x-2">
<CloseButton @size="xs" />
<CloseButton @size="sm" />
<CloseButton @size="md" />
<CloseButton @size="lg" />
<CloseButton @size="xl" />
</div>

{{outlet}}
14 changes: 14 additions & 0 deletions packages/core/tests/dummy/config/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable node/no-extraneous-require */

module.exports = {
future: {
removeDeprecatedGapUtilities: true,
purgeLayersByDefault: true
},
purge: [],
theme: {
extend: {}
},
variants: {},
plugins: [require('@frontile/core/tailwind')]
};
74 changes: 74 additions & 0 deletions packages/core/tests/integration/components/close-button-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';

module('Integration | Component | CloseButton', function (hooks) {
setupRenderingTest(hooks);

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

assert.equal(this.element.textContent?.trim(), 'Close');

this.set('title', 'Fechar Menu');
assert.equal(this.element.textContent?.trim(), 'Fechar Menu');
});

test('it allows to yield', async function (assert) {
await render(
hbs`<CloseButton><div class="icon">Here is my icon</div></CloseButton>`
);
assert.dom('.close-button .icon').exists();

assert.dom('.close-button .icon').hasText('Here is my icon');
});

test('it yields the icon classes', async function (assert) {
await render(
hbs`<CloseButton as |class|><div class="icon">{{class}}</div></CloseButton>`
);
assert
.dom('.close-button .icon')
.hasText('close-button__icon close-button--sm__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 .close-button__icon')
.hasClass('close-button--sm__icon');

this.set('size', 'xm');
assert.dom('.close-button').hasClass('close-button--xm');
assert
.dom('.close-button .close-button__icon')
.hasClass('close-button--xm__icon');

this.set('size', 'sm');
assert.dom('.close-button').hasClass('close-button--sm');
assert
.dom('.close-button .close-button__icon')
.hasClass('close-button--sm__icon');

this.set('size', 'md');
assert.dom('.close-button').hasClass('close-button--md');
assert
.dom('.close-button .close-button__icon')
.hasClass('close-button--md__icon');

this.set('size', 'lg');
assert.dom('.close-button').hasClass('close-button--lg');
assert
.dom('.close-button .close-button__icon')
.hasClass('close-button--lg__icon');

this.set('size', 'xl');
assert.dom('.close-button').hasClass('close-button--xl');
assert
.dom('.close-button .close-button__icon')
.hasClass('close-button--xl__icon');
});
});

0 comments on commit 3fcef9a

Please sign in to comment.