@avakhula/ui 0.0.32 → 0.0.34-4.1

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 (89) hide show
  1. package/.eslintrc.cjs +17 -10
  2. package/.storybook/preview-head.html +1 -0
  3. package/dist/index.js +9040 -7752
  4. package/dist/index.umd.cjs +87 -88
  5. package/dist/style.css +1 -1
  6. package/package.json +15 -15
  7. package/src/App.vue +138 -25
  8. package/src/assets/scss/mixins/dropdown-list-item.scss +8 -1
  9. package/src/assets/scss/mixins/tooltip-position.scss +1 -1
  10. package/src/assets/scss/variables/shadows.json +14 -30
  11. package/src/assets/scss/variables/shadows.scss +10 -15
  12. package/src/components/Accordion/Accordion.scss +4 -1
  13. package/src/components/Accordion/Accordion.vue +20 -3
  14. package/src/components/Accordion/Acordion.spec.js +75 -0
  15. package/src/components/Alert/Alert.spec.js +69 -0
  16. package/src/components/Alert/Alert.stories.js +1 -4
  17. package/src/components/Alert/Alert.vue +22 -3
  18. package/src/components/Alert/alert.scss +22 -0
  19. package/src/components/Alert/constants.js +1 -0
  20. package/src/components/Avatar/Avatar.stories.js +23 -0
  21. package/src/components/Avatar/Avatar.vue +125 -0
  22. package/src/components/Avatar/constants.js +4 -0
  23. package/src/components/Badge/Badge.spec.js +37 -0
  24. package/src/components/Badge/Badge.vue +1 -1
  25. package/src/components/Button/Button.spec.js +85 -0
  26. package/src/components/Button/Button.vue +14 -3
  27. package/src/components/Button/button.scss +5 -0
  28. package/src/components/Dropdown/Dropdown.vue +3 -3
  29. package/src/components/Dropdown/DropdownItem.vue +9 -3
  30. package/src/components/Form/Checkbox/Checkbox.scss +79 -53
  31. package/src/components/Form/Checkbox/Checkbox.stories.js +4 -2
  32. package/src/components/Form/Checkbox/Checkbox.vue +70 -48
  33. package/src/components/Form/CheckboxGroup/CheckboxGroup.vue +11 -0
  34. package/src/components/Form/CheckboxGroup/readme.mdx +2 -0
  35. package/src/components/Form/DatePicker/DatePicker.scss +259 -261
  36. package/src/components/Form/DatePicker/DatePicker.vue +1 -1
  37. package/src/components/Form/Input/Input.vue +69 -15
  38. package/src/components/Form/Input/constants.js +1 -0
  39. package/src/components/Form/Input/input.scss +33 -6
  40. package/src/components/Form/Label/Label.stories.js +7 -0
  41. package/src/components/Form/Label/Label.vue +43 -4
  42. package/src/components/Form/Label/readme.mdx +1 -0
  43. package/src/components/Form/PhoneInput/phoneInput.scss +3 -2
  44. package/src/components/Form/Radio/Radio.vue +31 -38
  45. package/src/components/Form/Radio/radio.scss +6 -3
  46. package/src/components/Form/Toggle/Toggle.vue +5 -1
  47. package/src/components/Form/Toggle/toggle.scss +4 -4
  48. package/src/components/IconButton/IconButton.scss +7 -0
  49. package/src/components/IconButton/IconButton.vue +10 -9
  50. package/src/components/List.vue +1 -1
  51. package/src/components/Modal/Modal.stories.js +6 -4
  52. package/src/components/Modal/Modal.vue +56 -11
  53. package/src/components/Pagination/LimitSelector.vue +3 -5
  54. package/src/components/Pagination/Pagination.vue +3 -0
  55. package/src/components/Pagination/pagination.scss +8 -14
  56. package/src/components/Panel/Panel.stories.js +0 -7
  57. package/src/components/Panel/Panel.vue +30 -29
  58. package/src/components/Popover/Popover.vue +43 -17
  59. package/src/components/Popover/constants.js +1 -1
  60. package/src/components/Popover/popover.scss +28 -8
  61. package/src/components/ProgressBar/ProgressBar.vue +14 -1
  62. package/src/components/ProgressBar/constants.js +1 -0
  63. package/src/components/ProgressBar/progressBar.scss +7 -0
  64. package/src/components/Sorting/Sorting.stories.js +12 -2
  65. package/src/components/Sorting/Sorting.vue +125 -37
  66. package/src/components/Sorting/sorting.scss +17 -14
  67. package/src/components/SplitButton/SplitButton.vue +8 -1
  68. package/src/components/SplitButton/splitButton.scss +3 -0
  69. package/src/components/StatusIndicator/icons.js +11 -11
  70. package/src/components/Tabs/Tabs.vue +25 -2
  71. package/src/components/Tabs/tabs.scss +1 -1
  72. package/src/components/ToggleTip/constants.js +1 -1
  73. package/src/components/ToggleTip/toggleTip.scss +2 -2
  74. package/src/components/Tooltip/Tooltip.vue +120 -4
  75. package/src/components/TreeSelect/Option.vue +36 -27
  76. package/src/components/TreeSelect/Select.stories.js +6 -88
  77. package/src/components/TreeSelect/Select.vue +272 -130
  78. package/src/components/TreeSelect/scss/option.scss +4 -0
  79. package/src/components/TreeSelect/scss/select.scss +51 -6
  80. package/src/directives/tooltip/TooltipController.js +184 -0
  81. package/src/directives/tooltip/readme.mdx +17 -0
  82. package/src/directives/tooltip/textOverflowTooltip.js +21 -49
  83. package/src/directives/tooltip/tooltip.js +57 -45
  84. package/src/directives/tooltip/tooltip.stories.js +39 -0
  85. package/src/helpers/removeEvents.js +2 -2
  86. package/src/index.js +1 -0
  87. package/src/main.js +1 -0
  88. package/src/scripts/parseScssVariables.js +23 -7
  89. package/src/components/Panel/constants.js +0 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avakhula/ui",
3
- "version": "0.0.32",
3
+ "version": "0.0.344.1",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.umd.cjs",
6
6
  "source": "src/index.js",
@@ -15,8 +15,8 @@
15
15
  "build": "vite build",
16
16
  "preview": "vite preview",
17
17
  "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --ignore-path .gitignore",
18
- "test:unit": "vitest",
19
- "test:unit:coverage": "vitest run --coverage",
18
+ "test": "vitest",
19
+ "test:coverage": "vitest run --coverage",
20
20
  "storybook": "storybook dev 6006",
21
21
  "build-storybook": "storybook build"
22
22
  },
@@ -29,23 +29,23 @@
29
29
  "@babel/core": "^7.20.7",
30
30
  "@babel/preset-env": "^7.21.4",
31
31
  "@rushstack/eslint-patch": "^1.1.4",
32
- "@storybook/addon-a11y": "^7.0.11",
33
- "@storybook/addon-actions": "^7.0.11",
34
- "@storybook/addon-docs": "^7.0.11",
35
- "@storybook/addon-essentials": "^7.0.11",
36
- "@storybook/addon-interactions": "^7.0.11",
37
- "@storybook/addon-links": "^7.0.11",
38
- "@storybook/addon-mdx-gfm": "^7.0.11",
39
- "@storybook/testing-library": "^0.1.0",
40
- "@storybook/vue3": "^7.0.11",
41
- "@storybook/vue3-vite": "^7.0.11",
32
+ "@storybook/addon-a11y": "^7.1.0",
33
+ "@storybook/addon-actions": "^7.1.0",
34
+ "@storybook/addon-docs": "^7.1.0",
35
+ "@storybook/addon-essentials": "^7.1.0",
36
+ "@storybook/addon-interactions": "^7.1.0",
37
+ "@storybook/addon-links": "^7.1.0",
38
+ "@storybook/addon-mdx-gfm": "^7.1.0",
39
+ "@storybook/testing-library": "^0.2.0",
40
+ "@storybook/vue3": "^7.1.0",
41
+ "@storybook/vue3-vite": "^7.1.0",
42
42
  "@vitejs/plugin-vue": "^4.0.0",
43
43
  "@vitest/coverage-c8": "^0.28.4",
44
44
  "@vue/eslint-config-prettier": "^7.0.0",
45
45
  "@vue/test-utils": "^2.2.10",
46
46
  "babel-loader": "^8.3.0",
47
47
  "eslint": "^8.22.0",
48
- "eslint-plugin-storybook": "^0.6.12",
48
+ "eslint-plugin-storybook": "^0.6.13",
49
49
  "eslint-plugin-vue": "^9.3.0",
50
50
  "flatpickr": "^4.6.13",
51
51
  "jsdom": "^21.1.0",
@@ -56,7 +56,7 @@
56
56
  "react-dom": "^18.2.0",
57
57
  "sass": "^1.57.1",
58
58
  "sass-loader": "^13.2.0",
59
- "storybook": "^7.0.11",
59
+ "storybook": "^7.1.0",
60
60
  "vite": "^4.0.0",
61
61
  "vitest": "^0.28.4",
62
62
  "vue-loader": "^16.8.3",
package/src/App.vue CHANGED
@@ -1,32 +1,145 @@
1
1
  <template>
2
- test
3
- <ib-panel>
4
- <template #title>
5
- Some title
2
+ <ib-select :options="opt">
3
+ <template v-slot:triggerContent="{ selectedCount }">
4
+ {{ selectedCount }}
6
5
  </template>
7
- <template #head-content>Some long long description</template>
8
- <template #body>
9
- <p>tests</p>
10
- <p>tests</p>
11
- <p>tests</p>
12
- <p>tests</p>
13
- <p>tests</p>
14
- <p>tests</p>
15
- <p>tests</p>
16
- <p>tests</p>
17
- <p>tests</p>
18
- </template>
19
- </ib-panel>
6
+ </ib-select>
7
+
8
+
20
9
  </template>
21
10
 
22
11
  <script>
23
- // import IbPanel from "./components/Panel/Panel.vue"
24
- import { IbPanel } from "./index";
12
+ import IbSelect from "./components/TreeSelect/Select.vue";
13
+ import label from "@/components/Form/Label/Label.vue";
14
+ import {IbCheckboxGroup} from "./index.js";
15
+ import {IbRadio} from "./index.js";
16
+ const testData1 = [
17
+ {
18
+ id: "1",
19
+ title: "A Education",
20
+ is_category: true,
21
+ initiallyVisible: true,
22
+ visible: true,
23
+ isDisabled: true,
24
+ checked: false,
25
+ isChildrenVisible: false,
26
+ },
27
+ {
28
+ id: "2",
29
+ title: "Education 2",
30
+ is_category: true,
31
+ initiallyVisible: true,
32
+ visible: true,
33
+ isDisabled: true,
34
+ checked: false,
35
+ isChildrenVisible: true,
36
+ },
37
+ {
38
+ id: "3",
39
+ title: "Education 3",
40
+ is_category: true,
41
+ initiallyVisible: true,
42
+ visible: true,
43
+ isDisabled: false,
44
+ checked: false,
45
+ isChildrenVisible: true,
46
+ },
47
+ {
48
+ id: "4",
49
+ title: "Education 4",
50
+ is_category: true,
51
+ initiallyVisible: true,
52
+ visible: true,
53
+ isDisabled: false,
54
+ checked: false,
55
+ isChildrenVisible: true,
56
+ },
57
+ {
58
+ id: "5",
59
+ title: "Education 5",
60
+ is_category: true,
61
+ initiallyVisible: true,
62
+ visible: true,
63
+ isDisabled: true,
64
+ checked: false,
65
+ isChildrenVisible: true,
66
+ },
67
+
68
+ {
69
+ id: "6",
70
+ title: "Education 6",
71
+ is_category: true,
72
+ initiallyVisible: true,
73
+ visible: true,
74
+ isDisabled: false,
75
+ checked: false,
76
+ isChildrenVisible: true,
77
+ },
78
+
79
+ {
80
+ id: "7",
81
+ title: "Education 7",
82
+ is_category: true,
83
+ initiallyVisible: true,
84
+ visible: true,
85
+ isDisabled: false,
86
+ checked: false,
87
+ isChildrenVisible: true,
88
+ },
89
+
90
+ {
91
+ id: "8",
92
+ title: "Education 8",
93
+ is_category: true,
94
+ initiallyVisible: true,
95
+ visible: true,
96
+ isDisabled: false,
97
+ checked: false,
98
+ isChildrenVisible: true,
99
+ },
100
+ {
101
+ id: "9",
102
+ title: "Education 9",
103
+ is_category: true,
104
+ initiallyVisible: true,
105
+ visible: true,
106
+ isDisabled: false,
107
+ checked: false,
108
+ isChildrenVisible: true,
109
+ },
110
+ {
111
+ id: "10",
112
+ title: "Education 10",
113
+ is_category: true,
114
+ initiallyVisible: true,
115
+ visible: true,
116
+ isDisabled: false,
117
+ checked: false,
118
+ isChildrenVisible: true,
119
+ },
120
+ {
121
+ id: "11",
122
+ title: "Education 11",
123
+ is_category: true,
124
+ initiallyVisible: true,
125
+ visible: true,
126
+ isDisabled: true,
127
+ checked: false,
128
+ isChildrenVisible: true,
129
+ },
130
+ ];
25
131
  export default {
26
- components: {
27
- IbPanel,
132
+ computed: {
133
+ label() {
134
+ return label
135
+ }
136
+ },
137
+ data() {
138
+ return {
139
+ opt: testData1,
140
+ checked: '1'
141
+ }
28
142
  },
29
- };
30
- </script>
31
- <style lang="scss">
32
- </style>
143
+ components: {IbSelect, IbCheckboxGroup, IbRadio}
144
+ }
145
+ </script>
@@ -20,7 +20,14 @@
20
20
  cursor: pointer;
21
21
  transition: background-color 0.3s, border-color 0.3s;
22
22
  @include lineClamp(1);
23
-
23
+ display: flex;
24
+ align-items: center;
25
+
26
+ ion-icon {
27
+ font-size: 16px;
28
+ margin-right: 15px;
29
+ }
30
+
24
31
  p {
25
32
  @include lineClamp(1);
26
33
  }
@@ -10,7 +10,7 @@
10
10
  }
11
11
 
12
12
  &.ib {
13
- &-top-Left {
13
+ &-top-left {
14
14
  bottom: calc(100% + 5px);
15
15
  right: calc(50% - 14px);
16
16
 
@@ -1,58 +1,42 @@
1
1
  [
2
- {
3
- "name": "$ib-shadow-m1",
4
- "value": "0px 0px 1px rgba(0, 0, 0, 0.2)"
5
- },
6
- {
7
- "name": "$ib-shadow-m2",
8
- "value": "0px 0px 1px rgba(0, 0, 0, 0.25)"
9
- },
10
- {
11
- "name": "$ib-shadow-m3",
12
- "value": "0px 0px 1px rgba(0, 0, 0, 0.15), 0px 1px 5px rgba(0, 0, 0, 0.1)"
13
- },
14
2
  {
15
3
  "name": "$ib-shadow-1",
16
- "value": "0px 0px 10px rgba(49, 63, 80, 0.05)"
4
+ "value": "0px 0px 4px 0px rgba(49, 63, 80, 0.15), 0px 1px 2px 0px rgba(0, 0, 0, 0.15)"
17
5
  },
18
6
  {
19
7
  "name": "$ib-shadow-2",
20
- "value": "0px 4px 4px rgba(49, 63, 80, 0.1)"
8
+ "value": "0px 1px 8px 0px rgba(49, 63, 80, 0.15), 0px 1px 2px 0px rgba(0, 0, 0, 0.15)"
21
9
  },
22
10
  {
23
11
  "name": "$ib-shadow-3",
24
- "value": "0px 3px 10px rgba(49, 63, 80, 0.14)"
12
+ "value": "0px 2px 10px 0px rgba(49, 63, 80, 0.15), 0px 1px 3px 0px rgba(0, 0, 0, 0.15)"
25
13
  },
26
14
  {
27
15
  "name": "$ib-shadow-4",
28
- "value": "0px 1px 10px rgba(49, 63, 80, 0.25)"
16
+ "value": "0px 4px 15px 0px rgba(49, 63, 80, 0.15), 0px 2px 3px 0px rgba(0, 0, 0, 0.15)"
29
17
  },
30
18
  {
31
19
  "name": "$ib-shadow-5",
32
- "value": "0px 5px 15px rgba(80, 80, 80, 0.15)"
20
+ "value": "0px 8px 20px 0px rgba(49, 63, 80, 0.15), 0px 4px 4px 0px rgba(0, 0, 0, 0.15)"
33
21
  },
34
22
  {
35
23
  "name": "$ib-shadow-6",
36
- "value": "0px 7px 20px rgba(49, 63, 80, 0.15)"
37
- },
38
- {
39
- "name": "$ib-shadow-7",
40
- "value": "0px 15px 25px rgba(49, 63, 80, 0.05)"
41
- },
42
- {
43
- "name": "$ib-shadow-r",
44
- "value": "-2px 0px 7px rgba(80, 80, 80, 0.1)"
24
+ "value": "0px 12px 25px 0px rgba(49, 63, 80, 0.15), 0px 6px 5px 0px rgba(0, 0, 0, 0.15)"
45
25
  },
46
26
  {
47
27
  "name": "$ib-shadow-r1",
48
- "value": "-4px 0px 14px rgba(80, 80, 80, 0.1)"
28
+ "value": "-2px 0px 7px 0px rgba(80, 80, 80, 0.10)"
49
29
  },
50
30
  {
51
- "name": "$ib-shadow-l",
52
- "value": "2px 0px 7px rgba(80, 80, 80, 0.1)"
31
+ "name": "$ib-shadow-r2",
32
+ "value": "-4px 0px 14px 0px rgba(80, 80, 80, 0.10)"
53
33
  },
54
34
  {
55
35
  "name": "$ib-shadow-l1",
56
- "value": "4px 0px 14px rgba(80, 80, 80, 0.1)"
36
+ "value": "2px 0px 7px 0px rgba(80, 80, 80, 0.10)"
37
+ },
38
+ {
39
+ "name": "$ib-shadow-l2",
40
+ "value": "4px 0px 14px 0px rgba(80, 80, 80, 0.10)"
57
41
  }
58
42
  ]
@@ -1,17 +1,12 @@
1
- $ib-shadow-m1: 0px 0px 1px rgba(0, 0, 0, 0.2);
2
- $ib-shadow-m2: 0px 0px 1px rgba(0, 0, 0, 0.25);
3
- $ib-shadow-m3: 0px 0px 1px rgba(0, 0, 0, 0.15), 0px 1px 5px rgba(0, 0, 0, 0.1);
1
+ $ib-shadow-1: 0px 0px 4px 0px rgba(49, 63, 80, 0.15), 0px 1px 2px 0px rgba(0, 0, 0, 0.15);
2
+ $ib-shadow-2: 0px 1px 8px 0px rgba(49, 63, 80, 0.15), 0px 1px 2px 0px rgba(0, 0, 0, 0.15);
3
+ $ib-shadow-3: 0px 2px 10px 0px rgba(49, 63, 80, 0.15), 0px 1px 3px 0px rgba(0, 0, 0, 0.15);
4
+ $ib-shadow-4: 0px 4px 15px 0px rgba(49, 63, 80, 0.15), 0px 2px 3px 0px rgba(0, 0, 0, 0.15);
5
+ $ib-shadow-5: 0px 8px 20px 0px rgba(49, 63, 80, 0.15), 0px 4px 4px 0px rgba(0, 0, 0, 0.15);
6
+ $ib-shadow-6: 0px 12px 25px 0px rgba(49, 63, 80, 0.15), 0px 6px 5px 0px rgba(0, 0, 0, 0.15);
4
7
 
5
- $ib-shadow-1: 0px 0px 10px rgba(49, 63, 80, 0.05);
6
- $ib-shadow-2: 0px 4px 4px rgba(49, 63, 80, 0.1);
7
- $ib-shadow-3: 0px 3px 10px rgba(49, 63, 80, 0.14);
8
- $ib-shadow-4: 0px 1px 10px rgba(49, 63, 80, 0.25);
9
- $ib-shadow-5: 0px 5px 15px rgba(80, 80, 80, 0.15);
10
- $ib-shadow-6: 0px 7px 20px rgba(49, 63, 80, 0.15);
11
- $ib-shadow-7: 0px 15px 25px rgba(49, 63, 80, 0.05);
8
+ $ib-shadow-r1: -2px 0px 7px 0px rgba(80, 80, 80, 0.10);
9
+ $ib-shadow-r2: -4px 0px 14px 0px rgba(80, 80, 80, 0.10);
12
10
 
13
- $ib-shadow-r: -2px 0px 7px rgba(80, 80, 80, 0.1);
14
- $ib-shadow-r1: -4px 0px 14px rgba(80, 80, 80, 0.1);
15
-
16
- $ib-shadow-l: 2px 0px 7px rgba(80, 80, 80, 0.1);
17
- $ib-shadow-l1: 4px 0px 14px rgba(80, 80, 80, 0.1);
11
+ $ib-shadow-l1: 2px 0px 7px 0px rgba(80, 80, 80, 0.10);
12
+ $ib-shadow-l2: 4px 0px 14px 0px rgba(80, 80, 80, 0.10);
@@ -76,10 +76,13 @@ $content-bg: $gray-50;
76
76
  .accordion-content {
77
77
  border-radius: 0 0 4px 4px;
78
78
  border: 1px solid $content-border-color;
79
- padding:10px 15px 15px;
80
79
  overflow: hidden;
81
80
  transition: height 0.3s, padding-top 0.3s, padding-bottom 0.3s;
82
81
  background-color: $content-bg;
82
+
83
+ .accordion-content-wrapper {
84
+ padding: 10px 15px 15px;
85
+ }
83
86
  }
84
87
 
85
88
  &.active {
@@ -1,6 +1,13 @@
1
1
  <template>
2
2
  <div class="ib-accordion" :class="{ active: isActive }">
3
- <button class="accordion-title" @click="onClick">
3
+ <button
4
+ class="accordion-title"
5
+ :id="'accordion' + uuid"
6
+ :aria-controls="'accordion-section-' + uuid"
7
+ :aria-expanded="isActive"
8
+ type="button"
9
+ @click.prevent="onClick"
10
+ >
4
11
  <slot name="title"></slot>
5
12
 
6
13
  <ib-icon class="chevron-icon" name="chevron-down-outline" />
@@ -12,14 +19,23 @@
12
19
  @after-enter="afterEnter"
13
20
  @leave="leave"
14
21
  >
15
- <div v-show="isActive" class="accordion-content">
16
- <slot name="content"></slot>
22
+ <div
23
+ v-show="isActive"
24
+ role="region"
25
+ class="accordion-content"
26
+ :id="'accordion-section-' + uuid"
27
+ :aria-labelledby="'accordion' + uuid"
28
+ >
29
+ <div class="accordion-content-wrapper">
30
+ <slot></slot>
31
+ </div>
17
32
  </div>
18
33
  </Transition>
19
34
  </div>
20
35
  </template>
21
36
 
22
37
  <script>
38
+ import generateUID from "../../helpers/generateUID";
23
39
  import expandAnimation from "../../mixins/expandAnimation";
24
40
  import IbIcon from "../Icon.vue";
25
41
 
@@ -40,6 +56,7 @@ export default {
40
56
  data() {
41
57
  return {
42
58
  isActive: this.isOpen,
59
+ uuid: generateUID(),
43
60
  };
44
61
  },
45
62
  methods: {
@@ -0,0 +1,75 @@
1
+ import { mount } from "@vue/test-utils";
2
+ import { describe, expect, it } from "vitest";
3
+ import Accordion from "./Accordion.vue";
4
+
5
+ const ROOT_CLASS = "ib-accordion";
6
+ const ROOT_ACTIVE_CLASS = "active";
7
+
8
+ let wrapper;
9
+ const createComponent = (props = {}, slots = {}) => {
10
+ return mount(Accordion, {
11
+ propsData: props,
12
+ slots,
13
+ });
14
+ };
15
+
16
+ const findContent = () => wrapper.find(".accordion-content");
17
+ const findTitle = () => wrapper.find(".accordion-title");
18
+
19
+ describe("Accordion", () => {
20
+ it("Default render", () => {
21
+ wrapper = createComponent();
22
+
23
+ expect(wrapper.classes()).toContain(ROOT_CLASS);
24
+ expect(wrapper.classes()).not.toContain(ROOT_ACTIVE_CLASS);
25
+ expect(findContent().isVisible()).toBe(false);
26
+ });
27
+
28
+ it("Opened accordion render", () => {
29
+ wrapper = createComponent({
30
+ isOpen: true,
31
+ });
32
+
33
+ expect(wrapper.classes()).toContain(ROOT_CLASS);
34
+ expect(wrapper.classes()).toContain(ROOT_ACTIVE_CLASS);
35
+ expect(findContent().isVisible()).toBe(true);
36
+ });
37
+
38
+ it("Accordion with correct slot render", () => {
39
+ const TITLE_CONTENT = "Some title";
40
+ const BODY_CONTENT = "Some content";
41
+
42
+ wrapper = createComponent(
43
+ {},
44
+ {
45
+ title: TITLE_CONTENT,
46
+ content: BODY_CONTENT,
47
+ }
48
+ );
49
+ expect(findTitle().html()).toContain(TITLE_CONTENT);
50
+ expect(findContent().html()).toContain(BODY_CONTENT);
51
+ });
52
+
53
+ it("toggles and emits 'open' / 'close' events the accordion content when the title button is clicked", async () => {
54
+ wrapper = createComponent(
55
+ {},
56
+ {
57
+ title: "Some title",
58
+ content: "Some content",
59
+ }
60
+ );
61
+
62
+ expect(wrapper.classes()).not.toContain(ROOT_ACTIVE_CLASS);
63
+ expect(findContent().isVisible()).toBe(false);
64
+
65
+ await findTitle().trigger("click");
66
+ expect(wrapper.classes()).toContain(ROOT_ACTIVE_CLASS);
67
+ expect(wrapper.emitted().open[0]).toBeTruthy();
68
+ expect(wrapper.emitted().open[0]).toEqual([true]);
69
+
70
+ await findTitle().trigger("click");
71
+ expect(wrapper.classes()).not.toContain(ROOT_ACTIVE_CLASS);
72
+ expect(wrapper.emitted().close[0]).toBeTruthy();
73
+ expect(wrapper.emitted().close[0]).toEqual([false]);
74
+ });
75
+ });
@@ -0,0 +1,69 @@
1
+ import { mount } from "@vue/test-utils";
2
+ import { describe, expect, it } from "vitest";
3
+ import Alert from "./Alert.vue";
4
+ import { alertTypeOptions } from "./constants";
5
+
6
+ let wrapper;
7
+ const createComponent = (props = {}, slots = {}) => {
8
+ return mount(Alert, {
9
+ propsData: props,
10
+ slots,
11
+ });
12
+ };
13
+
14
+ const findIcon = () => wrapper.find(".ib-alert-icon");
15
+ const findCloseButton = () => wrapper.find(".close-button");
16
+ const findTitle = () => wrapper.find(".ib-alert-title");
17
+
18
+ describe("Alert", () => {
19
+ it("Default render", () => {
20
+ wrapper = createComponent();
21
+
22
+ expect(wrapper).toBeDefined();
23
+ expect(wrapper.attributes("role")).toBe("alert");
24
+ expect(findIcon().exists()).toBe(false);
25
+ expect(findCloseButton().exists()).toBe(false);
26
+ });
27
+
28
+ it("Renders correctly with custom props", () => {
29
+ const TITLE = "Success Alert";
30
+ wrapper = createComponent({
31
+ type: alertTypeOptions.success,
32
+ showIcon: true,
33
+ showCloseButton: true,
34
+ title: TITLE,
35
+ });
36
+
37
+ expect(wrapper.classes()).contain(`ib-alert-${alertTypeOptions.success}`);
38
+ expect(findIcon().exists()).toBe(true);
39
+ expect(findCloseButton().exists()).toBe(true);
40
+ expect(findTitle().text()).toBe(TITLE);
41
+ });
42
+
43
+ it("emits close event when close button is clicked", async () => {
44
+ wrapper = createComponent({
45
+ showCloseButton: true,
46
+ });
47
+ const closeButton = wrapper.find(".close-button");
48
+ await closeButton.trigger("click");
49
+
50
+ expect(wrapper.emitted("close")).toBeTruthy();
51
+ });
52
+
53
+ it("renders correctly with custom props and slot content", () => {
54
+ wrapper = createComponent(
55
+ {
56
+ showIcon: true,
57
+ showCloseButton: true,
58
+ title: "Success Alert",
59
+ },
60
+ {
61
+ default: "<span>Default slot content</span>",
62
+ link: '<a href="#">Link slot content</a>',
63
+ }
64
+ );
65
+
66
+ expect(wrapper.find(".text-content").text()).toBe("Default slot content");
67
+ expect(wrapper.find(".link").html()).toContain("Link slot content");
68
+ });
69
+ });
@@ -54,10 +54,7 @@ const LargeTemplate = (args) => ({
54
54
  },
55
55
  template: `
56
56
  <ib-alert v-bind="args">
57
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
58
- <template #link>
59
- <a href="#" class="ib-standalone-link">View Server</a>
60
- </template>
57
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
61
58
  </ib-alert>`,
62
59
  });
63
60
 
@@ -19,9 +19,10 @@
19
19
 
20
20
  <ib-icon-button
21
21
  class="close-button"
22
+ kind="ghost"
22
23
  v-if="showCloseButton"
24
+ :prevent-default="true"
23
25
  @click="close"
24
- kind="ghost"
25
26
  >
26
27
  <ib-icon class="close-button-icon" name="close-outline" />
27
28
  </ib-icon-button>
@@ -56,8 +57,21 @@ export default {
56
57
  },
57
58
  mounted() {
58
59
  this.checkHeight();
60
+
61
+ if (this.$refs.content) {
62
+ this.contentObserver = new ResizeObserver(() => {
63
+ this.checkHeight();
64
+ });
65
+
66
+ this.contentObserver.observe(this.$refs.content);
67
+ }
59
68
  window.addEventListener("resize", () => this.checkHeight());
60
69
  },
70
+ data() {
71
+ return {
72
+ contentObserver: null,
73
+ };
74
+ },
61
75
  methods: {
62
76
  close() {
63
77
  this.$emit("close");
@@ -76,8 +90,12 @@ export default {
76
90
  this.$refs.content.classList.remove("large");
77
91
  }
78
92
 
79
- if (parseInt(contentStyle.height) > 37) {
80
- this.$refs.content.classList.add("large");
93
+ if (parseInt(contentStyle.height) > 37 && this.showIcon) {
94
+ if (this.title.length) {
95
+ this.$refs.content.classList.add("large");
96
+ } else {
97
+ this.$refs.content.classList.add("medium");
98
+ }
81
99
  }
82
100
  },
83
101
  },
@@ -117,6 +135,7 @@ export default {
117
135
  },
118
136
  },
119
137
  beforeUnmount() {
138
+ this.contentObserver?.disconnect();
120
139
  window.removeEventListener("resize", () => this.checkHeight());
121
140
  },
122
141
  components: {
@@ -95,6 +95,27 @@ $alert-success-secondary-color: $green-50;
95
95
  margin-top: 5px;
96
96
  margin-bottom: 5px;
97
97
  padding-left: 0;
98
+ word-break: break-word;
99
+ }
100
+ }
101
+
102
+ &.medium {
103
+ align-items: start;
104
+ padding-left: 3px;
105
+ padding-right: 5px;
106
+
107
+ .text-content {
108
+ @include Ib-P1-regular;
109
+ margin-bottom: 5px;
110
+ padding-left: 0!important;
111
+ word-break: break-word;
112
+ }
113
+
114
+ & + .close-button {
115
+ position: absolute;
116
+ right: 10px;
117
+ top: 10px;
118
+ transform: translateY(0);
98
119
  }
99
120
  }
100
121
  }
@@ -128,6 +149,7 @@ $alert-success-secondary-color: $green-50;
128
149
  margin-right: 5px;
129
150
  }
130
151
 
152
+ &-error,
131
153
  &-alert {
132
154
  border-left-color: $alert-alert-primary-color;
133
155
  background-color: $alert-alert-secondary-color;
@@ -1,5 +1,6 @@
1
1
  export const alertTypeOptions = {
2
2
  alert: "alert",
3
+ error: "error",
3
4
  warning: "warning",
4
5
  info: "info",
5
6
  success: "success",