Skip to content

Commit

Permalink
#306 - transform styles to tailwind classes
Browse files Browse the repository at this point in the history
  • Loading branch information
szafran89 committed Jun 4, 2021
1 parent aeabd22 commit ae592fe
Show file tree
Hide file tree
Showing 9 changed files with 346 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/atoms/blockquote/Blockquote.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.a-blockquote {
@apply my-2;
@apply py-2 pr-2 pl-4;
@apply border-l-4 border-solid border-light;
@apply border-l-4 border-solid border-gray-300;
@apply leading-relaxed;
}
21 changes: 21 additions & 0 deletions src/molecules/input/Input.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div :class="getClass('input')">
<!-- @slot Label (Named slot) -->
<slot name="label">
<a-label
v-if="label"
:class="getClass('input__label')"
:for="id"
>
{{ label }}
</a-label>
</slot>
<input
v-bind="$attrs"
v-on="listeners"
:value="value"
:id="id"
:class="getClass('input__field')"
>
<!-- @slot Icon (Named slot) -->
<slot name="icon" />
</div>
68 changes: 68 additions & 0 deletions src/molecules/input/Input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// @vue/component
import getClass from '../../../utils/helpers/get-class.js'

export default {
mixins: [getClass],
inheritAttrs: false,
props: {
/**
* Prop to handle v-model
*/
value: {
type: String,
default: null
},
/**
* Input id
*/
id: {
type: String,
required: true
},
/**
* Label text
*/
label: {
type: String,
default: null
}
},
computed: {
listeners () {
return {
...this.$listeners,
input: event => this.$emit('input', event.target.value)
}
}
},
data () {
return {
config: {
base: {
input: [
'relative'
],
input__field: [
'w-full', 'h-12',
'px-4'
]
},
primary: {
input__field: [
'border', 'border-solid', 'border-form',
'placeholder-primary'
]
},
inline: {
input: [
'flex', 'items-center'
],
input__label: [
'flex-shrink-0',
'm-4', 'mb-4'
]
}
}
}
}
}
50 changes: 50 additions & 0 deletions src/molecules/input/Input.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@import '../../../assets/styles/_globals.scss';

$input__margin : 0 0 $spacer--medium 0 !default;
$input-wrapper__label-margin : 0 $spacer--medium 0 0 !default;

$input__field-padding : 0 $spacer--large 0 $spacer--medium !default;
$input__field-width : 100% !default;
$input__field-height : 40px !default;
$input__field-border : 1px solid $form-elements-border-color !default;
$input__field-border-radius : $form-elements-radius !default;
$input__field-placeholder-color: $gray !default;

$input__icon-top : 20px !default;
$input__icon-right : 8px !default;

.a-input {
// position: relative;
// margin: $input__margin;

// &--inline {
// display: flex;
// align-items: center;

// .a-label {
// flex-shrink: 0;
// margin: $input-wrapper__label-margin;
// }
// }

// &__field {
// // width: $input__field-width;
// // height: $input__field-height;
// // padding: $input__field-padding;
// // border: $input__field-border;
// // border-radius: $input__field-border-radius;

// // &[type='search'] {
// // -webkit-appearance: textfield;

// // &::-webkit-search-decoration,
// // &::-webkit-search-cancel-button {
// // -webkit-appearance: none;
// // }
// // }

// // &::placeholder {
// // color: $input__field-placeholder-color;
// // }
// }
}
66 changes: 66 additions & 0 deletions src/molecules/input/Input.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { mount } from '@vue/test-utils'
import AInput from './Input.vue'

describe('Input', () => {
it('has default structure', () => {
const wrapper = mount(AInput, {
propsData: {
id: 'input-id'
}
})
const input = wrapper.find('.a-input__field')

expect(wrapper.is('div')).toBe(true)
expect(wrapper.classes()).toContain('a-input')
expect(wrapper.classes().length).toBe(1)

expect(input.is('input')).toBe(true)
expect(input.classes()).toContain('a-input__field')
expect(input.classes().length).toBe(1)
expect(input.attributes().id).toBeDefined()
expect(input.attributes().id).toBe('input-id')
})

it('renders email input when type set to email', () => {
const wrapper = mount(AInput, {
propsData: {
id: 'input-id',
type: 'email'
}
})

const input = wrapper.find('.a-input__field')
expect(input.attributes('type')).toBe('email')
})

it('renders slots content when passed', () => {
const wrapper = mount(AInput, {
propsData: {
id: 'input-id'
},
slots: {
label: '<label for="input-id">Alpaca UI</label>'
}
})

const label = wrapper.find('.a-input > label')

expect(label.exists()).toBe(true)
expect(label.text()).toEqual('Alpaca UI')
})

it('emits an input event', () => {
const wrapper = mount(AInput, {
propsData: {
id: 'input-id'
}
})

const textInput = wrapper.find('input')
textInput.setValue('Sample text')

expect(wrapper.emitted('input')).toBeTruthy()
expect(wrapper.emitted().input[0].length).toBe(1)
expect(wrapper.emitted().input[0][0]).toEqual('Sample text')
})
})
110 changes: 110 additions & 0 deletions src/molecules/input/Input.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import AInput from './Input.vue'
import AIcon from '../../atoms/icon/Icon.vue'
import AIconPerson from '../../atoms/icon/templates/IconPerson.vue'

export default {
title: 'Molecules/Input',
component: AInput,
argTypes: {
type: {
control: {
type: 'text'
}
},
placeholder: {
control: {
type: 'text'
}
},
label: {
control: {
type: 'text'
}
}
}
}

const args = {
type: 'text',
placeholder: 'Placeholder text...',
label: 'Label text'
}

const Template = (args, { argTypes }) => ({
components: { AInput },
props: Object.keys(argTypes),
data: () => {
return {
inputValue: ''
}
},
template: `
<div>
<a-input
v-model="inputValue"
id="input-id"
:type="type"
:placeholder="placeholder"
:label="label"
:variant="variant"
/>
<small class="flex mt-4">
Model: {{ inputValue }}
</small>
</div>
`
})

export const Default = Template.bind({})

export const Inline = Template.bind({})

export const WithSlots = (args, { argTypes }) => ({
components: { AInput, AIcon, AIconPerson },
props: Object.keys(argTypes),
data: () => {
return {
inputValue: '',
iconStyles: {
top: '29px',
right: '8px',
cursor: 'pointer'
}
}
},
template: `
<div>
<a-input
v-model="inputValue"
:label="label"
:type="type"
:placeholder="placeholder"
id="input-id-slit"
>
<template #icon>
<div
style="top: 29px;"
class="h-12 w-12 absolute flex items-center justify-center top-0 right-0"
>
<a-icon
title="Person icon"
@click.native="click"
>
<a-icon-person />
</a-icon>
</div>
</template>
</a-input>
<small class="flex mt-4">
Model: {{ inputValue }}
</small>
</div>
`
})

Default.args = args
Inline.args = {
...args,
variant: ['primary', 'inline']
}
WithSlots.args = args
14 changes: 14 additions & 0 deletions src/molecules/input/Input.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template src="./Input.html" />

<script>
import AInput from './Input.js'
import ALabel from '../../atoms/label/Label.vue'
export default {
name: 'AlpacaInput',
components: {
ALabel
},
mixins: [AInput]
}
</script>
27 changes: 15 additions & 12 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ module.exports = {
],
theme: {
extend: {
minHeight: {
24: '24px'
maxWidth: {
content: '1328px'
}
},
screens: {
Expand Down Expand Up @@ -52,29 +52,32 @@ module.exports = {
}),
borderColor: theme => ({
...theme('colors'),
default: theme('colors.gray.500'),
primary: theme('colors.gray.500'),
secondary: theme('colors.gray.600'),
dark: theme('colors.gray.800'),
light: theme('colors.gray.300')
// primary: theme('colors.gray.500'),
// secondary: theme('colors.gray.600'),
form: theme('colors.gray.500')
// default: theme('colors.gray.500'),
// dark: theme('colors.gray.800'),
// light: theme('colors.gray.300'),

}),
textColor: theme => ({
...theme('colors'),
default: theme('colors.gray.800'),
// default: theme('colors.gray.800'),
primary: theme('colors.gray.800'),
secondary: theme('colors.gray.600')
}),
placeholderColor: theme => ({
primary: theme('colors.gray.600'),
// secondary: theme('colors.gray.300')
}),
fill: theme => ({
...theme('colors'),
dark: theme('colors.gray.800'),
light: theme('colors.gray.200')
}),
outline: theme => ({
focus: [`2px solid ${theme('colors.bright-sky-blue')}`, '-1px']
}),
maxWidth: {
content: '1328px'
}
})
},
variants: {},
plugins: [],
Expand Down
Loading

0 comments on commit ae592fe

Please sign in to comment.