@v1nt1248/3nclient-lib 0.1.21 → 0.1.23

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.
@@ -202,7 +202,7 @@
202
202
  --warning-content-disabled: var(--orange-30);
203
203
  --warning-outline-default: var(--orange-5);
204
204
  --warning-outline-hover: var(--orange-10);
205
- --warning-outline-focused: var(--orange-50);
205
+ --warning-outline-focused: var(--orange-70);
206
206
  --warning-outline-pressed: var(--orange-10);
207
207
  --warning-outline-disabled: var(--orange-5);
208
208
  --success-fill-default: var(--emerald-5);
@@ -217,7 +217,7 @@
217
217
  --success-content-disabled: var(--emerald-30);
218
218
  --success-outline-default: var(--emerald-5);
219
219
  --success-outline-hover: var(--emerald-10);
220
- --success-outline-focused: var(--emerald-50);
220
+ --success-outline-focused: var(--emerald-70);
221
221
  --success-outline-pressed: var(--emerald-10);
222
222
  --success-outline-disabled: var(--emerald-5);
223
223
  --error-fill-default: var(--red-5);
@@ -232,7 +232,7 @@
232
232
  --error-content-disabled: var(--red-30);
233
233
  --error-outline-default: var(--red-5);
234
234
  --error-outline-hover: var(--red-10);
235
- --error-outline-focused: var(--red-50);
235
+ --error-outline-focused: var(--red-70);
236
236
  --error-outline-pressed: var(--red-10);
237
237
  --error-outline-disabled: var(--red-5);
238
238
  --info-fill-default: var(--blue-5);
@@ -346,7 +346,7 @@
346
346
  --warning-content-disabled: var(--orange-30);
347
347
  --warning-outline-default: var(--orange-5);
348
348
  --warning-outline-hover: var(--orange-10);
349
- --warning-outline-focused: var(--orange-50);
349
+ --warning-outline-focused: var(--orange-70);
350
350
  --warning-outline-pressed: var(--orange-10);
351
351
  --warning-outline-disabled: var(--orange-5);
352
352
  --success-fill-default: var(--emerald-5);
@@ -361,7 +361,7 @@
361
361
  --success-content-disabled: var(--emerald-30);
362
362
  --success-outline-default: var(--emerald-5);
363
363
  --success-outline-hover: var(--emerald-10);
364
- --success-outline-focused: var(--emerald-50);
364
+ --success-outline-focused: var(--emerald-70);
365
365
  --success-outline-pressed: var(--emerald-10);
366
366
  --success-outline-disabled: var(--emerald-5);
367
367
  --error-fill-default: var(--red-5);
@@ -376,7 +376,7 @@
376
376
  --error-content-disabled: var(--red-30);
377
377
  --error-outline-default: var(--red-5);
378
378
  --error-outline-hover: var(--red-10);
379
- --error-outline-focused: var(--red-50);
379
+ --error-outline-focused: var(--red-70);
380
380
  --error-outline-pressed: var(--red-10);
381
381
  --error-outline-disabled: var(--red-5);
382
382
  --info-fill-default: var(--blue-5);
@@ -568,6 +568,9 @@
568
568
  --color-text-chat-bubble-other-sub: var(--default-hint-default);
569
569
  --color-text-chat-bubble-other-sub-selected: var(--accent-content-default);
570
570
  --color-text-chat-bubble-other-sub-quote: var(--default-hint-default);
571
+ --color-border-button-primary-focused: var(--accent-outline-focused);
572
+ --color-border-button-secondary-focused: var(--s-accent-outline-focused);
573
+ --color-border-button-tritery-focused: var(--s-default-outline-focused);
571
574
  --color-border-block-primary-default: var(--default-outline-default);
572
575
  --color-border-block-primary-hover: var(--default-outline-hover);
573
576
  --color-border-block-primary-focused: var(--default-outline-focused);
@@ -744,3 +747,21 @@ div {
744
747
  .fade-leave-active {
745
748
  opacity: 0;
746
749
  }
750
+
751
+ @keyframes ripple {
752
+ to {
753
+ transform: scale(4);
754
+ opacity: 0;
755
+ }
756
+ }
757
+
758
+ .ui3n-ripple {
759
+ --ui3n-ripple-duration: 400ms;
760
+ --ui3n-ripple-bg-color: rgba(255, 255, 255, 0.7);
761
+
762
+ position: absolute;
763
+ border-radius: 50%;
764
+ transform: scale(0);
765
+ animation: ripple var(--ui3n-ripple-duration) linear;
766
+ background-color: var(--ui3n-ripple-bg-color);
767
+ }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@v1nt1248/3nclient-lib",
3
3
  "license": "AGPL-3.0-or-later",
4
4
  "author": "v1nt1248",
5
- "version": "0.1.21",
5
+ "version": "0.1.23",
6
6
  "description": "Library for 3NWeb clients",
7
7
  "type": "module",
8
8
  "files": [
@@ -15,6 +15,9 @@ export interface Ui3nButtonProps {
15
15
  export interface Ui3nButtonEmits {
16
16
  (ev: 'init', value: HTMLButtonElement): void;
17
17
  (ev: 'click', value: Event): void;
18
+ (ev: 'enter', value: HTMLButtonElement): void;
18
19
  (ev: 'focus', value: Event): void;
19
20
  (ev: 'blur', value: Event): void;
20
21
  }
22
+
23
+ export type Ui3nButtonEventName = 'init' | 'click' | 'enter' | 'focus' | 'blur';
@@ -1,7 +1,10 @@
1
1
  <script lang="ts" setup>
2
2
  import { onMounted, ref, watch } from 'vue';
3
3
  import Ui3nIcon from '../ui3n-icon/ui3n-icon.vue';
4
- import type { Ui3nButtonEmits, Ui3nButtonProps } from './types';
4
+ import Ui3nRipple from '../..//directives/ui3n-ripple';
5
+ import type { Ui3nButtonEmits, Ui3nButtonProps, Ui3nButtonEventName } from './types';
6
+
7
+ const vUi3nRipple = Ui3nRipple;
5
8
 
6
9
  const props = withDefaults(
7
10
  defineProps<Ui3nButtonProps>(),
@@ -16,6 +19,16 @@ const emits = defineEmits<Ui3nButtonEmits>();
16
19
 
17
20
  const buttonEl = ref<HTMLButtonElement | null>(null);
18
21
 
22
+ async function handleButtonEvent(eventName: Ui3nButtonEventName, value?: Event ) {
23
+ if (['init', 'enter'].includes(eventName)) {
24
+ // @ts-ignore
25
+ emits(eventName, buttonEl.value);
26
+ } else {
27
+ // @ts-ignore
28
+ emits(eventName, value!);
29
+ }
30
+ }
31
+
19
32
  watch(
20
33
  [() => props.color, () => props.textColor],
21
34
  (newValue: [string | undefined, string | undefined], prevValue: [string | undefined, string | undefined]) => {
@@ -41,26 +54,28 @@ onMounted(() => {
41
54
 
42
55
  props.type === 'custom' && props.textColor && buttonEl.value.style.setProperty('--ui3n-button-text-color-custom', props.textColor);
43
56
 
44
- emits('init', buttonEl.value);
57
+ handleButtonEvent('init');
45
58
  });
46
59
  </script>
47
60
 
48
61
  <template>
49
62
  <button
50
63
  ref="buttonEl"
64
+ v-ui3n-ripple
51
65
  :class="[
52
66
  $style.button,
53
- $style[size],
54
- $style[type],
67
+ $style[size!],
68
+ $style[type!],
55
69
  block && type !== 'icon' && $style.block,
56
70
  icon && $style[`withIcon-${iconPosition}`],
57
71
  elevation && $style.elevation,
58
72
  ]"
59
73
  type="button"
60
74
  :disabled="disabled"
61
- @click="emits('click', $event)"
62
- @focusin="emits('focus', $event)"
63
- @focusout="emits('blur', $event)"
75
+ @click="handleButtonEvent('click', $event)"
76
+ @focusin="handleButtonEvent('focus', $event)"
77
+ @focusout="handleButtonEvent('blur', $event)"
78
+ @keydown.enter="handleButtonEvent('enter')"
64
79
  >
65
80
  <ui3n-icon
66
81
  v-if="icon"
@@ -86,6 +101,8 @@ onMounted(() => {
86
101
  --ui3n-button-text-color-custom: var(--color-text-button-primary-default);
87
102
  --ui3n-button-bg-color-custom: var(--color-bg-button-primary-default);
88
103
 
104
+ position: relative;
105
+ width: max-content;
89
106
  display: flex;
90
107
  justify-content: center;
91
108
  align-items: center;
@@ -97,6 +114,11 @@ onMounted(() => {
97
114
  font-weight: 600;
98
115
  line-height: calc(var(--ui3n-button-text-size) * 1.25);
99
116
  user-select: none;
117
+ overflow: hidden;
118
+
119
+ &:not([disabled]) {
120
+ cursor: pointer;
121
+ }
100
122
  }
101
123
 
102
124
  .regular {
@@ -136,7 +158,10 @@ onMounted(() => {
136
158
  &:hover {
137
159
  background: var(--color-bg-button-primary-hover);
138
160
  color: var(--color-text-button-primary-hover);
139
- @include ripple(var(--color-bg-button-primary-hover));
161
+ }
162
+
163
+ &:focus {
164
+ outline: 1px solid var(--color-border-button-primary-focused);
140
165
  }
141
166
 
142
167
  &[disabled] {
@@ -153,7 +178,10 @@ onMounted(() => {
153
178
  &:hover {
154
179
  background: var(--color-bg-button-secondary-hover);
155
180
  color: var(--color-text-button-secondary-hover);
156
- @include ripple(var(--color-bg-button-secondary-hover));
181
+ }
182
+
183
+ &:focus {
184
+ outline: 1px solid var(--color-border-button-secondary-focused);
157
185
  }
158
186
 
159
187
  &[disabled] {
@@ -175,6 +203,10 @@ onMounted(() => {
175
203
  cursor: pointer;
176
204
  }
177
205
 
206
+ &:focus {
207
+ outline: 1px solid var(--color-border-button-secondary-focused);
208
+ }
209
+
178
210
  &[disabled] {
179
211
  background: transparent;
180
212
  color: var(--color-text-button-secondary-disabled);
@@ -203,7 +235,10 @@ onMounted(() => {
203
235
 
204
236
  &:hover {
205
237
  background: var(--ui3n-button-icon-bg-color);
206
- @include ripple(var(--ui3n-button-icon-bg-color));
238
+ }
239
+
240
+ &:focus {
241
+ outline: 1px solid hsl(from var(--ui3n-button-icon-bg-color) h s calc(l - 10));
207
242
  }
208
243
 
209
244
  &[disabled] {
@@ -220,7 +255,10 @@ onMounted(() => {
220
255
 
221
256
  &:hover {
222
257
  background: var(--ui3n-button-custom-bg-color);
223
- @include ripple(var(--ui3n-button-custom-bg-color));
258
+ }
259
+
260
+ &:focus {
261
+ outline: 1px solid hsl(from var(--ui3n-button-custom-bg-color) h s calc(l - 10));
224
262
  }
225
263
 
226
264
  &[disabled] {
@@ -38,7 +38,10 @@ onMounted(() => {
38
38
 
39
39
  watch(
40
40
  () => props.modelValue,
41
- val => text.value = val,
41
+ val => {
42
+ text.value = val;
43
+ validate(text.value);
44
+ },
42
45
  { immediate: true },
43
46
  );
44
47
 
@@ -48,40 +51,42 @@ watch(
48
51
  { immediate: true },
49
52
  );
50
53
 
51
- const onFocus = (event: Event) => {
54
+ function onFocus(event: Event) {
52
55
  isFocused.value = true;
53
56
  emits('focus', event);
54
- };
57
+ }
55
58
 
56
- const onBlur = (event: Event) => {
57
- isFocused.value = false;
58
- emits('blur', event);
59
- };
59
+ function onBlur(event: Event) {
60
+ setTimeout(() => {
61
+ isFocused.value = false;
62
+ emits('blur', event);
63
+ }, 100);
64
+ }
60
65
 
61
- const onChange = (event: Event) => {
66
+ function onChange(event: Event) {
62
67
  const value = (event.target as HTMLInputElement).value;
63
68
  validate(value);
64
69
  emits('change', value);
65
- };
70
+ }
66
71
 
67
- const onInput = (ev: Event) => {
72
+ function onInput(ev: Event) {
68
73
  const value = (ev.target as HTMLInputElement).value;
69
74
  text.value = value;
70
75
  validate(value);
71
76
  emits('update:modelValue', value);
72
77
  emits('input', value);
73
- };
78
+ }
74
79
 
75
- const clearValue = () => {
80
+ function clearValue() {
76
81
  text.value = '';
77
82
  validate('');
78
83
  emits('update:modelValue', '');
79
84
  emits('input', '');
80
85
  emits('change', '');
81
86
  emits('clear');
82
- };
87
+ }
83
88
 
84
- const validate = (text: string) => {
89
+ function validate(text: string) {
85
90
  errorMessage.value = '';
86
91
  if (props.rules && props.rules.length) {
87
92
  for (const validateFunction of props.rules) {
@@ -93,7 +98,7 @@ const validate = (text: string) => {
93
98
  }
94
99
  }
95
100
  }
96
- };
101
+ }
97
102
  </script>
98
103
 
99
104
  <template>
@@ -135,6 +140,15 @@ const validate = (text: string) => {
135
140
  :class="[$style.icon, disabled && $style.iconDisabled]"
136
141
  />
137
142
 
143
+ <ui3n-icon
144
+ v-if="displayStateMode === 'success' && displayStateWithIcon && !isFocused"
145
+ icon="round-check-circle-outline"
146
+ :width="16"
147
+ :height="16"
148
+ color="var(--success-content-default)"
149
+ :class="$style.successIcon"
150
+ />
151
+
138
152
  <ui3n-button
139
153
  v-if="clearable && !!text && !(displayStateMode === 'success' && displayStateWithIcon && !isFocused)"
140
154
  type="icon"
@@ -147,20 +161,11 @@ const validate = (text: string) => {
147
161
  @click="clearValue"
148
162
  />
149
163
 
150
- <ui3n-icon
151
- v-if="displayStateMode === 'success' && displayStateWithIcon && !isFocused"
152
- icon="round-check-circle-outline"
153
- :width="16"
154
- :height="16"
155
- color="var(--success-content-default)"
156
- :class="$style.successIcon"
157
- />
158
-
159
164
  <div
160
165
  v-if="errorMessage || displayStateMessage"
161
166
  :class="[
162
167
  $style.fieldMessage,
163
- errorMessage || (displayStateMode === 'error' && !!displayStateMessage) && $style.errorMessage,
168
+ (errorMessage || (displayStateMode === 'error' && !!displayStateMessage)) && $style.errorMessage,
164
169
  displayStateMode === 'success' && displayStateMessage && $style.successMessage,
165
170
  ]"
166
171
  >
@@ -260,7 +265,7 @@ const validate = (text: string) => {
260
265
  position: absolute;
261
266
  right: 0;
262
267
  top: calc((var(--ui3n-input-height) - 24px) / 2);
263
- z-index: 1;
268
+ z-index: 2;
264
269
  }
265
270
 
266
271
  .fieldMessage {
@@ -319,8 +324,14 @@ const validate = (text: string) => {
319
324
  top: calc((var(--ui3n-input-height) - 16px) / 2 + 20px);
320
325
  }
321
326
 
327
+ .successIcon {
328
+ bottom: auto;
329
+ top: calc((var(--ui3n-input-height) - 16px) / 2 + 20px);
330
+ }
331
+
322
332
  .clearBtn {
323
333
  top: calc((var(--ui3n-input-height) - 24px) / 2 + 20px);
334
+ z-index: 1;
324
335
  }
325
336
  }
326
337
  </style>