@kiva/kv-components 3.40.1 → 3.42.0
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/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,37 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [3.42.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.41.0...@kiva/kv-components@3.42.0) (2023-09-14)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* added event emitters ([3a84e6e](https://github.com/kiva/kv-ui-elements/commit/3a84e6e97b5d230ff747c296339bce31263d89da))
|
|
12
|
+
* added event emitters, addressed comments, updated tests ([35a8a0c](https://github.com/kiva/kv-ui-elements/commit/35a8a0c6b34eed36fba030c29d3389c356c06927))
|
|
13
|
+
* addressing build issues, made button square ([974bbdc](https://github.com/kiva/kv-ui-elements/commit/974bbdcac2558fc47c7280f6535d390ed8c824ef))
|
|
14
|
+
* stopped requiring default title ([f494700](https://github.com/kiva/kv-ui-elements/commit/f494700078a2660f72703b95327df6e407d16d5f))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* new edit button that opens up a lightbox for editing page settings in kiva at work pages ([9d9c2ca](https://github.com/kiva/kv-ui-elements/commit/9d9c2caf3df0f741c2039d2423e42e108e753ff0))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# [3.41.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.40.1...@kiva/kv-components@3.41.0) (2023-09-07)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Features
|
|
29
|
+
|
|
30
|
+
* add box shadow to all toasts ([57ccaf2](https://github.com/kiva/kv-ui-elements/commit/57ccaf2f2da006a6990f5d5b0d6adeca8d3081b0))
|
|
31
|
+
* rolled back some new tooltip props ([4ce96d6](https://github.com/kiva/kv-ui-elements/commit/4ce96d6eae3457a6a92bde9e407f226d5e53d332))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
6
37
|
## [3.40.1](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.40.0...@kiva/kv-components@3.40.1) (2023-09-07)
|
|
7
38
|
|
|
8
39
|
**Note:** Version bump only for package @kiva/kv-components
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kiva/kv-components",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.42.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"optional": true
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "5ce65863bbb21ba1ace0ac77c2afd89318410365"
|
|
79
79
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { render, fireEvent } from '@testing-library/vue';
|
|
2
|
+
import { axe } from 'jest-axe';
|
|
3
|
+
import { nextTick } from 'vue';
|
|
4
|
+
import addVueRouter from '../../utils/addVueRouter';
|
|
5
|
+
import KvEditButton from '../../../../vue/KvEditButton.vue';
|
|
6
|
+
|
|
7
|
+
describe('KvEditButton', () => {
|
|
8
|
+
const renderComponent = (options) => render(KvEditButton, addVueRouter(options));
|
|
9
|
+
|
|
10
|
+
it('renders the edit button', () => {
|
|
11
|
+
const { getByRole } = renderComponent();
|
|
12
|
+
getByRole('button', { name: /edit/i });
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('shows the lightbox when the edit button is clicked', async () => {
|
|
16
|
+
const { getByRole } = renderComponent();
|
|
17
|
+
const button = getByRole('button', { name: /edit/i });
|
|
18
|
+
await fireEvent.click(button);
|
|
19
|
+
expect(getByRole('dialog')).toBeVisible();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('closes the lightbox when the close event is emitted', async () => {
|
|
23
|
+
const { getByRole, queryByRole } = renderComponent();
|
|
24
|
+
const button = getByRole('button', { name: /edit/i });
|
|
25
|
+
await fireEvent.click(button);
|
|
26
|
+
await fireEvent.keyUp(document, { key: 'Escape', code: 'Escape' });
|
|
27
|
+
await nextTick();
|
|
28
|
+
expect(queryByRole('dialog')).not.toBeInTheDocument();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('renders a custom title for the lightbox if provided', () => {
|
|
32
|
+
const { getByText } = renderComponent({ props: { title: 'Custom Title' } });
|
|
33
|
+
getByText('Custom Title');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('has no automated accessibility violations', async () => {
|
|
37
|
+
const { container } = renderComponent();
|
|
38
|
+
const results = await axe(container);
|
|
39
|
+
expect(results).toHaveNoViolations();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('renders content in the default slot of the lightbox', async () => {
|
|
43
|
+
const customContent = 'Custom Content for Body';
|
|
44
|
+
const { getByText, getByRole } = renderComponent({
|
|
45
|
+
slots: { default: customContent },
|
|
46
|
+
});
|
|
47
|
+
const button = getByRole('button', { name: /edit/i });
|
|
48
|
+
await fireEvent.click(button);
|
|
49
|
+
expect(getByText(customContent)).toBeVisible();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('renders content in the header slot of the lightbox', async () => {
|
|
53
|
+
const customHeader = 'Custom Header Content';
|
|
54
|
+
const { getByText, getByRole } = renderComponent({
|
|
55
|
+
slots: { header: customHeader },
|
|
56
|
+
});
|
|
57
|
+
const button = getByRole('button', { name: /edit/i });
|
|
58
|
+
await fireEvent.click(button);
|
|
59
|
+
expect(getByText(customHeader)).toBeVisible();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('renders content in the controls slot of the lightbox', async () => {
|
|
63
|
+
const customControls = 'Custom Controls Content';
|
|
64
|
+
const { getByText, getByRole } = renderComponent({
|
|
65
|
+
slots: { controls: customControls },
|
|
66
|
+
});
|
|
67
|
+
const button = getByRole('button', { name: /edit/i });
|
|
68
|
+
await fireEvent.click(button);
|
|
69
|
+
expect(getByText(customControls)).toBeVisible();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<!-- Edit Button -->
|
|
4
|
+
<KvButton
|
|
5
|
+
variant="secondary"
|
|
6
|
+
aria-label="Edit"
|
|
7
|
+
class="tw-w-7 tw-h-10"
|
|
8
|
+
@click="showLightbox"
|
|
9
|
+
>
|
|
10
|
+
<KvMaterialIcon
|
|
11
|
+
class="tw-w-3 tw-h-3"
|
|
12
|
+
:icon="mdiPencil"
|
|
13
|
+
/>
|
|
14
|
+
</KvButton>
|
|
15
|
+
|
|
16
|
+
<!-- Lightbox -->
|
|
17
|
+
<KvLightbox
|
|
18
|
+
:visible="isVisible"
|
|
19
|
+
:title="title"
|
|
20
|
+
:prevent-close="preventClose"
|
|
21
|
+
:variant="variant"
|
|
22
|
+
@lightbox-closed="hideLightbox"
|
|
23
|
+
>
|
|
24
|
+
<template #header>
|
|
25
|
+
<slot name="header"></slot>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<!-- default slot (body) -->
|
|
29
|
+
<slot></slot>
|
|
30
|
+
|
|
31
|
+
<!-- controls slot -->
|
|
32
|
+
<template #controls>
|
|
33
|
+
<slot
|
|
34
|
+
name="controls"
|
|
35
|
+
:hideLightbox="hideLightbox"
|
|
36
|
+
></slot>
|
|
37
|
+
</template>
|
|
38
|
+
</KvLightbox>
|
|
39
|
+
</div>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<script>
|
|
43
|
+
import { ref } from 'vue-demi';
|
|
44
|
+
import { mdiPencil } from '@mdi/js';
|
|
45
|
+
import KvButton from './KvButton.vue';
|
|
46
|
+
import KvMaterialIcon from './KvMaterialIcon.vue';
|
|
47
|
+
import KvLightbox from './KvLightbox.vue';
|
|
48
|
+
|
|
49
|
+
export default {
|
|
50
|
+
components: {
|
|
51
|
+
KvButton,
|
|
52
|
+
KvMaterialIcon,
|
|
53
|
+
KvLightbox,
|
|
54
|
+
},
|
|
55
|
+
props: {
|
|
56
|
+
variant: {
|
|
57
|
+
type: String,
|
|
58
|
+
default: 'lightbox',
|
|
59
|
+
validator(value) {
|
|
60
|
+
return ['lightbox', 'alert'].includes(value);
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
/**
|
|
64
|
+
* The title of the dialog which describes the dialog to screenreaders, and if no
|
|
65
|
+
* content is in the `header` slot, will be displayed at the top of the lightbox.
|
|
66
|
+
* */
|
|
67
|
+
title: {
|
|
68
|
+
type: String,
|
|
69
|
+
default: '',
|
|
70
|
+
},
|
|
71
|
+
/**
|
|
72
|
+
* The dialog has no close X button, clicking the screen does not close,
|
|
73
|
+
* pressing ESC does not close.
|
|
74
|
+
* */
|
|
75
|
+
preventClose: {
|
|
76
|
+
type: Boolean,
|
|
77
|
+
default: false,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
emits: [
|
|
81
|
+
'lightbox-opened',
|
|
82
|
+
'lightbox-closed',
|
|
83
|
+
],
|
|
84
|
+
setup(_, { emit }) {
|
|
85
|
+
const isVisible = ref(false);
|
|
86
|
+
|
|
87
|
+
const showLightbox = () => {
|
|
88
|
+
isVisible.value = true;
|
|
89
|
+
emit('lightbox-opened');
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const hideLightbox = () => {
|
|
93
|
+
isVisible.value = false;
|
|
94
|
+
emit('lightbox-closed');
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
mdiPencil,
|
|
99
|
+
isVisible,
|
|
100
|
+
showLightbox,
|
|
101
|
+
hideLightbox,
|
|
102
|
+
};
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
</script>
|
package/vue/KvToast.vue
CHANGED
|
@@ -21,10 +21,11 @@
|
|
|
21
21
|
class="
|
|
22
22
|
tw-rounded tw-overflow-hidden
|
|
23
23
|
tw-flex
|
|
24
|
+
tw-bg-secondary
|
|
24
25
|
tw-mx-auto
|
|
25
26
|
tw-w-full md:tw-w-max md:tw-max-w-full md:tw-min-w-1/2
|
|
27
|
+
tw-shadow
|
|
26
28
|
"
|
|
27
|
-
:class="[backgroundClass, { 'tw-shadow': applyDropShadow }]"
|
|
28
29
|
>
|
|
29
30
|
<div
|
|
30
31
|
class="
|
|
@@ -91,9 +92,9 @@
|
|
|
91
92
|
tw-flex-shrink-0
|
|
92
93
|
tw-flex
|
|
93
94
|
tw-items-center tw-justify-center
|
|
95
|
+
tw-bg-secondary
|
|
94
96
|
hover:tw-text-action-highlight
|
|
95
97
|
"
|
|
96
|
-
:class="[backgroundClass]"
|
|
97
98
|
@click="close"
|
|
98
99
|
>
|
|
99
100
|
<kv-material-icon
|
|
@@ -150,19 +151,9 @@ export default {
|
|
|
150
151
|
const isVisible = ref(false);
|
|
151
152
|
const message = ref('');
|
|
152
153
|
const messageType = ref('confirmation'); // 'error', 'info', 'confirmation'
|
|
153
|
-
const backgroundType = ref('secondary'); // 'primary', 'secondary', 'tertiary'
|
|
154
|
-
const applyDropShadow = ref(false);
|
|
155
154
|
const persist = ref(false);
|
|
156
155
|
const timeout = ref(null);
|
|
157
156
|
|
|
158
|
-
const backgroundClass = computed(() => {
|
|
159
|
-
switch (backgroundType.value) {
|
|
160
|
-
case 'primary': return 'tw-bg-primary';
|
|
161
|
-
case 'tertiary': return 'tw-bg-tertiary';
|
|
162
|
-
default: return 'tw-bg-secondary';
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
|
|
166
157
|
const icon = computed(() => {
|
|
167
158
|
if (messageType.value === 'warning') {
|
|
168
159
|
return mdiAlert;
|
|
@@ -199,12 +190,10 @@ export default {
|
|
|
199
190
|
emit('close');
|
|
200
191
|
};
|
|
201
192
|
|
|
202
|
-
const show = (messageInput, type, persistInput, hideDelay
|
|
193
|
+
const show = (messageInput, type, persistInput, hideDelay) => {
|
|
203
194
|
isVisible.value = true;
|
|
204
195
|
message.value = typeof messageInput === 'string' ? messageInput : '';
|
|
205
196
|
messageType.value = typeof type === 'string' ? type : '';
|
|
206
|
-
backgroundType.value = typeof background === 'string' ? background : '';
|
|
207
|
-
applyDropShadow.value = Boolean(dropShadow);
|
|
208
197
|
persist.value = Boolean(persistInput);
|
|
209
198
|
|
|
210
199
|
if (!persist.value) {
|
|
@@ -226,8 +215,6 @@ export default {
|
|
|
226
215
|
close,
|
|
227
216
|
show,
|
|
228
217
|
hasToastContentSlot,
|
|
229
|
-
backgroundClass,
|
|
230
|
-
applyDropShadow,
|
|
231
218
|
};
|
|
232
219
|
},
|
|
233
220
|
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import KvEditButton from '../KvEditButton.vue';
|
|
2
|
+
import KvButton from '../KvButton.vue';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'KvEditButton',
|
|
6
|
+
component: KvEditButton,
|
|
7
|
+
argTypes: {
|
|
8
|
+
visible: {
|
|
9
|
+
control: 'boolean',
|
|
10
|
+
defaultValue: false,
|
|
11
|
+
},
|
|
12
|
+
title: {
|
|
13
|
+
control: 'text',
|
|
14
|
+
defaultValue: 'Edit',
|
|
15
|
+
},
|
|
16
|
+
variant: {
|
|
17
|
+
control: 'select',
|
|
18
|
+
options: ['lightbox', 'alert'],
|
|
19
|
+
defaultValue: 'lightbox',
|
|
20
|
+
},
|
|
21
|
+
preventClose: {
|
|
22
|
+
control: 'boolean',
|
|
23
|
+
defaultValue: false,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
args: {
|
|
27
|
+
visible: false,
|
|
28
|
+
title: '',
|
|
29
|
+
variant: 'lightbox',
|
|
30
|
+
preventClose: false,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const DefaultTemplate = (args, { argTypes }) => ({
|
|
35
|
+
props: Object.keys(argTypes),
|
|
36
|
+
components: { KvEditButton, KvButton },
|
|
37
|
+
template: `
|
|
38
|
+
<div>
|
|
39
|
+
<kv-edit-button v-bind="$props">
|
|
40
|
+
<template>This is the content that will appear inside the lightbox when the edit button is clicked.</template>
|
|
41
|
+
<template #header>
|
|
42
|
+
<h3>
|
|
43
|
+
Custom Header
|
|
44
|
+
</h3>
|
|
45
|
+
</template>
|
|
46
|
+
<template #controls="{ hideLightbox }">
|
|
47
|
+
<kv-button variant="ghost" @click="hideLightbox" ref="dontDoItRef">Cancel</kv-button>
|
|
48
|
+
<kv-button variant="danger" @click="hideLightbox" ref="doItRef">Delete</kv-button>
|
|
49
|
+
</template>
|
|
50
|
+
</kv-edit-button>
|
|
51
|
+
</div>
|
|
52
|
+
`,
|
|
53
|
+
data() {
|
|
54
|
+
return {
|
|
55
|
+
isLightboxVisible: args.visible,
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export const EditButtonWithLightbox = DefaultTemplate.bind({});
|
|
61
|
+
EditButtonWithLightbox.args = {
|
|
62
|
+
title: 'Edit Item Details',
|
|
63
|
+
};
|
|
@@ -31,16 +31,6 @@ export default {
|
|
|
31
31
|
type: 'number',
|
|
32
32
|
},
|
|
33
33
|
},
|
|
34
|
-
background: {
|
|
35
|
-
control: {
|
|
36
|
-
type: 'text',
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
dropShadow: {
|
|
40
|
-
control: {
|
|
41
|
-
type: 'boolean',
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
34
|
},
|
|
45
35
|
};
|
|
46
36
|
|
|
@@ -54,7 +44,7 @@ const Template = (args, {
|
|
|
54
44
|
},
|
|
55
45
|
template: `
|
|
56
46
|
<div>
|
|
57
|
-
<kv-button @click="showToast(message, type, persist, hideDelay
|
|
47
|
+
<kv-button @click="showToast(message, type, persist, hideDelay)">Show Toast</kv-button>
|
|
58
48
|
|
|
59
49
|
<!-- div below is a kludge for storybook docs -->
|
|
60
50
|
<div class="tw-fixed tw-z-toast tw-inset-0 tw-pointer-events-none">
|
|
@@ -64,8 +54,8 @@ const Template = (args, {
|
|
|
64
54
|
</div>
|
|
65
55
|
</div>`,
|
|
66
56
|
methods: {
|
|
67
|
-
showToast(messageInput, type, persistInput, hideDelay
|
|
68
|
-
this.$refs.toastRef.show(messageInput, type, persistInput, hideDelay
|
|
57
|
+
showToast(messageInput, type, persistInput, hideDelay) {
|
|
58
|
+
this.$refs.toastRef.show(messageInput, type, persistInput, hideDelay);
|
|
69
59
|
},
|
|
70
60
|
onClose() {
|
|
71
61
|
},
|
|
@@ -90,18 +80,6 @@ persist.args = { persist: true };
|
|
|
90
80
|
export const hideDelay = Template.bind({});
|
|
91
81
|
hideDelay.args = { hideDelay: 10000 };
|
|
92
82
|
|
|
93
|
-
export const backgroundPrimary = Template.bind({});
|
|
94
|
-
backgroundPrimary.args = { background: 'primary' };
|
|
95
|
-
|
|
96
|
-
export const backgroundSecondary = Template.bind({});
|
|
97
|
-
backgroundSecondary.args = { background: 'secondary' };
|
|
98
|
-
|
|
99
|
-
export const backgroundTertiary = Template.bind({});
|
|
100
|
-
backgroundTertiary.args = { background: 'tertiary' };
|
|
101
|
-
|
|
102
|
-
export const dropShadow = Template.bind({});
|
|
103
|
-
dropShadow.args = { dropShadow: true };
|
|
104
|
-
|
|
105
83
|
const KivaLogoTemplate = (args, {
|
|
106
84
|
argTypes,
|
|
107
85
|
}) => ({
|