tamagui 1.5.19 → 1.5.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/views/Group.tsx"],
4
- "sourcesContent": ["import {\n GetProps,\n TamaguiElement,\n getConfig,\n getExpandedShorthands,\n getTokens,\n getVariableValue,\n isTamaguiElement,\n mergeProps,\n spacedChildren,\n styled,\n useMediaPropsActive,\n} from '@tamagui/core'\nimport { ThemeableStack } from '@tamagui/stacks'\nimport React, { Children, forwardRef, isValidElement } from 'react'\nimport { ScrollView } from 'react-native'\n\nexport const GroupFrame = styled(ThemeableStack, {\n name: 'GroupFrame',\n backgroundColor: '$background',\n y: 0,\n\n variants: {\n size: (val, { tokens }) => {\n const borderRadius = tokens.radius[val] ?? val ?? tokens.radius['$true']\n return {\n borderRadius,\n }\n },\n } as const,\n\n defaultVariants: {\n size: '$true',\n },\n})\n\nexport type GroupProps = GetProps<typeof GroupFrame> & {\n scrollable?: boolean\n /**\n * @default false\n */\n showScrollIndicator?: boolean\n disabled?: boolean\n vertical?: boolean\n disablePassBorderRadius?: boolean\n}\n\nfunction createGroup(verticalDefault: boolean) {\n return forwardRef<TamaguiElement, GroupProps>((props, ref) => {\n const activeProps = useMediaPropsActive(props)\n\n const {\n children: childrenProp,\n space,\n size = '$true',\n spaceDirection,\n separator,\n scrollable,\n vertical = verticalDefault,\n disabled: disabledProp,\n disablePassBorderRadius: disablePassBorderRadiusProp,\n borderRadius,\n ...restProps\n } = getExpandedShorthands(activeProps)\n\n const radius =\n borderRadius ?? (size ? getVariableValue(getTokens().radius[size]) - 1 : undefined)\n\n const hasRadius = radius !== undefined\n const disablePassBorderRadius = disablePassBorderRadiusProp ?? !hasRadius\n const childrens = Children.toArray(childrenProp)\n const children = childrens.map((child, i) => {\n if (!isValidElement(child)) return child\n const disabled = child.props.disabled ?? disabledProp\n\n const isFirst = i === 0\n const isLast = i === childrens.length - 1\n\n const radiusStyles = disablePassBorderRadius\n ? null\n : {\n borderTopLeftRadius: 0,\n borderTopRightRadius: 0,\n borderBottomLeftRadius: 0,\n borderBottomRightRadius: 0,\n ...(hasRadius && {\n ...(isFirst &&\n !vertical && {\n borderTopLeftRadius: radius,\n borderBottomLeftRadius: radius,\n }),\n ...(isFirst &&\n vertical && {\n borderTopLeftRadius: radius,\n borderTopRightRadius: radius,\n }),\n ...(isLast &&\n !vertical && {\n borderTopRightRadius: radius,\n borderBottomRightRadius: radius,\n }),\n ...(isLast &&\n vertical && {\n borderBottomLeftRadius: radius,\n borderBottomRightRadius: radius,\n }),\n }),\n }\n\n const props = {\n disabled,\n ...(isTamaguiElement(child) ? radiusStyles : { style: radiusStyles }),\n }\n\n return cloneElementWithPropOrder(child, props)\n })\n\n return (\n <GroupFrame\n ref={ref}\n size={size}\n flexDirection={!vertical ? 'row' : 'column'}\n borderRadius={borderRadius}\n {...restProps}\n >\n {wrapScroll(\n activeProps,\n spacedChildren({\n direction: spaceDirection,\n separator,\n space,\n children,\n })\n )}\n </GroupFrame>\n )\n })\n}\n\nexport const YGroup = createGroup(true)\nexport const XGroup = createGroup(false)\n\nconst wrapScroll = (\n { scrollable, vertical, showScrollIndicator = false }: GroupProps,\n children: any\n) => {\n if (scrollable)\n return (\n <ScrollView\n {...(vertical && {\n showsVerticalScrollIndicator: showScrollIndicator,\n })}\n {...(!vertical && {\n horizontal: true,\n showsHorizontalScrollIndicator: showScrollIndicator,\n })}\n >\n {children}\n </ScrollView>\n )\n return children\n}\n\nconst cloneElementWithPropOrder = (child: any, props: Object) => {\n const next = mergeProps(child.props, props, false, getConfig().shorthands)[0]\n return React.cloneElement({ ...child, props: null }, next)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n GetProps,\n TamaguiElement,\n UnionableString,\n Variable,\n getConfig,\n getExpandedShorthands,\n getTokens,\n getVariableValue,\n isTamaguiElement,\n mergeProps,\n spacedChildren,\n styled,\n useMediaPropsActive,\n withStaticProperties,\n} from '@tamagui/core'\nimport { Scope, createContextScope } from '@tamagui/create-context'\nimport { ThemeableStack } from '@tamagui/stacks'\nimport { useControllableState } from '@tamagui/use-controllable-state'\nimport React, { Children, cloneElement, forwardRef, isValidElement } from 'react'\nimport { ScrollView } from 'react-native'\nimport { useIndex, useIndexedChildren } from 'reforest'\n\ninterface GroupContextValue {\n vertical: boolean\n disablePassBorderRadius: boolean\n onItemMount: () => void\n onItemUnmount: () => void\n radius?: number | UnionableString | Variable<any>\n disabled?: boolean\n}\n\nconst GROUP_NAME = 'Group'\n\ntype ScopedProps<P> = P & { __scopeGroup?: Scope }\nconst [createGroupContext, createGroupScope] = createContextScope(GROUP_NAME)\nconst [GroupProvider, useGroupContext] = createGroupContext<GroupContextValue>(GROUP_NAME)\n\nexport const GroupFrame = styled(ThemeableStack, {\n name: 'GroupFrame',\n\n variants: {\n unstyled: {\n false: {\n y: 0,\n backgroundColor: '$background',\n size: '$true',\n },\n },\n\n size: (val, { tokens }) => {\n const borderRadius = tokens.radius[val] ?? val ?? tokens.radius['$true']\n return {\n borderRadius,\n }\n },\n } as const,\n\n defaultVariants: {\n unstyled: false,\n },\n})\n\nexport type GroupProps = GetProps<typeof GroupFrame> & {\n axis?: 'horizontal' | 'vertical'\n\n scrollable?: boolean\n /**\n * @default false\n */\n showScrollIndicator?: boolean\n disabled?: boolean\n disablePassBorderRadius?: boolean\n /**\n * forces the group to use the Group.Item API\n */\n forceUseItem?: boolean\n}\n\nfunction createGroup(verticalDefault: boolean) {\n return withStaticProperties(\n forwardRef<TamaguiElement, ScopedProps<GroupProps>>((props, ref) => {\n const activeProps = useMediaPropsActive(props)\n\n const {\n __scopeGroup,\n children: childrenProp,\n space,\n size = '$true',\n spaceDirection,\n separator,\n scrollable,\n axis = verticalDefault ? 'vertical' : 'horizontal',\n disabled: disabledProp,\n disablePassBorderRadius: disablePassBorderRadiusProp,\n borderRadius,\n forceUseItem,\n ...restProps\n } = getExpandedShorthands(activeProps)\n\n const vertical = axis === 'vertical'\n const [itemChildrenCount, setItemChildrenCount] = useControllableState({\n defaultProp: forceUseItem ? 1 : 0,\n })\n const isUsingItems = itemChildrenCount > 0\n\n // 1 off given border to adjust for border radius? This should be user controllable\n const radius =\n borderRadius ??\n (size ? getVariableValue(getTokens().radius[size]) - 1 : undefined)\n\n const hasRadius = radius !== undefined\n const disablePassBorderRadius = disablePassBorderRadiusProp ?? !hasRadius\n\n const childrenArray = Children.toArray(childrenProp)\n const children = isUsingItems\n ? childrenProp\n : childrenArray.map((child, i) => {\n if (!isValidElement(child)) {\n return child\n }\n const disabled = child.props.disabled ?? disabledProp\n\n const isFirst = i === 0\n const isLast = i === childrenArray.length - 1\n\n const radiusStyles = disablePassBorderRadius\n ? null\n : getBorderRadius({ isFirst, isLast, radius, vertical })\n const props = {\n disabled,\n ...(isTamaguiElement(child) ? radiusStyles : { style: radiusStyles }),\n }\n\n return cloneElementWithPropOrder(child, props)\n })\n\n const indexedChildren = useIndexedChildren(\n spacedChildren({\n direction: spaceDirection,\n separator,\n space,\n children,\n })\n )\n\n const onItemMount = React.useCallback(\n () => setItemChildrenCount((prev) => prev + 1),\n []\n )\n const onItemUnmount = React.useCallback(\n () => setItemChildrenCount((prev) => prev - 1),\n []\n )\n\n return (\n <GroupProvider\n disablePassBorderRadius={disablePassBorderRadius}\n vertical={axis === 'vertical'}\n radius={radius}\n disabled={disabledProp}\n onItemMount={onItemMount}\n onItemUnmount={onItemUnmount}\n scope={__scopeGroup}\n >\n <GroupFrame\n ref={ref}\n size={size}\n flexDirection={axis === 'horizontal' ? 'row' : 'column'}\n borderRadius={borderRadius}\n {...restProps}\n >\n {wrapScroll({ ...activeProps, axis }, indexedChildren)}\n </GroupFrame>\n </GroupProvider>\n )\n }),\n {\n Item: GroupItem,\n }\n )\n}\n\nconst GroupItem = (props: ScopedProps<{ children: React.ReactNode }>) => {\n const { __scopeGroup, children } = props\n const treeIndex = useIndex()\n const context = useGroupContext('GroupItem', __scopeGroup)\n\n React.useEffect(() => {\n context.onItemMount()\n return () => {\n context.onItemUnmount()\n }\n }, [])\n\n if (!isValidElement(children)) {\n return children as any\n }\n\n const disabled = children.props.disabled ?? context.disabled\n\n if (!treeIndex) {\n throw Error('<Group.Item/> should only be used within a <Group/>')\n }\n\n const isFirst = treeIndex.index === 0\n const isLast = treeIndex.index === treeIndex.maxIndex\n\n let propsToPass: Record<string, any> = {\n disabled,\n }\n\n if (!context.disablePassBorderRadius) {\n const radiusStyles = getBorderRadius({\n radius: context.radius,\n isFirst,\n isLast,\n vertical: context.vertical,\n })\n if (isTamaguiElement(children)) {\n propsToPass = { ...propsToPass, ...radiusStyles }\n } else {\n propsToPass.style = radiusStyles\n }\n }\n\n return cloneElement(children, {\n ...propsToPass,\n // @ts-ignore\n style: {\n ...children.props?.['style'],\n ...propsToPass.style,\n },\n })\n}\n\nexport const Group = createGroup(true)\nexport const YGroup = Group\nexport const XGroup = createGroup(false)\n\nconst wrapScroll = (\n { scrollable, axis, showScrollIndicator = false }: GroupProps,\n children: any\n) => {\n if (scrollable)\n return (\n <ScrollView\n {...(axis === 'vertical' && {\n showsVerticalScrollIndicator: showScrollIndicator,\n })}\n {...(axis === 'horizontal' && {\n horizontal: true,\n showsHorizontalScrollIndicator: showScrollIndicator,\n })}\n >\n {children}\n </ScrollView>\n )\n return children\n}\n\nconst getBorderRadius = ({\n isFirst,\n isLast,\n radius,\n vertical,\n}: {\n radius: any\n vertical: boolean\n isFirst: boolean\n isLast: boolean\n}) => {\n // TODO: RTL support would be nice here\n return {\n borderTopLeftRadius: isFirst ? radius : 0,\n borderTopRightRadius: (vertical && isFirst) || (!vertical && isLast) ? radius : 0,\n borderBottomLeftRadius: (vertical && isLast) || (!vertical && isFirst) ? radius : 0,\n borderBottomRightRadius: isLast ? radius : 0,\n }\n}\n\nconst cloneElementWithPropOrder = (child: any, props: Object) => {\n const next = mergeProps(child.props, props, false, getConfig().shorthands)[0]\n return React.cloneElement({ ...child, props: null }, next)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["props"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tamagui",
3
- "version": "1.5.19",
3
+ "version": "1.5.21",
4
4
  "sideEffects": [
5
5
  "*.css",
6
6
  "setup.js"
@@ -40,59 +40,60 @@
40
40
  }
41
41
  },
42
42
  "dependencies": {
43
- "@tamagui/adapt": "^1.5.19",
44
- "@tamagui/alert-dialog": "^1.5.19",
45
- "@tamagui/animate-presence": "^1.5.19",
46
- "@tamagui/avatar": "^1.5.19",
47
- "@tamagui/button": "^1.5.19",
48
- "@tamagui/card": "^1.5.19",
49
- "@tamagui/checkbox": "^1.5.19",
50
- "@tamagui/compose-refs": "^1.5.19",
51
- "@tamagui/core": "^1.5.19",
52
- "@tamagui/create-context": "^1.5.19",
53
- "@tamagui/dialog": "^1.5.19",
54
- "@tamagui/fake-react-native": "^1.5.19",
55
- "@tamagui/focusable": "^1.5.19",
56
- "@tamagui/font-size": "^1.5.19",
57
- "@tamagui/form": "^1.5.19",
58
- "@tamagui/get-button-sized": "^1.5.19",
59
- "@tamagui/get-font-sized": "^1.5.19",
60
- "@tamagui/get-size": "^1.5.19",
61
- "@tamagui/helpers": "^1.5.19",
62
- "@tamagui/helpers-tamagui": "^1.5.19",
63
- "@tamagui/image": "^1.5.19",
64
- "@tamagui/label": "^1.5.19",
65
- "@tamagui/linear-gradient": "^1.5.19",
66
- "@tamagui/list-item": "^1.5.19",
67
- "@tamagui/popover": "^1.5.19",
68
- "@tamagui/popper": "^1.5.19",
69
- "@tamagui/portal": "^1.5.19",
70
- "@tamagui/progress": "^1.5.19",
71
- "@tamagui/radio-group": "^1.5.19",
72
- "@tamagui/react-native-media-driver": "^1.5.19",
73
- "@tamagui/scroll-view": "^1.5.19",
74
- "@tamagui/select": "^1.5.19",
75
- "@tamagui/separator": "^1.5.19",
76
- "@tamagui/shapes": "^1.5.19",
77
- "@tamagui/sheet": "^1.5.19",
78
- "@tamagui/slider": "^1.5.19",
79
- "@tamagui/stacks": "^1.5.19",
80
- "@tamagui/switch": "^1.5.19",
81
- "@tamagui/text": "^1.5.19",
82
- "@tamagui/tooltip": "^1.5.19",
83
- "@tamagui/use-controllable-state": "^1.5.19",
84
- "@tamagui/use-debounce": "^1.5.19",
85
- "@tamagui/use-event": "^1.5.19",
86
- "@tamagui/use-force-update": "^1.5.19",
87
- "@tamagui/use-window-dimensions": "^1.5.19",
88
- "@tamagui/visually-hidden": "^1.5.19"
43
+ "@tamagui/adapt": "^1.5.21",
44
+ "@tamagui/alert-dialog": "^1.5.21",
45
+ "@tamagui/animate-presence": "^1.5.21",
46
+ "@tamagui/avatar": "^1.5.21",
47
+ "@tamagui/button": "^1.5.21",
48
+ "@tamagui/card": "^1.5.21",
49
+ "@tamagui/checkbox": "^1.5.21",
50
+ "@tamagui/compose-refs": "^1.5.21",
51
+ "@tamagui/core": "^1.5.21",
52
+ "@tamagui/create-context": "^1.5.21",
53
+ "@tamagui/dialog": "^1.5.21",
54
+ "@tamagui/fake-react-native": "^1.5.21",
55
+ "@tamagui/focusable": "^1.5.21",
56
+ "@tamagui/font-size": "^1.5.21",
57
+ "@tamagui/form": "^1.5.21",
58
+ "@tamagui/get-button-sized": "^1.5.21",
59
+ "@tamagui/get-font-sized": "^1.5.21",
60
+ "@tamagui/get-size": "^1.5.21",
61
+ "@tamagui/helpers": "^1.5.21",
62
+ "@tamagui/helpers-tamagui": "^1.5.21",
63
+ "@tamagui/image": "^1.5.21",
64
+ "@tamagui/label": "^1.5.21",
65
+ "@tamagui/linear-gradient": "^1.5.21",
66
+ "@tamagui/list-item": "^1.5.21",
67
+ "@tamagui/popover": "^1.5.21",
68
+ "@tamagui/popper": "^1.5.21",
69
+ "@tamagui/portal": "^1.5.21",
70
+ "@tamagui/progress": "^1.5.21",
71
+ "@tamagui/radio-group": "^1.5.21",
72
+ "@tamagui/react-native-media-driver": "^1.5.21",
73
+ "@tamagui/scroll-view": "^1.5.21",
74
+ "@tamagui/select": "^1.5.21",
75
+ "@tamagui/separator": "^1.5.21",
76
+ "@tamagui/shapes": "^1.5.21",
77
+ "@tamagui/sheet": "^1.5.21",
78
+ "@tamagui/slider": "^1.5.21",
79
+ "@tamagui/stacks": "^1.5.21",
80
+ "@tamagui/switch": "^1.5.21",
81
+ "@tamagui/text": "^1.5.21",
82
+ "@tamagui/tooltip": "^1.5.21",
83
+ "@tamagui/use-controllable-state": "^1.5.21",
84
+ "@tamagui/use-debounce": "^1.5.21",
85
+ "@tamagui/use-event": "^1.5.21",
86
+ "@tamagui/use-force-update": "^1.5.21",
87
+ "@tamagui/use-window-dimensions": "^1.5.21",
88
+ "@tamagui/visually-hidden": "^1.5.21",
89
+ "reforest": "^0.12.1"
89
90
  },
90
91
  "peerDependencies": {
91
92
  "react": "*",
92
93
  "react-native-web": "*"
93
94
  },
94
95
  "devDependencies": {
95
- "@tamagui/build": "^1.5.19",
96
+ "@tamagui/build": "^1.5.21",
96
97
  "@types/node": "^16.11.9",
97
98
  "@types/react": "^18.0.15",
98
99
  "react": "^18.2.0",
@@ -1,6 +1,8 @@
1
1
  import {
2
2
  GetProps,
3
3
  TamaguiElement,
4
+ UnionableString,
5
+ Variable,
4
6
  getConfig,
5
7
  getExpandedShorthands,
6
8
  getTokens,
@@ -10,17 +12,42 @@ import {
10
12
  spacedChildren,
11
13
  styled,
12
14
  useMediaPropsActive,
15
+ withStaticProperties,
13
16
  } from '@tamagui/core'
17
+ import { Scope, createContextScope } from '@tamagui/create-context'
14
18
  import { ThemeableStack } from '@tamagui/stacks'
15
- import React, { Children, forwardRef, isValidElement } from 'react'
19
+ import { useControllableState } from '@tamagui/use-controllable-state'
20
+ import React, { Children, cloneElement, forwardRef, isValidElement } from 'react'
16
21
  import { ScrollView } from 'react-native'
22
+ import { useIndex, useIndexedChildren } from 'reforest'
23
+
24
+ interface GroupContextValue {
25
+ vertical: boolean
26
+ disablePassBorderRadius: boolean
27
+ onItemMount: () => void
28
+ onItemUnmount: () => void
29
+ radius?: number | UnionableString | Variable<any>
30
+ disabled?: boolean
31
+ }
32
+
33
+ const GROUP_NAME = 'Group'
34
+
35
+ type ScopedProps<P> = P & { __scopeGroup?: Scope }
36
+ const [createGroupContext, createGroupScope] = createContextScope(GROUP_NAME)
37
+ const [GroupProvider, useGroupContext] = createGroupContext<GroupContextValue>(GROUP_NAME)
17
38
 
18
39
  export const GroupFrame = styled(ThemeableStack, {
19
40
  name: 'GroupFrame',
20
- backgroundColor: '$background',
21
- y: 0,
22
41
 
23
42
  variants: {
43
+ unstyled: {
44
+ false: {
45
+ y: 0,
46
+ backgroundColor: '$background',
47
+ size: '$true',
48
+ },
49
+ },
50
+
24
51
  size: (val, { tokens }) => {
25
52
  const borderRadius = tokens.radius[val] ?? val ?? tokens.radius['$true']
26
53
  return {
@@ -30,127 +57,198 @@ export const GroupFrame = styled(ThemeableStack, {
30
57
  } as const,
31
58
 
32
59
  defaultVariants: {
33
- size: '$true',
60
+ unstyled: false,
34
61
  },
35
62
  })
36
63
 
37
64
  export type GroupProps = GetProps<typeof GroupFrame> & {
65
+ axis?: 'horizontal' | 'vertical'
66
+
38
67
  scrollable?: boolean
39
68
  /**
40
69
  * @default false
41
70
  */
42
71
  showScrollIndicator?: boolean
43
72
  disabled?: boolean
44
- vertical?: boolean
45
73
  disablePassBorderRadius?: boolean
74
+ /**
75
+ * forces the group to use the Group.Item API
76
+ */
77
+ forceUseItem?: boolean
46
78
  }
47
79
 
48
80
  function createGroup(verticalDefault: boolean) {
49
- return forwardRef<TamaguiElement, GroupProps>((props, ref) => {
50
- const activeProps = useMediaPropsActive(props)
51
-
52
- const {
53
- children: childrenProp,
54
- space,
55
- size = '$true',
56
- spaceDirection,
57
- separator,
58
- scrollable,
59
- vertical = verticalDefault,
60
- disabled: disabledProp,
61
- disablePassBorderRadius: disablePassBorderRadiusProp,
62
- borderRadius,
63
- ...restProps
64
- } = getExpandedShorthands(activeProps)
65
-
66
- const radius =
67
- borderRadius ?? (size ? getVariableValue(getTokens().radius[size]) - 1 : undefined)
68
-
69
- const hasRadius = radius !== undefined
70
- const disablePassBorderRadius = disablePassBorderRadiusProp ?? !hasRadius
71
- const childrens = Children.toArray(childrenProp)
72
- const children = childrens.map((child, i) => {
73
- if (!isValidElement(child)) return child
74
- const disabled = child.props.disabled ?? disabledProp
75
-
76
- const isFirst = i === 0
77
- const isLast = i === childrens.length - 1
78
-
79
- const radiusStyles = disablePassBorderRadius
80
- ? null
81
- : {
82
- borderTopLeftRadius: 0,
83
- borderTopRightRadius: 0,
84
- borderBottomLeftRadius: 0,
85
- borderBottomRightRadius: 0,
86
- ...(hasRadius && {
87
- ...(isFirst &&
88
- !vertical && {
89
- borderTopLeftRadius: radius,
90
- borderBottomLeftRadius: radius,
91
- }),
92
- ...(isFirst &&
93
- vertical && {
94
- borderTopLeftRadius: radius,
95
- borderTopRightRadius: radius,
96
- }),
97
- ...(isLast &&
98
- !vertical && {
99
- borderTopRightRadius: radius,
100
- borderBottomRightRadius: radius,
101
- }),
102
- ...(isLast &&
103
- vertical && {
104
- borderBottomLeftRadius: radius,
105
- borderBottomRightRadius: radius,
106
- }),
107
- }),
108
- }
109
-
110
- const props = {
111
- disabled,
112
- ...(isTamaguiElement(child) ? radiusStyles : { style: radiusStyles }),
113
- }
81
+ return withStaticProperties(
82
+ forwardRef<TamaguiElement, ScopedProps<GroupProps>>((props, ref) => {
83
+ const activeProps = useMediaPropsActive(props)
114
84
 
115
- return cloneElementWithPropOrder(child, props)
116
- })
85
+ const {
86
+ __scopeGroup,
87
+ children: childrenProp,
88
+ space,
89
+ size = '$true',
90
+ spaceDirection,
91
+ separator,
92
+ scrollable,
93
+ axis = verticalDefault ? 'vertical' : 'horizontal',
94
+ disabled: disabledProp,
95
+ disablePassBorderRadius: disablePassBorderRadiusProp,
96
+ borderRadius,
97
+ forceUseItem,
98
+ ...restProps
99
+ } = getExpandedShorthands(activeProps)
117
100
 
118
- return (
119
- <GroupFrame
120
- ref={ref}
121
- size={size}
122
- flexDirection={!vertical ? 'row' : 'column'}
123
- borderRadius={borderRadius}
124
- {...restProps}
125
- >
126
- {wrapScroll(
127
- activeProps,
128
- spacedChildren({
129
- direction: spaceDirection,
130
- separator,
131
- space,
132
- children,
101
+ const vertical = axis === 'vertical'
102
+ const [itemChildrenCount, setItemChildrenCount] = useControllableState({
103
+ defaultProp: forceUseItem ? 1 : 0,
104
+ })
105
+ const isUsingItems = itemChildrenCount > 0
106
+
107
+ // 1 off given border to adjust for border radius? This should be user controllable
108
+ const radius =
109
+ borderRadius ??
110
+ (size ? getVariableValue(getTokens().radius[size]) - 1 : undefined)
111
+
112
+ const hasRadius = radius !== undefined
113
+ const disablePassBorderRadius = disablePassBorderRadiusProp ?? !hasRadius
114
+
115
+ const childrenArray = Children.toArray(childrenProp)
116
+ const children = isUsingItems
117
+ ? childrenProp
118
+ : childrenArray.map((child, i) => {
119
+ if (!isValidElement(child)) {
120
+ return child
121
+ }
122
+ const disabled = child.props.disabled ?? disabledProp
123
+
124
+ const isFirst = i === 0
125
+ const isLast = i === childrenArray.length - 1
126
+
127
+ const radiusStyles = disablePassBorderRadius
128
+ ? null
129
+ : getBorderRadius({ isFirst, isLast, radius, vertical })
130
+ const props = {
131
+ disabled,
132
+ ...(isTamaguiElement(child) ? radiusStyles : { style: radiusStyles }),
133
+ }
134
+
135
+ return cloneElementWithPropOrder(child, props)
133
136
  })
134
- )}
135
- </GroupFrame>
136
- )
137
+
138
+ const indexedChildren = useIndexedChildren(
139
+ spacedChildren({
140
+ direction: spaceDirection,
141
+ separator,
142
+ space,
143
+ children,
144
+ })
145
+ )
146
+
147
+ const onItemMount = React.useCallback(
148
+ () => setItemChildrenCount((prev) => prev + 1),
149
+ []
150
+ )
151
+ const onItemUnmount = React.useCallback(
152
+ () => setItemChildrenCount((prev) => prev - 1),
153
+ []
154
+ )
155
+
156
+ return (
157
+ <GroupProvider
158
+ disablePassBorderRadius={disablePassBorderRadius}
159
+ vertical={axis === 'vertical'}
160
+ radius={radius}
161
+ disabled={disabledProp}
162
+ onItemMount={onItemMount}
163
+ onItemUnmount={onItemUnmount}
164
+ scope={__scopeGroup}
165
+ >
166
+ <GroupFrame
167
+ ref={ref}
168
+ size={size}
169
+ flexDirection={axis === 'horizontal' ? 'row' : 'column'}
170
+ borderRadius={borderRadius}
171
+ {...restProps}
172
+ >
173
+ {wrapScroll({ ...activeProps, axis }, indexedChildren)}
174
+ </GroupFrame>
175
+ </GroupProvider>
176
+ )
177
+ }),
178
+ {
179
+ Item: GroupItem,
180
+ }
181
+ )
182
+ }
183
+
184
+ const GroupItem = (props: ScopedProps<{ children: React.ReactNode }>) => {
185
+ const { __scopeGroup, children } = props
186
+ const treeIndex = useIndex()
187
+ const context = useGroupContext('GroupItem', __scopeGroup)
188
+
189
+ React.useEffect(() => {
190
+ context.onItemMount()
191
+ return () => {
192
+ context.onItemUnmount()
193
+ }
194
+ }, [])
195
+
196
+ if (!isValidElement(children)) {
197
+ return children as any
198
+ }
199
+
200
+ const disabled = children.props.disabled ?? context.disabled
201
+
202
+ if (!treeIndex) {
203
+ throw Error('<Group.Item/> should only be used within a <Group/>')
204
+ }
205
+
206
+ const isFirst = treeIndex.index === 0
207
+ const isLast = treeIndex.index === treeIndex.maxIndex
208
+
209
+ let propsToPass: Record<string, any> = {
210
+ disabled,
211
+ }
212
+
213
+ if (!context.disablePassBorderRadius) {
214
+ const radiusStyles = getBorderRadius({
215
+ radius: context.radius,
216
+ isFirst,
217
+ isLast,
218
+ vertical: context.vertical,
219
+ })
220
+ if (isTamaguiElement(children)) {
221
+ propsToPass = { ...propsToPass, ...radiusStyles }
222
+ } else {
223
+ propsToPass.style = radiusStyles
224
+ }
225
+ }
226
+
227
+ return cloneElement(children, {
228
+ ...propsToPass,
229
+ // @ts-ignore
230
+ style: {
231
+ ...children.props?.['style'],
232
+ ...propsToPass.style,
233
+ },
137
234
  })
138
235
  }
139
236
 
140
- export const YGroup = createGroup(true)
237
+ export const Group = createGroup(true)
238
+ export const YGroup = Group
141
239
  export const XGroup = createGroup(false)
142
240
 
143
241
  const wrapScroll = (
144
- { scrollable, vertical, showScrollIndicator = false }: GroupProps,
242
+ { scrollable, axis, showScrollIndicator = false }: GroupProps,
145
243
  children: any
146
244
  ) => {
147
245
  if (scrollable)
148
246
  return (
149
247
  <ScrollView
150
- {...(vertical && {
248
+ {...(axis === 'vertical' && {
151
249
  showsVerticalScrollIndicator: showScrollIndicator,
152
250
  })}
153
- {...(!vertical && {
251
+ {...(axis === 'horizontal' && {
154
252
  horizontal: true,
155
253
  showsHorizontalScrollIndicator: showScrollIndicator,
156
254
  })}
@@ -161,6 +259,26 @@ const wrapScroll = (
161
259
  return children
162
260
  }
163
261
 
262
+ const getBorderRadius = ({
263
+ isFirst,
264
+ isLast,
265
+ radius,
266
+ vertical,
267
+ }: {
268
+ radius: any
269
+ vertical: boolean
270
+ isFirst: boolean
271
+ isLast: boolean
272
+ }) => {
273
+ // TODO: RTL support would be nice here
274
+ return {
275
+ borderTopLeftRadius: isFirst ? radius : 0,
276
+ borderTopRightRadius: (vertical && isFirst) || (!vertical && isLast) ? radius : 0,
277
+ borderBottomLeftRadius: (vertical && isLast) || (!vertical && isFirst) ? radius : 0,
278
+ borderBottomRightRadius: isLast ? radius : 0,
279
+ }
280
+ }
281
+
164
282
  const cloneElementWithPropOrder = (child: any, props: Object) => {
165
283
  const next = mergeProps(child.props, props, false, getConfig().shorthands)[0]
166
284
  return React.cloneElement({ ...child, props: null }, next)