diff --git a/assets/icons/experimental/spinner.svg b/assets/icons/experimental/spinner.svg
new file mode 100644
index 00000000..e20399be
--- /dev/null
+++ b/assets/icons/experimental/spinner.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/components/experimental/Button/Button.tsx b/src/components/experimental/Button/Button.tsx
index c5fb7c26..a8395901 100644
--- a/src/components/experimental/Button/Button.tsx
+++ b/src/components/experimental/Button/Button.tsx
@@ -5,7 +5,7 @@ import { Button as BaseButton, ButtonProps as BaseButtonProps } from 'react-aria
import { getSemanticValue } from '../../../essentials/experimental/cssVariables';
import { get } from '../../../utils/experimental/themeGet';
import { textStyles } from '../Text/Text';
-import { InlineSpinner } from '../../InlineSpinner/InlineSpinner';
+import { InlineSpinner } from '../InlineSpinner/InlineSpinner';
type Emphasis = 'primary' | 'secondary' | 'textButton';
@@ -129,7 +129,11 @@ const spinnerColor: Record = {
function Button({ children, emphasis = 'primary', isLoading = false, ...restProps }: ButtonProps): ReactElement {
return (
- {isLoading ? : children}
+ {isLoading ? (
+
+ ) : (
+ children
+ )}
);
}
diff --git a/src/components/experimental/IconButton/IconButton.tsx b/src/components/experimental/IconButton/IconButton.tsx
index 41b83e60..b9b9f7d9 100644
--- a/src/components/experimental/IconButton/IconButton.tsx
+++ b/src/components/experimental/IconButton/IconButton.tsx
@@ -3,7 +3,7 @@ import styled from 'styled-components';
import { ButtonProps, Button } from 'react-aria-components';
import { IconProps } from '../../../icons';
import { getSemanticValue } from '../../../essentials/experimental';
-import { InlineSpinner } from '../../InlineSpinner/InlineSpinner';
+import { InlineSpinner } from '../InlineSpinner/InlineSpinner';
export interface IconButtonProps extends ButtonProps {
isActive?: boolean;
@@ -123,7 +123,7 @@ export const IconButton = ({
{...restProps}
>
{isLoading ? (
-
+
) : (
)}
diff --git a/src/components/experimental/InlineSpinner/InlineSpinner.tsx b/src/components/experimental/InlineSpinner/InlineSpinner.tsx
new file mode 100644
index 00000000..e64cb10c
--- /dev/null
+++ b/src/components/experimental/InlineSpinner/InlineSpinner.tsx
@@ -0,0 +1,67 @@
+import React from 'react';
+import styled, { keyframes } from 'styled-components';
+import { compose, variant } from 'styled-system';
+import SpinnerIcon from '../../../icons/experimental/SpinnerIcon';
+import { getSemanticValue } from '../../../essentials/experimental';
+
+interface InlineSpinnerProps {
+ /**
+ * Override the color of the spinner
+ */
+ color?: string;
+ /**
+ * Set the size of the component
+ */
+ size?: 'small' | 'medium' | 'large';
+}
+
+const sizeVariant = variant({
+ prop: 'size',
+ variants: {
+ small: {
+ width: '1rem',
+ height: '1rem'
+ },
+ medium: {
+ width: '1.25rem',
+ height: '1.25rem'
+ },
+ large: {
+ width: '2.5rem',
+ height: '2.5rem'
+ }
+ }
+});
+
+const rotation = keyframes`
+ to {
+ transform: rotate(360deg);
+ }
+`;
+
+const Wrapper = styled.span`
+ display: inline-flex;
+ box-sizing: border-box;
+ vertical-align: text-bottom;
+
+ ${compose(sizeVariant)}
+`;
+
+const Icon = styled(SpinnerIcon)`
+ width: 100%;
+ height: 100%;
+
+ animation: ${rotation} 750ms linear infinite;
+`;
+
+const InlineSpinner: React.FC = ({
+ color = getSemanticValue('interactive'),
+ size = 'medium',
+ ...rest
+}: InlineSpinnerProps) => (
+
+
+
+);
+
+export { InlineSpinner, InlineSpinnerProps };
diff --git a/src/components/experimental/InlineSpinner/docs/InlineSpinner.stories.tsx b/src/components/experimental/InlineSpinner/docs/InlineSpinner.stories.tsx
new file mode 100644
index 00000000..35bdb4ed
--- /dev/null
+++ b/src/components/experimental/InlineSpinner/docs/InlineSpinner.stories.tsx
@@ -0,0 +1,22 @@
+import { Meta, StoryObj } from '@storybook/react';
+import { InlineSpinner } from '../InlineSpinner';
+
+const meta: Meta = {
+ title: 'Experimental/Components/InlineSpinner',
+ component: InlineSpinner,
+ parameters: {
+ layout: 'centered'
+ },
+ argTypes: {
+ size: {
+ control: 'radio',
+ options: ['large', 'medium', 'small']
+ }
+ }
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/src/components/experimental/index.ts b/src/components/experimental/index.ts
index d652ba5b..53a27aa4 100644
--- a/src/components/experimental/index.ts
+++ b/src/components/experimental/index.ts
@@ -7,6 +7,7 @@ export { DatePicker } from './DatePicker/DatePicker';
export { Dialog } from './Dialog/Dialog';
export { Divider } from './Divider/Divider';
export { IconButton } from './IconButton/IconButton';
+export { InlineSpinner } from './InlineSpinner/InlineSpinner';
export { Label } from './Label/Label';
export { ListBox, ListBoxItem } from './ListBox/ListBox';
export { Popover } from './Popover/Popover';
diff --git a/src/icons/experimental/SpinnerIcon.tsx b/src/icons/experimental/SpinnerIcon.tsx
new file mode 100644
index 00000000..7934342c
--- /dev/null
+++ b/src/icons/experimental/SpinnerIcon.tsx
@@ -0,0 +1,27 @@
+// DO NOT EDIT. This file was generated by running `npm run generate`.;
+import * as React from 'react';
+import { get } from '../../utils/themeGet';
+import { IconProps } from '../IconProps';
+type Props = IconProps;
+const SpinnerIcon: React.FC = ({ size = 'medium', color = 'inherit', ...rest }) => {
+ const props = { ...rest, color };
+ const sizePx = Number.isFinite(size as number)
+ ? size
+ : get(`iconSizes.${size}`)(props) || get('iconSizes.medium')(props);
+ return (
+
+ );
+};
+export default SpinnerIcon;
diff --git a/src/icons/experimental/index.ts b/src/icons/experimental/index.ts
index 74db7afb..7af1405e 100644
--- a/src/icons/experimental/index.ts
+++ b/src/icons/experimental/index.ts
@@ -1,5 +1,6 @@
export { default as CalendarTodayOutlineIcon } from './CalendarTodayOutlineIcon';
-export { default as AccountOutlineIcon } from "./AccountOutlineIcon";
-export { default as CarGroupOutlineIcon } from "./CarGroupOutlineIcon";
-export { default as CarOutlineIcon } from "./CarOutlineIcon";
-export { default as LocationIcon } from "./LocationIcon";
+export { default as AccountOutlineIcon } from './AccountOutlineIcon';
+export { default as CarGroupOutlineIcon } from './CarGroupOutlineIcon';
+export { default as CarOutlineIcon } from './CarOutlineIcon';
+export { default as LocationIcon } from './LocationIcon';
+export { default as SpinnerIcon } from './SpinnerIcon';