plugin-ui-for-kzt 0.0.9 → 0.0.10

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 (93) hide show
  1. package/example/App.vue +355 -0
  2. package/example/index.html +12 -0
  3. package/example/main.ts +8 -0
  4. package/example/shims-vue.d.ts +5 -0
  5. package/package.json +17 -7
  6. package/src/assets/icons/arrow-down.svg +3 -0
  7. package/src/assets/icons/calendar.svg +12 -0
  8. package/src/assets/icons/checkbox-circle.svg +3 -0
  9. package/src/assets/icons/checkbox.svg +3 -0
  10. package/src/assets/icons/email-sms.svg +4 -0
  11. package/src/assets/icons/help.svg +3 -0
  12. package/src/assets/icons/kg.svg +16 -0
  13. package/src/assets/icons/kz.svg +42 -0
  14. package/src/assets/icons/loader.svg +13 -0
  15. package/src/assets/icons/ru.svg +12 -0
  16. package/src/assets/icons/uz.svg +26 -0
  17. package/src/components/BaseBreadCrumbs/BaseBreadCrumbs.vue +142 -0
  18. package/src/components/BaseBreadCrumbs/README.md +49 -0
  19. package/src/components/BaseButton/BaseButton.vue +489 -0
  20. package/src/components/BaseButton/README.md +53 -0
  21. package/src/components/BaseCalendar/BaseCalendar.vue +231 -0
  22. package/src/components/BaseCalendar/README.md +126 -0
  23. package/src/components/BaseCheckbox/BaseCheckbox.vue +252 -0
  24. package/src/components/BaseCheckbox/README.md +110 -0
  25. package/src/components/BaseDropdown/BaseDropdown.vue +160 -0
  26. package/src/components/BaseDropdown/README.md +91 -0
  27. package/src/components/BaseIcon/BaseIcon.vue +47 -0
  28. package/src/components/BaseIcon/README.md +35 -0
  29. package/src/components/BaseInput/BaseInput.vue +300 -0
  30. package/src/components/BaseInput/README.md +85 -0
  31. package/src/components/BaseInputCalendar/BaseInputCalendar.vue +242 -0
  32. package/src/components/BaseInputCalendar/README.md +84 -0
  33. package/src/components/BaseInputCurrency/BaseInputCurrency.vue +198 -0
  34. package/src/components/BaseInputCurrency/README.md +57 -0
  35. package/src/components/BaseInputEmail/BaseInputEmail.vue +89 -0
  36. package/src/components/BaseInputEmail/README.md +71 -0
  37. package/src/components/BaseInputPhone/BaseInputPhone.vue +175 -0
  38. package/src/components/BaseLoader/BaseLoader.vue +45 -0
  39. package/src/components/BaseLoader/README.md +29 -0
  40. package/src/components/BaseOpenedListItem/BaseOpenedListItem.vue +216 -0
  41. package/src/components/BaseOpenedListItem/README.md +67 -0
  42. package/src/components/BaseRadio/BaseRadio.vue +283 -0
  43. package/src/components/BaseRadio/README.md +74 -0
  44. package/src/components/BaseSegmentedButtons/BaseSegmentedButtons.vue +89 -0
  45. package/src/components/BaseSegmentedButtons/README.md +75 -0
  46. package/src/components/BaseSelect/BaseSelect.vue +370 -0
  47. package/src/components/BaseSelect/README.md +95 -0
  48. package/src/components/BaseSiteInput/BaseSiteInput.vue +153 -0
  49. package/src/components/BaseTextarea/BaseTextarea.vue +212 -0
  50. package/src/components/BaseTextarea/README.md +75 -0
  51. package/src/components/BaseToggle/BaseToggle.vue +271 -0
  52. package/src/components/BaseToggle/README.md +76 -0
  53. package/src/components/BaseTooltip/BaseTooltip.vue +318 -0
  54. package/src/components/BaseTooltip/README.md +74 -0
  55. package/src/components/Modal/Modal.vue +3 -1
  56. package/src/components/Spinner/Spinner.vue +2 -1
  57. package/src/composables/kit/color.ts +14 -0
  58. package/src/composables/kit/interactive.ts +53 -0
  59. package/src/composables/kit/size.ts +15 -0
  60. package/src/composables/kit/state.ts +28 -0
  61. package/src/composables/kit/style.ts +18 -0
  62. package/src/composables/kit/utils.ts +7 -0
  63. package/src/icons/index.ts +9 -0
  64. package/src/index.ts +93 -2
  65. package/src/shims-context.d.ts +19 -0
  66. package/src/styles/index.scss +2 -1
  67. package/src/styles/root.scss +167 -0
  68. package/src/styles/variables.scss +160 -0
  69. package/src/types/breadcrumbs.d.ts +13 -0
  70. package/src/types/button.d.ts +13 -0
  71. package/src/types/calendar.d.ts +16 -0
  72. package/src/types/checkbox-radio.d.ts +15 -0
  73. package/src/types/dropdown.d.ts +20 -0
  74. package/src/types/icon.d.ts +8 -0
  75. package/src/types/input.d.ts +56 -0
  76. package/src/types/toggle.d.ts +12 -0
  77. package/src/types/tooltip.d.ts +8 -0
  78. package/src/types/utils.d.ts +37 -0
  79. package/src/vue-virtual-scroller.d.ts +9 -0
  80. package/tsconfig.json +3 -1
  81. package/webpack.config.js +90 -35
  82. package/dist/components/DataTable/DataTable.vue.d.ts +0 -3
  83. package/dist/components/Modal/Modal.vue.d.ts +0 -3
  84. package/dist/components/Spinner/Spinner.vue.d.ts +0 -3
  85. package/dist/components/Toaster/Toaster.vue.d.ts +0 -3
  86. package/dist/components/Toaster/timer.d.ts +0 -12
  87. package/dist/components/Tooltip/Tooltip.vue.d.ts +0 -3
  88. package/dist/index.d.ts +0 -11
  89. package/dist/index.js +0 -4929
  90. package/dist/plugins/modalPlugin.d.ts +0 -17
  91. package/dist/plugins/toasterPlugin.d.ts +0 -26
  92. package/dist/store/modal.d.ts +0 -11
  93. package/dist/types/index.d.ts +0 -5
@@ -0,0 +1,45 @@
1
+ <template>
2
+ <div class="loader">
3
+ <div class="loader__circle">
4
+ <base-icon
5
+ class="loader__circle-icon"
6
+ name="loader"
7
+ />
8
+ </div>
9
+ </div>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+ import BaseIcon from '../BaseIcon/BaseIcon.vue';
14
+ </script>
15
+
16
+ <style lang="scss">
17
+ .loader {
18
+ position: relative;
19
+ display: block;
20
+ }
21
+
22
+ .loader__circle {
23
+ position: relative;
24
+ display: flex;
25
+ align-items: center;
26
+ justify-content: center;
27
+ width: 100%;
28
+ background: transparent;
29
+ border-radius: 50%;
30
+ }
31
+
32
+ .loader__circle-icon {
33
+ animation: loader-circle 1s linear infinite;
34
+ }
35
+
36
+ @keyframes loader-circle {
37
+ 0% {
38
+ transform: rotate(0deg);
39
+ }
40
+
41
+ 100% {
42
+ transform: rotate(360deg);
43
+ }
44
+ }
45
+ </style>
@@ -0,0 +1,29 @@
1
+ ### BaseLoader
2
+
3
+ Компонент загрузчика, отображающий анимированное вращающееся колесо. Он может использоваться для индикации загрузки данных или процесса в приложении.
4
+
5
+ ---
6
+
7
+ #### Пример использования
8
+
9
+ ```vue
10
+ <BaseLoader />
11
+ ```
12
+
13
+ ---
14
+
15
+ #### Стилизация
16
+
17
+ - Компонент представляет собой контейнер с кругом, внутри которого вращается иконка.
18
+ - Иконка вращается бесконечно благодаря анимации CSS `@keyframes loader-circle`, которая изменяет ее угол от 0 до 360 градусов за 1 секунду.
19
+ - Контейнер имеет размер 100% по ширине и фиксированную высоту, иконка центрирована внутри контейнера.
20
+
21
+ ---
22
+
23
+ #### Анимация
24
+
25
+ - Анимация выполняется бесконечно и вращает иконку, создавая эффект загрузки.
26
+
27
+ ---
28
+
29
+ Этот компонент можно использовать в интерфейсе для индикации того, что приложение или часть страницы находится в процессе загрузки.
@@ -0,0 +1,216 @@
1
+ <template>
2
+ <component
3
+ :is="actualComponent"
4
+ v-bind="componentAttrs"
5
+ class="base-opened-list-item"
6
+ :class="classList"
7
+ >
8
+ <div class="base-opened-list-item__wrapper">
9
+ <div
10
+ v-if="$slots.icon || icon"
11
+ class="base-opened-list-item__icon"
12
+ >
13
+ <slot
14
+ name="icon"
15
+ :icon="icon"
16
+ >
17
+ </slot>
18
+ </div>
19
+
20
+ <span class="base-opened-list-item__text">
21
+ <slot />
22
+ </span>
23
+
24
+ <div
25
+ v-if="active"
26
+ class="base-opened-list-item__postfix-icon"
27
+ >
28
+
29
+ <base-icon
30
+ name="checkbox-circle"
31
+ :size="size"
32
+ />
33
+ </div>
34
+ </div>
35
+ </component>
36
+ </template>
37
+
38
+ <script setup lang="ts">
39
+ import { computed, useAttrs } from 'vue';
40
+ import { useKitSize } from '../../composables/kit/size'
41
+ import { useKitState } from '../../composables/kit/state'
42
+ import BaseCheckbox from '../BaseCheckbox/BaseCheckbox.vue';
43
+ import type { IBaseOpenedListItemProps } from '../../types/dropdown';
44
+
45
+ const props = withDefaults(defineProps<IBaseOpenedListItemProps>(), {
46
+ tag: 'button',
47
+ active: false,
48
+ size: 'medium',
49
+ });
50
+
51
+ const { stateClassList, stateAttrs } = useKitState(props);
52
+ const attrs = useAttrs();
53
+
54
+ const componentAttrs = computed(() => ({
55
+ ...attrs,
56
+ ...stateAttrs.value,
57
+ }));
58
+
59
+ const { sizeClassList } = useKitSize(props);
60
+
61
+ const classList = computed(() => [
62
+ ...sizeClassList.value,
63
+ ...stateClassList.value,
64
+ {
65
+ '--is-active': props.active,
66
+ '--is-disabled': props.disabled,
67
+ },
68
+ ]);
69
+
70
+ const actualComponent = computed(() => {
71
+ return {
72
+ checkbox: BaseCheckbox,
73
+ button: 'button',
74
+ }[props.tag as 'button'];
75
+ });
76
+ </script>
77
+
78
+ <style scoped lang="scss">
79
+ @import '../../styles/variables';
80
+ @import '../../styles/root';
81
+
82
+ .base-opened-list-item {
83
+ $item: &;
84
+
85
+ display: block;
86
+ padding: 0;
87
+ user-select: none;
88
+ background-color: transparent;
89
+ border: none;
90
+ border-radius: 0;
91
+ outline: none;
92
+ width: 100%;
93
+ display: flex;
94
+
95
+ &__wrapper {
96
+ display: flex;
97
+ align-items: center;
98
+ width: 100%;
99
+ height: 100%;
100
+ text-align: left;
101
+ transition: all var(--ui-transition);
102
+
103
+ @include hover {
104
+ background: var(--primary-black-100);
105
+ }
106
+
107
+ @include pressed {
108
+ background: var(--primary-blue-100);
109
+ }
110
+ }
111
+
112
+ &__icon,
113
+ &__postfix-icon {
114
+ display: flex;
115
+ flex-shrink: 0;
116
+ align-items: center;
117
+ justify-content: center;
118
+ transition: inherit;
119
+ }
120
+
121
+ &__text {
122
+ flex: 1;
123
+ font: var(--ui-typography-body-regular);
124
+ color: var(--primary-text-primary);
125
+ transition: inherit;
126
+ }
127
+
128
+ &.--is-active,
129
+ &.router-link-active,
130
+ &.router-link-exact-active {
131
+ #{$item} {
132
+ &__wrapper {
133
+ background: var(--primary-black-50);
134
+ }
135
+ }
136
+ }
137
+
138
+ &.--is-disabled {
139
+ #{$item} {
140
+ &__text {
141
+ color: var(--primary-text-quaternary);
142
+ }
143
+
144
+ @include is-disabled-state;
145
+ }
146
+ }
147
+
148
+ &.--is-active.--is-disabled {
149
+ #{$item} {
150
+ &__wrapper {
151
+ background: var(--primary-black-100);
152
+ }
153
+ }
154
+ }
155
+
156
+ &.--small-size {
157
+ #{$item} {
158
+ &__wrapper {
159
+ gap: var(--spacing-s);
160
+ height: 14px;
161
+ padding: var(--spacing-s) var(--spacing-2l);
162
+ }
163
+
164
+ &__text {
165
+ font: var(--typography-text-m-regular);
166
+ }
167
+
168
+ &__icon,
169
+ &__postfix-icon {
170
+ width: 20px;
171
+ height: 20px;
172
+ }
173
+ }
174
+ }
175
+
176
+ &.--medium-size {
177
+ #{$item} {
178
+ &__wrapper {
179
+ gap: var(--spacing-m);
180
+ height: 24px;
181
+ padding: var(--spacing-m) var(--spacing-2l);
182
+ }
183
+
184
+ &__text {
185
+ font: var(--typography-text-m-regular);
186
+ }
187
+
188
+ &__icon,
189
+ &__postfix-icon {
190
+ width: 24px;
191
+ height: 24px;
192
+ }
193
+ }
194
+ }
195
+
196
+ &.--large-size {
197
+ #{$item} {
198
+ &__wrapper {
199
+ gap: var(--spacing-l);
200
+ height: 24px;
201
+ padding: var(--spacing-2l) var(--spacing-l);
202
+ }
203
+
204
+ &__text {
205
+ font: var(--typography-text-l-regular);
206
+ }
207
+
208
+ &__icon,
209
+ &__postfix-icon {
210
+ width: 32px;
211
+ height: 32px;
212
+ }
213
+ }
214
+ }
215
+ }
216
+ </style>
@@ -0,0 +1,67 @@
1
+ ### BaseOpenedListItem
2
+
3
+ Компонент, который представляет элемент списка с возможностью отображения иконок и постфиксных элементов (например, флажков или других иконок). Используется в списках, где требуется интерактивность, активное и неактивное состояние, а также стилизация элементов.
4
+
5
+ ---
6
+
7
+ #### Props
8
+
9
+ - `tag?: 'button'`
10
+ Указывает, какой элемент будет использоваться для рендеринга: `'button'` или кастомный компонент (например, `BaseCheckbox`).
11
+
12
+ - `icon?: string`
13
+ Иконка, которая будет отображаться слева от текста. Если не задано, используется слот для иконки.
14
+
15
+ - `postfixIcon?: string`
16
+ Иконка или элемент, который отображается справа от текста. По умолчанию используется компонент `BaseIcon` с именем "checkbox-circle", если `active` установлено в `true`.
17
+
18
+ - `active?: boolean`
19
+ Указывает, активен ли элемент. Если `true`, отображается постфикс-иконка.
20
+
21
+ - `disabled?: boolean`
22
+ Блокирует элемент, делая его неактивным и меняя его внешний вид (в том числе стилизуется как неактивный).
23
+
24
+ - `size?: 'small' | 'medium' | 'large'`
25
+ Устанавливает размер элемента. Доступные значения: `'small'`, `'medium'`, `'large'`.
26
+
27
+ ---
28
+
29
+ #### Поведение
30
+
31
+ - Если значение `active` установлено в `true`, справа от текста появляется иконка.
32
+ - Клик по элементу вызывает его активацию (если элемент не заблокирован).
33
+ - Для каждого из доступных размеров (`small`, `medium`, `large`) компонент меняет внутреннюю стилизацию: размер иконок и отступы.
34
+ - Компонент поддерживает ховер, нажатие и состояние активации для разных состояний (`--is-active`, `--is-disabled`).
35
+ - Используется в списках, где важна интерактивность и стиль.
36
+
37
+ ---
38
+
39
+ #### Стилизация
40
+
41
+ Компонент имеет адаптивный дизайн с тремя размерами (`small`, `medium`, `large`), изменяющими размеры текста, отступы и иконки. В зависимости от состояния элемент может менять цвет фона и текста:
42
+
43
+ - `--is-active` — при активном состоянии элемента.
44
+ - `--is-disabled` — при отключении элемента.
45
+ - Состояния ховера и нажатия применяются через `@include hover` и `@include pressed` в SCSS.
46
+
47
+ ---
48
+
49
+ #### Пример использования
50
+
51
+ ```vue
52
+ <BaseOpenedListItem
53
+ :active="isActive"
54
+ size="medium"
55
+ >
56
+ Основной текст элемента
57
+ </BaseOpenedListItem>
58
+ ```
59
+
60
+ ```ts
61
+ const selected = ref(false);
62
+ const isActive = ref(true);
63
+ ```
64
+
65
+ ---
66
+
67
+ Этот компонент можно использовать для создания динамичных списков с элементами, где каждый элемент может иметь активное состояние, иконки и стилизованное оформление в зависимости от состояния.
@@ -0,0 +1,283 @@
1
+ <template>
2
+ <div
3
+ class="base-radio"
4
+ :class="classList"
5
+ >
6
+ <div class="base-radio__wrapper" @click="handleToggle">
7
+
8
+ <div class="base-radio__input-wrapper">
9
+ <input
10
+ v-model="model"
11
+ v-bind="inputAttrs"
12
+ type="radio"
13
+ class="base-radio__input"
14
+ />
15
+ </div>
16
+
17
+ <div class="base-radio__icon" />
18
+
19
+ <div class="base-radio__label-wrapper">
20
+ <span v-if="label" class="base-radio__label">{{ label }}</span>
21
+
22
+ <span v-if="subLabel" class="base-radio__sublabel">{{ subLabel }}</span>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ import { computed, useAttrs } from 'vue';
30
+ import type { IBaseRadioProps } from '../../types/checkbox-radio';
31
+ import { useKitSize } from '../../composables/kit/size'
32
+ import { useKitState } from '../../composables/kit/state'
33
+
34
+ const props = withDefaults(defineProps<IBaseRadioProps>(), {
35
+ size: 'medium',
36
+ });
37
+
38
+ const emit = defineEmits<{
39
+ (e: 'update:modelValue', value: boolean): void;
40
+ }>();
41
+
42
+ const { sizeClassList } = useKitSize(props);
43
+ const { stateClassList, stateAttrs } = useKitState(props);
44
+
45
+ const model = computed({
46
+ get: () => props.modelValue,
47
+ set: (val) => emit('update:modelValue', val),
48
+ });
49
+
50
+ const attrs = useAttrs();
51
+
52
+ const inputAttrs = computed(() => {
53
+ return {
54
+ ...attrs,
55
+ ...stateAttrs.value,
56
+ id: props.id,
57
+ };
58
+ });
59
+
60
+ function handleToggle() {
61
+ model.value = !model.value;
62
+ }
63
+
64
+ const classList = computed(() => [
65
+ sizeClassList.value,
66
+ stateClassList.value,
67
+ {
68
+ '--is-active': model.value,
69
+ '--is-readonly': props.readonly,
70
+ },
71
+ ]);
72
+ </script>
73
+
74
+ <style scoped lang="scss">
75
+ @import '../../styles/variables';
76
+ @import '../../styles/root';
77
+
78
+ .base-radio {
79
+ $item: &;
80
+
81
+ &__wrapper {
82
+ display: flex;
83
+ column-gap: 10px;
84
+ width: 100%;
85
+ height: 100%;
86
+ cursor: pointer;
87
+ }
88
+
89
+ &__icon {
90
+ position: relative;
91
+ display: flex;
92
+ flex-shrink: 0;
93
+ background: var(--primary-black-white);
94
+ border-radius: 50%;
95
+ transition:
96
+ border-color 0.3s ease,
97
+ background-color 0.3s ease;
98
+
99
+ &::before,
100
+ &::after {
101
+ position: absolute;
102
+ top: 50%;
103
+ left: 50%;
104
+ width: 100%;
105
+ height: 100%;
106
+ content: '';
107
+ border-radius: 50%;
108
+ transform: translate3d(-50%, -50%, 0);
109
+ }
110
+
111
+ &::before {
112
+ background: var(--primary-blue-50);
113
+ opacity: 0;
114
+ transition: opacity 0.3s ease;
115
+ }
116
+
117
+ &::after {
118
+ background: var(--primary-blue);
119
+ opacity: 0;
120
+ transition:
121
+ opacity 0.3s ease,
122
+ transform 0.3s ease;
123
+ transform: translate3d(-50%, -50%, 0) scale(0.4);
124
+ }
125
+ }
126
+
127
+ &.--is-readonly {
128
+ pointer-events: none;
129
+ }
130
+
131
+ &.--medium-size {
132
+ #{$item} {
133
+ &__wrapper {
134
+ column-gap: var(--spacing-m);
135
+ }
136
+
137
+ &__label {
138
+ font: var(--typography-text-m-medium);
139
+ }
140
+
141
+ &__sublabel {
142
+ font: var(--typography-text-s-regular);
143
+ }
144
+
145
+ &__icon {
146
+ width: 32px;
147
+ height: 32px;
148
+ border: 2px solid var(--primary-black-400);
149
+
150
+ &::before {
151
+ width: calc(100% - 4px);
152
+ height: calc(100% - 4px);
153
+ }
154
+ }
155
+ }
156
+
157
+ &.--is-active {
158
+ #{$item} {
159
+ &__icon {
160
+ &::after {
161
+ width: 13px;
162
+ height: 13px;
163
+ }
164
+ }
165
+ }
166
+ }
167
+ }
168
+
169
+ &.--small-size {
170
+ #{$item} {
171
+ &__wrapper {
172
+ column-gap: var(--spacing-s);
173
+ }
174
+
175
+ &__label {
176
+ font: var(--typography-text-s-medium);
177
+ }
178
+
179
+ &__sublabel {
180
+ font: var(--typography-text-xs-regular);
181
+ }
182
+
183
+ &__icon {
184
+ width: 24px;
185
+ height: 24px;
186
+ border: 1.5px solid var(--primary-black-400);
187
+
188
+ &::before {
189
+ width: calc(100% - 2px);
190
+ height: calc(100% - 2px);
191
+ }
192
+ }
193
+ }
194
+
195
+ &.--is-active {
196
+ #{$item} {
197
+ &__icon {
198
+ &::after {
199
+ width: 9px;
200
+ height: 9px;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+
207
+ &__input-wrapper {
208
+ position: relative;
209
+ cursor: pointer;
210
+ transition: all 0.25s ease-out;
211
+
212
+ @include focused {
213
+ outline: 4px solid var(--effects-primary-focus);
214
+ }
215
+ }
216
+
217
+ &__input {
218
+ position: absolute;
219
+ inset: 0;
220
+ width: 100%;
221
+ height: 100%;
222
+ cursor: pointer;
223
+ opacity: 0 !important;
224
+ }
225
+
226
+ &__label-wrapper {
227
+ display: flex;
228
+ flex-direction: column;
229
+ justify-content: center;
230
+ cursor: pointer;
231
+ }
232
+
233
+ &__label {
234
+ color: var(--primary-text-primary);
235
+ user-select: none;
236
+ }
237
+
238
+ &__sublabel {
239
+ color: var(--primary-text-tertiary);
240
+ user-select: none;
241
+ }
242
+
243
+ @include hover {
244
+ #{$item} {
245
+ &__icon {
246
+ background-color: var(--primary-blue-100);
247
+ border-color: var(--primary-blue-deep);
248
+ }
249
+ }
250
+ }
251
+
252
+ &.--is-active {
253
+ #{$item} {
254
+ &__icon {
255
+ border: 2px solid var(--primary-blue);
256
+
257
+ &::before {
258
+ opacity: 1;
259
+ }
260
+
261
+ &::after {
262
+ opacity: 1;
263
+ transform: translate3d(-50%, -50%, 0) scale(1);
264
+ }
265
+ }
266
+ }
267
+ }
268
+
269
+ @include is-disabled-state {
270
+ #{$item} {
271
+ &__icon {
272
+ background: var(--primary-black-50);
273
+ border: 1px solid var(--primary-black-300);
274
+
275
+ &::after {
276
+ background: var(--primary-black-300);
277
+ }
278
+ }
279
+ }
280
+ }
281
+ }
282
+ </style>
283
+