plugin-ui-for-kzt 0.0.9 → 0.0.11

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 (128) hide show
  1. package/dist/example/App.vue.d.ts +46 -0
  2. package/dist/example/main.d.ts +1 -0
  3. package/dist/index.js +57224 -3923
  4. package/dist/index.js.map +1 -0
  5. package/dist/sprite.svg +4 -0
  6. package/dist/src/components/BaseBreadCrumbs/BaseBreadCrumbs.vue.d.ts +34 -0
  7. package/dist/src/components/BaseButton/BaseButton.vue.d.ts +189 -0
  8. package/dist/src/components/BaseCalendar/BaseCalendar.vue.d.ts +176 -0
  9. package/dist/src/components/BaseCheckbox/BaseCheckbox.vue.d.ts +174 -0
  10. package/dist/src/components/BaseDropdown/BaseDropdown.vue.d.ts +151 -0
  11. package/dist/src/components/BaseIcon/BaseIcon.vue.d.ts +29 -0
  12. package/dist/src/components/BaseInputCalendar/BaseInputCalendar.vue.d.ts +202 -0
  13. package/dist/src/components/BaseInputEmail/BaseInputEmail.vue.d.ts +176 -0
  14. package/dist/src/components/BaseInputPhone/BaseInputPhone.vue.d.ts +251 -0
  15. package/dist/src/components/BaseLoader/BaseLoader.vue.d.ts +4 -0
  16. package/dist/src/components/BaseOpenedListItem/BaseOpenedListItem.vue.d.ts +148 -0
  17. package/dist/src/components/BaseRadio/BaseRadio.vue.d.ts +173 -0
  18. package/dist/src/components/BaseSegmentedButtons/BaseSegmentedButtons.vue.d.ts +142 -0
  19. package/dist/src/components/BaseSelect/BaseSelect.vue.d.ts +265 -0
  20. package/dist/src/components/BaseSiteInput/BaseSiteInput.vue.d.ts +119 -0
  21. package/dist/src/components/BaseTextarea/BaseTextarea.vue.d.ts +195 -0
  22. package/dist/src/components/BaseToggle/BaseToggle.vue.d.ts +166 -0
  23. package/dist/src/components/BaseTooltip/BaseTooltip.vue.d.ts +76 -0
  24. package/dist/src/components/DataTable/DataTable.vue.d.ts +42 -0
  25. package/dist/src/components/Modal/Modal.vue.d.ts +36 -0
  26. package/dist/src/components/Spinner/Spinner.vue.d.ts +46 -0
  27. package/dist/src/components/Toaster/Toaster.vue.d.ts +117 -0
  28. package/dist/src/components/Tooltip/Tooltip.vue.d.ts +43 -0
  29. package/dist/src/composables/kit/color.d.ts +6 -0
  30. package/dist/src/composables/kit/interactive.d.ts +7 -0
  31. package/dist/src/composables/kit/size.d.ts +6 -0
  32. package/dist/src/composables/kit/state.d.ts +17 -0
  33. package/dist/src/composables/kit/style.d.ts +8 -0
  34. package/dist/src/composables/kit/utils.d.ts +1 -0
  35. package/dist/src/icons/index.d.ts +4 -0
  36. package/dist/src/index.d.ts +33 -0
  37. package/example/App.vue +355 -0
  38. package/example/index.html +12 -0
  39. package/example/main.ts +8 -0
  40. package/example/shims-vue.d.ts +5 -0
  41. package/package.json +17 -7
  42. package/src/assets/icons/arrow-down.svg +3 -0
  43. package/src/assets/icons/calendar.svg +12 -0
  44. package/src/assets/icons/checkbox-circle.svg +3 -0
  45. package/src/assets/icons/checkbox.svg +3 -0
  46. package/src/assets/icons/email-sms.svg +4 -0
  47. package/src/assets/icons/help.svg +3 -0
  48. package/src/assets/icons/kg.svg +16 -0
  49. package/src/assets/icons/kz.svg +42 -0
  50. package/src/assets/icons/loader.svg +13 -0
  51. package/src/assets/icons/ru.svg +12 -0
  52. package/src/assets/icons/uz.svg +26 -0
  53. package/src/components/BaseBreadCrumbs/BaseBreadCrumbs.vue +142 -0
  54. package/src/components/BaseBreadCrumbs/README.md +49 -0
  55. package/src/components/BaseButton/BaseButton.vue +489 -0
  56. package/src/components/BaseButton/README.md +53 -0
  57. package/src/components/BaseCalendar/BaseCalendar.vue +231 -0
  58. package/src/components/BaseCalendar/README.md +126 -0
  59. package/src/components/BaseCheckbox/BaseCheckbox.vue +252 -0
  60. package/src/components/BaseCheckbox/README.md +110 -0
  61. package/src/components/BaseDropdown/BaseDropdown.vue +160 -0
  62. package/src/components/BaseDropdown/README.md +91 -0
  63. package/src/components/BaseIcon/BaseIcon.vue +47 -0
  64. package/src/components/BaseIcon/README.md +35 -0
  65. package/src/components/BaseInput/BaseInput.vue +300 -0
  66. package/src/components/BaseInput/README.md +85 -0
  67. package/src/components/BaseInputCalendar/BaseInputCalendar.vue +242 -0
  68. package/src/components/BaseInputCalendar/README.md +84 -0
  69. package/src/components/BaseInputCurrency/BaseInputCurrency.vue +198 -0
  70. package/src/components/BaseInputCurrency/README.md +57 -0
  71. package/src/components/BaseInputEmail/BaseInputEmail.vue +89 -0
  72. package/src/components/BaseInputEmail/README.md +71 -0
  73. package/src/components/BaseInputPhone/BaseInputPhone.vue +175 -0
  74. package/src/components/BaseLoader/BaseLoader.vue +45 -0
  75. package/src/components/BaseLoader/README.md +29 -0
  76. package/src/components/BaseOpenedListItem/BaseOpenedListItem.vue +216 -0
  77. package/src/components/BaseOpenedListItem/README.md +67 -0
  78. package/src/components/BaseRadio/BaseRadio.vue +283 -0
  79. package/src/components/BaseRadio/README.md +74 -0
  80. package/src/components/BaseSegmentedButtons/BaseSegmentedButtons.vue +89 -0
  81. package/src/components/BaseSegmentedButtons/README.md +75 -0
  82. package/src/components/BaseSelect/BaseSelect.vue +370 -0
  83. package/src/components/BaseSelect/README.md +95 -0
  84. package/src/components/BaseSiteInput/BaseSiteInput.vue +153 -0
  85. package/src/components/BaseTextarea/BaseTextarea.vue +212 -0
  86. package/src/components/BaseTextarea/README.md +75 -0
  87. package/src/components/BaseToggle/BaseToggle.vue +271 -0
  88. package/src/components/BaseToggle/README.md +76 -0
  89. package/src/components/BaseTooltip/BaseTooltip.vue +318 -0
  90. package/src/components/BaseTooltip/README.md +74 -0
  91. package/src/components/Modal/Modal.vue +3 -1
  92. package/src/components/Spinner/Spinner.vue +2 -1
  93. package/src/composables/kit/color.ts +14 -0
  94. package/src/composables/kit/interactive.ts +53 -0
  95. package/src/composables/kit/size.ts +15 -0
  96. package/src/composables/kit/state.ts +28 -0
  97. package/src/composables/kit/style.ts +18 -0
  98. package/src/composables/kit/utils.ts +7 -0
  99. package/src/icons/index.ts +9 -0
  100. package/src/index.ts +93 -2
  101. package/src/shims-context.d.ts +19 -0
  102. package/src/styles/index.scss +2 -1
  103. package/src/styles/root.scss +167 -0
  104. package/src/styles/variables.scss +160 -0
  105. package/src/types/breadcrumbs.d.ts +13 -0
  106. package/src/types/button.d.ts +13 -0
  107. package/src/types/calendar.d.ts +16 -0
  108. package/src/types/checkbox-radio.d.ts +15 -0
  109. package/src/types/dropdown.d.ts +20 -0
  110. package/src/types/icon.d.ts +8 -0
  111. package/src/types/input.d.ts +56 -0
  112. package/src/types/toggle.d.ts +12 -0
  113. package/src/types/tooltip.d.ts +8 -0
  114. package/src/types/utils.d.ts +37 -0
  115. package/src/vue-virtual-scroller.d.ts +9 -0
  116. package/tsconfig.json +3 -1
  117. package/webpack.config.js +90 -35
  118. package/dist/components/DataTable/DataTable.vue.d.ts +0 -3
  119. package/dist/components/Modal/Modal.vue.d.ts +0 -3
  120. package/dist/components/Spinner/Spinner.vue.d.ts +0 -3
  121. package/dist/components/Toaster/Toaster.vue.d.ts +0 -3
  122. package/dist/components/Tooltip/Tooltip.vue.d.ts +0 -3
  123. package/dist/index.d.ts +0 -11
  124. /package/dist/{components → src/components}/Toaster/timer.d.ts +0 -0
  125. /package/dist/{plugins → src/plugins}/modalPlugin.d.ts +0 -0
  126. /package/dist/{plugins → src/plugins}/toasterPlugin.d.ts +0 -0
  127. /package/dist/{store → src/store}/modal.d.ts +0 -0
  128. /package/dist/{types → src/types}/index.d.ts +0 -0
@@ -0,0 +1,153 @@
1
+ <template>
2
+ <div :class="classList">
3
+ <div class="base-site-input__wrapper">
4
+ <div class="base-site-input__url">
5
+ https://
6
+ </div>
7
+ <base-input
8
+ v-bind="{...$props, ...$attrs}"
9
+ v-model="modelValue"
10
+ id="url"
11
+ type="url"
12
+ :error="urlError || props.error"
13
+ @update:modelValue="onUpdateModelValue"
14
+ />
15
+ </div>
16
+ </div>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ import { computed, ref, watch } from 'vue';
21
+ import BaseInput from '../BaseInput/BaseInput.vue';
22
+ import { useKitSize } from '../../composables/kit/size'
23
+ import type { ICorePropsBaseSiteInput } from '../../types/input'
24
+
25
+ const props = withDefaults(defineProps<ICorePropsBaseSiteInput>(),{
26
+ size: 'medium',
27
+ modelValue: '',
28
+ error: '',
29
+ })
30
+
31
+ const emit = defineEmits<{
32
+ (event: 'update:modelValue', value: string): void;
33
+ }>();
34
+
35
+ const urlError = ref('');
36
+ const { sizeClassList } = useKitSize(props);
37
+
38
+ const classList = computed(() => [
39
+ sizeClassList.value,
40
+ 'base-site-input',
41
+ ]);
42
+
43
+ const normalizedValue = computed(() => {
44
+ const trimmed = props.modelValue.replace(/^https?:\/\//, '');
45
+ return trimmed;
46
+ });
47
+
48
+ const modelValue = computed({
49
+ get: () => normalizedValue.value,
50
+ set: value => onUpdateModelValue(value),
51
+ });
52
+
53
+ function onUpdateModelValue(value: string) {
54
+ const normalized = value.startsWith('https://') ? value : `https://${value}`;
55
+ emit('update:modelValue', normalized);
56
+ }
57
+
58
+ watch(modelValue, (value) => {
59
+ const urlPattern = /^(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(?:\/[^\s]*)?(?:\?[^\s]*)?(?:#[^\s]*)?$/;
60
+ const trimmed = value.replace(/^https?:\/\//, '');
61
+
62
+ if (!urlPattern.test(trimmed)) {
63
+ urlError.value = props.validationText || 'Некорректный URL';
64
+ } else {
65
+ urlError.value = '';
66
+ }
67
+ });
68
+ </script>
69
+
70
+ <style scoped lang="scss">
71
+ @import '../../styles/variables';
72
+ @import '../../styles/root';
73
+
74
+ .base-site-input {
75
+ $input: &;
76
+
77
+ width: fit-content;
78
+
79
+ &__wrapper {
80
+ display: flex;
81
+ align-items: center;
82
+ justify-content: center;
83
+ width: 100%;
84
+ height: 100%;
85
+
86
+ :deep(.base-input__field) {
87
+ border-top-left-radius: unset !important;
88
+ border-bottom-left-radius: unset !important;
89
+ }
90
+ }
91
+
92
+ &__url {
93
+ display: flex;
94
+ align-items: center;
95
+ justify-content: center;
96
+ border-top: 1px solid var(--primary-black-300);
97
+ border-bottom: 1px solid var(--primary-black-300);
98
+ border-left: 1px solid var(--primary-black-300);
99
+ color: var(--primary-text-tertiary);
100
+ }
101
+
102
+ &.--small-size {
103
+ #{$input} {
104
+ &__url {
105
+ height: 22px;
106
+ font: var(--typography-text-m-regular);
107
+ border-top-left-radius: var(--corner-radius-s);
108
+ border-bottom-left-radius: var(--corner-radius-s);
109
+ padding: var(--spacing-s) var(--spacing-m) var(--spacing-s) var(--spacing-2l);
110
+ }
111
+ }
112
+
113
+ :deep(.base-input__label-text),
114
+ :deep(.base-input__hint) {
115
+ transform: translateX(-75px);
116
+ }
117
+ }
118
+
119
+ &.--medium-size {
120
+ #{$input} {
121
+ &__url {
122
+ height: 18px;
123
+ font: var(--typography-text-m-regular);
124
+ border-top-left-radius: var(--corner-radius-m);
125
+ border-bottom-left-radius: var(--corner-radius-m);
126
+ padding: var(--spacing-m) var(--spacing-m) var(--spacing-m) var(--spacing-2l);
127
+ }
128
+ }
129
+
130
+ :deep(.base-input__label-text),
131
+ :deep(.base-input__hint) {
132
+ transform: translateX(-75px);
133
+ }
134
+ }
135
+
136
+ &.--large-size {
137
+ #{$input} {
138
+ &__url {
139
+ height: 21px;
140
+ font: var(--typography-text-l-regular);
141
+ border-top-left-radius: var(--corner-radius-m);
142
+ border-bottom-left-radius: var(--corner-radius-m);
143
+ padding: var(--spacing-2l) var(--spacing-m) var(--spacing-2l) var(--spacing-l);
144
+ }
145
+ }
146
+
147
+ :deep(.base-input__label-text),
148
+ :deep(.base-input__hint) {
149
+ transform: translateX(-83px);
150
+ }
151
+ }
152
+ }
153
+ </style>
@@ -0,0 +1,212 @@
1
+ <template>
2
+ <div class="base-textarea" :class="classList">
3
+ <label class="base-textarea__label" :for="id">
4
+ <span v-if="label" class="base-textarea__label-text">{{ label }}</span>
5
+
6
+ <div class="base-textarea__wrapper">
7
+ <textarea
8
+ :id="id"
9
+ :value="modelValue"
10
+ v-bind="stateAttrs"
11
+ :placeholder="placeholder || ''"
12
+ :maxlength="maxLength"
13
+ class="base-textarea__field"
14
+ @input="handleInput"
15
+ />
16
+ <span v-if="maxLength" class="base-textarea__counter">
17
+ {{ modelValue.length }}/{{ maxLength }}
18
+ </span>
19
+ </div>
20
+
21
+ <div v-if="(error && typeof error === 'string') || hint" class="base-textarea__hint">
22
+ {{ error || hint }}
23
+ </div>
24
+ </label>
25
+ </div>
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ import { computed } from 'vue';
30
+ import type { ICoreTextareaProps } from '../../types/input';
31
+ import { useKitState } from '../../composables/kit/state';
32
+ import { useKitSize } from '../../composables/kit/size';
33
+
34
+ const props = withDefaults(defineProps<ICoreTextareaProps & { maxLength?: number }>(), {
35
+ modelValue: '',
36
+ placeholder: '' as string,
37
+ error: '',
38
+ hint: '',
39
+ size: 'medium',
40
+ });
41
+
42
+ const emit: (event: 'update:modelValue', value: string) => void = defineEmits();
43
+
44
+ const { stateClassList, stateAttrs } = useKitState(props);
45
+ const { sizeClassList } = useKitSize(props);
46
+
47
+ const classList = computed(() => [
48
+ stateClassList.value,
49
+ sizeClassList.value,
50
+ {
51
+ '--is-readonly': props.readonly,
52
+ },
53
+ ]);
54
+
55
+ function handleInput(event: Event) {
56
+ const target = event.target as HTMLTextAreaElement;
57
+ if (target) {
58
+ emit('update:modelValue', target.value.slice(0, props.maxLength));
59
+ }
60
+ }
61
+ </script>
62
+
63
+ <style scoped lang="scss">
64
+ @import '../../styles/variables';
65
+ @import '../../styles/root';
66
+
67
+ .base-textarea {
68
+ width: max-content;
69
+ $textarea: &;
70
+
71
+ textarea {
72
+ resize: none;
73
+ }
74
+
75
+ &__hint {
76
+ align-self: flex-start;
77
+ font: var(--typography-text-s-regular);
78
+ }
79
+
80
+ &__wrapper {
81
+ display: flex;
82
+ position: relative;
83
+ }
84
+
85
+ &__field {
86
+ min-width: 320px;
87
+ max-width: calc(-16px + 50vw);
88
+ color: var(--primary-text-primary);
89
+ background: var(--bg-light);
90
+ border: 1px solid var(--primary-black-300);
91
+
92
+ &::placeholder {
93
+ color: var(--primary-text-tertiary);
94
+ }
95
+
96
+ @include scrollbar;
97
+
98
+ @include pressed {
99
+ color: var(--primary-blue);
100
+ }
101
+
102
+ @include focused {
103
+ border: 1px solid var(--primary-blue-500);
104
+ outline: 4px solid var(--effects-primary-focus);
105
+ }
106
+
107
+ @include is-disabled-state {
108
+ & {
109
+ color: var(--primary-text-tertiary);
110
+ background: var(--primary-black-100);
111
+ }
112
+
113
+ #{$textarea}__hint {
114
+ color: var(--primary-text-secondary);
115
+ }
116
+ }
117
+ }
118
+
119
+ &__counter {
120
+ position: absolute;
121
+ font: var(--typography-text-s-regular);
122
+ color: var(--primary-text-quaternary);
123
+ }
124
+
125
+ &__label {
126
+ display: flex;
127
+ flex-direction: column;
128
+ gap: 6px;
129
+ align-items: center;
130
+ }
131
+
132
+ &__label-text {
133
+ align-self: flex-start;
134
+ font: var(--typography-text-s-medium);
135
+ color: var(--primary-text-primary);
136
+ }
137
+
138
+ &.--is-error {
139
+ #{$textarea}__hint {
140
+ color: var(--error-red);
141
+ }
142
+
143
+ #{$textarea}__field {
144
+ border-color: var(--error-red-light-01);
145
+
146
+ @include focused {
147
+ outline: 4px solid var(--effects-error-focus);
148
+ }
149
+ }
150
+ }
151
+
152
+ &.--small-size {
153
+ #{$textarea} {
154
+ &__wrapper {
155
+ height: 40px;
156
+ }
157
+
158
+ &__field {
159
+ padding: var(--spacing-s) calc(var(--spacing-2l) + 35px) var(--spacing-s) var(--spacing-2l);
160
+ font: var(--typography-text-m-regular);
161
+ border-radius: var(--corner-radius-s);
162
+ }
163
+
164
+ &__counter {
165
+ font-size: var(--typography-text-s-regular);
166
+ right: var(--spacing-s);
167
+ bottom: var(--spacing-2l);
168
+ }
169
+ }
170
+ }
171
+
172
+ &.--medium-size {
173
+ #{$textarea} {
174
+ &__wrapper {
175
+ height: 48px;
176
+ }
177
+
178
+ &__field {
179
+ padding: var(--spacing-m) calc(var(--spacing-2l) + 35px) var(--spacing-m) var(--spacing-2l);
180
+ font: var(--typography-text-m-regular);
181
+ border-radius: var(--corner-radius-m);
182
+ }
183
+
184
+ &__counter {
185
+ font-size: var(--typography-text-s-regular);
186
+ right: var(--spacing-m);
187
+ bottom: var(--spacing-2l);
188
+ }
189
+ }
190
+ }
191
+
192
+ &.--large-size {
193
+ #{$textarea} {
194
+ &__wrapper {
195
+ height: 56px;
196
+ }
197
+
198
+ &__field {
199
+ padding: var(--spacing-2l) calc(var(--spacing-l) + 35px) var(--spacing-2l) var(--spacing-l);
200
+ font: var(--typography-text-l-regular);
201
+ border-radius: var(--corner-radius-m);
202
+ }
203
+
204
+ &__counter {
205
+ font-size: var(--typography-text-m-regular);
206
+ right: var(--spacing-2l);
207
+ bottom: var(--spacing-l);
208
+ }
209
+ }
210
+ }
211
+ }
212
+ </style>
@@ -0,0 +1,75 @@
1
+ ## 📝 BaseTextarea
2
+
3
+ Компонент многострочного текстового поля (`textarea`) с поддержкой ошибок, подсказок и состояния `readonly`. Подходит для пользовательских форм и длинного ввода.
4
+
5
+ ---
6
+
7
+ ### ✅ Пример использования
8
+
9
+ ```vue
10
+ <base-textarea
11
+ v-model="description"
12
+ label="Описание"
13
+ placeholder="Введите текст..."
14
+ hint="Можно использовать до 300 символов"
15
+ :error="hasError && 'Поле обязательно'"
16
+ />
17
+ ```
18
+
19
+ ---
20
+
21
+ ### ⚙️ Пропсы
22
+
23
+ - `modelValue: string`
24
+ Значение поля. Управляется через `v-model`.
25
+
26
+ - `id: string`
27
+ Уникальный идентификатор для `textarea` и `label`.
28
+
29
+ - `label?: string`
30
+ Заголовок поля. Показывается над `textarea`.
31
+
32
+ - `placeholder?: string`
33
+ Текст-подсказка внутри поля.
34
+
35
+ - `readonly?: boolean`
36
+ Делает поле только для чтения.
37
+
38
+ - `hint?: string`
39
+ Вспомогательный текст под полем (например, с рекомендацией или лимитом).
40
+
41
+ - `error?: string | boolean`
42
+ Отображает сообщение об ошибке и подсвечивает поле. Если строка — используется как текст ошибки.
43
+
44
+ - `disabled?: boolean`
45
+ Деактивирует поле.
46
+
47
+ - `required?: boolean`
48
+ Добавляет `required`-поведение и соответствующие атрибуты.
49
+
50
+ - `loading?: boolean`
51
+ Добавляет визуальное состояние загрузки (влияет на стили).
52
+
53
+ - `active?: boolean` / `inactive?: boolean` / `selected?: boolean`
54
+ Управляют вспомогательными состояниями для кастомного внешнего вида.
55
+
56
+ ---
57
+
58
+ ### 📤 События
59
+
60
+ - `update:modelValue`
61
+ Эмитится при вводе текста. Возвращает текущее значение `string`.
62
+
63
+ ---
64
+
65
+ ### 🎨 Поведение и классы
66
+
67
+ Компонент использует `useKitState` для управления классами и атрибутами:
68
+
69
+ - `--is-disabled`, `--is-error`, `--is-loading` и другие — добавляются на корневой элемент.
70
+ - `--is-readonly` — активируется при `readonly: true`.
71
+ - Если `error` — добавляется стиль ошибки (граница и цвет текста).
72
+ - Если `hint` или строковое `error` — отображается блок подсказки под `textarea`.
73
+ - Поддерживаются размеры: `--small-size`, `--medium-size`, `--large-size`.
74
+ - Поддерживаются maxLength: для ограничения вводимых символов.
75
+
@@ -0,0 +1,271 @@
1
+ <template>
2
+ <div class="base-toggle" :class="[classList]">
3
+ <div class="base-toggle__wrapper">
4
+
5
+ <div class="base-toggle__toggle">
6
+ <input
7
+ v-model="model"
8
+ v-bind="inputAttrs"
9
+ type="checkbox"
10
+ class="base-toggle__input"
11
+ />
12
+ </div>
13
+
14
+ <div
15
+ class="base-toggle__label-wrapper"
16
+ @click="handleToggle"
17
+ >
18
+ <span v-if="label" class="base-toggle__label">{{ label }}</span>
19
+
20
+ <span v-if="subLabel" class="base-toggle__sublabel">{{ subLabel }}</span>
21
+ </div>
22
+ </div>
23
+ </div>
24
+ </template>
25
+
26
+ <script setup lang="ts">
27
+ import { computed, useAttrs } from 'vue';
28
+ import type { ICoreToggleProps } from '../../types/toggle';
29
+ import { useKitSize } from '../../composables/kit/size'
30
+ import { useKitState } from '../../composables/kit/state'
31
+
32
+ const props = withDefaults(defineProps<ICoreToggleProps>(), {
33
+ size: 'medium',
34
+ });
35
+
36
+ const emit = defineEmits<{
37
+ (e: 'update:modelValue', value: boolean): void;
38
+ }>();
39
+
40
+ const model = computed({
41
+ get: () => props.modelValue,
42
+ set: (val) => emit('update:modelValue', val),
43
+ });
44
+
45
+ const { sizeClassList } = useKitSize(props);
46
+ const { stateClassList, stateAttrs } = useKitState(props);
47
+
48
+ const classList = computed(() => [
49
+ sizeClassList.value,
50
+ stateClassList.value,
51
+
52
+ {
53
+ '--is-active-value': model.value,
54
+ '--is-readonly': props.readonly,
55
+ '--is-left-label-position': props.labelPosition === 'left',
56
+ },
57
+ ]);
58
+
59
+ const attrs = useAttrs();
60
+
61
+ const inputAttrs = computed(() => {
62
+ return {
63
+ ...attrs,
64
+ ...stateAttrs.value,
65
+ id: props.id,
66
+ };
67
+ });
68
+
69
+ function handleToggle() {
70
+ model.value = !model.value;
71
+ }
72
+ </script>
73
+
74
+ <style lang="scss">
75
+ @import '../../styles/variables';
76
+ @import '../../styles/root';
77
+
78
+ .base-toggle {
79
+ $toggle: &;
80
+
81
+ @include is-disabled-state;
82
+
83
+ &__wrapper {
84
+ display: flex;
85
+ align-items: flex-start;
86
+ width: 100%;
87
+ height: 100%;
88
+ }
89
+
90
+ &__label-wrapper {
91
+ display: flex;
92
+ flex-direction: column;
93
+ gap: 2px;
94
+ cursor: pointer;
95
+ user-select: none;
96
+ }
97
+
98
+ &__toggle {
99
+ position: relative;
100
+ cursor: pointer;
101
+ transition: all 0.25s ease-out;
102
+
103
+ &::before {
104
+ position: absolute;
105
+ content: '';
106
+ border-radius: 50%;
107
+ box-shadow: 1px 1px 4px var(--effects-toggles-shadows);
108
+ transition: all 0.25s ease-out;
109
+ }
110
+ }
111
+
112
+ &__input {
113
+ position: absolute;
114
+ inset: 0;
115
+ width: 100%;
116
+ height: 100%;
117
+ cursor: pointer;
118
+ opacity: 0 !important;
119
+ }
120
+
121
+ &.--is-readonly {
122
+ pointer-events: none;
123
+ }
124
+
125
+ &.--is-left-label-position {
126
+ #{$toggle} {
127
+ &__label-wrapper {
128
+ order: -1;
129
+ }
130
+ }
131
+ }
132
+
133
+ &.--medium-size {
134
+ #{$toggle} {
135
+ &__wrapper {
136
+ column-gap: var(--spacing-s);
137
+ }
138
+
139
+ &__label {
140
+ font: var(--typography-text-m-medium);
141
+ }
142
+
143
+ &__sublabel {
144
+ font: var(--typography-text-s-regular);
145
+ }
146
+
147
+ &__toggle {
148
+ width: 56px;
149
+ height: 32px;
150
+ border-radius: var(--corner-radius-l);
151
+
152
+ &::before {
153
+ inset: 2px;
154
+ width: 28px;
155
+ height: 28px;
156
+ }
157
+ }
158
+ }
159
+
160
+ &.--is-active-value {
161
+ #{$toggle} {
162
+ &__toggle {
163
+ &::before {
164
+ left: calc(100% - 30px);
165
+ }
166
+ }
167
+ }
168
+ }
169
+ }
170
+
171
+ &.--small-size {
172
+ #{$toggle} {
173
+ &__wrapper {
174
+ column-gap: var(--spacing-l);
175
+ }
176
+
177
+ &__label {
178
+ font: var(--typography-text-s-medium);
179
+ }
180
+
181
+ &__sublabel {
182
+ font: var(--typography-text-xs-regular);
183
+ }
184
+
185
+ &__toggle {
186
+ width: 40px;
187
+ height: 24px;
188
+ border-radius: var(--corner-radius-m);
189
+
190
+ &::before {
191
+ inset: 2px;
192
+ width: 20px;
193
+ height: 20px;
194
+ }
195
+ }
196
+ }
197
+
198
+ &.--is-active-value {
199
+ #{$toggle} {
200
+ &__toggle {
201
+ &::before {
202
+ left: calc(100% - 22px);
203
+ }
204
+ }
205
+ }
206
+ }
207
+ }
208
+
209
+ #{$toggle} {
210
+ &__wrapper {
211
+ @include hover {
212
+ #{$toggle} {
213
+ &__toggle {
214
+ background: var(--primary-black-400);
215
+ }
216
+ }
217
+ }
218
+ }
219
+
220
+ &__label {
221
+ color: var(--primary-text-primary);
222
+ }
223
+
224
+ &__sublabel {
225
+ color: var(--primary-text-tertiary);
226
+ }
227
+
228
+ &__toggle {
229
+ background: var(--primary-black-300);
230
+
231
+ @include focused {
232
+ outline: 4px solid var(--effects-primary-focus);
233
+ }
234
+
235
+ &::before {
236
+ background: var(--primary-black-white);
237
+ }
238
+ }
239
+ }
240
+
241
+ &.--is-active-value {
242
+ #{$toggle} {
243
+ &__toggle {
244
+ background: var(--primary-blue);
245
+ }
246
+
247
+ &__wrapper {
248
+ @include hover {
249
+ #{$toggle} {
250
+ &__toggle {
251
+ background: var(--primary-blue-deep);
252
+ }
253
+ }
254
+ }
255
+ }
256
+ }
257
+ }
258
+
259
+ @include is-disabled-state {
260
+ #{$toggle} {
261
+ &__toggle {
262
+ background: var(--primary-black-100);
263
+
264
+ &::before {
265
+ background: var(--primary-black-50);
266
+ }
267
+ }
268
+ }
269
+ }
270
+ }
271
+ </style>