diff --git a/src/components/NcInputField/NcInputField.vue b/src/components/NcInputField/NcInputField.vue
index 6ed116ca16..a69e47f6b7 100644
--- a/src/components/NcInputField/NcInputField.vue
+++ b/src/components/NcInputField/NcInputField.vue
@@ -20,6 +20,9 @@ For a list of all available props and attributes, please check the [HTMLInputEle
@@ -34,9 +37,6 @@ For a list of all available props and attributes, please check the [HTMLInputEle
aria-live="polite"
:class="[inputClass,
{
- 'input-field__input--trailing-icon': showTrailingButton || hasTrailingIcon,
- 'input-field__input--leading-icon': hasLeadingIcon,
- 'input-field__input--label-outside': labelOutside,
'input-field__input--success': success,
'input-field__input--error': error,
}]"
@@ -46,10 +46,6 @@ For a list of all available props and attributes, please check the [HTMLInputEle
@@ -330,34 +326,45 @@ export default {
.input-field {
--input-border-radius: var(--border-radius-element, var(--border-radius-large));
- // styles
+ // The padding before the input can start (leading button or border)
+ --input-padding-start: var(--border-radius-large);
+ // The padding where the input has to end (trailing button or border)
+ --input-padding-end: var(--border-radius-large);
+ // positional styles
position: relative;
width: 100%;
margin-block-start: 6px; // for the label in active state
- &__main-wrapper {
- height: var(--default-clickable-area);
- position: relative;
- }
-
&--disabled {
opacity: 0.4;
filter: saturate(0.4);
}
+ // If there is no internal label we reset the margin reserved for it
+ &--label-outside {
+ margin-block-start: 0;
+ }
+
+ &--leading-icon {
+ --input-padding-start: calc(var(--default-clickable-area) - var(--default-grid-baseline));
+ }
+
+ &--trailing-icon {
+ --input-padding-end: calc(var(--default-clickable-area) - var(--default-grid-baseline));
+ }
+
&--pill {
--input-border-radius: var(--border-radius-pill);
}
- &__input {
- margin: 0;
- padding-inline: 12px 6px; // align with label 8px margin label + 6px padding label - 2px border input
- height: var(--default-clickable-area) !important;
- width: 100%;
-
- font-size: var(--default-font-size);
- text-overflow: ellipsis;
+ &__main-wrapper {
+ height: var(--default-clickable-area);
+ position: relative;
+ }
+ &__input {
+ // If border width differes between focused and unfocused we need to compensate to prevent jumping
+ --input-border-width-offset: calc(var(--border-width-input-focused, 2px) - var(--border-width-input, 2px));
background-color: var(--color-main-background);
color: var(--color-main-text);
border: var(--border-width-input, 2px) solid var(--color-border-maxcontrast);
@@ -368,10 +375,14 @@ export default {
-moz-appearance: textfield !important;
appearance: textfield !important;
- // Center text if external label is used
- &--label-outside {
- padding-block: 0;
- }
+ font-size: var(--default-font-size);
+ text-overflow: ellipsis;
+
+ height: calc(var(--default-clickable-area) - 2 * var(--input-border-width-offset)) !important;
+ width: 100%;
+
+ padding-inline: calc(var(--input-padding-start) + var(--input-border-width-offset)) calc(var(--input-padding-end) + var(--input-border-width-offset));
+ padding-block: var(--input-border-width-offset);
&:active:not([disabled]),
&:hover:not([disabled]),
@@ -379,6 +390,8 @@ export default {
border-width: var(--border-width-input-focused, 2px);
border-color: var(--color-main-text) !important;
box-shadow: 0 0 0 2px var(--color-main-background) !important;
+ // Reset padding offset when focused
+ --input-border-width-offset: 0px;
}
&:focus + .input-field__label,
@@ -386,11 +399,6 @@ export default {
color: var(--color-main-text);
}
- // Hide placeholder while not focussed -> show label instead (only if internal label is used)
- &:not(:focus,&--label-outside)::placeholder {
- opacity: 0;
- }
-
&:focus {
cursor: text;
}
@@ -403,14 +411,6 @@ export default {
box-shadow: unset !important; // Override server rules
}
- &--leading-icon {
- padding-inline-start: var(--default-clickable-area);
- }
-
- &--trailing-icon {
- padding-inline-end: var(--default-clickable-area);
- }
-
&--success {
border-color: var(--color-success) !important; //Override hover border color
&:focus-visible {
@@ -426,12 +426,19 @@ export default {
}
}
+ // Hide placeholder while not focussed -> show label instead (only if internal label is used)
+ &:not(&--label-outside) &__input:not(:focus)::placeholder {
+ opacity: 0;
+ }
+
&__label {
+ --input-label-font-size: var(--default-font-size);
position: absolute;
- margin-inline: 14px 0;
+ margin-inline: var(--input-padding-start) var(--input-padding-end);
max-width: fit-content;
+ font-size: var(--input-label-font-size);
inset-block-start: calc((var(--default-clickable-area) - var(--default-line-height)) / 2); // center the label vertically
- inset-inline: 0;
+ inset-inline: var(--border-width-input-focused, 2px);
// Fix color so that users do not think the input already has content
color: var(--color-text-maxcontrast);
// only one line labels are allowed
@@ -442,31 +449,21 @@ export default {
pointer-events: none;
// Position transition
transition: height var(--animation-quick), inset-block-start var(--animation-quick), font-size var(--animation-quick), color var(--animation-quick), background-color var(--animation-quick) var(--animation-slow);
-
- &--leading-icon {
- margin-inline-start: var(--default-clickable-area);
- }
-
- &--trailing-icon {
- margin-inline-end: var(--default-clickable-area);
- }
}
&__input:focus + &__label,
&__input:not(:placeholder-shown) + &__label {
- inset-block-start: -10px;
+ --input-label-font-size: 13px; // minimum allowed font size for accessibility
line-height: 1.5; // minimum allowed line height for accessibility
- font-size: 13px; // minimum allowed font size for accessibility
+ // 1.5 * font-size = line-height; line-height / 2 for centering and make it negative as we need to move outside the element
+ inset-block-start: calc(-1.5 * var(--input-label-font-size) / 2);
font-weight: 500;
border-radius: var(--default-grid-baseline) var(--default-grid-baseline) 0 0;
background-color: var(--color-main-background);
- padding-inline: 5px;
- margin-inline-start: 9px;
+ padding-inline: var(--default-grid-baseline);
+ margin-inline: calc(var(--input-padding-start) - var(--default-grid-baseline)) calc(var(--input-padding-end) - var(--default-grid-baseline));
transition: height var(--animation-quick), inset-block-start var(--animation-quick), font-size var(--animation-quick), color var(--animation-quick);
- &--leading-icon {
- margin-inline-start: 41px;
- }
}
&__icon {
@@ -478,14 +475,14 @@ export default {
justify-content: center;
opacity: 0.7;
+ inset-block-end: 0;
+
&--leading {
- inset-block-end: 0;
- inset-inline-start: 2px;
+ inset-inline-start: 0px;
}
&--trailing {
- inset-block-end: 0;
- inset-inline-end: 2px;
+ inset-inline-end: 0px;
}
}