diff --git a/changelog/entries/1.21.0/feature/1918_restyle_switch_and_checkbox_components.json b/changelog/entries/1.21.0/feature/1918_restyle_switch_and_checkbox_components.json new file mode 100644 index 000000000..00382be2c --- /dev/null +++ b/changelog/entries/1.21.0/feature/1918_restyle_switch_and_checkbox_components.json @@ -0,0 +1,7 @@ +{ + "type": "feature", + "message": "Restyle switch and checkbox components", + "issue_number": 1918, + "bullet_points": [], + "created_at": "2023-10-10" +} \ No newline at end of file diff --git a/premium/web-frontend/modules/baserow_premium/components/views/BaserowLogoShareLinkOption.vue b/premium/web-frontend/modules/baserow_premium/components/views/BaserowLogoShareLinkOption.vue index 774eb7918..19baef3ea 100644 --- a/premium/web-frontend/modules/baserow_premium/components/views/BaserowLogoShareLinkOption.vue +++ b/premium/web-frontend/modules/baserow_premium/components/views/BaserowLogoShareLinkOption.vue @@ -6,18 +6,17 @@ @click="click" > <SwitchInput - large :value="!view.show_logo" :disabled="!hasPremiumFeatures" @input="update" + > + <img src="@baserow/modules/core/static/img/baserow-icon.svg" /> + <span> + {{ $t('shareLinkOptions.baserowLogo.label') }} + </span> + <i v-if="!hasPremiumFeatures" class="deactivated-label iconoir-lock"></i ></SwitchInput> - <img src="@baserow/modules/core/static/img/baserow-icon.svg" /> - <span> - {{ $t('shareLinkOptions.baserowLogo.label') }} - </span> - <i v-if="!hasPremiumFeatures" class="deactivated-label iconoir-lock"></i> - <PremiumModal v-if="!hasPremiumFeatures" ref="premiumModal" diff --git a/web-frontend/modules/core/assets/scss/components/form.scss b/web-frontend/modules/core/assets/scss/components/form.scss index 3ee224d66..2742ffcb0 100644 --- a/web-frontend/modules/core/assets/scss/components/form.scss +++ b/web-frontend/modules/core/assets/scss/components/form.scss @@ -194,23 +194,15 @@ .checkbox { position: relative; height: 28px; - line-height: 28px; - padding-left: 18px; cursor: pointer; user-select: none; - - &.checkbox--has-content { - padding-left: 24px; - } + @include flex-align-items(4px); &::before { - @include absolute(5px, auto, 0, 0); - content: ''; border: 1px solid $color-neutral-400; - width: 18px; - height: 18px; - line-height: 18px; + width: 20px; + height: 20px; text-align: center; background-color: $white; color: $color-success-600; @@ -226,14 +218,14 @@ color: $color-neutral-500; } } +} - &.checkbox--small::before { - @include absolute(6px, auto, 0, 0); +.checkbox__label { + color: $palette-neutral-900; + cursor: pointer; - width: 16px; - height: 16px; - line-height: 16px; - font-size: 12px; + .checkbox.active & { + color: $palette-neutral-1200; } } @@ -243,7 +235,7 @@ left: 2px; transform: translateY(-50%); color: $color-success-600; - font-size: 14px; + font-size: 16px; } .radio { @@ -324,109 +316,127 @@ .switch { position: relative; - line-height: 28px; - height: 28px; - padding-left: 22px; cursor: pointer; user-select: none; - - @include flex-align-items(4px); + height: 28px; + line-height: 28px; + @include flex-align-items(10px); &.switch--static { cursor: initial; user-select: initial; } - &.switch--has-content { - padding-left: 28px; - } - &::before { content: ''; - width: 22px; - height: 12px; - background-color: $color-neutral-200; - @include rounded($rounded-xl); - @include absolute(9px, auto, auto, 0); + + width: 24px; + height: 16px; + background-color: $color-neutral-600; } &::after { content: ''; border-radius: 100%; - width: 6px; - height: 6px; + width: 12px; + height: 12px; background-color: $white; - transition: left 0.085s ease-in; + transition: left 0.1s ease-in; + box-shadow: 0 1px 3px 0 rgba(7, 13, 16, 0.15), + 0 0 1px 0 rgba(7, 13, 16, 0.15); - @include absolute(12px, auto, auto, 4px); - } - - &.active { - &::before { - background-color: $color-success-500; - } - - &::after { - left: 12px; - } + @include absolute(8px, auto, auto, 2px); } &.unknown { &::before { - background-color: $color-warning-500; + background-color: $palette-yellow-500; + } + + &:hover { + &::before { + background-color: $palette-yellow-800; + } } &::after { - left: 8px; + left: 6px; + } + } + + &:hover { + &::before { + background-color: $color-neutral-500; + } + } + + &.active { + &::before { + background-color: $palette-green-500; + } + + &:hover { + &::before { + background-color: $palette-green-800; + } + } + + &::after { + left: 10px; + } + } + + &.switch--disabled { + cursor: not-allowed; + + &::before { + background-color: $palette-neutral-400; + } + + &::after { + box-shadow: none; } } &.switch--large { - padding-left: 28px; - - &.switch--has-content { - padding-left: 36px; - } - &::before { - top: 6px; - height: 16px; - width: 28px; + height: 24px; + width: 40px; } &::after { - top: 10px; - width: 7px; - height: 7px; + top: 4px; + width: 20px; + height: 20px; + } + + &.unknown { + &::after { + left: 8px; + } } &.active::after { left: 17px; } - - &.unknown::after { - left: 10.5px; - } - } - - &.switch--disabled { - cursor: inherit; - - &.active::before { - background-color: $color-neutral-600; - } - - &.unknown::before { - background-color: $color-neutral-400; - } } } -.switch__icon { - margin-right: 4px; - color: $color-neutral-600; - font-size: 16px; +.switch__label { + display: flex; + align-items: center; + gap: 5px; + color: $palette-neutral-900; + cursor: pointer; + + .switch--disabled & { + color: $palette-neutral-700; + } + + .switch.active & { + color: $palette-neutral-1200; + } } .error { diff --git a/web-frontend/modules/core/components/Checkbox.vue b/web-frontend/modules/core/components/Checkbox.vue index ad7e3ed0b..43205c4d7 100644 --- a/web-frontend/modules/core/components/Checkbox.vue +++ b/web-frontend/modules/core/components/Checkbox.vue @@ -1,7 +1,7 @@ <template> <div class="checkbox" :class="classNames" @click="toggle(value)"> <i v-if="value === true" class="checkbox__checked-icon iconoir-check"></i> - <slot></slot> + <label class="checkbox__label"><slot></slot></label> </div> </template> diff --git a/web-frontend/modules/core/components/SwitchInput.vue b/web-frontend/modules/core/components/SwitchInput.vue index ad88603d9..e9138d87a 100644 --- a/web-frontend/modules/core/components/SwitchInput.vue +++ b/web-frontend/modules/core/components/SwitchInput.vue @@ -1,6 +1,6 @@ <template> <div class="switch" :class="classNames" @click="toggle(value)"> - <slot></slot> + <label v-if="hasSlot" class="switch__label"> <slot></slot></label> </div> </template> @@ -37,6 +37,9 @@ export default { unknown: this.value !== true && this.value !== false, } }, + hasSlot() { + return !!this.$slots.default + }, }, methods: { toggle(value) { diff --git a/web-frontend/modules/core/pages/styleGuide.vue b/web-frontend/modules/core/pages/styleGuide.vue index 8e3cea970..5f368c56d 100644 --- a/web-frontend/modules/core/pages/styleGuide.vue +++ b/web-frontend/modules/core/pages/styleGuide.vue @@ -229,16 +229,19 @@ <div class="control__elements"> value: {{ switchValue }} <br /> - <br /> <SwitchInput v-model="switchValue"></SwitchInput> <SwitchInput v-model="switchValue">With text</SwitchInput> <SwitchInput v-model="switchUnknown">With text</SwitchInput> - <SwitchInput v-model="switchValue" :large="true"></SwitchInput> - <SwitchInput v-model="switchValue" :large="true"> - With text + <SwitchInput v-model="switchUnknown" large>With text</SwitchInput> + <SwitchInput v-model="switchValue" large></SwitchInput> + <SwitchInput v-model="switchValue" large> + Large with text </SwitchInput> - <SwitchInput v-model="switchUnknown" :large="true"> - With text + <SwitchInput v-model="switchUnknown" disabled> + Disabled + </SwitchInput> + <SwitchInput v-model="switchUnknown" disabled large> + Large disabled </SwitchInput> </div> </div> @@ -1623,10 +1626,7 @@ class="data-table__table-cell data-table__table-cell--sticky-left data-table__table-cell--header" > <div class="data-table__table-cell-head"> - <Checkbox - v-model="checkbox" - class="checkbox--small" - ></Checkbox> + <Checkbox v-model="checkbox"></Checkbox> </div> </th> <th @@ -1684,10 +1684,7 @@ class="data-table__table-cell data-table__table-cell--sticky-left" > <div class="data-table__table-cell-content"> - <Checkbox - v-model="checkbox" - class="checkbox--small" - ></Checkbox> + <Checkbox v-model="checkbox"></Checkbox> </div> </td> <td class="data-table__table-cell"> diff --git a/web-frontend/modules/database/components/settings/APIToken.vue b/web-frontend/modules/database/components/settings/APIToken.vue index 7830e0efe..c8aa891f9 100644 --- a/web-frontend/modules/database/components/settings/APIToken.vue +++ b/web-frontend/modules/database/components/settings/APIToken.vue @@ -117,10 +117,9 @@ :key="operation" class="api-token__permission" > - {{ operationName }} + <span>{{ operationName }}</span> <SwitchInput :value="isActive(operation)" - :large="true" @input="toggle(operation, $event)" ></SwitchInput> </div> @@ -140,7 +139,6 @@ > <SwitchInput :value="isDatabaseActive(database, operation)" - :large="true" @input="toggleDatabase(database, databases, operation, $event)" ></SwitchInput> </div> diff --git a/web-frontend/modules/database/components/view/ShareViewLink.vue b/web-frontend/modules/database/components/view/ShareViewLink.vue index a777f9d54..1f948d83c 100644 --- a/web-frontend/modules/database/components/view/ShareViewLink.vue +++ b/web-frontend/modules/database/components/view/ShareViewLink.vue @@ -63,21 +63,19 @@ <div class="view-sharing__option"> <SwitchInput :value="view.public_view_has_password" - :large="true" @input="toggleShareViewPassword" > + <i + class="view-sharing__option-icon" + :class="[ + view.public_view_has_password + ? 'iconoir-lock' + : 'iconoir-globe', + ]" + ></i> + <span>{{ $t(optionPasswordText) }}</span> </SwitchInput> - <i - class="view-sharing__option-icon" - :class="[ - view.public_view_has_password - ? 'iconoir-lock' - : 'iconoir-globe', - ]" - ></i> - <span>{{ $t(optionPasswordText) }}</span> - <a v-if="view.public_view_has_password" class="view-sharing__option-change-password" diff --git a/web-frontend/modules/database/components/view/form/FormViewField.vue b/web-frontend/modules/database/components/view/form/FormViewField.vue index fceb6aac8..6d03861e6 100644 --- a/web-frontend/modules/database/components/view/form/FormViewField.vue +++ b/web-frontend/modules/database/components/view/form/FormViewField.vue @@ -101,7 +101,6 @@ </div> <SwitchInput :value="fieldOptions.required" - :large="true" :disabled="readOnly" @input="$emit('updated-field-options', { required: $event })" >{{ $t('formViewField.required') }}</SwitchInput @@ -109,7 +108,6 @@ <SwitchInput v-if="allowedConditionalFields.length > 0" :value="fieldOptions.show_when_matching_conditions" - :large="true" :disabled="readOnly" @input="setShowWhenMatchingConditions($event)" >{{ $t('formViewField.showWhenMatchingConditions') }}</SwitchInput diff --git a/web-frontend/test/unit/database/components/export/__snapshots__/exportTableModal.spec.js.snap b/web-frontend/test/unit/database/components/export/__snapshots__/exportTableModal.spec.js.snap index 603f4788a..f1c98ba53 100644 --- a/web-frontend/test/unit/database/components/export/__snapshots__/exportTableModal.spec.js.snap +++ b/web-frontend/test/unit/database/components/export/__snapshots__/exportTableModal.spec.js.snap @@ -1495,7 +1495,12 @@ exports[`Preview exportTableModal Modal with no view 1`] = ` <i class="checkbox__checked-icon iconoir-check" /> - common.yes + + <label + class="checkbox__label" + > + common.yes + </label> </div> </div> </div> @@ -3026,7 +3031,12 @@ exports[`Preview exportTableModal Modal with view 1`] = ` <i class="checkbox__checked-icon iconoir-check" /> - common.yes + + <label + class="checkbox__label" + > + common.yes + </label> </div> </div> </div> diff --git a/web-frontend/test/unit/database/components/view/__snapshots__/viewFilterForm.spec.js.snap b/web-frontend/test/unit/database/components/view/__snapshots__/viewFilterForm.spec.js.snap index 125f03a20..0d5a5d59d 100644 --- a/web-frontend/test/unit/database/components/view/__snapshots__/viewFilterForm.spec.js.snap +++ b/web-frontend/test/unit/database/components/view/__snapshots__/viewFilterForm.spec.js.snap @@ -1048,7 +1048,11 @@ exports[`ViewFilterForm component Full view filter component 1`] = ` <div class="switch switch--has-content" > - viewFilterContext.disableAllFilters + <label + class="switch__label" + > + viewFilterContext.disableAllFilters + </label> </div> </div> </div> @@ -1466,7 +1470,11 @@ exports[`ViewFilterForm component Test rating filter 1`] = ` <div class="switch switch--has-content" > - viewFilterContext.disableAllFilters + <label + class="switch__label" + > + viewFilterContext.disableAllFilters + </label> </div> </div> </div> @@ -1884,7 +1892,11 @@ exports[`ViewFilterForm component Test rating filter 2`] = ` <div class="switch switch--has-content" > - viewFilterContext.disableAllFilters + <label + class="switch__label" + > + viewFilterContext.disableAllFilters + </label> </div> </div> </div>