From ba9f960ef999cfa92afea09f703898956cc69421 Mon Sep 17 00:00:00 2001 From: Joshua Graber <68428039+joshuagraber@users.noreply.github.com> Date: Fri, 7 Jun 2024 11:10:49 -0400 Subject: [PATCH] feat(components): loading (#82) --- .vscode/extensions.json | 2 +- src/components/Spinner/PdapSpinner.vue | 78 +++++++++++++ .../__snapshots__/spinner.spec.ts.snap | 54 +++++++++ src/components/Spinner/index.ts | 1 + src/components/Spinner/spinner.spec.ts | 60 ++++++++++ src/components/Spinner/types.ts | 6 + src/components/index.ts | 1 + src/demo/pages/ComponentDemo.vue | 106 +++++++++++++++--- src/styles/utilities.css | 6 +- 9 files changed, 295 insertions(+), 19 deletions(-) create mode 100644 src/components/Spinner/PdapSpinner.vue create mode 100644 src/components/Spinner/__snapshots__/spinner.spec.ts.snap create mode 100644 src/components/Spinner/index.ts create mode 100644 src/components/Spinner/spinner.spec.ts create mode 100644 src/components/Spinner/types.ts diff --git a/.vscode/extensions.json b/.vscode/extensions.json index d3d2b7d..f830b89 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,6 @@ { "recommendations": [ "tailwind.tailwindcss", - "vue.volar" + "Vue.volar" ] } \ No newline at end of file diff --git a/src/components/Spinner/PdapSpinner.vue b/src/components/Spinner/PdapSpinner.vue new file mode 100644 index 0000000..15f665f --- /dev/null +++ b/src/components/Spinner/PdapSpinner.vue @@ -0,0 +1,78 @@ + + + + + + + diff --git a/src/components/Spinner/__snapshots__/spinner.spec.ts.snap b/src/components/Spinner/__snapshots__/spinner.spec.ts.snap new file mode 100644 index 0000000..5a0f390 --- /dev/null +++ b/src/components/Spinner/__snapshots__/spinner.spec.ts.snap @@ -0,0 +1,54 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`PdapSpinner > applies custom color and size 1`] = ` +
+ + + + + + + + + +
+`; + +exports[`PdapSpinner > does not render spinner when show prop is false 1`] = ` +
+ + + + + + +
+`; + +exports[`PdapSpinner > renders spinner when show prop is true 1`] = ` +
+ + + + + + + + + +
+`; + +exports[`PdapSpinner > renders text when text prop is provided 1`] = ` +
+ + + + + + + +

Loading...

+
+
+`; diff --git a/src/components/Spinner/index.ts b/src/components/Spinner/index.ts new file mode 100644 index 0000000..aa1f02b --- /dev/null +++ b/src/components/Spinner/index.ts @@ -0,0 +1 @@ +export { default as Spinner } from './PdapSpinner.vue'; diff --git a/src/components/Spinner/spinner.spec.ts b/src/components/Spinner/spinner.spec.ts new file mode 100644 index 0000000..5cede75 --- /dev/null +++ b/src/components/Spinner/spinner.spec.ts @@ -0,0 +1,60 @@ +import { shallowMount } from '@vue/test-utils'; +import PdapSpinner from './PdapSpinner.vue'; + +import { describe, expect, it } from 'vitest'; + +describe('PdapSpinner', () => { + it('renders spinner when show prop is true', () => { + const wrapper = shallowMount(PdapSpinner, { + props: { + show: true, + }, + }); + + expect(wrapper.find('svg').exists()).toBe(true); + expect(wrapper.html()).toMatchSnapshot(); + }); + + it('does not render spinner when show prop is false', () => { + const wrapper = shallowMount(PdapSpinner, { + props: { + show: false, + }, + }); + + expect(wrapper.find('svg').exists()).toBe(false); + expect(wrapper.html()).toMatchSnapshot(); + }); + + it('renders text when text prop is provided', () => { + const text = 'Loading...'; + const wrapper = shallowMount(PdapSpinner, { + props: { + show: true, + text, + }, + }); + + expect(wrapper.text()).toContain(text); + expect(wrapper.html()).toMatchSnapshot(); + }); + + it('applies custom color and size', () => { + const color = 'red'; + const size = 48; + const wrapper = shallowMount(PdapSpinner, { + props: { + show: true, + color, + size, + }, + }); + const svg = wrapper.find('svg'); + expect(svg.attributes('width')).toBe(`${size}`); + expect(svg.attributes('height')).toBe(`${size}`); + expect(wrapper.find('path').attributes('stroke')).toBe(color); + expect(wrapper.find('path').attributes('fill')).toBe(color); + + expect(wrapper.html()).toMatchSnapshot(); + }); +}); diff --git a/src/components/Spinner/types.ts b/src/components/Spinner/types.ts new file mode 100644 index 0000000..896fd23 --- /dev/null +++ b/src/components/Spinner/types.ts @@ -0,0 +1,6 @@ +export interface PdapSpinnerProps { + color?: string; + size?: number; + text?: string; + show: boolean; +} diff --git a/src/components/index.ts b/src/components/index.ts index 4d15c5f..14e16a2 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -9,3 +9,4 @@ export { QuickSearchForm } from './QuickSearchForm'; export { TileIcon } from './TileIcon'; export { Dropdown } from './Dropdown'; export { Breadcrumbs } from './Breadcrumbs'; +export { Spinner } from './Spinner'; diff --git a/src/demo/pages/ComponentDemo.vue b/src/demo/pages/ComponentDemo.vue index 3e4935d..e7deb6e 100644 --- a/src/demo/pages/ComponentDemo.vue +++ b/src/demo/pages/ComponentDemo.vue @@ -17,17 +17,61 @@

Breadcrumbs

Click to navigate: - Home - Foo - FooBar - FooBarBaz + Home + Foo + FooBar + FooBarBaz
+

Loading

+

+ The loading-shimmer class (which is just a wrapper around + the TailwindCSS animate-pulse class) can be applied to + anything. +

+
+

Like this:

+
+
+
+

Or this:

+
+ +
+
+
+

Or this:

+
+
+
+

Or this:

+
+
+ +

Loading spinner:

+ + + + + + + + + + +

Buttons

These are all contained within a grid container, defined by using the @@ -37,25 +81,27 @@

Button primary

- +

Button secondary

+ Secondary button +

Button tertiary

+ Tertiary button +

This is an unstyled button meant to take any styling (see the clickable pills in current data sources search results) @@ -76,8 +122,8 @@ }" > Press to toggle dropdown open/closed + > + + > +