Change 'revert' button to title case
- Switch 'revert' button text to title case for consistency and more formal and professional look. - Update related styles to reflect the new case usage. - Adjust tests to match the new button label casing. - Remove reduntant visibility switch between to elements to simpify the DOM and style rules.
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
v-model="isReverted"
|
v-model="isReverted"
|
||||||
:stop-click-propagation="true"
|
:stop-click-propagation="true"
|
||||||
:label="'revert'"
|
:label="'Revert'"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,15 @@
|
|||||||
>
|
>
|
||||||
<div class="toggle-animation">
|
<div class="toggle-animation">
|
||||||
<div class="circle" />
|
<div class="circle" />
|
||||||
<span class="label-off">{{ label }}</span>
|
<span
|
||||||
<span class="label-on">{{ label }}</span>
|
class="label"
|
||||||
|
:class="{
|
||||||
|
'label-off': !isChecked,
|
||||||
|
'label-on': isChecked,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -91,16 +98,6 @@ $gap : 0.25em;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin setVisibility($isVisible: true) {
|
|
||||||
@if $isVisible {
|
|
||||||
display: block;
|
|
||||||
opacity: 1;
|
|
||||||
} @else {
|
|
||||||
display: none;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle-switch {
|
.toggle-switch {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -155,34 +152,22 @@ $gap : 0.25em;
|
|||||||
left: $padded-left-offset;
|
left: $padded-left-offset;
|
||||||
background-color: $color-toggle-checked;
|
background-color: $color-toggle-checked;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.label-off {
|
.label {
|
||||||
@include setVisibility(false);
|
font-weight: bold;
|
||||||
|
transition: all 0.3s ease-out, color 0s;
|
||||||
|
&.label-off {
|
||||||
|
@include locateNearCircle('left');
|
||||||
|
padding-right: $padding-horizontal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label-on {
|
&.label-on {
|
||||||
@include setVisibility(true);
|
color: $color-text-checked;
|
||||||
|
|
||||||
|
@include locateNearCircle('right');
|
||||||
|
padding-left: $padding-horizontal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.label-off, .label-on {
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: 700;
|
|
||||||
transition: all 0.3s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label-off {
|
|
||||||
@include setVisibility(true);
|
|
||||||
@include locateNearCircle('left');
|
|
||||||
padding-right: $padding-horizontal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label-on {
|
|
||||||
@include setVisibility(false);
|
|
||||||
color: $color-text-checked;
|
|
||||||
|
|
||||||
@include locateNearCircle('right');
|
|
||||||
padding-left: $padding-horizontal;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
|
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
|
||||||
|
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';
|
||||||
import { openCard } from './support/interactions/card';
|
import { openCard } from './support/interactions/card';
|
||||||
|
|
||||||
describe('revert toggle', () => {
|
describe('revert toggle', () => {
|
||||||
@@ -21,7 +22,7 @@ describe('revert toggle', () => {
|
|||||||
it('should have revert label', () => {
|
it('should have revert label', () => {
|
||||||
cy.get('@toggleSwitch')
|
cy.get('@toggleSwitch')
|
||||||
.find('span')
|
.find('span')
|
||||||
.contains('revert');
|
.contains('revert', { matchCase: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render label completely without clipping', () => { // Regression test for a bug where label is partially rendered (clipped)
|
it('should render label completely without clipping', () => { // Regression test for a bug where label is partially rendered (clipped)
|
||||||
@@ -34,7 +35,11 @@ describe('revert toggle', () => {
|
|||||||
const expectedMinimumTextWidth = getTextWidth(text, font);
|
const expectedMinimumTextWidth = getTextWidth(text, font);
|
||||||
const containerWidth = $label.parent().width();
|
const containerWidth = $label.parent().width();
|
||||||
expectExists(containerWidth);
|
expectExists(containerWidth);
|
||||||
expect(expectedMinimumTextWidth).to.be.lessThan(containerWidth);
|
expect(expectedMinimumTextWidth).to.be.lessThan(containerWidth, formatAssertionMessage([
|
||||||
|
'Label is not rendered completely.',
|
||||||
|
`Expected minimum text width: ${expectedMinimumTextWidth}`,
|
||||||
|
`Actual text container width: ${containerWidth}`,
|
||||||
|
]));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,19 @@ import {
|
|||||||
} from '@vue/test-utils';
|
} from '@vue/test-utils';
|
||||||
import { nextTick, defineComponent } from 'vue';
|
import { nextTick, defineComponent } from 'vue';
|
||||||
import ToggleSwitch from '@/presentation/components/Scripts/View/Tree/NodeContent/ToggleSwitch.vue';
|
import ToggleSwitch from '@/presentation/components/Scripts/View/Tree/NodeContent/ToggleSwitch.vue';
|
||||||
|
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';
|
||||||
|
|
||||||
const DOM_INPUT_TOGGLE_CHECKBOX_SELECTOR = 'input.toggle-input';
|
const DOM_INPUT_TOGGLE_CHECKBOX_SELECTOR = 'input.toggle-input';
|
||||||
const DOM_INPUT_TOGGLE_LABEL_OFF_SELECTOR = 'span.label-off';
|
const DOM_INPUT_TOGGLE_LABEL_OFF_SELECTOR = '.label-off';
|
||||||
const DOM_INPUT_TOGGLE_LABEL_ON_SELECTOR = 'span.label-on';
|
const DOM_INPUT_TOGGLE_LABEL_ON_SELECTOR = '.label-on';
|
||||||
const DOM_INPUT_CIRCLE_ICON_SELECTOR = '.circle';
|
const DOM_INPUT_CIRCLE_ICON_SELECTOR = '.circle';
|
||||||
|
|
||||||
describe('ToggleSwitch.vue', () => {
|
describe('ToggleSwitch.vue', () => {
|
||||||
describe('initial state', () => {
|
describe('initial state', () => {
|
||||||
const testCases = [
|
const testScenarios: ReadonlyArray<{
|
||||||
|
readonly description: string;
|
||||||
|
readonly initialValue: boolean;
|
||||||
|
}> = [
|
||||||
{
|
{
|
||||||
initialValue: false,
|
initialValue: false,
|
||||||
description: 'unchecked for false',
|
description: 'unchecked for false',
|
||||||
@@ -23,7 +27,7 @@ describe('ToggleSwitch.vue', () => {
|
|||||||
description: 'checked for true',
|
description: 'checked for true',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
testCases.forEach(({ initialValue, description }) => {
|
testScenarios.forEach(({ initialValue, description }) => {
|
||||||
it(`renders as ${description}`, () => {
|
it(`renders as ${description}`, () => {
|
||||||
// arrange
|
// arrange
|
||||||
const expectedState = initialValue;
|
const expectedState = initialValue;
|
||||||
@@ -42,17 +46,23 @@ describe('ToggleSwitch.vue', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('label rendering', () => {
|
describe('label rendering', () => {
|
||||||
const testCases = [
|
const testScenarios: ReadonlyArray<{
|
||||||
|
readonly description: string;
|
||||||
|
readonly initialValue: boolean;
|
||||||
|
readonly selector: string;
|
||||||
|
}> = [
|
||||||
{
|
{
|
||||||
description: 'off label',
|
description: 'off label',
|
||||||
|
initialValue: false,
|
||||||
selector: DOM_INPUT_TOGGLE_LABEL_OFF_SELECTOR,
|
selector: DOM_INPUT_TOGGLE_LABEL_OFF_SELECTOR,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: 'on label',
|
description: 'on label',
|
||||||
|
initialValue: true,
|
||||||
selector: DOM_INPUT_TOGGLE_LABEL_ON_SELECTOR,
|
selector: DOM_INPUT_TOGGLE_LABEL_ON_SELECTOR,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
testCases.forEach(({ selector, description }) => {
|
testScenarios.forEach(({ selector, initialValue, description }) => {
|
||||||
it(description, () => {
|
it(description, () => {
|
||||||
// arrange
|
// arrange
|
||||||
const expectedLabel = 'expected-test-label';
|
const expectedLabel = 'expected-test-label';
|
||||||
@@ -61,18 +71,26 @@ describe('ToggleSwitch.vue', () => {
|
|||||||
const wrapper = mountComponent({
|
const wrapper = mountComponent({
|
||||||
properties: {
|
properties: {
|
||||||
label: expectedLabel,
|
label: expectedLabel,
|
||||||
|
modelValue: initialValue,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
const element = wrapper.find(selector);
|
const element = wrapper.find(selector);
|
||||||
|
expect(element.exists()).to.equal(true, formatAssertionMessage([
|
||||||
|
`Selector "${selector}" could not find the DOM element`,
|
||||||
|
`HTML:\n${wrapper.html()}`,
|
||||||
|
]));
|
||||||
expect(element.text()).to.equal(expectedLabel);
|
expect(element.text()).to.equal(expectedLabel);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('model updates', () => {
|
describe('model updates', () => {
|
||||||
describe('emission on change', () => {
|
describe('emission on change', () => {
|
||||||
const testCases = [
|
const testScenarios: ReadonlyArray<{
|
||||||
|
readonly initialValue: boolean;
|
||||||
|
readonly newCheckValue: boolean;
|
||||||
|
}> = [
|
||||||
{
|
{
|
||||||
initialValue: true,
|
initialValue: true,
|
||||||
newCheckValue: false,
|
newCheckValue: false,
|
||||||
@@ -82,7 +100,7 @@ describe('ToggleSwitch.vue', () => {
|
|||||||
newCheckValue: true,
|
newCheckValue: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
testCases.forEach(({ initialValue, newCheckValue }) => {
|
testScenarios.forEach(({ initialValue, newCheckValue }) => {
|
||||||
it(`emits ${newCheckValue} when initial value is ${initialValue} and checkbox value changes`, async () => {
|
it(`emits ${newCheckValue} when initial value is ${initialValue} and checkbox value changes`, async () => {
|
||||||
// arrange
|
// arrange
|
||||||
const wrapper = mountComponent({
|
const wrapper = mountComponent({
|
||||||
@@ -102,7 +120,10 @@ describe('ToggleSwitch.vue', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('no emission on identical value', () => {
|
describe('no emission on identical value', () => {
|
||||||
const testCases = [
|
const testScenarios: ReadonlyArray<{
|
||||||
|
readonly description: string;
|
||||||
|
readonly value: boolean;
|
||||||
|
}> = [
|
||||||
{
|
{
|
||||||
value: true,
|
value: true,
|
||||||
description: 'true',
|
description: 'true',
|
||||||
@@ -112,7 +133,7 @@ describe('ToggleSwitch.vue', () => {
|
|||||||
description: 'false',
|
description: 'false',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
testCases.forEach(({ value, description }) => {
|
testScenarios.forEach(({ value, description }) => {
|
||||||
it(`does not emit for an unchanged value of ${description}`, async () => {
|
it(`does not emit for an unchanged value of ${description}`, async () => {
|
||||||
// arrange
|
// arrange
|
||||||
const wrapper = mountComponent({
|
const wrapper = mountComponent({
|
||||||
|
|||||||
Reference in New Issue
Block a user