-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Switch): introduce switch component (#190)
- Loading branch information
1 parent
fa38362
commit 8e33e98
Showing
9 changed files
with
641 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
describe('forms/Switch', () => { | ||
beforeEach(() => { | ||
cy.visit('/switches'); | ||
}); | ||
|
||
it('checks for switches', () => { | ||
cy.contains('h2[data-cy=switches]', 'Switches'); | ||
|
||
cy.get('input[type="checkbox"]').first().as('firstSwitch'); | ||
cy.get('input[type="checkbox"]').eq(1).as('secondSwitch'); | ||
cy.get('input[type="checkbox"][disabled]').first().as('disabledSwitch'); | ||
|
||
cy.get('@firstSwitch').should('not.be.checked'); | ||
cy.get('@firstSwitch').click(); | ||
cy.get('@firstSwitch').should('be.checked'); | ||
|
||
cy.get('@secondSwitch').should('not.be.checked'); | ||
cy.get('@secondSwitch').click(); | ||
cy.get('@secondSwitch').should('be.checked'); | ||
|
||
cy.get('@disabledSwitch').should('be.disabled'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
<script lang="ts" setup> | ||
import { RuiSwitch, type SwitchProps } from '@rotki/ui-library'; | ||
import { ref } from 'vue'; | ||
type SwitchData = SwitchProps & { | ||
value?: boolean; | ||
}; | ||
const switches = ref<SwitchData[]>([ | ||
{ value: false, color: 'primary' }, | ||
{ value: false, color: 'secondary' }, | ||
{ value: false, color: 'error' }, | ||
{ value: false, color: 'warning' }, | ||
{ value: false, color: 'info' }, | ||
{ value: false, color: 'success' }, | ||
{ value: true, color: 'primary' }, | ||
{ value: true, color: 'secondary' }, | ||
{ value: true, color: 'error' }, | ||
{ value: true, color: 'warning' }, | ||
{ value: true, color: 'info' }, | ||
{ value: true, color: 'success' }, | ||
{ value: false, color: 'primary', size: 'sm' }, | ||
{ value: false, color: 'secondary', size: 'sm' }, | ||
{ value: false, color: 'error', size: 'sm' }, | ||
{ value: false, color: 'warning', size: 'sm' }, | ||
{ value: false, color: 'info', size: 'sm' }, | ||
{ value: false, color: 'success', size: 'sm' }, | ||
{ value: false, color: 'primary', disabled: true }, | ||
{ value: false, color: 'secondary', disabled: true }, | ||
{ value: false, color: 'error', disabled: true }, | ||
{ value: false, color: 'warning', disabled: true }, | ||
{ value: false, color: 'info', disabled: true }, | ||
{ value: false, color: 'success', disabled: true }, | ||
{ value: true, color: 'primary', disabled: true }, | ||
{ value: true, color: 'secondary', disabled: true }, | ||
{ value: true, color: 'error', disabled: true }, | ||
{ value: true, color: 'warning', disabled: true }, | ||
{ value: true, color: 'info', disabled: true }, | ||
{ value: true, color: 'success', disabled: true }, | ||
{ value: false, color: 'primary', hint: 'Switch hint' }, | ||
{ value: false, color: 'secondary', hint: 'Switch hint' }, | ||
{ value: false, color: 'error', hint: 'Switch hint' }, | ||
{ value: false, color: 'warning', hint: 'Switch hint' }, | ||
{ value: false, color: 'info', hint: 'Switch hint' }, | ||
{ value: false, color: 'success', hint: 'Switch hint' }, | ||
{ value: false, color: 'primary', errorMessages: ['Switch error message'] }, | ||
{ | ||
value: false, | ||
color: 'secondary', | ||
errorMessages: 'Switch error message', | ||
}, | ||
{ value: false, color: 'error', errorMessages: ['Switch error message'] }, | ||
{ value: false, color: 'warning', errorMessages: 'Switch error message' }, | ||
{ value: false, color: 'info', errorMessages: ['Switch error message'] }, | ||
{ value: false, color: 'success', errorMessages: 'Switch error message' }, | ||
{ | ||
value: false, | ||
color: 'primary', | ||
successMessages: ['Switch success message'], | ||
}, | ||
{ | ||
value: false, | ||
color: 'secondary', | ||
successMessages: 'Switch success message', | ||
}, | ||
{ | ||
value: false, | ||
color: 'error', | ||
successMessages: ['Switch success message'], | ||
}, | ||
{ | ||
value: false, | ||
color: 'warning', | ||
successMessages: 'Switch success message', | ||
}, | ||
{ | ||
value: false, | ||
color: 'info', | ||
successMessages: ['Switch success message'], | ||
}, | ||
{ | ||
value: false, | ||
color: 'success', | ||
successMessages: 'Switch success message', | ||
}, | ||
]); | ||
</script> | ||
|
||
<template> | ||
<div> | ||
<h2 | ||
class="text-h4 mb-6" | ||
data-cy="switches" | ||
> | ||
Switches | ||
</h2> | ||
<div class="grid gap-3 grid-rows-2 grid-cols-6"> | ||
<RuiSwitch | ||
v-for="(sw, i) in switches" | ||
:key="i" | ||
v-model="sw.value" | ||
v-bind="sw" | ||
> | ||
<span class="capitalize"> {{ sw.color }} </span> | ||
</RuiSwitch> | ||
</div> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
import { type ComponentMountingOptions, mount } from '@vue/test-utils'; | ||
import Switch from '@/components/forms/switch/Switch.vue'; | ||
|
||
function createWrapper(options?: ComponentMountingOptions<typeof Switch>) { | ||
return mount(Switch, { ...options }); | ||
} | ||
|
||
describe('forms/Switch', () => { | ||
it('renders properly', () => { | ||
const label = 'Switch Label'; | ||
const wrapper = createWrapper({ | ||
slots: { | ||
default: () => label, | ||
}, | ||
}); | ||
expect(wrapper.text()).toContain(label); | ||
expect(wrapper.get('label > div > div').classes()).toMatch(/_toggle_/); | ||
}); | ||
|
||
it('passes disabled props', async () => { | ||
const wrapper = createWrapper(); | ||
expect(wrapper.find('input').attributes('disabled')).toBeUndefined(); | ||
expect(wrapper.get('label').classes()).not.toMatch(/_disabled_/); | ||
await wrapper.setProps({ disabled: true }); | ||
expect(wrapper.find('input').attributes('disabled')).toBeDefined(); | ||
expect(wrapper.get('label').classes()).toMatch(/_disabled_/); | ||
await wrapper.setProps({ disabled: false }); | ||
expect(wrapper.find('input').attributes('disabled')).toBeUndefined(); | ||
expect(wrapper.get('label').classes()).not.toMatch(/_disabled_/); | ||
}); | ||
|
||
it('passes color props', async () => { | ||
const wrapper = createWrapper({ props: { color: 'primary' } }); | ||
expect(wrapper.find('label').classes()).toMatch(/_primary_/); | ||
|
||
await wrapper.setProps({ color: 'secondary' }); | ||
expect(wrapper.find('label').classes()).toMatch(/_secondary_/); | ||
|
||
await wrapper.setProps({ color: 'error' }); | ||
expect(wrapper.find('label').classes()).toMatch(/_error_/); | ||
|
||
await wrapper.setProps({ color: 'success' }); | ||
expect(wrapper.find('label').classes()).toMatch(/_success_/); | ||
}); | ||
|
||
it('passes size props', async () => { | ||
const wrapper = createWrapper({ props: { size: 'sm' } }); | ||
expect(wrapper.find('label').classes()).toMatch(/_sm_/); | ||
}); | ||
|
||
it('passes hint props', async () => { | ||
const wrapper = createWrapper(); | ||
expect(wrapper.find('.details > div').exists()).toBeFalsy(); | ||
|
||
const hint = 'Switch Hints'; | ||
await wrapper.setProps({ hint }); | ||
expect(wrapper.find('.details > div').classes()).toMatch( | ||
/text-rui-text-secondary/, | ||
); | ||
expect(wrapper.find('.details > div').text()).toBe(hint); | ||
}); | ||
|
||
it('passes hint errorMessages', async () => { | ||
const wrapper = createWrapper(); | ||
expect(wrapper.find('.details > div').exists()).toBeFalsy(); | ||
|
||
const errorMessage = 'Switch Error Message'; | ||
await wrapper.setProps({ errorMessages: [errorMessage] }); | ||
expect(wrapper.find('.details > div').classes()).toMatch(/text-rui-error/); | ||
expect(wrapper.find('.details > div').text()).toBe(errorMessage); | ||
}); | ||
|
||
it('passes hideDetails', () => { | ||
const wrapper = createWrapper({ | ||
props: { | ||
hideDetails: true, | ||
hint: 'This hint should not be rendered', | ||
}, | ||
}); | ||
expect(wrapper.find('.details > div').exists()).toBeFalsy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { contextColors } from '@/consts/colors'; | ||
import { type Props, default as Switch } from './Switch.vue'; | ||
import type { Meta, StoryFn, StoryObj } from '@storybook/vue3'; | ||
|
||
type PropsAndLabel = Props & { label: string }; | ||
|
||
const render: StoryFn<PropsAndLabel> = args => ({ | ||
components: { Switch }, | ||
setup() { | ||
const modelValue = computed({ | ||
get() { | ||
return args.modelValue; | ||
}, | ||
set(val) { | ||
args.modelValue = val; | ||
}, | ||
}); | ||
|
||
return { args, modelValue }; | ||
}, | ||
template: `<Switch v-bind="args" v-model="modelValue"> | ||
{{ args.label }} | ||
</Switch>`, | ||
}); | ||
|
||
const meta: Meta<PropsAndLabel> = { | ||
argTypes: { | ||
color: { control: 'select', options: contextColors }, | ||
disabled: { control: 'boolean', table: { category: 'State' } }, | ||
errorMessages: { control: 'array', defaultValue: [] }, | ||
hideDetails: { control: 'boolean' }, | ||
hint: { control: 'text' }, | ||
label: { control: 'text' }, | ||
modelValue: { control: 'boolean' }, | ||
size: { control: 'select', options: ['medium', 'sm'] }, | ||
successMessages: { control: 'array', defaultValue: [] }, | ||
}, | ||
component: Switch, | ||
parameters: { | ||
docs: { | ||
controls: { exclude: ['default'] }, | ||
}, | ||
}, | ||
render, | ||
tags: ['autodocs'], | ||
title: 'Components/Forms/Switch', | ||
}; | ||
|
||
type Story = StoryObj<PropsAndLabel>; | ||
|
||
export const Checked: Story = { | ||
args: { | ||
modelValue: true, | ||
}, | ||
}; | ||
|
||
export const Small: Story = { | ||
args: { | ||
label: 'asdfa', | ||
size: 'sm', | ||
}, | ||
}; | ||
|
||
export const Primary: Story = { | ||
args: { | ||
color: 'primary', | ||
}, | ||
}; | ||
|
||
export const WithLabel: Story = { | ||
args: { | ||
label: 'With Label', | ||
}, | ||
}; | ||
|
||
export const Disabled: Story = { | ||
args: { | ||
disabled: true, | ||
label: 'Disabled', | ||
}, | ||
}; | ||
|
||
export const WithErrorMessage: Story = { | ||
args: { | ||
errorMessages: ['With error messages'], | ||
label: 'Label', | ||
}, | ||
}; | ||
|
||
export const WithSuccessMessage: Story = { | ||
args: { | ||
label: 'Label', | ||
successMessages: ['With success messages'], | ||
}, | ||
}; | ||
|
||
export const WithHint: Story = { | ||
args: { | ||
hint: 'With hint', | ||
label: 'Label', | ||
}, | ||
}; | ||
|
||
export const HideDetails: Story = { | ||
args: { | ||
hideDetails: true, | ||
hint: 'Hint (should be invisible)', | ||
label: 'Label', | ||
}, | ||
}; | ||
|
||
export default meta; |
Oops, something went wrong.