Skip to content

Commit c98d566

Browse files
authored
Revert "ChipInput Updates (#2612)" (#2619)
This reverts commit 46d89d6.
1 parent be8b458 commit c98d566

File tree

4 files changed

+44
-93
lines changed

4 files changed

+44
-93
lines changed

src/lib/holocene/input/chip-input.stories.svelte

+1-13
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
removeChipButtonLabel: 'Remove',
1919
labelHidden: false,
2020
validator: isEmail,
21-
maxLength: undefined,
2221
chips: ['[email protected]'],
2322
},
2423
argTypes: {
@@ -31,7 +30,6 @@
3130
labelHidden: { name: 'Label Hidden', control: 'boolean' },
3231
chips: { name: 'Chips', table: { disable: true } },
3332
validator: { table: { disable: true } },
34-
maxLength: { name: 'Maximum Length', control: 'number' },
3533
removeChipButtonLabel: {
3634
name: 'Aria label for remove button',
3735
control: 'text',
@@ -82,21 +80,11 @@
8280
/>
8381

8482
<Story
85-
name="Error"
83+
name="Invalid"
8684
play={async ({ canvasElement, id }) => {
8785
const canvas = within(canvasElement);
8886
const input = canvas.getByTestId(id);
8987
await userEvent.type(input, 'bonbon');
9088
await userEvent.keyboard('{enter}');
9189
}}
9290
/>
93-
94-
<Story
95-
name="With Maximum Length"
96-
args={{ maxLength: 10 }}
97-
play={async ({ canvasElement, id }) => {
98-
const canvas = within(canvasElement);
99-
const input = canvas.getByTestId(id);
100-
await userEvent.click(input);
101-
}}
102-
/>

src/lib/holocene/input/chip-input.svelte

+41-67
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script lang="ts">
22
import { writable } from 'svelte/store';
33
4-
import { afterUpdate } from 'svelte';
4+
import { afterUpdate, onDestroy } from 'svelte';
55
import { twMerge as merge } from 'tailwind-merge';
66
77
import Chip from '$lib/holocene/chip.svelte';
@@ -19,10 +19,10 @@
1919
export let validator: (value: string) => boolean = () => true;
2020
export let removeChipButtonLabel: string | ((chipValue: string) => string);
2121
export let external = false;
22-
export let maxLength = 0;
2322
2423
const values = writable<string[]>(chips);
2524
let displayValue = '';
25+
let shouldScrollToInput = false;
2626
let inputContainer: HTMLDivElement;
2727
let input: HTMLInputElement;
2828
@@ -32,8 +32,25 @@
3232
let className = '';
3333
export { className as class };
3434
35+
const scrollToInput = () => {
36+
let rect = input.getBoundingClientRect();
37+
inputContainer.scrollTo(rect.x, rect.y);
38+
shouldScrollToInput = false;
39+
};
40+
41+
const unsubscribe = values.subscribe((updatedChips) => {
42+
shouldScrollToInput = updatedChips.length > chips.length;
43+
chips = updatedChips;
44+
});
45+
3546
afterUpdate(() => {
36-
input.scrollIntoView();
47+
if (shouldScrollToInput) {
48+
scrollToInput();
49+
}
50+
});
51+
52+
onDestroy(() => {
53+
unsubscribe();
3754
});
3855
3956
const handleKeydown = (e: KeyboardEvent) => {
@@ -57,17 +74,11 @@
5774
5875
const handlePaste = (e: ClipboardEvent) => {
5976
e.preventDefault();
60-
if (maxLength && $values.length >= maxLength) return;
6177
const clipboardContents = e.clipboardData.getData('text/plain');
62-
let newValues = clipboardContents
63-
.split(',')
64-
.map((content) => content.trim());
65-
66-
if (maxLength) {
67-
newValues = newValues.slice(0, maxLength - $values.length);
68-
}
69-
70-
values.update((previous) => [...previous, ...newValues]);
78+
values.update((previous) => [
79+
...previous,
80+
...clipboardContents.split(',').map((content) => content.trim()),
81+
]);
7182
};
7283
7384
const handleBlur = () => {
@@ -86,14 +97,15 @@
8697
};
8798
</script>
8899

89-
<div
90-
class={merge(
91-
'group flex flex-col gap-1',
92-
disabled && 'cursor-not-allowed',
93-
className,
94-
)}
95-
>
96-
<Label {required} {label} {disabled} hidden={labelHidden} for={id} />
100+
<div class={merge(disabled && 'cursor-not-allowed', className)}>
101+
<Label
102+
class="pb-1"
103+
{required}
104+
{label}
105+
{disabled}
106+
hidden={labelHidden}
107+
for={id}
108+
/>
97109
<div
98110
bind:this={inputContainer}
99111
class={merge(
@@ -132,37 +144,15 @@
132144
on:blur={handleBlur}
133145
on:keydown|stopPropagation={handleKeydown}
134146
on:paste={handlePaste}
135-
maxlength={maxLength && $values.length >= maxLength ? 0 : undefined}
136147
/>
137148
</div>
138-
139-
{#if (invalid && hintText) || (maxLength && !disabled)}
140-
<div class="flex justify-between gap-2">
141-
<div
142-
class="error-msg"
143-
class:min-width={maxLength}
144-
aria-live={invalid ? 'assertive' : 'off'}
145-
>
146-
{#if invalid && hintText}
147-
<p>{hintText}</p>
148-
{/if}
149-
</div>
150-
{#if maxLength && !disabled}
151-
<span class="count">
152-
<span
153-
class="text-information"
154-
class:warn={maxLength - $values?.length <= 5}
155-
class:error={maxLength === $values?.length}
156-
>
157-
{$values?.length ?? 0}
158-
</span>&nbsp;/&nbsp;{maxLength}
159-
</span>
160-
{/if}
161-
</div>
149+
{#if invalid && hintText}
150+
<span class="hint">
151+
{hintText}
152+
</span>
162153
{/if}
163-
164154
{#if $values.length > 0 && external}
165-
<div class="flex flex-row flex-wrap gap-1">
155+
<div class="mt-1 flex flex-row flex-wrap gap-1">
166156
{#each $values as chip, i (`${chip}-${i}`)}
167157
{@const valid = validator(chip)}
168158
<Chip
@@ -184,26 +174,10 @@
184174
}
185175
186176
input {
187-
@apply surface-primary inline-block grow focus:outline-none;
188-
}
189-
190-
.error-msg {
191-
@apply break-words text-sm text-danger;
192-
}
193-
194-
.error-msg.min-width {
195-
@apply w-[calc(100%-6rem)];
196-
}
197-
198-
.count {
199-
@apply invisible text-right text-sm font-medium text-primary group-focus-within:visible;
200-
}
201-
202-
.count > .warn {
203-
@apply text-warning;
177+
@apply surface-primary inline-block w-full focus:outline-none;
204178
}
205179
206-
.count > .error {
207-
@apply text-danger;
180+
.hint {
181+
@apply text-xs text-danger;
208182
}
209183
</style>

src/lib/holocene/textarea.stories.svelte

+2-12
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,17 @@
4141
<script lang="ts">
4242
import { action } from '@storybook/addon-actions';
4343
import { Story, Template } from '@storybook/addon-svelte-csf';
44-
import { userEvent, within } from '@storybook/test';
4544
4645
import { shouldNotBeTransparent } from './test-utilities';
4746
</script>
4847

49-
<Template let:args let:context>
48+
<Template let:args>
5049
<Textarea
5150
on:input={action('input')}
5251
on:blur={action('blue')}
5352
on:change={action('change')}
5453
on:focus={action('focus')}
5554
on:keydown={action('keydown')}
56-
id={context.id}
5755
{...args}
5856
/>
5957
</Template>
@@ -71,15 +69,7 @@
7169

7270
<Story name="Hidden Label" args={{ labelHidden: true }} />
7371

74-
<Story
75-
name="With Maximum Length"
76-
args={{ maxLength: 10 }}
77-
play={async ({ canvasElement, id }) => {
78-
const canvas = within(canvasElement);
79-
const input = canvas.getByTestId(id);
80-
await userEvent.click(input);
81-
}}
82-
/>
72+
<Story name="With Maximum Length" args={{ maxLength: 10 }} />
8373

8474
<Story name="With Value" args={{ value: 'Some text…' }} />
8575

src/lib/holocene/textarea.svelte

-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@
6868
on:blur
6969
on:keydown|stopPropagation
7070
maxlength={maxLength > 0 ? maxLength : undefined}
71-
data-testid={id}
7271
{...$$restProps}
7372
/>
7473
</div>

0 commit comments

Comments
 (0)