@kiva/kv-components 1.4.5 → 3.0.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 (51) hide show
  1. package/{.eslintrc.js → .eslintrc.cjs} +1 -1
  2. package/CHANGELOG.md +78 -0
  3. package/README.md +1 -1
  4. package/__mocks__/ResizeObserver.js +13 -0
  5. package/package.json +23 -10
  6. package/{postcss.config.js → postcss.config.cjs} +2 -2
  7. package/{tailwind.config.js → tailwind.config.cjs} +3 -3
  8. package/tests/unit/jest-setup.js +5 -0
  9. package/tests/unit/specs/components/KvButton.spec.js +38 -25
  10. package/tests/unit/specs/components/KvCarousel.spec.js +11 -0
  11. package/tests/unit/specs/components/KvCheckbox.spec.js +73 -14
  12. package/tests/unit/specs/components/KvLightbox.spec.js +14 -0
  13. package/tests/unit/specs/components/KvProgressBar.spec.js +11 -0
  14. package/tests/unit/specs/components/KvRadio.spec.js +94 -5
  15. package/tests/unit/specs/components/KvSelect.spec.js +113 -0
  16. package/tests/unit/specs/components/KvSwitch.spec.js +92 -33
  17. package/tests/unit/specs/components/KvTabPanel.spec.js +11 -0
  18. package/tests/unit/specs/components/KvTabs.spec.js +99 -0
  19. package/tests/unit/specs/components/KvTextInput.spec.js +86 -9
  20. package/tests/unit/specs/components/KvTextLink.spec.js +16 -24
  21. package/tests/unit/specs/components/KvToast.spec.js +11 -0
  22. package/tests/unit/utils/addVueRouter.js +24 -0
  23. package/utils/attrs.js +62 -0
  24. package/utils/{themeUtils.js → themeUtils.cjs} +0 -0
  25. package/vue/.storybook/{main.js → main.cjs} +13 -5
  26. package/vue/.storybook/preview.js +6 -1
  27. package/vue/KvButton.vue +75 -53
  28. package/vue/KvCarousel.vue +142 -106
  29. package/vue/KvCheckbox.vue +86 -60
  30. package/vue/KvContentfulImg.vue +45 -34
  31. package/vue/KvLightbox.vue +108 -69
  32. package/vue/KvProgressBar.vue +33 -19
  33. package/vue/KvRadio.vue +72 -41
  34. package/vue/KvSelect.vue +46 -20
  35. package/vue/KvSwitch.vue +55 -33
  36. package/vue/KvTab.vue +49 -21
  37. package/vue/KvTabPanel.vue +26 -6
  38. package/vue/KvTabs.vue +70 -53
  39. package/vue/KvTextInput.vue +71 -48
  40. package/vue/KvTextLink.vue +42 -20
  41. package/vue/KvThemeProvider.vue +1 -1
  42. package/vue/KvToast.vue +53 -37
  43. package/vue/stories/KvCheckbox.stories.js +5 -5
  44. package/vue/stories/KvSwitch.stories.js +2 -2
  45. package/vue/stories/KvTabs.stories.js +8 -8
  46. package/vue/stories/KvTextInput.stories.js +1 -1
  47. package/vue/stories/KvThemeProvider.stories.js +1 -1
  48. package/vue/stories/KvToast.stories.js +3 -2
  49. package/vue/stories/StyleguidePrimitives.stories.js +9 -9
  50. package/.babelrc +0 -16
  51. package/jest.config.js +0 -36
@@ -4,7 +4,7 @@ module.exports = {
4
4
  node: true,
5
5
  },
6
6
  extends: [
7
- '../../.eslintrc',
7
+ '../../.eslintrc.cjs',
8
8
  'plugin:vue/recommended',
9
9
  ],
10
10
  plugins: [
package/CHANGELOG.md CHANGED
@@ -3,6 +3,84 @@
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.0.1](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.0.0...@kiva/kv-components@3.0.1) (2022-02-16)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **KvButton:** pass through click event for parent ([65c042f](https://github.com/kiva/kv-ui-elements/commit/65c042ff7b4780a514766ab476f443562b195eab))
12
+
13
+
14
+
15
+
16
+
17
+ # [3.0.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@2.0.0...@kiva/kv-components@3.0.0) (2022-02-16)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **deps:** add required missing vue composition api for storybook ([7c4629e](https://github.com/kiva/kv-ui-elements/commit/7c4629eac8820a53ce86de0056a5ac17cfd25b73))
23
+ * input reference was back to ref ([fce5264](https://github.com/kiva/kv-ui-elements/commit/fce52641b384efb83d5d8d5cfd4587cc924b4484))
24
+ * **KvSwitch:** ensure component attributes behave the same way across vue versions ([1414899](https://github.com/kiva/kv-ui-elements/commit/14148990c48449548614d02ee4869ddd72c87f74))
25
+ * model added to work correctly ([8992e83](https://github.com/kiva/kv-ui-elements/commit/8992e8330a86c41e75a42dddc5ed3531aad1da43))
26
+ * set correct module type for importing the package ([ef7e828](https://github.com/kiva/kv-ui-elements/commit/ef7e82876544f9016a09e743d68da3451e1ab3d6))
27
+ * update path ([f33c2fb](https://github.com/kiva/kv-ui-elements/commit/f33c2fb7383ceb2caf916db2ec8d4e940697b5e7))
28
+ * value attr was added to msToDisplayToast computed ref to show the toast correctly ([5c5199c](https://github.com/kiva/kv-ui-elements/commit/5c5199c3d9601f34f9342c971f643c2ed1bde80f))
29
+
30
+
31
+ ### Features
32
+
33
+ * checked prop was replaced by modelValue for composition api ([01e31a4](https://github.com/kiva/kv-ui-elements/commit/01e31a41976fc7cb406fbe0c6e41bb2ebf4573b1))
34
+ * files for kvcheckbox component were updated for tests passing ([e788ef3](https://github.com/kiva/kv-ui-elements/commit/e788ef34be213831cfce2034b94c4ebb843d7401))
35
+ * **KvCarousel:** component was rewritten to use composition api ([#149](https://github.com/kiva/kv-ui-elements/issues/149)) ([0e7ab21](https://github.com/kiva/kv-ui-elements/commit/0e7ab219902858fe05626231ca0027498b2d1280))
36
+ * kvcheckbox component was rewritten to use composition api ([945edee](https://github.com/kiva/kv-ui-elements/commit/945edeee9efcec4f47cb4dafbec81d856406cb16))
37
+ * kvcheckbox component was rewritten to use composition api ([787e9cf](https://github.com/kiva/kv-ui-elements/commit/787e9cf9448f7c9db5732fd3e1b2d441c52c389e))
38
+ * kvcontentfulimg component was rewritten to use composition api ([#145](https://github.com/kiva/kv-ui-elements/issues/145)) ([e30526c](https://github.com/kiva/kv-ui-elements/commit/e30526c994e65cfce7d479dd9f06e333588e7360))
39
+ * **KvLightbox:** component was rewritten using composition api ([#156](https://github.com/kiva/kv-ui-elements/issues/156)) ([8a83c6f](https://github.com/kiva/kv-ui-elements/commit/8a83c6ff01b32f2a46c3133c67033051de3ee8cf))
40
+ * kvprogressbar component was rewritten using composition api ([#152](https://github.com/kiva/kv-ui-elements/issues/152)) ([9cda6b6](https://github.com/kiva/kv-ui-elements/commit/9cda6b603a5eff1ea746b58bc1385f54bcb0cb50))
41
+ * **KvRadio:** component was rewritten to use composition api ([#146](https://github.com/kiva/kv-ui-elements/issues/146)) ([5b8f342](https://github.com/kiva/kv-ui-elements/commit/5b8f34213f445e876981197c91e333949ba73eb2))
42
+ * **KvSelect:** component was rewritten and basic test file was added ([#150](https://github.com/kiva/kv-ui-elements/issues/150)) ([69f99d8](https://github.com/kiva/kv-ui-elements/commit/69f99d814e46bdb622c27792fb955261ea7ff7bd))
43
+ * kvswitch component was rewritten using composition api ([a51c00e](https://github.com/kiva/kv-ui-elements/commit/a51c00e67b6f85b83bc24e3672de3d22994b5db1))
44
+ * KvTabs, KvTab, & KvTabPanel updated to support composition api ([#165](https://github.com/kiva/kv-ui-elements/issues/165)) ([c4758ae](https://github.com/kiva/kv-ui-elements/commit/c4758ae7dee98adf4f9a58fad6ef2d87d3fefcf7))
45
+ * **KvTextInput:** component was rewritten using composition api ([#159](https://github.com/kiva/kv-ui-elements/issues/159)) ([6d4ae80](https://github.com/kiva/kv-ui-elements/commit/6d4ae809003b07aea3c6eb97565a09c95289c0e8))
46
+ * kvtextlink component was rewritten to use composition api ([#151](https://github.com/kiva/kv-ui-elements/issues/151)) ([7181775](https://github.com/kiva/kv-ui-elements/commit/7181775d6d30c1bee5955670f615b4fdd587f9fe))
47
+ * pointer was added to switch component ([44ffb45](https://github.com/kiva/kv-ui-elements/commit/44ffb45c6dd5f4c71b5b8bfd3b8b2b65ab0818a2))
48
+ * testing file was added for kvtoast component ([cd6abe9](https://github.com/kiva/kv-ui-elements/commit/cd6abe9dea2218e705fc1efb94127d6b184e3800))
49
+
50
+
51
+ ### BREAKING CHANGES
52
+
53
+ * **KvSelect:** The KvSelect prop `value` was renamed to `modelValue`.
54
+ The KvCheckbox prop `checked` has been renamed to `modelValue`.
55
+ The KvCheckbox event `change` has been renamed to `update:modelValue`.
56
+ * **KvTextInput:** The KvTextInput prop `value` has been renamed to `modelValue`
57
+
58
+
59
+
60
+
61
+
62
+ # [2.0.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@1.4.6...@kiva/kv-components@2.0.0) (2022-02-03)
63
+
64
+
65
+ * feat!: upgrade Tailwind to v3 ([18c1653](https://github.com/kiva/kv-ui-elements/commit/18c1653565eb42b8abfaaba6b3712173ff341850))
66
+
67
+
68
+ ### BREAKING CHANGES
69
+
70
+ * Tailwind dependency is now v3
71
+
72
+
73
+
74
+
75
+
76
+ ## [1.4.6](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@1.4.5...@kiva/kv-components@1.4.6) (2022-02-03)
77
+
78
+ **Note:** Version bump only for package @kiva/kv-components
79
+
80
+
81
+
82
+
83
+
6
84
  ## [1.4.5](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@1.4.4...@kiva/kv-components@1.4.5) (2022-02-03)
7
85
 
8
86
  **Note:** Version bump only for package @kiva/kv-components
package/README.md CHANGED
@@ -7,7 +7,7 @@ A library of accessible UI components that adhere to Kiva's Design System. Curre
7
7
  1. [Install tailwind](https://tailwindcss.com/docs/installation) into your project
8
8
  2. Install components and design definitions:
9
9
  `npm install @kiva/kv-components && npm install @kiva/kv-tokens --save-dev`
10
- 3. Add our tailwind config as a [preset](https://tailwindcss.com/docs/configuration#presets) in your tailwind.config.js
10
+ 3. Add our Tailwind config as a [preset](https://tailwindcss.com/docs/configuration#presets) in your tailwind.config.js
11
11
 
12
12
  ```js
13
13
  // tailwind.config.js
@@ -0,0 +1,13 @@
1
+ /* eslint-disable class-methods-use-this */
2
+ class ResizeObserver {
3
+ observe() {
4
+ // do nothing
5
+ }
6
+
7
+ disconnect() {
8
+ // do nothing
9
+ }
10
+ }
11
+
12
+ window.ResizeObserver = ResizeObserver;
13
+ export default ResizeObserver;
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@kiva/kv-components",
3
- "version": "1.4.5",
3
+ "version": "3.0.1",
4
+ "type": "module",
4
5
  "publishConfig": {
5
6
  "access": "public"
6
7
  },
@@ -18,8 +19,10 @@
18
19
  "@storybook/addons": "^6.4.17",
19
20
  "@storybook/vue": "^6.4.17",
20
21
  "@testing-library/dom": "^8.1.0",
22
+ "@testing-library/jest-dom": "^5.16.2",
21
23
  "@testing-library/user-event": "^13.2.1",
22
24
  "@testing-library/vue": "^5.8.1",
25
+ "@vue/composition-api": "^1.4.1",
23
26
  "autoprefixer": "^10.4.2",
24
27
  "babel-core": "^7.0.0-bridge.0",
25
28
  "babel-jest": "^27.0.6",
@@ -30,30 +33,40 @@
30
33
  "eslint-plugin-import": "^2.20.2",
31
34
  "eslint-plugin-storybook": "^0.5.6",
32
35
  "eslint-plugin-vue": "^7.9.0",
33
- "jest": "^27.0.6",
36
+ "jest": "^27.4.3",
34
37
  "jest-axe": "^5.0.1",
35
38
  "postcss": "^8.4.5",
36
39
  "storybook-dark-mode": "^1.0.8",
37
40
  "tailwindcss": "^3.0.18",
38
- "vue-jest": "^3.0.7",
41
+ "vue": "^2.6.14",
39
42
  "vue-loader": "^15.9.6",
40
43
  "vue-router": "^3.5.2",
41
44
  "vue-template-compiler": "^2.6.12"
42
45
  },
43
46
  "scripts": {
44
- "storybook": "start-storybook -p 6006 -c vue/.storybook",
45
- "build-storybook": "build-storybook -c vue/.storybook",
47
+ "storybook": "vue-demi-switch 2 && start-storybook -p 6006 -c vue/.storybook",
48
+ "build-storybook": "vue-demi-switch 2 && build-storybook -c vue/.storybook",
46
49
  "lint": "eslint --ext .js,.vue ./",
47
- "test": "jest"
50
+ "test": "npm run lint"
48
51
  },
49
52
  "dependencies": {
50
- "@kiva/kv-tokens": "^1.3.2",
53
+ "@kiva/kv-tokens": "^2.0.1",
51
54
  "@mdi/js": "^5.9.55",
55
+ "@vueuse/integrations": "^7.6.0",
52
56
  "aria-hidden": "^1.1.3",
53
57
  "embla-carousel": "^4.5.3",
58
+ "focus-trap": "^6.7.2",
54
59
  "nanoid": "^3.1.23",
55
- "vue": "^2.6.12",
56
- "vue-focus-lock": "^1.4.1"
60
+ "vue-demi": "^0.12.1"
57
61
  },
58
- "gitHead": "12bb59eb8dbffd590a8624347a8a3f98bf5ffba3"
62
+ "peerDependencies": {
63
+ "@vue/composition-api": "^1.0.0-rc.1",
64
+ "vue": "^2.6.0 || >=3.0.0"
65
+ },
66
+ "peerDependenciesMeta": {
67
+ "@vue/composition-api": {
68
+ "optional": true
69
+ }
70
+ },
71
+ "gitHead": "2a8ff1a1fb9a3ad59f371d1e938a858e52372c62"
59
72
  }
@@ -1,6 +1,6 @@
1
1
  module.exports = {
2
2
  plugins: {
3
3
  tailwindcss: {},
4
- autoprefixer: {},
5
- },
4
+ autoprefixer: {}
5
+ }
6
6
  };
@@ -1,9 +1,9 @@
1
1
  const resolveConfig = require('tailwindcss/resolveConfig'); // eslint-disable-line import/no-extraneous-dependencies
2
- const { textStyles } = require('@kiva/kv-tokens/configs/kivaTypography');
3
- const sharedConfig = require('@kiva/kv-tokens/configs/tailwind.config');
2
+ const { textStyles } = require('@kiva/kv-tokens/configs/kivaTypography.cjs');
3
+ const sharedConfig = require('@kiva/kv-tokens/configs/tailwind.config.cjs');
4
4
  const {
5
5
  headerNumberCase, kebabCase, buildTailwindClassName,
6
- } = require('./utils/themeUtils');
6
+ } = require('./utils/themeUtils.cjs');
7
7
 
8
8
  const config = resolveConfig(sharedConfig);
9
9
  const { theme } = config;
@@ -0,0 +1,5 @@
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
+ import '@testing-library/jest-dom';
3
+ import { toHaveNoViolations } from 'jest-axe';
4
+
5
+ expect.extend(toHaveNoViolations);
@@ -1,41 +1,38 @@
1
1
  import { render, fireEvent } from '@testing-library/vue';
2
- import { axe, toHaveNoViolations } from 'jest-axe';
3
- import VueRouter from 'vue-router';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { axe } from 'jest-axe';
4
+ import addVueRouter from '../../utils/addVueRouter';
4
5
  import KvButton from '../../../../vue/KvButton.vue';
5
6
 
6
- const router = new VueRouter();
7
-
8
- expect.extend(toHaveNoViolations);
9
-
10
7
  describe('Default Button', () => {
8
+ const renderTestButton = (options) => render(KvButton, addVueRouter({
9
+ slots: { default: 'Test Button' },
10
+ ...options,
11
+ }));
12
+
11
13
  it('renders as a button tag by default', () => {
12
- const { getByRole } = render(KvButton, {
13
- slots: { default: 'Test Button' },
14
- });
14
+ const { getByRole } = renderTestButton();
15
15
  getByRole('button', { name: 'Test Button' });
16
16
  });
17
17
 
18
18
  it('renders as an anchor tag when passed an href prop', () => {
19
- const { getByRole } = render(KvButton, {
19
+ const { getByRole } = renderTestButton({
20
20
  props: { href: 'https://www.example.com/' },
21
- slots: { default: 'Test Button' },
22
21
  });
23
22
  const anchorEl = getByRole('link', { name: 'Test Button' });
24
23
  expect(anchorEl.href).toEqual('https://www.example.com/');
25
24
  });
26
25
 
27
26
  it('renders as an anchor tag when passed a route string', () => {
28
- const { getByRole } = render(KvButton, {
27
+ const { getByRole } = renderTestButton({
29
28
  props: { to: '/home' },
30
- slots: { default: 'Test Button' },
31
- routes: router,
32
29
  });
33
30
  const anchorEl = getByRole('link', { name: 'Test Button' });
34
31
  expect(anchorEl.href).toEqual('http://localhost/#/home');
35
32
  });
36
33
 
37
34
  it('renders as an anchor tag when passed a route object', () => {
38
- const { getByRole } = render(KvButton, {
35
+ const { getByRole } = renderTestButton({
39
36
  props: {
40
37
  to: {
41
38
  path: 'test-route-with-query',
@@ -44,35 +41,51 @@ describe('Default Button', () => {
44
41
  },
45
42
  },
46
43
  },
47
- slots: { default: 'Test Button' },
48
- routes: router,
49
44
  });
50
45
  const anchorEl = getByRole('link', { name: 'Test Button' });
51
46
  expect(anchorEl.href).toEqual('http://localhost/#/test-route-with-query?param1=a');
52
47
  });
53
48
 
54
49
  it('shows a ripple animation when clicked', async () => {
55
- const { getByText, getByTestId } = render(KvButton, {
56
- slots: { default: 'Test Button' },
57
- });
50
+ const { getByText, getByTestId } = renderTestButton();
58
51
  const btnEl = getByText('Test Button');
59
52
  await fireEvent.click(btnEl);
60
53
  getByTestId('ripple');
61
54
  });
62
55
 
56
+ it('passes through click events', async () => {
57
+ const onClick = jest.fn();
58
+ const { getByText } = render({
59
+ template: `<div>
60
+ <KvButton @click.prevent="onClick">Button tag</KvButton>
61
+ <KvButton href="#test" @click.prevent="onClick">Anchor tag</KvButton>
62
+ <KvButton to="/test" @click.native.prevent="onClick">Router-link</KvButton>
63
+ </div>`,
64
+ components: {
65
+ KvButton,
66
+ },
67
+ methods: {
68
+ onClick,
69
+ },
70
+ }, addVueRouter());
71
+
72
+ // Click all the buttons and expect the onClick method to have been called 3 times
73
+ await userEvent.click(getByText('Button tag'));
74
+ await userEvent.click(getByText('Anchor tag'));
75
+ await userEvent.click(getByText('Router-link'));
76
+ expect(onClick.mock.calls.length).toBe(3);
77
+ });
78
+
63
79
  it('when passed a loading prop, the button is disabled', () => {
64
- const { getByRole } = render(KvButton, {
80
+ const { getByRole } = renderTestButton({
65
81
  props: { state: 'loading' },
66
- slots: { default: 'Test Button' },
67
82
  });
68
83
  const btnEl = getByRole('button', { name: 'Test Button' });
69
84
  expect(btnEl.disabled).toBeTruthy();
70
85
  });
71
86
 
72
87
  it('has no automated accessibility violations', async () => {
73
- const { container } = render(KvButton, {
74
- slots: { default: 'Test Button' },
75
- });
88
+ const { container } = renderTestButton();
76
89
  const results = await axe(container);
77
90
  expect(results).toHaveNoViolations();
78
91
  });
@@ -0,0 +1,11 @@
1
+ import { render } from '@testing-library/vue';
2
+ import { axe } from 'jest-axe';
3
+ import KvCarousel from '../../../../vue/KvCarousel.vue';
4
+
5
+ describe('KvCarousel', () => {
6
+ it('has no automated accessibility violations', async () => {
7
+ const { container } = render(KvCarousel);
8
+ const results = await axe(container);
9
+ expect(results).toHaveNoViolations();
10
+ });
11
+ });
@@ -1,9 +1,7 @@
1
- import { render } from '@testing-library/vue';
2
- import { axe, toHaveNoViolations } from 'jest-axe';
1
+ import { render, fireEvent } from '@testing-library/vue';
2
+ import { axe } from 'jest-axe';
3
3
  import KvCheckbox from '../../../../vue/KvCheckbox.vue';
4
4
 
5
- expect.extend(toHaveNoViolations);
6
-
7
5
  describe('KvCheckbox', () => {
8
6
  it('renders with a role of "checkbox"', () => {
9
7
  const { getByRole } = render(KvCheckbox, {
@@ -26,18 +24,79 @@ describe('KvCheckbox', () => {
26
24
  expect(checkboxEl.checked).toEqual(false);
27
25
  });
28
26
 
29
- it('emits a change event when toggled', async () => {
30
- const { getByLabelText, emitted } = render(KvCheckbox, {
31
- slots: { default: 'Test Checkbox' },
32
- });
33
- const checkboxEl = getByLabelText('Test Checkbox');
27
+ it('works with v-model', async () => {
28
+ const TestComponent = {
29
+ template:
30
+ `<div>
31
+ <KvCheckbox v-model="checkboxValue">Test Checkbox</KvCheckbox>
32
+ <button @click="checkboxValue = false">reset</button>
33
+ <span>The checkbox value is {{ checkboxValue }}</span>
34
+ </div>`,
35
+ components: { KvCheckbox },
36
+ data: () => ({ checkboxValue: false }),
37
+ };
38
+ const { getByLabelText, getByText } = render(TestComponent);
39
+ const checkboxEl = getByText('Test Checkbox');
40
+ const checkboxInput = getByLabelText('Test Checkbox');
34
41
 
35
- await checkboxEl.click();
36
- expect(emitted().change[0]).toEqual([true]);
42
+ // Check that the value is `false` initially
43
+ expect(getByText('The checkbox value is false')).toBeDefined();
44
+ expect(checkboxInput.checked).toEqual(false);
37
45
 
38
- await checkboxEl.click();
39
- expect(emitted().change[1]).toEqual([false]);
40
- expect(emitted().change.length).toBe(2);
46
+ // Click the checkbox and expect the value to be `true` now
47
+ await fireEvent.click(checkboxEl);
48
+ expect(getByText('The checkbox value is true')).toBeDefined();
49
+ expect(checkboxInput.checked).toEqual(true);
50
+
51
+ // Click the reset button and expect the value to be `false` again
52
+ await fireEvent.click(getByText('reset'));
53
+ expect(getByText('The checkbox value is false')).toBeDefined();
54
+ expect(checkboxInput.checked).toEqual(false);
55
+ });
56
+
57
+ it('applies parent event listeners to the input element', async () => {
58
+ const onInput = jest.fn();
59
+ const TestComponent = {
60
+ template: '<KvCheckbox @input="onInput">Test Checkbox</KvCheckbox>',
61
+ components: { KvCheckbox },
62
+ methods: { onInput },
63
+ };
64
+ const { getByText } = render(TestComponent);
65
+
66
+ const checkboxEl = getByText('Test Checkbox');
67
+ await fireEvent.click(checkboxEl);
68
+ expect(onInput.mock.calls.length).toBe(1);
69
+ });
70
+
71
+ it('applies parent attributes to the input element', async () => {
72
+ const TestComponent = {
73
+ template: '<KvCheckbox name="test-checkbox">Test Checkbox</KvCheckbox>',
74
+ components: { KvCheckbox },
75
+ };
76
+ const { getByRole } = render(TestComponent);
77
+
78
+ const checkboxEl = getByRole('checkbox');
79
+ expect(checkboxEl.name).toBe('test-checkbox');
80
+ });
81
+
82
+ it('applies parent styles to the root element', async () => {
83
+ const TestComponent = {
84
+ template: '<KvCheckbox style="padding-top:1234px">Test Checkbox</KvCheckbox>',
85
+ components: { KvCheckbox },
86
+ };
87
+ const { container } = render(TestComponent);
88
+
89
+ expect(container.firstChild.style.paddingTop).toEqual('1234px');
90
+ });
91
+
92
+ it('applies parent classes to the root element', async () => {
93
+ const TestComponent = {
94
+ template: '<KvCheckbox class="test-class">Test Checkbox</KvCheckbox>',
95
+ components: { KvCheckbox },
96
+ };
97
+ const { container } = render(TestComponent);
98
+
99
+ expect(container.firstChild.classList).toContain('test-class');
41
100
  });
42
101
 
43
102
  it('has no automated accessibility violations', async () => {
@@ -0,0 +1,14 @@
1
+ import { render } from '@testing-library/vue';
2
+ import { axe } from 'jest-axe';
3
+ import KvLightbox from '../../../../vue/KvLightbox.vue';
4
+
5
+ describe('KvLightbox', () => {
6
+ it('has no automated accessibility violations', async () => {
7
+ const { container } = render(KvLightbox,
8
+ {
9
+ props: { title: 'Lightbox Title' },
10
+ });
11
+ const results = await axe(container);
12
+ expect(results).toHaveNoViolations();
13
+ });
14
+ });
@@ -0,0 +1,11 @@
1
+ import { render } from '@testing-library/vue';
2
+ import KvProgressBar from '../../../../vue/KvProgressBar.vue';
3
+
4
+ describe('KvProgressBar', () => {
5
+ it('renders with a role of "progressbar"', () => {
6
+ const { getByRole } = render(KvProgressBar);
7
+ const progressbarEl = getByRole('progressbar');
8
+
9
+ expect(progressbarEl).toBeDefined();
10
+ });
11
+ });
@@ -1,9 +1,7 @@
1
- import { render } from '@testing-library/vue';
2
- import { axe, toHaveNoViolations } from 'jest-axe';
1
+ import { render, fireEvent } from '@testing-library/vue';
2
+ import { axe } from 'jest-axe';
3
3
  import KvRadio from '../../../../vue/KvRadio.vue';
4
4
 
5
- expect.extend(toHaveNoViolations);
6
-
7
5
  const radioGroup = {
8
6
  components: { KvRadio },
9
7
  data() { return { testModel: 'foo' }; },
@@ -70,7 +68,6 @@ describe('KvRadio', () => {
70
68
  it('One radio element can be checked at a time', async () => {
71
69
  const { getAllByRole, getByLabelText } = render(radioGroup);
72
70
  const radioEls = getAllByRole('radio');
73
-
74
71
  expect(radioEls[0].value).toBe('foo');
75
72
  expect(radioEls[1].value).toBe('bar');
76
73
  expect(radioEls[2].value).toBe('baz');
@@ -87,6 +84,98 @@ describe('KvRadio', () => {
87
84
  expect(radioEls[2].checked).toBe(true);
88
85
  });
89
86
 
87
+ it('works with v-model', async () => {
88
+ const TestComponent = {
89
+ template:
90
+ `<fieldset>
91
+ <KvRadio v-model="radioValue" value="foo">Foo</KvRadio>
92
+ <KvRadio v-model="radioValue" value="bar">Bar</KvRadio>
93
+ <KvRadio v-model="radioValue" value="baz">Baz</KvRadio>
94
+ <button @click="radioValue = 'baz'">choose baz</button>
95
+ <button @click="radioValue = ''">reset</button>
96
+ <span>The radio value is {{ radioValue }}</span>
97
+ </fieldset>`,
98
+ components: { KvRadio },
99
+ data: () => ({ radioValue: 'bar' }),
100
+ };
101
+ const { getByLabelText, getByText } = render(TestComponent);
102
+ const radioFoo = getByLabelText('Foo');
103
+ const radioBar = getByLabelText('Bar');
104
+ const radioBaz = getByLabelText('Baz');
105
+
106
+ // Check that the value is 'bar' initially
107
+ expect(getByText('The radio value is bar')).toBeDefined();
108
+ expect(radioFoo.checked).toBe(false);
109
+ expect(radioBar.checked).toBe(true);
110
+ expect(radioBaz.checked).toBe(false);
111
+
112
+ // Click the 'Foo' radio and expect the value to be 'foo' now
113
+ await fireEvent.click(radioFoo);
114
+ expect(getByText('The radio value is foo')).toBeDefined();
115
+ expect(radioFoo.checked).toBe(true);
116
+ expect(radioBar.checked).toBe(false);
117
+ expect(radioBaz.checked).toBe(false);
118
+
119
+ // Click the 'choose baz' button and expect the value to be 'baz' now
120
+ await fireEvent.click(getByText('choose baz'));
121
+ expect(getByText('The radio value is baz')).toBeDefined();
122
+ expect(radioFoo.checked).toBe(false);
123
+ expect(radioBar.checked).toBe(false);
124
+ expect(radioBaz.checked).toBe(true);
125
+
126
+ // Click the reset button and expect the value to be blank now
127
+ await fireEvent.click(getByText('reset'));
128
+ expect(getByText('The radio value is')).toBeDefined();
129
+ expect(radioFoo.checked).toBe(false);
130
+ expect(radioBar.checked).toBe(false);
131
+ expect(radioBaz.checked).toBe(false);
132
+ });
133
+
134
+ it('applies parent event listeners to the input element', async () => {
135
+ const onInput = jest.fn();
136
+ const TestComponent = {
137
+ template: '<KvRadio @input="onInput" value="foo">Foo</KvRadio>',
138
+ components: { KvRadio },
139
+ methods: { onInput },
140
+ };
141
+ const { getByRole } = render(TestComponent);
142
+
143
+ const radioEl = getByRole('radio');
144
+ await fireEvent.click(radioEl);
145
+ expect(onInput.mock.calls.length).toBe(1);
146
+ });
147
+
148
+ it('applies parent attributes to the input element', async () => {
149
+ const TestComponent = {
150
+ template: '<KvRadio name="test-radio" value="foo">Foo</KvRadio>',
151
+ components: { KvRadio },
152
+ };
153
+ const { getByRole } = render(TestComponent);
154
+
155
+ const radioEl = getByRole('radio');
156
+ expect(radioEl.name).toBe('test-radio');
157
+ });
158
+
159
+ it('applies parent styles to the root element', async () => {
160
+ const TestComponent = {
161
+ template: '<KvRadio style="padding-top:1234px" value="foo">Foo</KvRadio>',
162
+ components: { KvRadio },
163
+ };
164
+ const { container } = render(TestComponent);
165
+
166
+ expect(container.firstChild.style.paddingTop).toEqual('1234px');
167
+ });
168
+
169
+ it('applies parent classes to the root element', async () => {
170
+ const TestComponent = {
171
+ template: '<KvRadio class="test-class" value="foo">Foo</KvRadio>',
172
+ components: { KvRadio },
173
+ };
174
+ const { container } = render(TestComponent);
175
+
176
+ expect(container.firstChild.classList).toContain('test-class');
177
+ });
178
+
90
179
  it('has no automated accessibility violations', async () => {
91
180
  const { container } = render(radioGroup);
92
181
  const results = await axe(container);