Skip to content

Commit

Permalink
initialize
Browse files Browse the repository at this point in the history
  • Loading branch information
harshitpdoshi committed Jan 1, 2025
1 parent e5cccdd commit 7789780
Show file tree
Hide file tree
Showing 427 changed files with 73,031 additions and 4,683 deletions.
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,60 @@ This is the GitHub Pages repo for our official website at:
## Contributing

If you find bugs, please file an issue.

## Technology Stack

### Client-side

- JavaScript & TypeScript
- HTML & JSX
- CSS
- TamaGUI
- ReactJS & NextJS
- React Native & Expo

### Server-side

- Python

## Directory Structure

- `clients`: Client-side code
- `packages`: shared packages across apps ([Bootstrapping](https://tamagui.dev/docs/guides/create-tamagui-app))
- `app`: you'll be importing most files from `app/`
- `features`: don't use a `screens` folder, organize by feature
- `provider`: all the providers that wrap the app, and some no-ops for Web
- `navigation`: only for starter-free template, contains the navigation code for React Native
- You can add other folders inside of packages/ if you know what you're doing and have a good reason to.
- `servers`: Server-side code

## tamagui / ui

Apart from the notes below, it's recommended to read the [official `tamagui/ui` documentation](https://tamagui.dev/ui/intro). Additional links to different, relevant sections of the documentation are provided below.

- [Stacks](https://tamagui.dev/ui/stacks?subpath=stacks): An optional base for creating flex-based layouts.

- **Features**:
- X, Y, and Z stacks for easy flex layouts.
- Gap property to add space between elements.
- Handle press, focus, and layout events easily.
- Tamagui UI includes optional stack views - `XStack`, `YStack` and `ZStack`. They extend directly off the `View` from `@tamagui/core`.
- `XStack` is a horizontal stack.
- `YStack` is a vertical stack.
- `ZStack` is a stack that can be used to overlay elements.

- [Headings](https://tamagui.dev/ui/headings?subpath=headings): Heading components that mimic HTML equivalents.

- **Features**:
- Accepts size prop that works on all styles.
- Define custom fonts with styles per-size.
- Tamagui UI includes heading components - `H1`, `H2`, `H3`, `H4`, `H5`, `H6`.

- [Text](https://tamagui.dev/ui/text?subpath=text): Text primitives with themes custom to each font.

- **Features**:
- Themes that give you control over spacing, weights, and sizes custom to each font.
- Size prop that automatically matches all theme values.
- Media query styles, `hoverStyle`, `pressStyle`, `focusStyle`.
- Tamagui UI includes text components - `Text`, `Paragraph`, `SizableText`.
- **Note**: _`Paragraph` renders to a `p` tag on web, which can cause issues when you nest them during SSR. If you don't mind rendering to a span, use `SizableText`, otherwise, be careful when nesting items inside a `Paragraph`._
98 changes: 98 additions & 0 deletions assets/bento-bundle/animation/avatars/AvatarsTooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import type { SizeTokens } from 'tamagui'
import { Avatar, Paragraph, Tooltip, View, styled, withStaticProperties } from 'tamagui'

const items = ['Developer', 'User', 'Athlete', 'User', 'Designer']

/** ------ EXAMPLE ------ */
export function AvatarsTooltip() {
return (
<View gap="$6">
<View flexDirection="row">
{items.map((item, index) => (
<View
marginLeft={index !== 0 ? '$-2' : undefined}
key={item}
hoverStyle={{
zIndex: 1,
scale: 1.05,
}}
animation="bouncy"
cursor="pointer"
>
<AvatarTip offset={5} placement="bottom" restMs={0} delay={0}>
<AvatarTip.Trigger>
<Item size="$4" imageUrl={`/avatars/300.jpeg`} />
</AvatarTip.Trigger>
<AvatarTip.Content elevation={2} transformOrigin="center top">
<AvatarTip.Arrow />
<Paragraph size="$2" lineHeight="$1">
{item}
</Paragraph>
</AvatarTip.Content>
</AvatarTip>
</View>
))}
</View>
<View flexDirection="row">
{items.map((item, index) => (
<View
marginLeft={index !== 0 ? '$-4' : undefined}
key={item}
hoverStyle={{
zIndex: 1,
scale: 1.05,
}}
animation="bouncy"
cursor="pointer"
>
<AvatarTip offset={5} placement="bottom" delay={0}>
<AvatarTip.Trigger>
<Item size="$6" imageUrl={`/avatars/300.jpeg`} />
</AvatarTip.Trigger>
<AvatarTip.Content elevation={2} transformOrigin="center top">
<AvatarTip.Arrow />
<Paragraph size="$2" lineHeight="$1">
{item}
</Paragraph>
</AvatarTip.Content>
</AvatarTip>
</View>
))}
</View>
</View>
)
}

AvatarsTooltip.fileName = 'AvatarsTooltip'

function Item({ imageUrl, size }: { imageUrl: string; size: SizeTokens }) {
return (
<Avatar borderWidth="$1" borderColor="$color1" circular size={size}>
<Avatar.Image src={imageUrl} />
<Avatar.Fallback backgroundColor="$background" />
</Avatar>
)
}

const AvatarTooltipContent = styled(Tooltip.Content, {
enterStyle: { x: 0, y: -5, opacity: 0, scale: 0.9 },
exitStyle: { x: 0, y: -5, opacity: 0, scale: 0.9 },
scale: 1,
x: 0,
y: 0,
opacity: 1,
animation: [
'100ms',
{
y: {
overshootClamping: true,
},
},
],
})

const AvatarTip = withStaticProperties(Tooltip, {
Trigger: Tooltip.Trigger,
Content: AvatarTooltipContent,
Arrow: Tooltip.Arrow,
})
137 changes: 137 additions & 0 deletions assets/bento-bundle/animation/avatars/AvatarsTooltipFancy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { useEffect, useRef, useState } from 'react'
import type { SizeTokens, TamaguiElement } from 'tamagui'
import {
Avatar,
Paragraph,
Tooltip,
View,
isWeb,
styled,
withStaticProperties,
} from 'tamagui'

const items = ['Developer', 'User', 'Athlete', 'User', 'Designer']

/** ------ EXAMPLE ------ */
export function AvatarsTooltipFancy() {
return (
<View gap="$6">
<View flexDirection="row">
{items.map((item, index) => (
<Item item={item} index={index} key={item} />
))}
</View>
</View>
)
}

AvatarsTooltipFancy.fileName = 'AvatarsTooltipFancy'

function Item(props: { item: string; index: number }) {
const { item, index } = props
const [innerRef, setInnerRef] = useState<TamaguiElement | null>(null)
const [outerRef, setOuterRef] = useState<TamaguiElement | null>(null)
const [position, setPosition] = useState({ degree: '0deg', x: 0 })

useCircleInteraction(innerRef, outerRef, ({ degree, x }) => {
setPosition({ degree, x })
})

return (
<View
marginLeft={index !== 0 ? '$-4' : undefined}
zIndex={index}
key={item}
cursor="pointer"
>
<AvatarTip offset={5} placement="top" delay={0}>
<AvatarTip.Trigger>
<Avatar
ref={setInnerRef}
borderWidth="$1"
borderColor="$color1"
circular
size="$6"
>
<Avatar.Image src={`/avatars/300.jpeg`} />
<Avatar.Fallback backgroundColor="$background" />
</Avatar>
</AvatarTip.Trigger>
<AvatarTip.Content
ref={setOuterRef}
elevation={8}
x={position.x / 2}
rotate={position.degree}
transformOrigin="center bottom"
>
<Paragraph size="$2" lineHeight="$1" paddingHorizontal="$2">
{item}
</Paragraph>
</AvatarTip.Content>
</AvatarTip>
</View>
)
}

const AvatarTooltipContent = styled(Tooltip.Content, {
enterStyle: { x: 0, y: 15, opacity: 0, scale: 0.9 },
exitStyle: { x: 0, y: 15, opacity: 0, scale: 0.9 },
scale: 1,
x: 0,
y: 0,
opacity: 1,
animation: [
'bouncy',
{
opacity: {
overshootClamping: true,
},
},
],
})

const AvatarTip = withStaticProperties(Tooltip, {
Trigger: Tooltip.Trigger,
Content: AvatarTooltipContent,
Arrow: Tooltip.Arrow,
})

function useCircleInteraction(
innerRef: any,
outerRef: any,
callback: (arg0: { degree: string; x: number }) => void
) {
if (!isWeb) return
useEffect(() => {
function handleMouseMove(event: MouseEvent) {
const innerRect = innerRef.getBoundingClientRect()
const circleCenterX = innerRect.left + innerRect.width / 2
const circleWidth = innerRect.width

const relativeX = event.clientX - circleCenterX

let degree = (relativeX / (circleWidth / 2)) * -15

if (degree > 15) {
degree = 15
} else if (degree < -15) {
degree = -15
}

degree /= 2

if (typeof callback === 'function') {
callback({ degree: degree + 'deg', x: -relativeX })
}
}
if (innerRef && outerRef) {
innerRef.addEventListener('mousemove', handleMouseMove)
}

return () => {
if (innerRef && outerRef) {
innerRef.removeEventListener('mousemove', handleMouseMove)
}
}
}, [innerRef, callback])
}
2 changes: 2 additions & 0 deletions assets/bento-bundle/animation/avatars/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './AvatarsTooltip'
export * from './AvatarsTooltipFancy'
78 changes: 78 additions & 0 deletions assets/bento-bundle/animation/buttons/ButtonLoading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { useEffect, useState } from 'react'
import { AnimatePresence, Button, Spinner, Theme, View } from 'tamagui'

/** ------ EXAMPLE ------ */
export function ButtonLoading() {
return (
<View
flexDirection="row"
gap="$4"
flexWrap="wrap"
alignItems="center"
justifyContent="center"
maxWidth={400}
>
<ButtonLoadingExample />
<Theme name="blue">
<ButtonLoadingExample />
</Theme>
<Theme name="purple">
<ButtonLoadingExample />
</Theme>
<Theme name="pink">
<ButtonLoadingExample />
</Theme>
<Theme name="red">
<ButtonLoadingExample />
</Theme>
<Theme name="orange">
<ButtonLoadingExample />
</Theme>
<Theme name="yellow">
<ButtonLoadingExample />
</Theme>
<Theme name="green">
<ButtonLoadingExample />
</Theme>
</View>
)
}

function ButtonLoadingExample() {
const [loading, setLoading] = useState(true)
useEffect(() => {
// toggle loading state after every 1 second
const interval = setInterval(() => {
setLoading(!loading)
}, 3000)
return () => clearInterval(interval as NodeJS.Timeout)
})
return (
<Button onPress={() => setLoading(!loading)} size="$5">
<View
animation="bouncy"
flexDirection="row"
x={loading ? 0 : -15}
gap="$3"
alignItems="center"
justifyContent="center"
>
<Button.Icon>
<Spinner
animation="slow"
enterStyle={{
scale: 0,
}}
exitStyle={{
scale: 0,
}}
opacity={loading ? 1 : 0}
/>
</Button.Icon>
<Button.Text>Click</Button.Text>
</View>
</Button>
)
}

ButtonLoading.fileName = 'ButtonLoading'
Loading

0 comments on commit 7789780

Please sign in to comment.