Skip to content

Commit 32e117e

Browse files
committed
feat(input): switch to translate instead of absolute
1 parent 473b4c7 commit 32e117e

File tree

3 files changed

+84
-64
lines changed

3 files changed

+84
-64
lines changed

demo/components/DemoInputs.svelte

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,19 +80,20 @@
8080
},
8181
8282
{
83-
label: 'Label',
83+
label: 'Floating',
8484
props: {
85-
label,
85+
label: 'Floating',
8686
placeholder: 'Placeholder',
87+
floating: true,
8788
prefix,
8889
suffix,
8990
suffixProps: { onclick },
9091
},
9192
},
9293
{
93-
label: 'Floating',
94+
label: 'Label',
9495
props: {
95-
label: 'Floating',
96+
label,
9697
placeholder: 'Placeholder',
9798
floating: true,
9899
prefix,
@@ -171,7 +172,10 @@
171172
</div>
172173

173174
{#snippet label()}
174-
<span style="color: lightseagreen">Custom label Snippet</span>
175+
<div>
176+
<div style="color: lightseagreen">Custom snippet label</div>
177+
<div style="color: cadetblue">With multiple lines</div>
178+
</div>
175179
{/snippet}
176180

177181
{#snippet text()}

src/lib/input/NeoInput.svelte

Lines changed: 72 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,15 @@
137137
138138
const affix = $derived(clearable || loading !== undefined);
139139
const close = $derived(clearable && (focused || hovered) && value?.length && !rest?.disabled && !rest?.readonly);
140+
const isFloating = $derived(floating && !focused && !value?.length);
141+
142+
let labelRef = $state<HTMLLabelElement>();
143+
let labelHeight = $state();
144+
145+
$effect(() => {
146+
if (!labelRef || !floating) return;
147+
labelHeight = `${labelRef?.clientHeight ?? 0}px`;
148+
});
140149
141150
const context: NeoInputContext = $derived({
142151
// Ref
@@ -230,8 +239,8 @@
230239
class:start
231240
class:skeleton
232241
class:disabled={rest?.disabled}
233-
class:raised={elevation > 3 || hover > 3}
234-
class:inset={elevation < -3 || hover < -3}
242+
class:raised={elevation > 3 || elevation + hover > 3}
243+
class:inset={elevation < -3 || elevation + hover < -3}
235244
class:flat={!elevation}
236245
class:hover-flat={hoverFlat}
237246
class:flat-hover={flatHover}
@@ -249,8 +258,8 @@
249258
>
250259
{@render before()}
251260
{#if label}
252-
<div class="neo-input-label-container" class:placeholder={floating && !focused && !value?.length}>
253-
<label for={id} class="neo-input-label" class:prefix class:rounded>
261+
<div class="neo-input-label-container" class:prefix class:placeholder={isFloating}>
262+
<label bind:this={labelRef} for={id} class="neo-input-label" class:prefix class:rounded style:--neo-input-label-height={labelHeight}>
254263
{#if typeof label === 'string'}
255264
{label}
256265
{:else}
@@ -268,47 +277,6 @@
268277
<style lang="scss">
269278
@use 'src/lib/styles/mixin' as mixin;
270279
271-
.neo-input-label-container {
272-
position: relative;
273-
flex: 1 1 auto;
274-
padding-top: calc(0.5rem + var(--neo-font-size-xs));
275-
276-
.neo-input-label {
277-
position: absolute;
278-
top: 0.3rem;
279-
left: 0;
280-
width: 100%;
281-
padding: 0.1rem 0.75rem;
282-
overflow: hidden;
283-
font-size: var(--neo-font-size-xs);
284-
white-space: nowrap;
285-
text-overflow: ellipsis;
286-
transition:
287-
color 0.3s ease,
288-
font-size 0.3s ease,
289-
top 0.3s ease,
290-
left 0.3s ease;
291-
pointer-events: unset;
292-
293-
&.prefix {
294-
padding-left: 0;
295-
}
296-
}
297-
298-
&.placeholder {
299-
.neo-input-label {
300-
top: calc(50% - 0.1rem - var(--neo-font-size-xs));
301-
color: var(--neo-input-placeholder-color, var(--neo-text-color-disabled));
302-
font-size: var(--neo-font-size);
303-
pointer-events: none;
304-
}
305-
306-
::placeholder {
307-
opacity: 0;
308-
}
309-
}
310-
}
311-
312280
.neo-input-group,
313281
.neo-input,
314282
.neo-input-clear,
@@ -450,6 +418,46 @@
450418
}
451419
}
452420
421+
.neo-input-label-container {
422+
flex: 1 1 auto;
423+
424+
.neo-input-label {
425+
display: flex;
426+
min-height: var(--neo-input-label-height);
427+
padding: 0.5rem 1rem 0;
428+
overflow: hidden;
429+
font-size: var(--neo-font-size-xs);
430+
text-wrap: stable;
431+
text-overflow: ellipsis;
432+
transition:
433+
width 0.3s ease,
434+
color 0.3s ease,
435+
font-size 0.3s ease,
436+
translate 0.3s ease;
437+
will-change: width, color, font-size, translate;
438+
439+
&.prefix {
440+
padding-left: 0.25rem;
441+
}
442+
}
443+
444+
.neo-input {
445+
padding: 0.25rem 1rem 0.75rem;
446+
}
447+
448+
&.placeholder {
449+
.neo-input-label {
450+
color: var(--neo-input-placeholder-color, var(--neo-text-color-disabled));
451+
font-size: var(--neo-font-size);
452+
translate: 0 calc(50% + 0.75rem - var(--neo-input-label-height) / 2);
453+
}
454+
455+
::placeholder {
456+
opacity: 0;
457+
}
458+
}
459+
}
460+
453461
.neo-input-group {
454462
margin: var(--neo-shadow-margin, 0.6rem);
455463
color: var(--neo-input-text-color, inherit);
@@ -463,7 +471,7 @@
463471
}
464472
465473
&.inset {
466-
padding: var(--neo-shadow-padding, 0.6rem);
474+
padding: 0.25rem;
467475
}
468476
469477
&.hover.flat-hover:hover,
@@ -480,18 +488,6 @@
480488
&.rounded {
481489
border-radius: var(--neo-border-radius-lg, 2rem);
482490
483-
.neo-input-label-container {
484-
padding-left: 0.5rem;
485-
486-
.neo-input-label {
487-
left: 0.5rem;
488-
489-
&:not(.prefix) {
490-
left: 0.75rem;
491-
}
492-
}
493-
}
494-
495491
.neo-input {
496492
padding: 0.75rem 1rem;
497493
border-radius: var(--neo-border-radius-lg, 2rem);
@@ -517,6 +513,24 @@
517513
padding-right: 0.75rem;
518514
}
519515
}
516+
517+
.neo-input-label-container {
518+
&:not(.prefix) {
519+
padding-left: 0.75rem;
520+
}
521+
522+
.neo-input-label {
523+
padding: 0.5rem 1rem 0;
524+
525+
&.prefix {
526+
padding-left: 0.125rem;
527+
}
528+
}
529+
530+
.neo-input {
531+
padding: 0.25rem 1rem 0.75rem;
532+
}
533+
}
520534
}
521535
522536
&.glass {

src/lib/styles/common/colors.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@
117117
--neo-dark-skeleton-color: var(--neo-grey-strong-dark);
118118
--neo-dark-skeleton-color-step: 0.05;
119119
--neo-dark-close-color: oklch(from var(--neo-red) calc(l + 0.15) c h);
120-
--neo-dark-close-color-focused: oklch(from var(--neo-red-75) calc(l + 0.3) c h);
120+
--neo-dark-close-color-hover: oklch(from var(--neo-red-75) calc(l + 0.3) c h);
121+
--neo-dark-close-color-focused: oklch(from var(--neo-red-50) calc(l + 0.3) c h);
121122
--neo-dark-close-bg-color-hover: oklch(from var(--neo-red-10) calc(l + 0.3) c h);
122123
--neo-dark-close-bg-color-focused: oklch(from var(--neo-red-5) calc(l + 0.3) c h);
123124

@@ -164,6 +165,7 @@
164165
--neo-skeleton-color: var(--neo-dark-skeleton-color);
165166
--neo-skeleton-color-step: var(--neo-dark-skeleton-color-step);
166167
--neo-close-color: var(--neo-dark-close-color);
168+
--neo-close-color-hover: var(--neo-dark-close-color-hover);
167169
--neo-close-color-focused: var(--neo-dark-close-color-focused);
168170
--neo-close-bg-color-hover: var(--neo-dark-close-bg-color-hover);
169171
--neo-close-bg-color-focused: var(--neo-dark-close-bg-color-focused);

0 commit comments

Comments
 (0)