@avakhula/ui 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.
- package/.babelrc.json +14 -0
- package/.eslintrc.cjs +15 -0
- package/.nvmrc +1 -0
- package/.prettierrc.json +1 -0
- package/.storybook/intelliboardTheme.js +10 -0
- package/.storybook/main.js +25 -0
- package/.storybook/manager.js +7 -0
- package/.storybook/preview-head.html +11 -0
- package/.storybook/preview.js +24 -0
- package/.storybook/scss-loader.scss +6 -0
- package/.storybook/withSource.js +97 -0
- package/README.md +35 -0
- package/dist/favicon.ico +0 -0
- package/dist/index.mjs +19366 -0
- package/dist/index.umd.js +209 -0
- package/dist/style.css +1 -0
- package/index.html +21 -0
- package/package.json +63 -0
- package/public/favicon.ico +0 -0
- package/src/App.vue +37 -0
- package/src/EventEmmiter.js +19 -0
- package/src/assets/scss/mixins/dropdown-list-item.scss +45 -0
- package/src/assets/scss/mixins/tooltip-position.scss +147 -0
- package/src/assets/scss/mixins.scss +21 -0
- package/src/assets/scss/reset.scss +12 -0
- package/src/assets/scss/style.scss +73 -0
- package/src/assets/scss/typography.scss +155 -0
- package/src/assets/scss/variables/colors.scss +115 -0
- package/src/assets/scss/variables/shadows.scss +17 -0
- package/src/components/Accordion/Accordion.scss +94 -0
- package/src/components/Accordion/Accordion.stories.js +41 -0
- package/src/components/Accordion/Accordion.vue +104 -0
- package/src/components/Accordion/readme.mdx +38 -0
- package/src/components/Alert/Alert.stories.js +69 -0
- package/src/components/Alert/Alert.vue +131 -0
- package/src/components/Alert/alert.scss +166 -0
- package/src/components/Alert/constants.js +6 -0
- package/src/components/Alert/readme.mdx +63 -0
- package/src/components/Badge/Badge.stories.js +53 -0
- package/src/components/Badge/Badge.vue +58 -0
- package/src/components/Badge/readme.mdx +38 -0
- package/src/components/Breadcrumbs/Breadcrumbs.vue +98 -0
- package/src/components/Breadcrumbs/breadcrumbs.scss +77 -0
- package/src/components/Breadcrumbs/breadcrumbs.stories.js +37 -0
- package/src/components/Button/Button.stories.js +124 -0
- package/src/components/Button/Button.vue +165 -0
- package/src/components/Button/button.scss +217 -0
- package/src/components/Button/constants.js +8 -0
- package/src/components/Button/readme.mdx +118 -0
- package/src/components/ButtonGroup/ButtonGroup.stories.js +27 -0
- package/src/components/ButtonGroup/ButtonGroup.vue +24 -0
- package/src/components/ButtonGroup/readme.mdx +10 -0
- package/src/components/Dropdown/Dropdown.spec.js +90 -0
- package/src/components/Dropdown/Dropdown.stories.js +48 -0
- package/src/components/Dropdown/Dropdown.vue +313 -0
- package/src/components/Dropdown/DropdownDivider.vue +15 -0
- package/src/components/Dropdown/DropdownItem.vue +59 -0
- package/src/components/Dropdown/DropdownList.stories.js +174 -0
- package/src/components/Dropdown/DropdownList.vue +93 -0
- package/src/components/Dropdown/constants.js +10 -0
- package/src/components/Dropdown/readme.mdx +88 -0
- package/src/components/Form/CharactersCount.vue +55 -0
- package/src/components/Form/Checkbox/Checkbox.scss +226 -0
- package/src/components/Form/Checkbox/Checkbox.stories.js +63 -0
- package/src/components/Form/Checkbox/Checkbox.vue +128 -0
- package/src/components/Form/Checkbox/readme.mdx +69 -0
- package/src/components/Form/CheckboxGroup/CheckboxGroup.stories.js +64 -0
- package/src/components/Form/CheckboxGroup/CheckboxGroup.vue +87 -0
- package/src/components/Form/CheckboxGroup/readme.mdx +56 -0
- package/src/components/Form/DatePicker/DatePicker.scss +479 -0
- package/src/components/Form/DatePicker/DatePicker.stories.js +78 -0
- package/src/components/Form/DatePicker/DatePicker.vue +284 -0
- package/src/components/Form/DatePicker/Icons/chevron-back.js +5 -0
- package/src/components/Form/DatePicker/Icons/chevron-forward.js +5 -0
- package/src/components/Form/DatePicker/readme.mdx +115 -0
- package/src/components/Form/FormGroup/FormGroup.stories.js +48 -0
- package/src/components/Form/FormGroup/FormGroup.vue +61 -0
- package/src/components/Form/FormGroup/FormGroupSet.stories.js +32 -0
- package/src/components/Form/FormGroup/FormGroupSet.vue +75 -0
- package/src/components/Form/Input/Input.stories.js +137 -0
- package/src/components/Form/Input/Input.vue +231 -0
- package/src/components/Form/Input/constants.js +5 -0
- package/src/components/Form/Input/input.scss +133 -0
- package/src/components/Form/Input/readme.mdx +68 -0
- package/src/components/Form/Label/Label.stories.js +29 -0
- package/src/components/Form/Label/Label.vue +87 -0
- package/src/components/Form/Label/readme.mdx +25 -0
- package/src/components/Form/PhoneInput/PhoneInput.stories.js +43 -0
- package/src/components/Form/PhoneInput/PhoneInput.vue +105 -0
- package/src/components/Form/PhoneInput/phoneInput.scss +197 -0
- package/src/components/Form/PhoneInput/readme.mdx +37 -0
- package/src/components/Form/Radio/Radio.stories.js +34 -0
- package/src/components/Form/Radio/Radio.vue +109 -0
- package/src/components/Form/Radio/radio.scss +187 -0
- package/src/components/Form/Radio/readme.mdx +48 -0
- package/src/components/Form/TextEditor/TextEditor.stories.js +58 -0
- package/src/components/Form/TextEditor/TextEditor.vue +305 -0
- package/src/components/Form/TextEditor/icons/svg/chevron-down.svg +3 -0
- package/src/components/Form/TextEditor/icons/toolbarIcons.js +111 -0
- package/src/components/Form/TextEditor/plugins/alphabetList.js +43 -0
- package/src/components/Form/TextEditor/readme.mdx +59 -0
- package/src/components/Form/TextEditor/textEditor.scss +684 -0
- package/src/components/Form/Textarea/Textarea.spec.js +107 -0
- package/src/components/Form/Textarea/Textarea.stories.js +68 -0
- package/src/components/Form/Textarea/Textarea.vue +102 -0
- package/src/components/Form/Textarea/readme.mdx +45 -0
- package/src/components/Form/Textarea/textarea.scss +84 -0
- package/src/components/Form/Toggle/Toggle.stories.js +44 -0
- package/src/components/Form/Toggle/Toggle.vue +122 -0
- package/src/components/Form/Toggle/readme.mdx +39 -0
- package/src/components/Form/Toggle/toggle.scss +166 -0
- package/src/components/Icon.vue +41 -0
- package/src/components/IconButton/IconButton.scss +91 -0
- package/src/components/IconButton/IconButton.stories.js +115 -0
- package/src/components/IconButton/IconButton.vue +100 -0
- package/src/components/IconButton/constants.js +14 -0
- package/src/components/IconButton/readme.mdx +66 -0
- package/src/components/List.vue +150 -0
- package/src/components/Modal/Modal.stories.js +48 -0
- package/src/components/Modal/Modal.vue +231 -0
- package/src/components/Modal/readme.mdx +76 -0
- package/src/components/Pagination/LimitSelector.vue +73 -0
- package/src/components/Pagination/Pagination.stories.js +54 -0
- package/src/components/Pagination/Pagination.vue +227 -0
- package/src/components/Pagination/pagination.scss +189 -0
- package/src/components/Popover/Popover.stories.js +46 -0
- package/src/components/Popover/Popover.vue +81 -0
- package/src/components/Popover/constants.js +14 -0
- package/src/components/Popover/popover.scss +26 -0
- package/src/components/Popover/readme.mdx +42 -0
- package/src/components/ProgressBar/ProgressBar.stories.js +90 -0
- package/src/components/ProgressBar/ProgressBar.vue +58 -0
- package/src/components/ProgressBar/constants.js +6 -0
- package/src/components/ProgressBar/progressBar.scss +116 -0
- package/src/components/ProgressBar/readme.mdx +67 -0
- package/src/components/Sorting/Sorting.stories.js +35 -0
- package/src/components/Sorting/Sorting.vue +128 -0
- package/src/components/Sorting/constants.js +10 -0
- package/src/components/Sorting/sorting.scss +87 -0
- package/src/components/SplitButton/SplitButton.stories.js +39 -0
- package/src/components/SplitButton/SplitButton.vue +132 -0
- package/src/components/SplitButton/SplitButtonItem.vue +34 -0
- package/src/components/SplitButton/constants.js +4 -0
- package/src/components/SplitButton/readme.mdx +77 -0
- package/src/components/SplitButton/splitButton.scss +161 -0
- package/src/components/StatusIndicator/StatusIndicator.stories.js +40 -0
- package/src/components/StatusIndicator/StatusIndicator.vue +52 -0
- package/src/components/StatusIndicator/constants.js +10 -0
- package/src/components/StatusIndicator/icons.js +48 -0
- package/src/components/StatusIndicator/readme.mdx +21 -0
- package/src/components/Table/Cells/Cell.vue +71 -0
- package/src/components/Table/Cells/CheckboxCell.vue +48 -0
- package/src/components/Table/Row.vue +26 -0
- package/src/components/Table/Table.stories.js +59 -0
- package/src/components/Table/Table.vue +36 -0
- package/src/components/Tabs/Tab.vue +37 -0
- package/src/components/Tabs/TabDropdown.vue +93 -0
- package/src/components/Tabs/Tabs.stories.js +57 -0
- package/src/components/Tabs/Tabs.vue +94 -0
- package/src/components/Tabs/tabs.scss +157 -0
- package/src/components/TagPill/TagPill.stories.js +30 -0
- package/src/components/TagPill/TagPill.vue +133 -0
- package/src/components/TagPill/constants.js +9 -0
- package/src/components/TagPill/readme.mdx +37 -0
- package/src/components/ToggleTip/ToggleTip.stories.js +98 -0
- package/src/components/ToggleTip/ToggleTip.vue +112 -0
- package/src/components/ToggleTip/constants.js +14 -0
- package/src/components/ToggleTip/readme.mdx +46 -0
- package/src/components/ToggleTip/toggleTip.scss +55 -0
- package/src/components/Tooltip/Tooltip.stories.js +56 -0
- package/src/components/Tooltip/Tooltip.vue +49 -0
- package/src/components/Tooltip/readme.mdx +43 -0
- package/src/components/TreeSelect/Option.vue +325 -0
- package/src/components/TreeSelect/Select.stories.js +349 -0
- package/src/components/TreeSelect/Select.vue +909 -0
- package/src/components/TreeSelect/TreeSelect.stories.js +270 -0
- package/src/components/TreeSelect/scss/option.scss +204 -0
- package/src/components/TreeSelect/scss/select.scss +166 -0
- package/src/constants/events.js +2 -0
- package/src/constants/keyCodes.js +8 -0
- package/src/directives/outside/outside.js +81 -0
- package/src/directives/outside/outside.stories.js +29 -0
- package/src/directives/outside/readme.mdx +24 -0
- package/src/helpers/generateUID.js +3 -0
- package/src/helpers/getHrefFromID.js +3 -0
- package/src/helpers/multiLineOverflows.js +3 -0
- package/src/helpers/removeEvents.js +9 -0
- package/src/index.js +49 -0
- package/src/main.js +12 -0
- package/src/stories/link.readme.mdx +57 -0
- package/src/stories/link.stories.js +59 -0
- package/static/Logo.svg +25 -0
- package/static/docks/button.pdf +147566 -0
- package/vite.config.js +47 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<component
|
|
3
|
+
:is="href.length ? 'a' : 'button'"
|
|
4
|
+
@click="onClick($event)"
|
|
5
|
+
v-bind="attrs"
|
|
6
|
+
>
|
|
7
|
+
<slot name="icon"></slot>
|
|
8
|
+
<slot></slot>
|
|
9
|
+
|
|
10
|
+
<form
|
|
11
|
+
v-if="href.length && linkMethod.toUpperCase() !== 'GET'"
|
|
12
|
+
ref="form"
|
|
13
|
+
:method="formMethod"
|
|
14
|
+
:action="href"
|
|
15
|
+
v-show="false"
|
|
16
|
+
>
|
|
17
|
+
<input type="hidden" name="_method" :value="linkMethod" />
|
|
18
|
+
<input type="hidden" name="_token" :value="token" />
|
|
19
|
+
<input
|
|
20
|
+
v-for="(optionKey, index) in Object.keys(postOptions)"
|
|
21
|
+
:key="index"
|
|
22
|
+
type="hidden"
|
|
23
|
+
:name="optionKey"
|
|
24
|
+
:value="postOptions[optionKey]"
|
|
25
|
+
/>
|
|
26
|
+
</form>
|
|
27
|
+
</component>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script>
|
|
31
|
+
import { buttonKindOptions } from "./constants";
|
|
32
|
+
import removeEvents from "../../helpers/removeEvents";
|
|
33
|
+
|
|
34
|
+
export default {
|
|
35
|
+
name: "IbButton",
|
|
36
|
+
props: {
|
|
37
|
+
kind: {
|
|
38
|
+
type: String,
|
|
39
|
+
default: buttonKindOptions.primary,
|
|
40
|
+
},
|
|
41
|
+
disabled: {
|
|
42
|
+
type: Boolean,
|
|
43
|
+
required: false,
|
|
44
|
+
default: false,
|
|
45
|
+
},
|
|
46
|
+
preventDefault: {
|
|
47
|
+
type: Boolean,
|
|
48
|
+
default: null,
|
|
49
|
+
},
|
|
50
|
+
confirmMessage: {
|
|
51
|
+
type: String,
|
|
52
|
+
default: "",
|
|
53
|
+
},
|
|
54
|
+
block: {
|
|
55
|
+
type: Boolean,
|
|
56
|
+
required: false,
|
|
57
|
+
default: false,
|
|
58
|
+
},
|
|
59
|
+
href: {
|
|
60
|
+
type: String,
|
|
61
|
+
default: "",
|
|
62
|
+
},
|
|
63
|
+
linkMethod: {
|
|
64
|
+
type: String,
|
|
65
|
+
default: "get",
|
|
66
|
+
},
|
|
67
|
+
disableAfterClick: {
|
|
68
|
+
type: Boolean,
|
|
69
|
+
default: false,
|
|
70
|
+
},
|
|
71
|
+
postOptions: {
|
|
72
|
+
type: Object,
|
|
73
|
+
default: () => ({}),
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
data() {
|
|
77
|
+
return {
|
|
78
|
+
isDisabled: this.disabled,
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
watch: {
|
|
82
|
+
disabled(newVal) {
|
|
83
|
+
this.isDisabled = newVal;
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
methods: {
|
|
87
|
+
onClick(e) {
|
|
88
|
+
if (this.preventDefault || this.isDisabled) {
|
|
89
|
+
e.preventDefault();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (this.confirmMessage.length > 0) {
|
|
93
|
+
if (!confirm(this.confirmMessage)) {
|
|
94
|
+
e.preventDefault();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (
|
|
100
|
+
!this.isDisabled &&
|
|
101
|
+
this.href.length &&
|
|
102
|
+
!this.preventDefault &&
|
|
103
|
+
this.linkMethod.toUpperCase() !== "GET"
|
|
104
|
+
) {
|
|
105
|
+
e.preventDefault();
|
|
106
|
+
this.$refs.form.submit();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (!this.isDisabled) {
|
|
110
|
+
this.$emit("click", e);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (this.disableAfterClick && !this.disabled) {
|
|
114
|
+
this.isDisabled = true;
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
computed: {
|
|
119
|
+
classes() {
|
|
120
|
+
const classList = ["ib-button"];
|
|
121
|
+
classList.push(`ib-btn-${this.kind}`);
|
|
122
|
+
|
|
123
|
+
if (this.isDisabled) {
|
|
124
|
+
classList.push("ib-btn-disabled");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (this.block) {
|
|
128
|
+
classList.push("ib-btn-block");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (this.hasIcon) {
|
|
132
|
+
classList.push("ib-btn-has-icon");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return classList;
|
|
136
|
+
},
|
|
137
|
+
attrs() {
|
|
138
|
+
const attrsList = { ...removeEvents({ ...this.$attrs }) };
|
|
139
|
+
|
|
140
|
+
attrsList.class = [...this.classes, attrsList.class];
|
|
141
|
+
attrsList.disabled = this.isDisabled;
|
|
142
|
+
|
|
143
|
+
if (this.href.length) {
|
|
144
|
+
attrsList.href = this.href;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return attrsList;
|
|
148
|
+
},
|
|
149
|
+
hasIcon() {
|
|
150
|
+
return !!this.$slots.icon;
|
|
151
|
+
},
|
|
152
|
+
formMethod() {
|
|
153
|
+
return this.linkMethod === "GET" ? "GET" : "POST";
|
|
154
|
+
},
|
|
155
|
+
token() {
|
|
156
|
+
return document.head.querySelector('meta[name="csrf-token"]').content;
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
inheritAttrs: false,
|
|
160
|
+
};
|
|
161
|
+
</script>
|
|
162
|
+
|
|
163
|
+
<style lang="scss">
|
|
164
|
+
@import "./button.scss";
|
|
165
|
+
</style>
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
@import "../../assets/scss/variables/colors.scss";
|
|
2
|
+
@import "../../assets/scss/typography.scss";
|
|
3
|
+
@import "../../assets/scss/mixins.scss";
|
|
4
|
+
|
|
5
|
+
// Primary button colors
|
|
6
|
+
$primary-btn-background: $blue-800;
|
|
7
|
+
$primary-btn-color: $white;
|
|
8
|
+
$primary-btn-hover-background: $blue-700;
|
|
9
|
+
$primary-btn-focus-background: $blue-800;
|
|
10
|
+
$primary-btn-active-background: $blue-900;
|
|
11
|
+
|
|
12
|
+
// Secondary button colors
|
|
13
|
+
$secondary-btn-background: $blue-50;
|
|
14
|
+
$secondary-btn-color: $blue-800;
|
|
15
|
+
$secondary-btn-hover-background: $blue-100;
|
|
16
|
+
$secondary-btn-focus-background: $blue-50;
|
|
17
|
+
$secondary-btn-active-background: $blue-50;
|
|
18
|
+
$secondary-btn-active-color: $blue-900;
|
|
19
|
+
|
|
20
|
+
// Tertiary button colors
|
|
21
|
+
$tertiary-btn-background: $gray-100;
|
|
22
|
+
$tertiary-btn-color: $neutral-900;
|
|
23
|
+
$tertiary-btn-hover-background: $blue-100;
|
|
24
|
+
$tertiary-btn-hover-color: $blue-700;
|
|
25
|
+
$tertiary-btn-focus-background: $gray-100;
|
|
26
|
+
$tertiary-btn-focus-color: $neutral-900;
|
|
27
|
+
$tertiary-btn-active-background: $blue-50;
|
|
28
|
+
$tertiary-btn-active-color: $blue-900;
|
|
29
|
+
|
|
30
|
+
// Danger button colors
|
|
31
|
+
$danger-btn-background: $red-800;
|
|
32
|
+
$danger-btn-color: $white;
|
|
33
|
+
$danger-btn-hover-background: $red-700;
|
|
34
|
+
$danger-btn-focus-background: $red-800;
|
|
35
|
+
$danger-btn-active-background: $red-900;
|
|
36
|
+
|
|
37
|
+
// Ghost button colors
|
|
38
|
+
$ghost-btn-background: transparent;
|
|
39
|
+
$ghost-btn-hover-background: $blue-100;
|
|
40
|
+
$ghost-btn-color: $neutral-900;
|
|
41
|
+
$ghost-btn-hover-color: $blue-700;
|
|
42
|
+
$ghost-btn-disabled-background: transparent;
|
|
43
|
+
$ghost-btn-active-background: $blue-50;
|
|
44
|
+
$ghost-btn-active-color: $blue-900;
|
|
45
|
+
|
|
46
|
+
// Ghost danger button colors
|
|
47
|
+
$ghostDanger-btn-background: transparent;
|
|
48
|
+
$ghostDanger-btn-color: $red-800;
|
|
49
|
+
$ghostDanger-btn-hover-color: $red-700;
|
|
50
|
+
$ghostDanger-btn-hover-background: $red-100;
|
|
51
|
+
$ghostDanger-btn-disabled-background: transparent;
|
|
52
|
+
$ghostDanger-btn-active-color: $red-900;
|
|
53
|
+
$ghostDanger-btn-active-background: $red-50;
|
|
54
|
+
|
|
55
|
+
// Disabled button colors
|
|
56
|
+
$disabled-btn-background: $gray-100;
|
|
57
|
+
$disabled-btn-color: $neutral-500;
|
|
58
|
+
|
|
59
|
+
.ib-button {
|
|
60
|
+
@include Ib-H4-medium;
|
|
61
|
+
padding: 0 15px;
|
|
62
|
+
border-radius: 4px;
|
|
63
|
+
border: none;
|
|
64
|
+
outline: none;
|
|
65
|
+
text-decoration: none;
|
|
66
|
+
cursor: pointer;
|
|
67
|
+
height: 36px;
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
width: fit-content;
|
|
71
|
+
transition: color 0.3s, background 0.3s;
|
|
72
|
+
|
|
73
|
+
&.ib-btn-has-icon {
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
padding-left: 10px;
|
|
77
|
+
|
|
78
|
+
ion-icon {
|
|
79
|
+
font-size: 16px;
|
|
80
|
+
margin-right: 5px;
|
|
81
|
+
color: inherit;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
&:focus {
|
|
86
|
+
@include focus(2px);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&.ib-btn {
|
|
90
|
+
&-primary {
|
|
91
|
+
color: $primary-btn-color;
|
|
92
|
+
background: $primary-btn-background;
|
|
93
|
+
|
|
94
|
+
&:hover {
|
|
95
|
+
background: $primary-btn-hover-background;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
&:focus {
|
|
99
|
+
background: $primary-btn-focus-background;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
&:active {
|
|
103
|
+
background: $primary-btn-active-background;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
&-secondary {
|
|
108
|
+
color: $secondary-btn-color;
|
|
109
|
+
background: $secondary-btn-background;
|
|
110
|
+
|
|
111
|
+
&:hover {
|
|
112
|
+
background: $secondary-btn-hover-background;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&:focus {
|
|
116
|
+
background: $secondary-btn-focus-background;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
&:active {
|
|
120
|
+
color: $secondary-btn-active-color;
|
|
121
|
+
background: $secondary-btn-active-background;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
&-tertiary {
|
|
126
|
+
color: $tertiary-btn-color;
|
|
127
|
+
background: $tertiary-btn-background;
|
|
128
|
+
|
|
129
|
+
&:hover {
|
|
130
|
+
color: $tertiary-btn-hover-color;
|
|
131
|
+
background: $tertiary-btn-hover-background;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
&:focus {
|
|
135
|
+
color: $tertiary-btn-focus-color;
|
|
136
|
+
background: $tertiary-btn-focus-background;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
&:active {
|
|
140
|
+
color: $tertiary-btn-active-color;
|
|
141
|
+
background: $tertiary-btn-active-background;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
&-ghost {
|
|
146
|
+
color: $ghost-btn-color;
|
|
147
|
+
background: $ghost-btn-background;
|
|
148
|
+
|
|
149
|
+
&:hover {
|
|
150
|
+
color: $ghost-btn-hover-color;
|
|
151
|
+
background: $ghost-btn-hover-background;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
&:active {
|
|
155
|
+
color: $ghost-btn-active-color;
|
|
156
|
+
background: $ghost-btn-active-background;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
&.ib-btn-disabled {
|
|
160
|
+
&:disabled {
|
|
161
|
+
background: $ghost-btn-disabled-background;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
&-danger {
|
|
167
|
+
color: $danger-btn-color;
|
|
168
|
+
background: $danger-btn-background;
|
|
169
|
+
|
|
170
|
+
&:hover {
|
|
171
|
+
background: $danger-btn-hover-background;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
&:focus {
|
|
175
|
+
background: $danger-btn-focus-background;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
&:active {
|
|
179
|
+
background: $danger-btn-active-background;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
&-ghostDanger {
|
|
184
|
+
color: $ghostDanger-btn-color;
|
|
185
|
+
background: $ghostDanger-btn-background;
|
|
186
|
+
|
|
187
|
+
&:hover {
|
|
188
|
+
color: $ghostDanger-btn-hover-color;
|
|
189
|
+
background: $ghostDanger-btn-hover-background;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
&:active {
|
|
193
|
+
color: $ghostDanger-btn-active-color;
|
|
194
|
+
background: $ghostDanger-btn-active-background;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
&.ib-btn-disabled {
|
|
198
|
+
&:disabled {
|
|
199
|
+
background: $ghostDanger-btn-disabled-background;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
&.ib-btn-block {
|
|
206
|
+
display: block;
|
|
207
|
+
text-align: center;
|
|
208
|
+
width: 100%;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
&.ib-btn-disabled {
|
|
212
|
+
&:disabled {
|
|
213
|
+
background: $disabled-btn-background;
|
|
214
|
+
color: $disabled-btn-color;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# IbButton
|
|
2
|
+
|
|
3
|
+
import { Story, Canvas } from "@storybook/addon-docs";
|
|
4
|
+
|
|
5
|
+
Buttons are used to initialize an action. Button labels express what action will occur when the user interacts with it.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
Buttons are clickable elements that are used to trigger actions. They communicate calls to action to the user and allow users to interact with pages in a variety of ways. Button labels express what action will occur when the user interacts with it.
|
|
10
|
+
|
|
11
|
+
### When to use
|
|
12
|
+
|
|
13
|
+
Use buttons to communicate actions users can take and to allow users to interact with the page. Each page should have only one primary button, and any remaining calls to action should be represented as lower emphasis buttons.
|
|
14
|
+
|
|
15
|
+
### When not to use
|
|
16
|
+
|
|
17
|
+
Do not use buttons as navigational elements. Instead, use [links](?path=/story/links--inline-link) when the desired action is to take the user to a new page.
|
|
18
|
+
|
|
19
|
+
### Props
|
|
20
|
+
|
|
21
|
+
| Name | type | Default Value | Description |
|
|
22
|
+
| ----------------- | ------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
23
|
+
| kind | String | primary | The kind of button to be displayed. Possible values are: `primary`, `secondary`, `tertiary`, `ghost`, `danger`, and `ghost-danger`. |
|
|
24
|
+
| disabled | Boolean | false | Whether the button is disabled or not. |
|
|
25
|
+
| confirmMessage | String | "" | A message to be displayed in a confirmation dialog before the button action is triggered. |
|
|
26
|
+
| block | Boolean | false | Whether the button should be displayed as a block element or not. |
|
|
27
|
+
| href | String | "" | The URL to be navigated to when the button is clicked |
|
|
28
|
+
| linkMethod | String | "get" | The HTTP method to be used when submitting a form. |
|
|
29
|
+
| disableAfterClick | Boolean | false | Whether the button should be disabled after it is clicked or not. |
|
|
30
|
+
| postOptions | Object | {} | The options to be included in a POST request when submitting a form. |
|
|
31
|
+
|
|
32
|
+
### Slots
|
|
33
|
+
|
|
34
|
+
| Slot name | Description |
|
|
35
|
+
| --------- | ----------------------------------------------------- |
|
|
36
|
+
| icon | An icon to be displayed inside the button container. |
|
|
37
|
+
| default | The default slot for the button text or content. |
|
|
38
|
+
|
|
39
|
+
### Events
|
|
40
|
+
|
|
41
|
+
| Event name | Parameters | Description |
|
|
42
|
+
| ---------- | ---------- | ----------------------------------- |
|
|
43
|
+
| click | event | Emitted when the button is clicked. |
|
|
44
|
+
|
|
45
|
+
### Default
|
|
46
|
+
|
|
47
|
+
<Canvas>
|
|
48
|
+
<Story id="button--default" />
|
|
49
|
+
</Canvas>
|
|
50
|
+
|
|
51
|
+
### With icon
|
|
52
|
+
|
|
53
|
+
Example when we added the icon
|
|
54
|
+
|
|
55
|
+
<Canvas>
|
|
56
|
+
<Story id="button--button-with-icon" />
|
|
57
|
+
</Canvas>
|
|
58
|
+
|
|
59
|
+
### Kind
|
|
60
|
+
|
|
61
|
+
Each button variant has a particular function and its design signals that function to the user. It is therefore very important that the different variants are implemented consistently across products, so that they message the correct actions.
|
|
62
|
+
|
|
63
|
+
<Canvas>
|
|
64
|
+
<Story id="button--kinds" />
|
|
65
|
+
</Canvas>
|
|
66
|
+
|
|
67
|
+
### Description for all types
|
|
68
|
+
|
|
69
|
+
#### Primary
|
|
70
|
+
|
|
71
|
+
For the principal call to action on the page. Primary buttons should only appear once per screen (not including the application header, modal dialog, or side panel).
|
|
72
|
+
|
|
73
|
+
<Canvas>
|
|
74
|
+
<Story id="button--default" />
|
|
75
|
+
</Canvas>
|
|
76
|
+
|
|
77
|
+
#### Seconsary
|
|
78
|
+
|
|
79
|
+
For secondary actions on each page. Secondary buttons can only be used in conjunction with a primary button. As part of a pair, the secondary button’s function is to perform the negative action of the set, such as “Cancel” or “Back”. Do not use a secondary button in isolation and do not use a secondary button for a positive action.
|
|
80
|
+
|
|
81
|
+
<Canvas>
|
|
82
|
+
<Story id="button--secondary" />
|
|
83
|
+
</Canvas>
|
|
84
|
+
|
|
85
|
+
#### Tertiary
|
|
86
|
+
|
|
87
|
+
For less prominent, and sometimes independent, actions. Tertiary buttons can be used in isolation or paired with a primary button when there are multiple calls to action. Tertiary buttons can also be used for sub-tasks on a page where a primary button for the main and final action is present.
|
|
88
|
+
|
|
89
|
+
<Canvas>
|
|
90
|
+
<Story id="button--tertiary" />
|
|
91
|
+
</Canvas>
|
|
92
|
+
|
|
93
|
+
#### Ghost
|
|
94
|
+
|
|
95
|
+
For the least pronounced actions; often used in conjunction with a primary button. In a situation such as a progress flow, a ghost button may be paired with a primary and secondary button set, where the primary button is for forward action, the secondary button is for “Back”, and the ghost button is for “Cancel”.
|
|
96
|
+
|
|
97
|
+
<Canvas>
|
|
98
|
+
<Story id="button--ghost" />
|
|
99
|
+
</Canvas>
|
|
100
|
+
|
|
101
|
+
#### Danger
|
|
102
|
+
|
|
103
|
+
For actions that could have destructive effects on the user’s data (for example, delete or remove). Danger button has two styles: primary and ghost.
|
|
104
|
+
|
|
105
|
+
<Canvas>
|
|
106
|
+
<Story id="button--danger" />
|
|
107
|
+
</Canvas>
|
|
108
|
+
|
|
109
|
+
#### Danger ghost
|
|
110
|
+
|
|
111
|
+
For actions that could have destructive effects on the user’s data (for example, delete or remove). Danger button has two styles: primary and ghost.
|
|
112
|
+
|
|
113
|
+
<Canvas>
|
|
114
|
+
<Story id="button--danger-ghost" />
|
|
115
|
+
</Canvas>
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
## <a href="./docks/button.pdf" target="_blank">Read more</a>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import IbButtonGroup from "./ButtonGroup.vue";
|
|
2
|
+
import IbButton from "../Button/Button.vue";
|
|
3
|
+
import readme from "./readme.mdx";
|
|
4
|
+
export default {
|
|
5
|
+
title: "Button group",
|
|
6
|
+
component: IbButtonGroup,
|
|
7
|
+
parameters: {
|
|
8
|
+
docs: {
|
|
9
|
+
page: readme,
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const Template = (args) => ({
|
|
15
|
+
components: { IbButtonGroup, IbButton },
|
|
16
|
+
setup() {
|
|
17
|
+
return { args };
|
|
18
|
+
},
|
|
19
|
+
template: `
|
|
20
|
+
<ib-button-group>
|
|
21
|
+
<ib-button>primary</ib-button>
|
|
22
|
+
<ib-button kind='secondary'>secondary</ib-button>
|
|
23
|
+
</ib-button-group>`,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export const Default = Template.bind({});
|
|
27
|
+
Default.args = {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="ib-button-group">
|
|
3
|
+
<slot></slot>
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script>
|
|
8
|
+
export default {
|
|
9
|
+
name: "IbButtonGroup",
|
|
10
|
+
};
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<style lang="scss">
|
|
14
|
+
.ib-button-group {
|
|
15
|
+
display: flex;
|
|
16
|
+
|
|
17
|
+
button,
|
|
18
|
+
a {
|
|
19
|
+
&:not(:first-child) {
|
|
20
|
+
margin-left: 15px;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
</style>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { h } from "vue";
|
|
2
|
+
import { mount } from "@vue/test-utils";
|
|
3
|
+
import { describe, it, expect, vi } from "vitest";
|
|
4
|
+
import Dropdown from "./Dropdown.vue";
|
|
5
|
+
|
|
6
|
+
const $globalEvents = {
|
|
7
|
+
$on: vi.fn(),
|
|
8
|
+
$off: vi.fn(),
|
|
9
|
+
$emit: vi.fn(),
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const $emitEvent = vi.fn();
|
|
13
|
+
|
|
14
|
+
const defaultContent = "<div>Test</div>";
|
|
15
|
+
const triggerContent = "<button>Trigger</button>";
|
|
16
|
+
|
|
17
|
+
const slotsList = {
|
|
18
|
+
trigger: triggerContent,
|
|
19
|
+
body: defaultContent,
|
|
20
|
+
};
|
|
21
|
+
const createComponent = (props = {}, slots = slotsList) => {
|
|
22
|
+
return mount(Dropdown, {
|
|
23
|
+
global: {
|
|
24
|
+
mocks: {
|
|
25
|
+
$globalEvents,
|
|
26
|
+
$emitEvent,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
slots: slots,
|
|
30
|
+
propsData: props,
|
|
31
|
+
attachTo: document.body,
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
describe("Dropdown", () => {
|
|
36
|
+
it("Default state", () => {
|
|
37
|
+
const component = createComponent();
|
|
38
|
+
const menu = component.find(".dropdown-body");
|
|
39
|
+
const trigger = component.find(".dropdown-trigger");
|
|
40
|
+
|
|
41
|
+
expect(trigger.html()).toContain(triggerContent);
|
|
42
|
+
expect(trigger.isVisible()).toBe(true);
|
|
43
|
+
|
|
44
|
+
expect(menu.html()).toContain(defaultContent);
|
|
45
|
+
expect(menu.isVisible()).toBe(false);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("Should open when click to trigger", async () => {
|
|
49
|
+
const component = createComponent();
|
|
50
|
+
|
|
51
|
+
const trigger = component.find(".dropdown-trigger");
|
|
52
|
+
await trigger.trigger("click");
|
|
53
|
+
|
|
54
|
+
const menu = component.find(".dropdown-body");
|
|
55
|
+
expect(menu.isVisible()).toBe(true);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("Close when click is outside", async () => {
|
|
59
|
+
const App = {
|
|
60
|
+
render() {
|
|
61
|
+
return h("span", { id: "container" }, [
|
|
62
|
+
h(Dropdown, null, {
|
|
63
|
+
trigger: () =>
|
|
64
|
+
h("button", { className: "dropdown-trigger" }, "test"),
|
|
65
|
+
body: () =>
|
|
66
|
+
h("div", { className: "dropdown-body" }, "Body content"),
|
|
67
|
+
}),
|
|
68
|
+
]);
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
const wrapper = mount(App, {
|
|
72
|
+
attachTo: document.body,
|
|
73
|
+
global: {
|
|
74
|
+
mocks: {
|
|
75
|
+
$globalEvents,
|
|
76
|
+
$emitEvent,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const container = wrapper.find("#container");
|
|
82
|
+
const trigger = wrapper.find(".dropdown-trigger");
|
|
83
|
+
let menu = wrapper.find(".dropdown-body");
|
|
84
|
+
|
|
85
|
+
await trigger.trigger("click");
|
|
86
|
+
expect(menu.isVisible()).toBe(true);
|
|
87
|
+
await container.trigger("click");
|
|
88
|
+
expect(menu.isVisible()).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
});
|