diff --git a/__snapshots__/icon button.md b/__snapshots__/icon button.md
index a26cde0aba..faa877048e 100644
--- a/__snapshots__/icon button.md	
+++ b/__snapshots__/icon button.md	
@@ -4,13 +4,13 @@
 
 ```html
 <button
-  aria-label=""
+  aria-label="bin"
   class="mdc-icon-button"
 >
   <vwc-icon
-    class="icon"
+    class="vwc-icon"
     size="small"
-    type=""
+    type="bin"
   >
   </vwc-icon>
   <span class="default-slot-container">
diff --git a/common/foundation/scss/mixins/_layout-mixins.scss b/common/foundation/scss/mixins/_layout-mixins.scss
index f1bdabeb1c..613ee5b6db 100644
--- a/common/foundation/scss/mixins/_layout-mixins.scss
+++ b/common/foundation/scss/mixins/_layout-mixins.scss
@@ -3,7 +3,7 @@
 @use '../functions';
 
 // override to apply relevance
-$layouts: filled outlined soft text !default;
+$layouts: filled outlined soft text ghost !default;
 ////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////
 $allLayouts: (
@@ -11,6 +11,7 @@ $allLayouts: (
 	outlined: 'outlined',
 	soft: 'soft',
 	text: 'text',
+	ghost: 'ghost',
 );
 
 $bg: var(#{color-semantic.$vvd-color-connotation});
@@ -32,6 +33,12 @@ $bg: var(#{color-semantic.$vvd-color-connotation});
 	--opaque: 20;
 }
 
+%text,
+%ghost {
+	--background-color: transparent;
+	--color: var(#{scheme-variables.$vvd-color-on-base});
+}
+
 @mixin layout() {
 	@each $layout in functions.pick($layouts, $allLayouts) {
 		#{':host([layout="#{$layout}"])'} {
diff --git a/common/foundation/scss/mixins/_shape-mixins.scss b/common/foundation/scss/mixins/_shape-mixins.scss
index eedcb93537..4cf9a307a0 100644
--- a/common/foundation/scss/mixins/_shape-mixins.scss
+++ b/common/foundation/scss/mixins/_shape-mixins.scss
@@ -18,6 +18,7 @@
 	$shapes: (
 		rounded: var(#{shape-var-names.$shape-border-radius-md-css-variable-name}),
 		pill: var(#{shape-var-names.$shape-border-radius-lg-css-variable-name}),
+		circled: 50%,
 	),
 	$default: rounded
 ) {
diff --git a/common/foundation/src/constants.ts b/common/foundation/src/constants.ts
index e4fa40f613..561027e9db 100644
--- a/common/foundation/src/constants.ts
+++ b/common/foundation/src/constants.ts
@@ -13,6 +13,7 @@ export enum Connotation {
 export enum Shape {
 	Rounded = 'rounded',
 	Pill = 'pill',
+	Circled = 'circled',
 }
 
 export enum Size {
@@ -27,4 +28,5 @@ export enum Layout {
 	Filled = 'filled',
 	Outlined = 'outlined',
 	Soft = 'soft',
+	Ghost = 'ghost',
 }
diff --git a/components/badge/src/vwc-badge-base.ts b/components/badge/src/vwc-badge-base.ts
index 1b85eb8211..9c8257b37f 100644
--- a/components/badge/src/vwc-badge-base.ts
+++ b/components/badge/src/vwc-badge-base.ts
@@ -17,12 +17,14 @@ type BadgeLayout = Extract<
 	Layout.Filled | Layout.Outlined | Layout.Soft
 >;
 
+type BadgeShape = Extract<Shape, Shape.Rounded | Shape.Pill>;
+
 export class BadgeBase extends LitElement {
 	@property({ type: String, reflect: true })
 	connotation: BadgeConnotation = Connotation.Primary;
 
 	@property({ type: String, reflect: true })
-	shape?: Shape;
+	shape?: BadgeShape;
 
 	@property({ type: String, reflect: true })
 	layout: BadgeLayout = Layout.Filled;
diff --git a/components/badge/stories/arg-types.js b/components/badge/stories/arg-types.js
index 0432f85219..e736b0696c 100644
--- a/components/badge/stories/arg-types.js
+++ b/components/badge/stories/arg-types.js
@@ -13,7 +13,9 @@ export const argTypes = {
 	shape: {
 		control: {
 			type: 'select',
-			options: Object.values(Shape)
+			options: Object.values(Shape).filter(s => [
+				Shape.Rounded, Shape.Pill
+			].includes(s)),
 		}
 	},
 	layout: {
diff --git a/components/button/src/vwc-button.ts b/components/button/src/vwc-button.ts
index 3042c2ef3c..72afd871a4 100644
--- a/components/button/src/vwc-button.ts
+++ b/components/button/src/vwc-button.ts
@@ -35,6 +35,8 @@ type ButtonConnotation = Extract<
 	| Connotation.Announcement
 >;
 
+type ButtonShape = Extract<Shape, Shape.Rounded | Shape.Pill>;
+
 /**
  * This component is an extension of [<mwc-button>](https://github.com/material-components/material-components-web-components/tree/master/packages/button)
  * Our button supports native features like the 'form' and 'type' attributes
@@ -51,7 +53,7 @@ export class VWCButton extends MWCButton {
 	connotation: ButtonConnotation = Connotation.Primary;
 
 	@property({ type: String, reflect: true })
-	shape?: Shape;
+	shape?: ButtonShape;
 
 	@property({ type: String, reflect: true })
 	type: ButtonType[number] = 'submit';
diff --git a/components/button/stories/arg-types.js b/components/button/stories/arg-types.js
index 89c3dc9331..b980342897 100644
--- a/components/button/stories/arg-types.js
+++ b/components/button/stories/arg-types.js
@@ -19,7 +19,9 @@ export const argTypes = {
 	shape: {
 		control: {
 			type: 'select',
-			options: Object.values(Shape),
+			options: Object.values(Shape).filter(s => [
+				Shape.Rounded, Shape.Pill
+			].includes(s)),
 		}
 	},
 	dense: {
diff --git a/components/button/test/button.connotation.test.js b/components/button/test/button.connotation.test.js
index 33fcc13aa9..6cb584a3ee 100644
--- a/components/button/test/button.connotation.test.js
+++ b/components/button/test/button.connotation.test.js
@@ -1,4 +1,3 @@
-import '../vwc-button.js';
 import {
 	textToDomToParent,
 	isolatedElementsCreation,
@@ -7,16 +6,19 @@ import {
 	assertConnotationAttribute,
 	assertConnotationProperty,
 } from '@vonage/vvd-foundation/test/connotation.test.js';
+import { Connotation } from '@vonage/vvd-foundation/constants';
+
+const CONNOTATIONS_SUPPORTED = Object.values(Connotation).filter((c) =>
+	[
+		Connotation.Primary,
+		Connotation.CTA,
+		Connotation.Success,
+		Connotation.Alert,
+		Connotation.Info,
+		Connotation.Announcement,
+	].includes(c)
+);
 
-const VWC_BUTTON = 'vwc-button';
-const CONNOTATIONS_SUPPORTED = [
-	'primary',
-	'cta',
-	'success',
-	'alert',
-	'info',
-	'announcement',
-];
 const LAYOUTS_AFFECTED = [
 	{
 		layout: 'filled',
@@ -36,7 +38,7 @@ const LAYOUTS_AFFECTED = [
 	},
 ];
 
-describe('button connotation', () => {
+export async function connotationTestCases(COMPONENT_NAME) {
 	const addElement = isolatedElementsCreation();
 
 	for (const { layout, childrenAffected, stylesAffected } of LAYOUTS_AFFECTED) {
@@ -44,7 +46,9 @@ describe('button connotation', () => {
 			it(`should reflect '${connotation}' connotation (attribute) visually, ${layout}`, async () => {
 				const [button] = addElement(
 					textToDomToParent(
-						`<${VWC_BUTTON} layout="${layout}">Button</${VWC_BUTTON}>`
+						`<${COMPONENT_NAME} layout="${layout}" icon="bin">
+							${COMPONENT_NAME === 'vwc-button' ? 'Button' : ''}
+						</${COMPONENT_NAME}>`
 					)
 				);
 				await assertConnotationAttribute({
@@ -58,7 +62,9 @@ describe('button connotation', () => {
 			it(`should reflect '${connotation}' connotation (property) visually, ${layout}`, async () => {
 				const [button] = addElement(
 					textToDomToParent(
-						`<${VWC_BUTTON} layout="${layout}">Button</${VWC_BUTTON}>`
+						`<${COMPONENT_NAME} layout="${layout}" icon="bin">
+							${COMPONENT_NAME === 'vwc-button' ? 'Button' : ''}
+						</${COMPONENT_NAME}>`
 					)
 				);
 				await assertConnotationProperty({
@@ -70,4 +76,4 @@ describe('button connotation', () => {
 			});
 		}
 	}
-});
+}
diff --git a/components/button/test/button.test.js b/components/button/test/button.test.js
index ac9da7742e..af68ecb479 100644
--- a/components/button/test/button.test.js
+++ b/components/button/test/button.test.js
@@ -4,7 +4,12 @@ import {
 	textToDomToParent,
 	assertComputedStyle,
 } from '../../../test/test-helpers.js';
-import { shapeStyles } from '../../../test/style-utils.js';
+import {
+	sizingTestCases,
+	shapeRoundedTestCases,
+	shapePillTestCases,
+} from '../../../test/shared';
+import { connotationTestCases } from './button.connotation.test.js';
 import { chaiDomDiff } from '@open-wc/semantic-dom-diff';
 import {
 	isolatedElementsCreation,
@@ -362,65 +367,15 @@ describe('button', () => {
 	});
 
 	describe('sizing', () => {
-		it('should have normal size by default', async () => {
-			const addedElements = addElement(
-				textToDomToParent(`<${COMPONENT_NAME}>Button Text</${COMPONENT_NAME}>`)
-			);
-			const actualElement = addedElements[0];
-			await waitNextTask();
-			assertComputedStyle(actualElement, { height: '40px' });
-		});
-
-		it('should have dense size when dense', async () => {
-			const addedElements = addElement(
-				textToDomToParent(
-					`<${COMPONENT_NAME} dense>Button Text</${COMPONENT_NAME}>`
-				)
-			);
-			const actualElement = addedElements[0];
-			await waitNextTask();
-			assertComputedStyle(actualElement, { height: '32px' });
-		});
-
-		it('should have enlarged size when enlarged', async () => {
-			const addedElements = addElement(
-				textToDomToParent(
-					`<${COMPONENT_NAME} enlarged>Button Text</${COMPONENT_NAME}>`
-				)
-			);
-			const actualElement = addedElements[0];
-			await waitNextTask();
-			assertComputedStyle(actualElement, { height: '48px' });
-		});
+		sizingTestCases(COMPONENT_NAME);
 	});
 
 	describe('shape', () => {
-		let formElement, actualElement;
-		beforeEach(async () => {
-			const addedElements = addElement(
-				textToDomToParent(
-					`<${COMPONENT_NAME} layout="filled">Button Text</${COMPONENT_NAME}>`
-				)
-			);
-			await waitNextTask();
-			formElement = addedElements[0];
-			actualElement = formElement.shadowRoot.querySelector('#button');
-		});
-
-		it('should have rounded shape by default', async () => {
-			assertComputedStyle(actualElement, shapeStyles('rounded'));
-		});
-
-		it('should have rounded shape when shape set to rounded', async () => {
-			formElement.shape = 'rounded';
-			await waitNextTask();
-			assertComputedStyle(actualElement, shapeStyles('rounded'));
-		});
+		shapeRoundedTestCases(COMPONENT_NAME);
+		shapePillTestCases(COMPONENT_NAME);
+	});
 
-		it('should have pill shape when shape set to pill', async () => {
-			formElement.shape = 'pill';
-			await waitNextTask();
-			assertComputedStyle(actualElement, shapeStyles('pill'));
-		});
+	describe('button connotation', () => {
+		connotationTestCases(COMPONENT_NAME);
 	});
 });
diff --git a/components/icon-button/src/vwc-icon-button.scss b/components/icon-button/src/vwc-icon-button.scss
index a3c4a2991b..87aeca2548 100644
--- a/components/icon-button/src/vwc-icon-button.scss
+++ b/components/icon-button/src/vwc-icon-button.scss
@@ -1,22 +1,52 @@
 @use '@vonage/vvd-design-tokens/build/scss/semantic-variables/scheme-variables';
 @use '@vonage/vvd-foundation/scss/variable-names/color-semantic-variable-names' as color-semantic;
+@use '@vonage/vvd-foundation/scss/mixins/shape-mixins';
+@use '@vonage/vvd-foundation/scss/mixins/color-connotation-mixins' with (
+	$connotations: primary cta success alert info announcement
+);
+@use '@vonage/vvd-foundation/scss/mixins/layout-mixins' with (
+	$layouts: filled outlined ghost
+);
 
 :host {
 	.mdc-icon-button {
+		background-color: var(--background-color);
+		border: var(--border);
+		border-radius: var(--border-radius);
+		color: var(--color);
 		display: inline-flex;
 		align-items: center;
 		justify-content: center;
+		overflow: hidden;
+	}
+
+	.vwc-icon {
+		--size: 20px;
+		height: var(--size);
+		width: var(--size);
 	}
 }
 
 // theming
-:host {
-	.mdc-icon-button {
-		color: var(#{scheme-variables.$vvd-color-on-base});
+@include color-connotation-mixins.connotations-context(
+	':host([layout="filled"]#{color-connotation-mixins.$connotation-placeholder}),:host([layout="outlined"]#{color-connotation-mixins.$connotation-placeholder})'
+);
+
+:host([layout='filled']) {
+	.mdc-icon-button:disabled {
+		background-color: var(#{scheme-variables.$vvd-color-contrast-soft});
+	}
+}
+
+:host([layout='outlined']) {
+	.mdc-icon-button:disabled {
+		border-color: var(#{color-semantic.$formfield-disabled-ink});
 	}
+}
 
+:host {
 	.mdc-icon-button:disabled {
-		color: var(	#{color-semantic.$formfield-disabled-ink});
+		color: var(#{color-semantic.$formfield-disabled-ink});
 	}
 }
 
@@ -27,8 +57,25 @@
 
 :host([dense]) {
 	--mdc-icon-button-size: 32px;
+
+	.vwc-icon {
+		--size: 16px;
+	}
 }
 
 :host([enlarged]) {
 	--mdc-icon-button-size: 48px;
+
+	.vwc-icon {
+		--size: 24px;
+	}
 }
+
+@include shape-mixins.shape(
+	$shapes: (
+		rounded: 6px,
+		circled: 50%,
+	)
+);
+
+@include layout-mixins.layout();
diff --git a/components/icon-button/src/vwc-icon-button.ts b/components/icon-button/src/vwc-icon-button.ts
index d649fba11d..c8447d4763 100644
--- a/components/icon-button/src/vwc-icon-button.ts
+++ b/components/icon-button/src/vwc-icon-button.ts
@@ -5,6 +5,8 @@ import { IconButton as MWCIconButton } from '@material/mwc-icon-button';
 import { style as vwcButtonStyle } from './vwc-icon-button.css';
 import { style as mwcIconButtonStyle } from '@material/mwc-icon-button/mwc-icon-button-css.js';
 import { style as styleCoupling } from '@vonage/vvd-style-coupling/vvd-style-coupling.css.js';
+import { Connotation, Shape, Layout } from '@vonage/vvd-foundation/constants';
+import { handleMultipleDenseProps } from '@vonage/vvd-foundation/general-utils';
 import { html, TemplateResult } from 'lit-element';
 
 declare global {
@@ -17,11 +19,37 @@ declare global {
 // @ts-ignore
 MWCIconButton.styles = [styleCoupling, mwcIconButtonStyle, vwcButtonStyle];
 
+type IconButtonLayout = Extract<
+	Layout,
+	Layout.Filled | Layout.Outlined | Layout.Ghost
+>;
+
+type IconButtonShape = Extract<Shape, Shape.Rounded | Shape.Circled>;
+
+type IconButtonConnotation = Extract<
+	Connotation,
+	| Connotation.Primary
+	| Connotation.CTA
+	| Connotation.Success
+	| Connotation.Alert
+	| Connotation.Info
+	| Connotation.Announcement
+>;
+
 /**
  * This component is an extension of [<mwc-icon-button>](https://github.com/material-components/material-components-web-components/tree/master/packages/icon-button)
  */
 @customElement('vwc-icon-button')
 export class VWCIconButton extends MWCIconButton {
+	@property({ type: String, reflect: true })
+	layout: IconButtonLayout = Layout.Ghost;
+
+	@property({ type: String, reflect: true })
+	connotation: IconButtonConnotation = Connotation.Primary;
+
+	@property({ type: String, reflect: true })
+	shape?: IconButtonShape;
+
 	@property({ type: Boolean, reflect: true })
 	dense = false;
 
@@ -29,18 +57,7 @@ export class VWCIconButton extends MWCIconButton {
 	enlarged = false;
 
 	protected updated(changes: Map<string, boolean>): void {
-		if (changes.has('dense')) {
-			if (this.dense && this.enlarged) {
-				this.enlarged = false;
-			}
-		}
-
-		if (changes.has('enlarged')) {
-			if (this.enlarged && this.dense) {
-				this.removeAttribute('dense');
-				this.dense = false;
-			}
-		}
+		handleMultipleDenseProps(this, changes);
 	}
 
 	protected render(): TemplateResult {
@@ -66,9 +83,15 @@ export class VWCIconButton extends MWCIconButton {
 
 	protected renderIcon(): TemplateResult {
 		return html`<vwc-icon
-			class="icon"
+			class="vwc-icon"
 			size="small"
 			type="${this.icon}"
 		></vwc-icon>`;
 	}
+
+	renderRipple(): TemplateResult | '' {
+		return this.shouldRenderRipple
+			? html` <mwc-ripple .disabled="${this.disabled}"></mwc-ripple>`
+			: '';
+	}
 }
diff --git a/components/icon-button/stories/arg-types.js b/components/icon-button/stories/arg-types.js
index 5c54336a88..032e7cf979 100644
--- a/components/icon-button/stories/arg-types.js
+++ b/components/icon-button/stories/arg-types.js
@@ -1,4 +1,30 @@
+import { Connotation, Shape, Layout } from '@vonage/vvd-foundation/constants';
+
 export const argTypes = {
+	connotation: {
+		control: {
+			type: 'select',
+			options: Object.values(Connotation).filter(c => [
+				Connotation.Primary, Connotation.CTA, Connotation.Success, Connotation.Alert, Connotation.Info, Connotation.Announcement
+			].includes(c)),
+		}
+	},
+	layout: {
+		control: {
+			type: 'select',
+			options: Object.values(Layout).filter(l => [
+				Layout.Filled, Layout.Outlined, Layout.Ghost
+			].includes(l)),
+		}
+	},
+	shape: {
+		control: {
+			type: 'select',
+			options: Object.values(Shape).filter(s => [
+				Shape.Rounded, Shape.Circled
+			].includes(s)),
+		}
+	},
 	dense: {
 		control: {
 			type: 'inline-radio',
diff --git a/components/icon-button/stories/icon-button.stories.js b/components/icon-button/stories/icon-button.stories.js
index d1f24574c5..8496151fff 100644
--- a/components/icon-button/stories/icon-button.stories.js
+++ b/components/icon-button/stories/icon-button.stories.js
@@ -14,11 +14,20 @@ const Template = args => html`<vwc-icon-button ...=${spread(args)}></vwc-icon-bu
 export const Basic = Template.bind({});
 Basic.args = { icon: 'bin' };
 
+export const Filled = Template.bind({});
+Filled.args = { icon: 'bin', layout: 'filled' };
+
+export const Outlined = Template.bind({});
+Outlined.args = { icon: 'bin', layout: 'outlined' };
+
+export const CircledShape = Template.bind({});
+CircledShape.args = { icon: 'bin', shape: 'circled', layout: 'filled' };
+
 export const Dense = Template.bind({});
-Dense.args = { icon: 'home', dense: true };
+Dense.args = { icon: 'home', dense: true, layout: 'filled' };
 
 export const Enlarged = Template.bind({});
-Enlarged.args = { icon: 'home', enlarged: true };
+Enlarged.args = { icon: 'home', enlarged: true, layout: 'filled' };
 
 export const Disabled = Template.bind({});
-Disabled.args = { icon: 'code', disabled: true };
\ No newline at end of file
+Disabled.args = { icon: 'code', disabled: true, layout: 'filled' };
\ No newline at end of file
diff --git a/components/icon-button/test/icon-button.test.js b/components/icon-button/test/icon-button.test.js
index fb7e3cbdbc..14d280e168 100644
--- a/components/icon-button/test/icon-button.test.js
+++ b/components/icon-button/test/icon-button.test.js
@@ -1,5 +1,16 @@
 import '../vwc-icon-button.js';
-import { waitNextTask, textToDomToParent } from '../../../test/test-helpers.js';
+import {
+	waitNextTask,
+	textToDomToParent,
+	assertComputedStyle,
+} from '../../../test/test-helpers.js';
+import { layoutStyles, topLevelSelectors } from '../../../test/style-utils.js';
+import {
+	sizingTestCases,
+	shapeRoundedTestCases,
+	shapeCircledTestCases,
+} from '../../../test/shared';
+import { connotationTestCases } from '../../button/test/button.connotation.test.js';
 import { chaiDomDiff } from '@open-wc/semantic-dom-diff';
 import { isolatedElementsCreation } from '../../../test/test-helpers';
 
@@ -18,9 +29,58 @@ describe('icon button', () => {
 
 	it('should internal contents', async () => {
 		const [e] = addElement(
-			textToDomToParent(`<${COMPONENT_NAME}></${COMPONENT_NAME}>`)
+			textToDomToParent(`<${COMPONENT_NAME} icon="bin"></${COMPONENT_NAME}>`)
 		);
 		await waitNextTask();
 		expect(e.shadowRoot.innerHTML).to.equalSnapshot();
 	});
+
+	describe('sizing', () => {
+		sizingTestCases(COMPONENT_NAME);
+	});
+
+	describe('shape', () => {
+		shapeRoundedTestCases(COMPONENT_NAME);
+		shapeCircledTestCases(COMPONENT_NAME);
+	});
+
+	describe('icon button connotation', () => {
+		connotationTestCases(COMPONENT_NAME);
+	});
+
+	describe('icon button layout', () => {
+		let formElement, actualElement;
+		beforeEach(async () => {
+			const addedElements = addElement(
+				textToDomToParent(`<${COMPONENT_NAME} icon="bin"></${COMPONENT_NAME}>`)
+			);
+			await waitNextTask();
+			formElement = addedElements[0];
+			actualElement = formElement.shadowRoot.querySelector(
+				topLevelSelectors[COMPONENT_NAME]
+			);
+		});
+
+		it('should have ghost layout by default', async () => {
+			assertComputedStyle(actualElement, layoutStyles('ghost'));
+		});
+
+		it('should have ghost layout when layout set to ghost', async () => {
+			formElement.layout = 'ghost';
+			await waitNextTask();
+			assertComputedStyle(actualElement, layoutStyles('ghost'));
+		});
+
+		it('should have filled layout when layout set to filled', async () => {
+			formElement.layout = 'filled';
+			await waitNextTask();
+			assertComputedStyle(actualElement, layoutStyles('filled'));
+		});
+
+		it('should have outlined layout when layout set to outlined', async () => {
+			formElement.layout = 'outlined';
+			await waitNextTask();
+			assertComputedStyle(actualElement, layoutStyles('outlined'));
+		});
+	});
 });
diff --git a/components/select/src/vwc-select.ts b/components/select/src/vwc-select.ts
index 9fe067c6aa..bd064a194d 100644
--- a/components/select/src/vwc-select.ts
+++ b/components/select/src/vwc-select.ts
@@ -27,6 +27,8 @@ declare global {
 // @ts-ignore
 MWCSelect.styles = [styleCoupling, mwcSelectStyle, vwcSelectStyle];
 
+type SelectShape = Extract<Shape, Shape.Rounded | Shape.Pill>;
+
 /**
  * This component is an extension of [<mwc-select>](https://github.com/material-components/material-components-web-components/tree/master/packages/select)
  */
@@ -36,7 +38,7 @@ export class VWCSelect extends MWCSelect {
 	dense = false;
 
 	@property({ type: String, reflect: true })
-	shape?: Shape;
+	shape?: SelectShape;
 
 	@property({ type: String, reflect: true })
 	form: string | undefined;
diff --git a/components/select/stories/arg-types.js b/components/select/stories/arg-types.js
index 09149537bb..13817021b3 100644
--- a/components/select/stories/arg-types.js
+++ b/components/select/stories/arg-types.js
@@ -21,11 +21,13 @@ export const argTypes = {
     },
   },
   shape: {
-    control: {
-      type: 'select',
-      options: Object.values(Shape),
-    }
-  },
+		control: {
+			type: 'select',
+			options: Object.values(Shape).filter(s => [
+				Shape.Rounded, Shape.Pill
+			].includes(s)),
+		}
+	},
   required: {
     control: {
       type: 'inline-radio',
diff --git a/components/select/test/select.test.js b/components/select/test/select.test.js
index ab5b16b7f9..9aad2b9b82 100644
--- a/components/select/test/select.test.js
+++ b/components/select/test/select.test.js
@@ -10,7 +10,10 @@ import {
 	isolatedElementsCreation,
 	getTypographyStyle,
 } from '../../../test/test-helpers.js';
-import { shapeStyles } from '../../../test/style-utils.js';
+import {
+	shapeRoundedTestCases,
+	shapePillTestCases,
+} from '../../../test/shared';
 import {
 	assertDenseStyles,
 	hasNotchedOutline,
@@ -325,36 +328,8 @@ describe('select', () => {
 	});
 
 	describe('shape', () => {
-		let formElement, actualElement;
-		beforeEach(async () => {
-			const addedElements = addElement(
-				textToDomToParent(`
-				<${COMPONENT_NAME} outlined>
-					<vwc-list-item>Item 1</vwc-list-item>
-					<vwc-list-item>Item 2</vwc-list-item>
-				</${COMPONENT_NAME}>
-			`)
-			);
-			await waitNextTask();
-			formElement = addedElements[0];
-			actualElement = formElement.shadowRoot.querySelector('.mdc-select');
-		});
-
-		it('should have rounded shape by default', async () => {
-			assertComputedStyle(actualElement, shapeStyles('rounded'));
-		});
-
-		it('should have rounded shape when shape set to rounded', async () => {
-			formElement.shape = 'rounded';
-			await waitNextTask();
-			assertComputedStyle(actualElement, shapeStyles('rounded'));
-		});
-
-		it('should have pill shape when shape set to pill', async () => {
-			formElement.shape = 'pill';
-			await waitNextTask();
-			assertComputedStyle(actualElement, shapeStyles('pill'));
-		});
+		shapeRoundedTestCases(COMPONENT_NAME);
+		shapePillTestCases(COMPONENT_NAME);
 	});
 
 	describe(`performance acceptability`, function () {
diff --git a/components/textfield/src/vwc-textfield.ts b/components/textfield/src/vwc-textfield.ts
index 5aed438aba..480f49da37 100644
--- a/components/textfield/src/vwc-textfield.ts
+++ b/components/textfield/src/vwc-textfield.ts
@@ -27,6 +27,8 @@ declare global {
 	}
 }
 
+type TextfieldShape = Extract<Shape, Shape.Rounded | Shape.Pill>;
+
 /* eslint-disable @typescript-eslint/ban-ts-comment */
 // @ts-ignore
 MWCTextField.styles = [styleCoupling, mwcTextFieldStyle, vwcTextFieldStyle];
@@ -37,7 +39,7 @@ export class VWCTextField extends MWCTextField {
 	dense = false;
 
 	@property({ type: String, reflect: true })
-	shape?: Shape;
+	shape?: TextfieldShape;
 
 	@property({ type: String, reflect: true })
 	form: string | undefined;
diff --git a/components/textfield/stories/arg-types.js b/components/textfield/stories/arg-types.js
index f4b1105475..6f69bc30e7 100644
--- a/components/textfield/stories/arg-types.js
+++ b/components/textfield/stories/arg-types.js
@@ -21,11 +21,13 @@ export const argTypes = {
     },
   },
   shape: {
-    control: {
-      type: 'select',
-      options: Object.values(Shape),
-    }
-  },
+		control: {
+			type: 'select',
+			options: Object.values(Shape).filter(s => [
+				Shape.Rounded, Shape.Pill
+			].includes(s)),
+		}
+	},
   required: {
     control: {
       type: 'inline-radio',
diff --git a/components/textfield/test/textfield.test.js b/components/textfield/test/textfield.test.js
index 2a6f92a8db..acd1c92365 100644
--- a/components/textfield/test/textfield.test.js
+++ b/components/textfield/test/textfield.test.js
@@ -9,7 +9,10 @@ import {
 	randomAlpha,
 	listenToSubmission,
 } from '../../../test/test-helpers.js';
-import { shapeStyles } from '../../../test/style-utils.js';
+import {
+	shapeRoundedTestCases,
+	shapePillTestCases,
+} from '../../../test/shared';
 import {
 	typographyTestCases,
 	assertDenseStyles,
@@ -288,30 +291,7 @@ describe('textfield', () => {
 	});
 
 	describe('shape', () => {
-		let formElement, actualElement;
-		beforeEach(async () => {
-			const addedElements = addElement(
-				textToDomToParent(`<${COMPONENT_NAME} outlined></${COMPONENT_NAME}>`)
-			);
-			await waitNextTask();
-			formElement = addedElements[0];
-			actualElement = formElement.shadowRoot.querySelector('.mdc-text-field');
-		});
-
-		it('should have rounded shape by default', async () => {
-			assertComputedStyle(actualElement, shapeStyles('rounded'));
-		});
-
-		it('should have rounded shape when shape set to rounded', async () => {
-			formElement.shape = 'rounded';
-			await waitNextTask();
-			assertComputedStyle(actualElement, shapeStyles('rounded'));
-		});
-
-		it('should have pill shape when shape set to pill', async () => {
-			formElement.shape = 'pill';
-			await waitNextTask();
-			assertComputedStyle(actualElement, shapeStyles('pill'));
-		});
+		shapeRoundedTestCases(COMPONENT_NAME);
+		shapePillTestCases(COMPONENT_NAME);
 	});
 });
diff --git a/test/shared/index.js b/test/shared/index.js
new file mode 100644
index 0000000000..b8ddffe0b4
--- /dev/null
+++ b/test/shared/index.js
@@ -0,0 +1,6 @@
+export {
+  shapeRoundedTestCases,
+  shapePillTestCases,
+  shapeCircledTestCases
+} from './shape.test.js';
+export { sizingTestCases } from './sizing.test.js';
diff --git a/test/shared/shape.test.js b/test/shared/shape.test.js
new file mode 100644
index 0000000000..2d64e73fcc
--- /dev/null
+++ b/test/shared/shape.test.js
@@ -0,0 +1,61 @@
+import {
+	waitNextTask,
+	textToDomToParent,
+	assertComputedStyle,
+	isolatedElementsCreation,
+} from '../test-helpers.js';
+import {
+	shapeStyles,
+  topLevelSelectors,
+} from '../style-utils.js';
+
+export async function shapeRoundedTestCases(COMPONENT_NAME) {
+	const addElement = isolatedElementsCreation();
+
+	const addedElements = addElement(
+		textToDomToParent(`<${COMPONENT_NAME}></${COMPONENT_NAME}>`)
+	);
+	await waitNextTask();
+	const formElement = addedElements[0];
+	const actualElement = formElement.shadowRoot.querySelector(topLevelSelectors[COMPONENT_NAME]);
+
+	it('should have rounded shape by default', async () => {
+		assertComputedStyle(actualElement, shapeStyles('rounded'));
+	});
+
+	it('should have rounded shape when shape set to rounded', async () => {
+		formElement.shape = 'rounded';
+		await waitNextTask();
+		assertComputedStyle(actualElement, shapeStyles('rounded'));
+	});
+}
+
+export async function shapePillTestCases(COMPONENT_NAME) {
+	const addElement = isolatedElementsCreation();
+
+	const addedElements = addElement(
+		textToDomToParent(`<${COMPONENT_NAME} shape="pill"></${COMPONENT_NAME}>`)
+	);
+	await waitNextTask();
+	const formElement = addedElements[0];
+	const actualElement = formElement.shadowRoot.querySelector(topLevelSelectors[COMPONENT_NAME]);
+
+	it('should have pill shape when shape set to pill', async () => {
+		assertComputedStyle(actualElement, shapeStyles('pill'));
+	});
+}
+
+export async function shapeCircledTestCases(COMPONENT_NAME) {
+	const addElement = isolatedElementsCreation();
+	
+	const addedElements = addElement(
+		textToDomToParent(`<${COMPONENT_NAME} shape="circled"></${COMPONENT_NAME}>`)
+	);
+	await waitNextTask();
+	const formElement = addedElements[0];
+	const actualElement = formElement.shadowRoot.querySelector(topLevelSelectors[COMPONENT_NAME]);
+
+	it('should have circled shape when shape set to circled', async () => {
+		assertComputedStyle(actualElement, shapeStyles('circled'));
+	});
+}
diff --git a/test/shared/sizing.test.js b/test/shared/sizing.test.js
new file mode 100644
index 0000000000..53860712b0
--- /dev/null
+++ b/test/shared/sizing.test.js
@@ -0,0 +1,40 @@
+import {
+	waitNextTask,
+	textToDomToParent,
+	assertComputedStyle,
+	isolatedElementsCreation,
+} from '../test-helpers.js';
+import {
+	sizeStyles,
+  topLevelSelectors,
+} from '../style-utils.js';
+
+let addElement = isolatedElementsCreation();
+
+export async function sizingTestCases(COMPONENT_NAME) {
+	let formElement, actualElement;
+	beforeEach(async () => {
+		const addedElements = addElement(
+			textToDomToParent(`<${COMPONENT_NAME}></${COMPONENT_NAME}>`)
+		);
+		await waitNextTask();
+		formElement = addedElements[0];
+		actualElement = formElement.shadowRoot.querySelector(topLevelSelectors[COMPONENT_NAME]);
+	});
+
+	it('should have normal size by default', async () => {
+		assertComputedStyle(actualElement, sizeStyles('default'));
+	});
+
+	it('should have dense size when dense', async () => {
+		formElement.setAttribute('dense', 'true');
+		await waitNextTask();
+		assertComputedStyle(actualElement, sizeStyles('dense'));
+	});
+
+	it('should have enlarged size when enlarged', async () => {
+		formElement.enlarged = true;
+		await waitNextTask();
+		assertComputedStyle(actualElement, sizeStyles('enlarged'));
+	});
+}
diff --git a/test/style-utils.js b/test/style-utils.js
index 1e802dc53d..1b87eddcbe 100644
--- a/test/style-utils.js
+++ b/test/style-utils.js
@@ -1,21 +1,78 @@
+export const topLevelSelectors = {
+	'vwc-button': '.mdc-button',
+	'vwc-icon-button': '.mdc-icon-button',
+	'vwc-select': '.mdc-select',
+	'vwc-textfield': '.mdc-text-field',
+}
+
 function borderRadiusStyles(expectedRadius) {
 	return {
-		borderTopLeftRadius: `${expectedRadius}px`,
-		borderTopRightRadius: `${expectedRadius}px`,
-		borderBottomLeftRadius: `${expectedRadius}px`,
-		borderBottomRightRadius: `${expectedRadius}px`,
+		borderTopLeftRadius: expectedRadius,
+		borderTopRightRadius: expectedRadius,
+		borderBottomLeftRadius: expectedRadius,
+		borderBottomRightRadius: expectedRadius,
 	};
 }
 
 export function shapeStyles(shape, element) {
 	const shapeRadius = {
-		rounded: element === 'badge' ? 4 : 6,
-		pill: element === 'badge' ? 14 : 24,
+		rounded: element === 'badge' ? '4px' : '6px',
+		pill: element === 'badge' ? '14px' : '24px',
+		circled: '50%',
 	}
 
 	return borderRadiusStyles(shapeRadius[shape]);
 }
 
+export function sizeStyles(size) {
+	const sizes = {
+		dense: 32,
+		enlarged: 48,
+		default: 40,
+	}
+
+	return { height: `${sizes[size]}px` };
+}
+
+export function layoutStyles(layout) {
+	const layouts = {
+		filled: {
+			backgroundColor: 'rgb(0, 0, 0)',
+			borderTopWidth: '0px',
+			borderRightWidth: '0px',
+			borderBottomWidth: '0px',
+			borderLeftWidth: '0px',
+			color: 'rgb(255, 255, 255)',
+		},
+		outlined: {
+			backgroundColor: 'rgba(0, 0, 0, 0)',
+			borderTopWidth: '1px',
+			borderRightWidth: '1px',
+			borderBottomWidth: '1px',
+			borderLeftWidth: '1px',
+			borderTopStyle: 'solid',
+			borderRightStyle: 'solid',
+			borderBottomStyle: 'solid',
+			borderLeftStyle: 'solid',
+			borderTopColor: 'rgb(0, 0, 0)',
+			borderRightColor: 'rgb(0, 0, 0)',
+			borderBottomColor: 'rgb(0, 0, 0)',
+			borderLeftColor: 'rgb(0, 0, 0)',
+			color: 'rgb(0, 0, 0)',
+		},
+		ghost: {
+			backgroundColor: 'rgba(0, 0, 0, 0)',
+			borderTopWidth: '0px',
+			borderRightWidth: '0px',
+			borderBottomWidth: '0px',
+			borderLeftWidth: '0px',
+			color: 'rgb(0, 0, 0)',
+		},
+	}
+
+	return layouts[layout];
+}
+
 export const PRINCIPAL_SCHEME_VARIABLES_FILTER = /-(on-|)(base|surface|primary)$/;
 
 export function getSchemeFiles() {
@@ -99,4 +156,4 @@ export function assertBaseVarsMatch(scheme, variablesFilter, element) {
 			);
 		}
 	});
-}
\ No newline at end of file
+}