@x33025/sveltely 0.0.29 → 0.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -50,6 +50,12 @@
50
50
  return;
51
51
  }
52
52
 
53
+ if (event.key === 'Enter' && !inputValue.trim()) {
54
+ event.preventDefault();
55
+ showInput = false;
56
+ return;
57
+ }
58
+
53
59
  if (event.key === 'Escape') {
54
60
  inputValue = '';
55
61
  showInput = false;
@@ -57,7 +63,8 @@
57
63
  }
58
64
 
59
65
  if (event.key === 'Backspace' && !inputValue && tags.length > 0) {
60
- tags = tags.slice(0, -1);
66
+ event.preventDefault();
67
+ startEditing(tags[tags.length - 1]);
61
68
  }
62
69
  };
63
70
 
@@ -75,14 +82,34 @@
75
82
  editingEl?.select();
76
83
  };
77
84
 
78
- const commitEdit = () => {
79
- if (!editingTag) return;
85
+ const commitEdit = async (source: 'enter' | 'blur' | 'advance', targetTag: string) => {
86
+ if (!editingTag || editingTag !== targetTag) return;
80
87
 
81
88
  const previous = editingTag;
82
89
  const next = editingValue.trim();
83
90
  editingTag = null;
84
91
 
85
- if (!next || next === previous) return;
92
+ if (!next) {
93
+ if (source === 'enter' || source === 'advance') {
94
+ const previousIndex = tags.indexOf(previous);
95
+ const nextTags = tags.filter((tag) => tag !== previous);
96
+ tags = nextTags;
97
+ if (selection?.includes(previous)) {
98
+ selection = selection.filter((tag) => tag !== previous);
99
+ }
100
+
101
+ if (source === 'advance' && nextTags.length > 0) {
102
+ const nextIndex = Math.min(previousIndex, nextTags.length - 1);
103
+ await startEditing(nextTags[nextIndex]);
104
+ } else if (nextTags.length === 0) {
105
+ inputValue = '';
106
+ await openInput();
107
+ }
108
+ }
109
+ return;
110
+ }
111
+
112
+ if (next === previous) return;
86
113
  if (tags.includes(next)) return;
87
114
 
88
115
  tags = tags.map((tag) => (tag === previous ? next : tag));
@@ -96,10 +123,16 @@
96
123
  editingValue = '';
97
124
  };
98
125
 
99
- const onEditKeydown = (event: KeyboardEvent) => {
126
+ const onEditKeydown = async (event: KeyboardEvent, tag: string) => {
100
127
  if (event.key === 'Enter') {
101
128
  event.preventDefault();
102
- commitEdit();
129
+ await commitEdit('enter', tag);
130
+ return;
131
+ }
132
+
133
+ if ((event.key === 'Backspace' || event.key === 'Delete') && !editingValue.trim()) {
134
+ event.preventDefault();
135
+ await commitEdit('advance', tag);
103
136
  return;
104
137
  }
105
138
 
@@ -124,86 +157,87 @@
124
157
  });
125
158
  </script>
126
159
 
127
- <div class="w-full max-w-lg">
128
- <div class="tag-row flex flex-wrap items-center">
129
- {#each tags as tag (tag)}
130
- {#if editingTag === tag}
131
- <input
132
- bind:this={editingEl}
133
- bind:value={editingValue}
134
- class="tag-surface tag-input-field min-w-20 outline-none"
135
- onblur={commitEdit}
136
- onkeydown={onEditKeydown}
137
- />
138
- {:else if selectionEnabled}
139
- <button
140
- type="button"
141
- class="tag-surface inline-flex items-center gap-2"
142
- class:tag-selected={selection?.includes(tag)}
143
- onclick={() => toggleSelected(tag)}
144
- ondblclick={() => startEditing(tag)}
145
- aria-pressed={selection?.includes(tag)}
146
- >
147
- {tag}
148
- </button>
149
- {:else}
150
- <button
151
- type="button"
152
- class="tag-surface inline-flex items-center gap-2"
153
- ondblclick={() => startEditing(tag)}>{tag}</button
154
- >
155
- {/if}
156
- {/each}
157
-
158
- {#if showInput}
160
+ <div class="chip-row flex w-full flex-wrap items-center">
161
+ {#each tags as tag (tag)}
162
+ {#if editingTag === tag}
159
163
  <input
160
- bind:this={inputEl}
161
- bind:value={inputValue}
162
- class="tag-surface tag-input-field min-w-36 outline-none"
163
- {placeholder}
164
- onkeydown={onKeydown}
165
- onblur={onBlur}
164
+ bind:this={editingEl}
165
+ bind:value={editingValue}
166
+ size={Math.max(editingValue.length, 1)}
167
+ class="chip-surface chip-input-field outline-none"
168
+ onblur={() => commitEdit('blur', tag)}
169
+ onkeydown={(event) => onEditKeydown(event, tag)}
166
170
  />
167
- {:else}
171
+ {:else if selectionEnabled}
168
172
  <button
169
173
  type="button"
170
- class="tag-surface chip-input-action inline-flex items-center justify-center font-semibold"
171
- aria-label="Add tag"
172
- onclick={openInput}
174
+ class="chip-surface inline-flex items-center gap-2"
175
+ class:chip-selected={selection?.includes(tag)}
176
+ onclick={() => toggleSelected(tag)}
177
+ ondblclick={() => startEditing(tag)}
178
+ aria-pressed={selection?.includes(tag)}
173
179
  >
174
- <Plus style="width: var(--chip-input-font-size); height: var(--chip-input-font-size);" />
180
+ {tag}
175
181
  </button>
182
+ {:else}
183
+ <button
184
+ type="button"
185
+ class="chip-surface inline-flex items-center gap-2"
186
+ ondblclick={() => startEditing(tag)}>{tag}</button
187
+ >
176
188
  {/if}
177
-
178
- {#if action}
179
- {@render action()}
180
- {/if}
181
- </div>
189
+ {/each}
190
+
191
+ {#if showInput}
192
+ <input
193
+ bind:this={inputEl}
194
+ bind:value={inputValue}
195
+ size={Math.max(inputValue.length, placeholder.length, 1)}
196
+ class="chip-surface chip-input-field outline-none"
197
+ {placeholder}
198
+ onkeydown={onKeydown}
199
+ onblur={onBlur}
200
+ />
201
+ {:else}
202
+ <button
203
+ type="button"
204
+ class="chip-surface chip-input-action inline-flex items-center justify-center font-semibold"
205
+ aria-label="Add tag"
206
+ onclick={openInput}
207
+ >
208
+ <Plus style="width: var(--chip-input-font-size); height: var(--chip-input-font-size);" />
209
+ </button>
210
+ {/if}
211
+
212
+ {#if action}
213
+ {@render action()}
214
+ {/if}
182
215
  </div>
183
216
 
184
217
  <style>
185
- .tag-row {
218
+ .chip-row {
186
219
  gap: var(--chip-input-gap);
187
220
  }
188
221
 
189
- .tag-surface {
222
+ .chip-surface {
190
223
  background: var(--chip-input-background);
191
224
  color: var(--chip-input-text);
192
225
  font-size: var(--chip-input-font-size);
193
226
  border-radius: var(--chip-input-border-radius);
194
227
  padding: var(--chip-input-padding);
195
228
  border: 1px solid var(--chip-input-border-color);
229
+ white-space: nowrap;
196
230
  }
197
231
 
198
- .tag-selected {
232
+ .chip-selected {
199
233
  border-color: var(--chip-input-highlight);
200
234
  }
201
235
 
202
- .tag-surface:hover {
236
+ .chip-surface:hover {
203
237
  background: var(--chip-input-hover);
204
238
  }
205
239
 
206
- .tag-input-field:hover {
240
+ .chip-input-field:hover {
207
241
  background: var(--chip-input-background);
208
242
  }
209
243
  </style>
package/dist/style.css CHANGED
@@ -22,7 +22,6 @@
22
22
  --color-black: #000;
23
23
  --color-white: #fff;
24
24
  --spacing: 0.25rem;
25
- --container-lg: 32rem;
26
25
  --text-sm: 0.875rem;
27
26
  --text-sm--line-height: calc(1.25 / 0.875);
28
27
  --font-weight-medium: 500;
@@ -269,15 +268,6 @@
269
268
  .w-full {
270
269
  width: 100%;
271
270
  }
272
- .max-w-lg {
273
- max-width: var(--container-lg);
274
- }
275
- .min-w-20 {
276
- min-width: calc(var(--spacing) * 20);
277
- }
278
- .min-w-36 {
279
- min-width: calc(var(--spacing) * 36);
280
- }
281
271
  .flex-1 {
282
272
  flex: 1;
283
273
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x33025/sveltely",
3
- "version": "0.0.29",
3
+ "version": "0.0.32",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",