Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions apps/docs/pages/docs/v2/Components/spinner.en-US.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
searchable: true
---

import { CodeEditor } from '@components/code-editor';

# Spinner

Simple spinner component that is based on react native `ActivityIndicator` component.

## Import

```js
import { Spinner } from "@ficus-ui/native";
import PropsTable from "@components/docs/props-table";
```

## Usage

<CodeEditor code={`<HStack spacing={10}>
<Spinner />
<Spinner color="blue.500" size="sm" />
<Spinner color="red.500" size="lg" />
<Spinner color="green.500" size="lg" />
<Spinner color="pink.500" size="lg" />
</HStack>`} />

## Props

Extends every `Box` props and react native `ActivityIndicator` component.

https://reactnative.dev/docs/activityindicator#props

### `color`
<PropsTable
description="The color property for `ActivityIndicator`."
prop={{ type: "string", required: false }}
/>

### `size`
<PropsTable
description="The size property for `ActivityIndicator`."
prop={{ type: "number, string", required: false }}
/>
29 changes: 29 additions & 0 deletions apps/examples/app/components-v2/Spinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import ExampleSection from "@/src/ExampleSection";
import { Box, SafeAreaBox, Spinner, Spinner2, Text } from "@ficus-ui/native";


const SpinnerComponent = () => {
return (
<SafeAreaBox style={{ flex: 1 }}>
<Text mx="xl" fontSize="4xl">
Spinner component
</Text>
<ExampleSection name="spinner original">
<Box mx="xl" mt="lg">
<Spinner2 />
<Spinner2 color="red" size="small" />
<Spinner2 color="black" size="large" />
</Box>
</ExampleSection>
<ExampleSection name="spinner ficus">
<Box mx="xl" mt="lg">
<Spinner />
<Spinner color="red" size="small" />
<Spinner color="black" size="large" />
</Box>
</ExampleSection>
</SafeAreaBox>
);
};

export default SpinnerComponent;
2 changes: 2 additions & 0 deletions apps/examples/app/items-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import BadgeComponent from './components-v2/Badge';
import TouchableHighlightComponent from './components-v2/TouchableHighlight';
import TouchableOpacityComponent from './components-v2/TouchableOpacity';
import TouchableWithoutFeedbackComponent from './components-v2/TouchableWithoutFeedback';
import SpinnerComponent from '@/app/components-v2/Spinner';

type ExampleComponentType = {
onScreenName: string;
Expand All @@ -29,4 +30,5 @@ export const components: ExampleComponentType[] = [
{ navigationPath: 'TouchableHighlight', onScreenName: 'TouchableHighlight', component: TouchableHighlightComponent },
{ navigationPath: 'TouchableOpacity', onScreenName: 'TouchableOpacity', component: TouchableOpacityComponent },
{ navigationPath: 'TouchableWithoutFeedback', onScreenName: 'TouchableWithoutFeedback', component: TouchableWithoutFeedbackComponent },
{ navigationPath: 'Spinner', onScreenName: 'Spinner', component: SpinnerComponent },
];
1 change: 1 addition & 0 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export * from './safe-area-box';
export * from './center';
export * from './badge';
export * from './touchables';
export * from './spinner';

export { ThemeProvider } from '@ficus-ui/theme';
11 changes: 11 additions & 0 deletions packages/components/src/spinner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ActivityIndicator } from 'react-native';

import { type NativeFicusProps, ficus } from '../system';

export interface SpinnerProps extends NativeFicusProps<'ActivityIndicator'> {}

export const Spinner = ficus('ActivityIndicator'); // something wrong with ficus making color return undefined but size still working correctly
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is because ActivityIndicator has a color prop and it conflicts with the color prop from Ficus

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes but i think it need to fix inside factory file
since using directly like this below still not work for color but size still work
<ficus.ActivityIndicator color='red' size='large' />;
<ficus.ActivityIndicator color='#000000' size='large' />;
<ficus.ActivityIndicator color='rgba(0,0,0,1)' size='large' />;

// color return undefined can be check in spinner.spec.tsx
export const Spinner2 = (props: SpinnerProps) => {
return <ActivityIndicator {...props} />; // using normal ActivityIndicator instead of ficus until found out why color isnt working
Copy link
Member

@ntatoud ntatoud Feb 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try to export getThemeColor from the style-system and use it here to resolve theme colors.

To improve but to give you an idea:

import {transforms} from '@ficus-ui/style-system'
/** ... */
export const Spinner2 = (props: SpinnerProps) => {
  const { theme } = useTheme();
  const color = transforms.getThemeColor(theme.colors, props.color);
  return <ActivityIndicator {...props} />; // using normal ActivityIndicator instead of ficus until found out why color isnt working

Usage:

<Spinner color="red.500" /> // should work

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesnt work

};
26 changes: 26 additions & 0 deletions packages/components/src/spinner/spinner.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';

import { render } from '@testing-library/react-native';

import { Spinner } from '.';

describe('ActivityIndicator Component', () => {
it('renders with default props', () => {
const { getByTestId } = render(<Spinner testID="loading-indicator" />);
expect(getByTestId('loading-indicator')).toBeTruthy();
});

it('applies custom color', () => {
const { getByTestId } = render(
<Spinner testID="loading-indicator" color="red" />
);
expect(getByTestId('loading-indicator').props.color).toBe('red');
});

it('applies custom size', () => {
const { getByTestId } = render(
<Spinner testID="loading-indicator" size="large" />
);
expect(getByTestId('loading-indicator').props.size).toBe('large');
});
});
2 changes: 2 additions & 0 deletions packages/components/src/system/base-elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
TouchableOpacity as RNTouchableOpacity,
TouchableWithoutFeedback as RNTouchableWithoutFeedback,
View as RNView,
ActivityIndicator as RNActivityIndicator,
} from 'react-native';

/**
Expand All @@ -21,6 +22,7 @@ export const baseRNElements = {
TouchableHighlight: RNTouchableHighlight,
TouchableOpacity: RNTouchableOpacity,
TouchableWithoutFeedback: RNTouchableWithoutFeedback,
ActivityIndicator: RNActivityIndicator,
} as const;

export type BaseRNElements = keyof typeof baseRNElements;
Loading