@youcan/celeste 0.17.2 → 0.18.0

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.
Files changed (34) hide show
  1. package/ai/README.md +1 -1
  2. package/ai/component-registry.json +2 -2
  3. package/ai/icons.json +2 -2
  4. package/ai/tokens.json +2 -2
  5. package/dist/celeste.css +205 -144
  6. package/dist/cjs/chunks/ComboboxItem.cjs +6 -0
  7. package/dist/cjs/chunks/combobox-item.cjs +63 -7
  8. package/dist/cjs/chunks/combobox-list.cjs +1 -1
  9. package/dist/cjs/chunks/combobox-trigger.cjs +1 -1
  10. package/dist/cjs/chunks/combobox.cjs +2 -2
  11. package/dist/cjs/chunks/components.cjs +1 -1
  12. package/dist/cjs/chunks/text-input-affix.cjs +1 -1
  13. package/dist/cjs/chunks/text-input-button.cjs +1 -1
  14. package/dist/cjs/chunks/text-input.cjs +2 -1
  15. package/dist/cjs/index.cjs +1 -1
  16. package/dist/es/chunks/ComboboxItem.js +1 -1
  17. package/dist/es/chunks/combobox-item.js +65 -9
  18. package/dist/es/chunks/combobox-list.js +1 -1
  19. package/dist/es/chunks/combobox-trigger.js +1 -1
  20. package/dist/es/chunks/combobox.js +2 -2
  21. package/dist/es/chunks/components.js +1 -1
  22. package/dist/es/chunks/text-input-affix.js +1 -1
  23. package/dist/es/chunks/text-input-button.js +1 -1
  24. package/dist/es/chunks/text-input.js +2 -1
  25. package/dist/es/index.js +1 -1
  26. package/package.json +3 -3
  27. package/src/components/combobox/combobox-item.vue +15 -7
  28. package/src/components/combobox/combobox-list.vue +2 -2
  29. package/src/components/combobox/combobox-trigger.vue +38 -0
  30. package/src/components/combobox/combobox.vue +2 -0
  31. package/src/components/text-input/stories/text-input.stories.ts +53 -3
  32. package/src/components/text-input/text-input-affix.vue +7 -3
  33. package/src/components/text-input/text-input-button.vue +6 -2
  34. package/src/components/text-input/text-input.vue +45 -34
@@ -73,15 +73,21 @@ export const Size: Story = {
73
73
  template: `
74
74
  <div style="display: grid; gap: 20px; justify-content: center;">
75
75
  <TextInput v-bind="args" style="width: 300px" size="md">
76
- <i class="i-celeste-user-6-line" />
76
+ <template #leadingIcon>
77
+ <i class="i-celeste-user-6-line" />
78
+ </template>
77
79
  </TextInput>
78
80
 
79
81
  <TextInput v-bind="args" style="width: 300px" size="sm">
80
- <i class="i-celeste-user-6-line" />
82
+ <template #leadingIcon>
83
+ <i class="i-celeste-user-6-line" />
84
+ </template>
81
85
  </TextInput>
82
86
 
83
87
  <TextInput v-bind="args" style="width: 300px" size="xs">
84
- <i class="i-celeste-user-6-line" />
88
+ <template #leadingIcon>
89
+ <i class="i-celeste-user-6-line" />
90
+ </template>
85
91
  </TextInput>
86
92
  </div>
87
93
  `,
@@ -361,3 +367,47 @@ export const WithTrailingCombobox: Story = {
361
367
  `,
362
368
  }),
363
369
  };
370
+
371
+ function flag(color: string): string {
372
+ return `data:image/svg+xml,${encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><circle cx="10" cy="10" r="10" fill="${color}"/></svg>`)}`;
373
+ }
374
+
375
+ const COUNTRIES = [
376
+ { value: 'MA', label: 'Morocco (+212)', shortLabel: '+212', image: flag('#c1272d') },
377
+ { value: 'FR', label: 'France (+33)', shortLabel: '+33', image: flag('#002654') },
378
+ { value: 'US', label: 'United States (+1)', shortLabel: '+1', image: flag('#3c3b6e') },
379
+ ];
380
+
381
+ export const Phone: Story = {
382
+ args: {
383
+ type: 'tel',
384
+ placeholder: '610-101010',
385
+ },
386
+
387
+ render: args => ({
388
+ components: { TextInput, Combobox },
389
+ setup() {
390
+ const country = ref(COUNTRIES[0]);
391
+ const phone = ref('+212610101010');
392
+
393
+ return { args, COUNTRIES, country, phone };
394
+ },
395
+ template: `
396
+ <div style="display: grid; gap: 20px; width: 360px;">
397
+ <TextInput v-for="size in ['md', 'sm', 'xs']" :key="size" v-bind="args" v-model="phone" :size="size">
398
+ <template #leadingNode>
399
+ <Combobox
400
+ v-model="country"
401
+ searchable
402
+ :options="COUNTRIES"
403
+ :size="size"
404
+ value-by="value"
405
+ label-by="shortLabel"
406
+ type="compact-input"
407
+ />
408
+ </template>
409
+ </TextInput>
410
+ </div>
411
+ `,
412
+ }),
413
+ };
@@ -27,18 +27,22 @@ const delegatedProps = useDelegatedProps(props, 'class');
27
27
  flex-shrink: 0;
28
28
  align-items: center;
29
29
  color: var(--celeste-text-input-affix-color);
30
+ unicode-bidi: plaintext;
30
31
 
31
32
  &[inline='false'] {
32
- padding-inline: var(--spacing-10);
33
+ padding-inline: var(--input-affix-padding);
33
34
  background-color: var(--celeste-text-input-affix-background-color);
34
35
  }
35
36
 
36
37
  &[askbd='true'] {
38
+ box-sizing: border-box;
37
39
  width: fit-content;
38
- height: fit-content;
39
- padding: var(--spacing-2) calc(var(--spacing-8) - var(--spacing-2));
40
+ height: 20px;
41
+ padding-inline: var(--spacing-6);
40
42
  border: 1px solid var(--color-stroke-soft-200);
41
43
  border-radius: var(--radius-4);
44
+ background-color: var(--color-bg-white-0);
45
+ color: var(--celeste-text-input-muted-color);
42
46
  font: var(--subheading-xs);
43
47
  }
44
48
  }
@@ -37,10 +37,14 @@ const delegatedProps = useDelegatedProps(props, 'class');
37
37
  }
38
38
 
39
39
  &[inline='false'] {
40
- padding: var(--spacing-10);
40
+ padding-inline: var(--spacing-14);
41
41
  border-end-start-radius: 0;
42
42
  border-start-start-radius: 0;
43
43
 
44
+ &:has(> :only-child:is(i)) {
45
+ padding-inline: var(--spacing-10);
46
+ }
47
+
44
48
  &:is(.celeste-button-intent-neutral, .celeste-button-variant-stroke):not(:disabled) {
45
49
  background-color: var(--color-bg-white-0);
46
50
 
@@ -53,7 +57,7 @@ const delegatedProps = useDelegatedProps(props, 'class');
53
57
  &[inline='true'] {
54
58
  width: 20px;
55
59
  height: 20px;
56
- color: var(--celeste-text-input-icon-color) !important;
60
+ color: var(--celeste-text-input-muted-color) !important;
57
61
 
58
62
  &:hover {
59
63
  background-color: transparent !important;
@@ -80,6 +80,7 @@ function clearInput() {
80
80
  >
81
81
  <TextInputButton
82
82
  v-if="showClearButton"
83
+ inline
83
84
  type="button"
84
85
  aria-label="Clear search"
85
86
  @click="clearInput"
@@ -97,8 +98,9 @@ function clearInput() {
97
98
  .celeste-text-input-wrapper {
98
99
  --celeste-text-input-border-color: var(--color-stroke-soft-200);
99
100
  --celeste-text-input-drop-shadow: var(--shadow-regular-xs);
100
- --celeste-text-input-icon-color: var(--color-text-soft-400);
101
- --celeste-text-input-affix-color: var(--color-text-soft-400);
101
+ --celeste-text-input-icon-color: var(--color-text-sub-600);
102
+ --celeste-text-input-affix-color: var(--color-text-sub-600);
103
+ --celeste-text-input-muted-color: var(--color-text-soft-400);
102
104
  --celeste-text-input-placeholder-color: var(--color-text-soft-400);
103
105
  --celeste-text-input-affix-background-color: var(--color-bg-white-0);
104
106
 
@@ -106,12 +108,10 @@ function clearInput() {
106
108
  box-sizing: border-box;
107
109
  align-items: center;
108
110
  height: var(--input-height);
109
- padding-inline: calc(var(--input-padding) + var(--spacing-2)) var(--input-padding);
111
+ padding-inline: var(--input-padding);
110
112
  transition: all var(--animation-fast) ease-out;
111
113
  border: 1px solid var(--celeste-text-input-border-color);
112
114
  border-radius: var(--input-radius);
113
- outline: 2px solid transparent;
114
- outline-offset: 2px;
115
115
  background-color: var(--color-bg-white-0);
116
116
  box-shadow: var(--celeste-text-input-drop-shadow);
117
117
  color: var(--color-text-strong-950);
@@ -119,24 +119,27 @@ function clearInput() {
119
119
  gap: var(--input-gap);
120
120
 
121
121
  &[size='xs'] {
122
- --input-gap: 8px;
122
+ --input-gap: var(--spacing-6);
123
123
  --input-height: 32px;
124
124
  --input-radius: var(--radius-8);
125
- --input-padding: calc(var(--spacing-8) - var(--spacing-2));
125
+ --input-padding: var(--spacing-8);
126
+ --input-affix-padding: var(--spacing-10);
126
127
  }
127
128
 
128
129
  &[size='sm'] {
129
- --input-gap: 6px;
130
+ --input-gap: var(--spacing-8);
130
131
  --input-height: 36px;
131
132
  --input-radius: var(--radius-8);
132
- --input-padding: var(--spacing-8);
133
+ --input-padding: var(--spacing-10);
134
+ --input-affix-padding: var(--spacing-10);
133
135
  }
134
136
 
135
137
  &[size='md'] {
136
- --input-gap: 6px;
138
+ --input-gap: var(--spacing-8);
137
139
  --input-height: 40px;
138
140
  --input-radius: var(--radius-10);
139
- --input-padding: var(--spacing-10);
141
+ --input-padding: var(--spacing-12);
142
+ --input-affix-padding: var(--spacing-12);
140
143
  }
141
144
 
142
145
  &[has-error='true'] {
@@ -158,6 +161,12 @@ function clearInput() {
158
161
  color: var(--celeste-text-input-placeholder-color);
159
162
  }
160
163
 
164
+ &[type='tel'] {
165
+ direction: ltr;
166
+ text-align: -webkit-match-parent;
167
+ text-align: match-parent;
168
+ }
169
+
161
170
  // Hide default webkit search cancel button
162
171
  &[type='search'] {
163
172
  &::-webkit-search-cancel-button {
@@ -199,18 +208,36 @@ function clearInput() {
199
208
  padding-inline-end: 0;
200
209
  }
201
210
 
211
+ &:has(.celeste-text-input:placeholder-shown) {
212
+ --celeste-text-input-icon-color: var(--color-text-soft-400);
213
+ --celeste-text-input-affix-color: var(--color-text-soft-400);
214
+ }
215
+
216
+ &:hover:not(:has(.celeste-text-input:focus)) {
217
+ --celeste-text-input-drop-shadow: none;
218
+
219
+ &:not([has-error='true'], :has(.celeste-text-input-node)) {
220
+ --celeste-text-input-border-color: transparent;
221
+ }
222
+
223
+ &:not(:has(.celeste-text-input-node:hover)) {
224
+ --celeste-text-input-icon-color: var(--color-text-sub-600);
225
+ --celeste-text-input-placeholder-color: var(--color-text-sub-600);
226
+
227
+ background-color: var(--color-bg-weak-50);
228
+ }
229
+ }
230
+
202
231
  &:has(.celeste-text-input:focus) {
203
232
  --celeste-text-input-border-color: var(--color-stroke-strong-950);
233
+ --celeste-text-input-drop-shadow: var(--shadow-buttons-important-focus);
204
234
  --celeste-text-input-placeholder-color: var(--color-text-sub-600);
205
235
  --celeste-text-input-icon-color: var(--color-text-sub-600);
206
236
  --celeste-text-input-affix-color: var(--color-text-sub-600);
207
237
 
208
- outline-color: var(--color-stroke-soft-200);
209
-
210
238
  &[has-error='true'] {
211
239
  --celeste-text-input-border-color: var(--color-state-error-base);
212
-
213
- outline-color: var(--color-state-error-lighter);
240
+ --celeste-text-input-drop-shadow: var(--shadow-buttons-error-focus);
214
241
  }
215
242
  }
216
243
 
@@ -229,35 +256,17 @@ function clearInput() {
229
256
  --celeste-text-input-drop-shadow: none;
230
257
  --celeste-text-input-affix-background-color: var(--color-bg-weak-50);
231
258
  --celeste-text-input-affix-color: var(--color-text-disabled-300);
259
+ --celeste-text-input-muted-color: var(--color-text-disabled-300);
232
260
  --celeste-text-input-placeholder-color: var(--color-text-disabled-300);
233
261
  --celeste-text-input-icon-color: var(--color-text-disabled-300);
234
262
 
235
263
  background-color: var(--color-bg-weak-50);
236
- box-shadow: none;
237
264
  color: var(--color-text-disabled-300);
238
265
  pointer-events: none;
239
266
 
240
267
  .celeste-text-input::placeholder {
241
268
  color: currentcolor;
242
269
  }
243
-
244
- .celeste-text-input-clear-button {
245
- color: var(--color-text-disabled-300);
246
- pointer-events: none;
247
- }
248
- }
249
-
250
- &:has(.celeste-text-input:hover:not(:focus, :disabled)) {
251
- &:not(:has(.celeste-text-input-node)) {
252
- --celeste-text-input-border-color: transparent;
253
- }
254
-
255
- &:not(:has(.celeste-text-input-node:hover)) {
256
- --celeste-text-input-icon-color: var(--color-text-sub-600);
257
- --celeste-text-input-placeholder-color: var(--color-text-sub-600);
258
-
259
- background-color: var(--color-bg-weak-50);
260
- }
261
270
  }
262
271
 
263
272
  .celeste-text-input-icon {
@@ -274,6 +283,7 @@ function clearInput() {
274
283
  }
275
284
 
276
285
  :deep(.celeste-text-input-node.celeste-text-input-leading-node) {
286
+ margin-inline-end: calc(var(--input-padding) - var(--input-gap));
277
287
  border-inline-end: 1px solid var(--color-stroke-soft-200);
278
288
  border-start-start-radius: var(--input-radius);
279
289
  border-start-end-radius: 0;
@@ -282,6 +292,7 @@ function clearInput() {
282
292
  }
283
293
 
284
294
  :deep(.celeste-text-input-node.celeste-text-input-trailing-node) {
295
+ margin-inline-start: calc(var(--input-padding) - var(--input-gap));
285
296
  border-inline-start: 1px solid var(--color-stroke-soft-200);
286
297
  border-start-start-radius: 0;
287
298
  border-start-end-radius: var(--input-radius);