@ornikar/bumper 2.8.1-canary.1768839311.501438316959a9593513e74c70cb87b0597f2db6.0 → 2.8.1-canary.1768927687.5a0439490957cfbbe8b8c5136c5fc68b0828466d.0

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +3 -6
  2. package/dist/definitions/index.d.ts +3 -0
  3. package/dist/definitions/index.d.ts.map +1 -1
  4. package/dist/definitions/system/content/icon/Icon.d.ts +4 -7
  5. package/dist/definitions/system/content/icon/Icon.d.ts.map +1 -1
  6. package/dist/definitions/system/content/typography/Typography.d.ts +8 -7
  7. package/dist/definitions/system/content/typography/Typography.d.ts.map +1 -1
  8. package/dist/definitions/system/content/typography/TypographyIcon.d.ts +9 -0
  9. package/dist/definitions/system/content/typography/TypographyIcon.d.ts.map +1 -0
  10. package/dist/definitions/system/content/typography/TypographyView.d.ts +18 -0
  11. package/dist/definitions/system/content/typography/TypographyView.d.ts.map +1 -0
  12. package/dist/definitions/system/content/typography/utils/getVariantAndWeightValues.d.ts +2 -1
  13. package/dist/definitions/system/content/typography/utils/getVariantAndWeightValues.d.ts.map +1 -1
  14. package/dist/definitions/system/content/typography/utils/typographyContext.d.ts +16 -0
  15. package/dist/definitions/system/content/typography/utils/typographyContext.d.ts.map +1 -0
  16. package/dist/definitions/system/core/primitives/Image/Image.d.ts +3 -0
  17. package/dist/definitions/system/core/primitives/Image/Image.d.ts.map +1 -0
  18. package/dist/index-metro.es.android.js +116 -11
  19. package/dist/index-metro.es.android.js.map +1 -1
  20. package/dist/index-metro.es.ios.js +116 -11
  21. package/dist/index-metro.es.ios.js.map +1 -1
  22. package/dist/index-node-22.22.cjs.js +119 -7
  23. package/dist/index-node-22.22.cjs.js.map +1 -1
  24. package/dist/index-node-22.22.cjs.web.js +119 -7
  25. package/dist/index-node-22.22.cjs.web.js.map +1 -1
  26. package/dist/index-node-22.22.es.mjs +120 -9
  27. package/dist/index-node-22.22.es.mjs.map +1 -1
  28. package/dist/index-node-22.22.es.web.mjs +120 -9
  29. package/dist/index-node-22.22.es.web.mjs.map +1 -1
  30. package/dist/index.es.js +114 -11
  31. package/dist/index.es.js.map +1 -1
  32. package/dist/index.es.web.js +114 -11
  33. package/dist/index.es.web.js.map +1 -1
  34. package/dist/tsbuildinfo +1 -1
  35. package/package.json +11 -10
  36. package/src/index.ts +3 -0
  37. package/src/system/content/icon/Icon.tsx +4 -14
  38. package/src/system/content/icon/__snapshots_web__/Icon.features.stories.tsx.snap +2 -2
  39. package/src/system/content/icon/__snapshots_web__/Icon.stories.tsx.snap +1 -1
  40. package/src/system/content/typography/Typography.tsx +24 -15
  41. package/src/system/content/typography/TypographyIcon.features.stories.tsx +163 -0
  42. package/src/system/content/typography/TypographyIcon.stories.tsx +52 -0
  43. package/src/system/content/typography/TypographyIcon.tsx +33 -0
  44. package/src/system/content/typography/TypographyView.tsx +34 -0
  45. package/src/system/content/typography/__snapshots__/TypographyIcon.features.stories.tsx.snap +839 -0
  46. package/src/system/content/typography/__snapshots__/TypographyIcon.stories.tsx.snap +31 -0
  47. package/src/system/content/typography/__snapshots_web__/Typography.features.stories.tsx.snap +7 -7
  48. package/src/system/content/typography/__snapshots_web__/Typography.stories.tsx.snap +1 -1
  49. package/src/system/content/typography/__snapshots_web__/TypographyIcon.features.stories.tsx.snap +543 -0
  50. package/src/system/content/typography/__snapshots_web__/TypographyIcon.stories.tsx.snap +37 -0
  51. package/src/system/content/typography/utils/getVariantAndWeightValues.tsx +2 -6
  52. package/src/system/content/typography/utils/typographyContext.ts +29 -0
  53. package/src/system/core/primitives/Image/Image.stories.tsx +39 -0
  54. package/src/system/core/primitives/Image/Image.ts +2 -0
  55. package/src/system/core/primitives/Image/__snapshots__/Image.stories.tsx.snap +30 -0
  56. package/src/system/core/primitives/Image/__snapshots_web__/Image.stories.tsx.snap +40 -0
  57. package/src/system/core/primitives/ScrollView/__snapshots_web__/ScrollView.features.stories.tsx.snap +11 -11
  58. package/src/system/core/primitives/ScrollView/__snapshots_web__/ScrollView.stories.tsx.snap +3 -3
  59. package/src/system/core/primitives/__snapshots_web__/Center.features.stories.tsx.snap +2 -2
  60. package/src/system/core/primitives/__snapshots_web__/Center.stories.tsx.snap +1 -1
  61. package/src/system/core/primitives/__snapshots_web__/Pressable.features.stories.tsx.snap +3 -3
  62. package/src/system/core/primitives/__snapshots_web__/Pressable.stories.tsx.snap +1 -1
  63. package/src/system/core/primitives/__snapshots_web__/Stack.features.stories.tsx.snap +6 -6
  64. package/src/system/core/primitives/__snapshots_web__/Stack.stories.tsx.snap +1 -1
  65. package/src/system/core/primitives/__snapshots_web__/View.features.stories.tsx.snap +11 -11
  66. package/src/system/core/primitives/__snapshots_web__/View.stories.tsx.snap +1 -1
  67. package/src/system/core/themes/__snapshots_web__/light.stories.tsx.snap +1 -1
  68. package/src/system/core/tokens/__snapshots_web__/breakpoints.stories.tsx.snap +1 -1
  69. package/src/system/core/tokens/__snapshots_web__/fonts.stories.tsx.snap +1 -1
  70. package/src/system/core/tokens/__snapshots_web__/radius.stories.tsx.snap +1 -1
  71. package/src/system/core/tokens/__snapshots_web__/size.stories.tsx.snap +1 -1
  72. package/src/system/core/tokens/__snapshots_web__/space.stories.tsx.snap +1 -1
  73. package/src/system/core/tokens/palettes/__snapshots_web__/deepPurpleColorPalette.stories.tsx.snap +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ornikar/bumper",
3
- "version": "2.8.1-canary.1768839311.501438316959a9593513e74c70cb87b0597f2db6.0",
3
+ "version": "2.8.1-canary.1768927687.5a0439490957cfbbe8b8c5136c5fc68b0828466d.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "directory": "@ornikar/bumper",
@@ -28,14 +28,15 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@babel/runtime": "^7.24.0",
31
- "@ornikar/kitt-icons": "14.3.2-canary.1768839311.501438316959a9593513e74c70cb87b0597f2db6.0",
31
+ "@ornikar/kitt-icons": "14.3.2-canary.1768927687.5a0439490957cfbbe8b8c5136c5fc68b0828466d.0",
32
32
  "@tamagui/core": "1.144.2",
33
+ "@tamagui/image": "1.144.2",
33
34
  "@tamagui/scroll-view": "1.144.2"
34
35
  },
35
36
  "peerDependencies": {
36
37
  "@storybook/preview-api": ">=8.6.15",
37
- "react": "^19.0.0",
38
- "react-dom": "^19.0.0",
38
+ "react": "^18.3.1",
39
+ "react-dom": "^18.3.1",
39
40
  "react-native": ">=0.76.9"
40
41
  },
41
42
  "peerDependenciesMeta": {
@@ -53,13 +54,13 @@
53
54
  "@babel/core": "7.27.1",
54
55
  "@phosphor-icons/core": "2.1.1",
55
56
  "@testing-library/dom": "10.4.1",
56
- "@testing-library/react": "16.3.1",
57
+ "@testing-library/react": "16.3.2",
57
58
  "@testing-library/react-native": "13.3.3",
58
- "@types/react": "19.0.10",
59
- "react": "19.0.0",
60
- "react-dom": "19.0.0",
61
- "react-native": "0.79.6",
62
- "react-test-renderer": "19.0.0"
59
+ "@types/react": "18.3.27",
60
+ "react": "18.3.1",
61
+ "react-dom": "18.3.1",
62
+ "react-native": "0.76.9",
63
+ "react-test-renderer": "18.3.1"
63
64
  },
64
65
  "expo": {},
65
66
  "exports": {
package/src/index.ts CHANGED
@@ -4,6 +4,8 @@ export { BumperProvider } from './system/core/provider/BumperProvider';
4
4
  // Primitives
5
5
  export type { CenterProps } from './system/core/primitives/Center';
6
6
  export { Center } from './system/core/primitives/Center';
7
+ export type { ImageProps } from './system/core/primitives/Image/Image';
8
+ export { Image } from './system/core/primitives/Image/Image';
7
9
  export type { PressableProps } from './system/core/primitives/Pressable';
8
10
  export { Pressable } from './system/core/primitives/Pressable';
9
11
  export type { ScrollViewProps } from './system/core/primitives/ScrollView/ScrollView';
@@ -16,6 +18,7 @@ export { View } from './system/core/primitives/View';
16
18
  // Typography
17
19
  export type { TypographyTextProps } from './system/content/typography/Typography';
18
20
  export { Typography } from './system/content/typography/Typography';
21
+ export type { TypographyIconProps } from './system/content/typography/TypographyIcon';
19
22
 
20
23
  // Breakpoints
21
24
  export { useBreakpointValue } from './system/core/breakpoints/hooks/useBreakpointValue';
@@ -19,12 +19,8 @@ const IconContainer = styled(View, {
19
19
 
20
20
  type IconContainerProps = GetProps<typeof IconContainer>;
21
21
 
22
- interface IconElementProps {
23
- color?: ColorTokens;
24
- }
25
-
26
- interface IconProps {
27
- icon: ReactElement<IconElementProps>;
22
+ interface InternalIconProps {
23
+ icon: ReactElement;
28
24
  color?: ColorTokens;
29
25
  size?: IconContainerProps['size'];
30
26
  testID?: IconContainerProps['testID'];
@@ -32,15 +28,9 @@ interface IconProps {
32
28
  alignSelf?: IconContainerProps['alignSelf'];
33
29
  }
34
30
 
35
- type IconWithMediaProps = IconProps & WithMediaProps<IconProps>;
31
+ export type IconProps = InternalIconProps & WithMediaProps<InternalIconProps>;
36
32
 
37
- export function Icon({
38
- icon,
39
- color = '$content.base.hi',
40
- size = '$size.20',
41
- testID,
42
- alignSelf,
43
- }: IconWithMediaProps): ReactNode {
33
+ export function Icon({ icon, color = '$content.base.hi', size = '$size.20', testID, alignSelf }: IconProps): ReactNode {
44
34
  const style = useStyle({ color });
45
35
 
46
36
  const clonedIcon = cloneElement(icon, { color: style.color });
@@ -3,7 +3,7 @@
3
3
  exports[`Bumper/Content/Icon/Features Colors 1`] = `
4
4
  <DocumentFragment>
5
5
  <div
6
- class="css-view-g5y9jx r-flex-13awgt0"
6
+ class="css-view-175oi2r r-flex-13awgt0"
7
7
  >
8
8
  <span
9
9
  class=""
@@ -175,7 +175,7 @@ exports[`Bumper/Content/Icon/Features Colors 1`] = `
175
175
  exports[`Bumper/Content/Icon/Features Sizes 1`] = `
176
176
  <DocumentFragment>
177
177
  <div
178
- class="css-view-g5y9jx r-flex-13awgt0"
178
+ class="css-view-175oi2r r-flex-13awgt0"
179
179
  >
180
180
  <span
181
181
  class=""
@@ -3,7 +3,7 @@
3
3
  exports[`Bumper/Content/Icon Default 1`] = `
4
4
  <DocumentFragment>
5
5
  <div
6
- class="css-view-g5y9jx r-flex-13awgt0"
6
+ class="css-view-175oi2r r-flex-13awgt0"
7
7
  >
8
8
  <span
9
9
  class=""
@@ -1,6 +1,5 @@
1
- import type { GetProps, GetThemeValueForKey, TamaguiComponent, WithMediaProps } from '@tamagui/core';
1
+ import type { ColorTokens, GetProps, GetThemeValueForKey, TamaguiComponent, WithMediaProps } from '@tamagui/core';
2
2
  import { Text, styled } from '@tamagui/core';
3
- import { createContext, useContext } from 'react';
4
3
  import { type Except } from 'type-fest';
5
4
  import type {
6
5
  BodyFontVariants,
@@ -9,7 +8,18 @@ import type {
9
8
  HeadingFontVariants,
10
9
  LabelFontVariants,
11
10
  } from '../../core/tokens/fonts';
11
+ import { TypographyIcon } from './TypographyIcon';
12
12
  import { getVariantAndWeightValues } from './utils/getVariantAndWeightValues';
13
+ import {
14
+ TypograhyColorContext,
15
+ TypographyContext,
16
+ TypographyVariantContext,
17
+ TypographyWeightContext,
18
+ useTypographyColor,
19
+ useTypographyContext,
20
+ useTypographyVariant,
21
+ useTypographyWeight,
22
+ } from './utils/typographyContext';
13
23
 
14
24
  // Should use type from tamagui (PropsWithoutMediaStyles) when fixed: https://github.com/tamagui/tamagui/pull/3783
15
25
  type PropsWithoutMedia<A> = {
@@ -55,14 +65,6 @@ const InternalTypography = styled(Text, {
55
65
 
56
66
  export type InternalTypographyProps = GetProps<typeof InternalTypography>;
57
67
 
58
- export type TypographyVariantContextValue = FontVariants | null;
59
- export type TypographyWeightContextValue = 'regular' | 'bold' | 'semibold' | null;
60
- export type TypograhyColorContextValue = InternalTypographyProps['color'] | null;
61
-
62
- const TypographyVariantContext = createContext<TypographyVariantContextValue>(null);
63
- const TypographyWeightContext = createContext<TypographyWeightContextValue>(null);
64
- const TypograhyColorContext = createContext<TypograhyColorContextValue>(null);
65
-
66
68
  // Remove font-related style props from InternalTypography Props
67
69
  type TypographyExcludedFontStyleProps =
68
70
  | 'fontFamily'
@@ -70,9 +72,12 @@ type TypographyExcludedFontStyleProps =
70
72
  | 'lineHeight'
71
73
  | 'fontStyle'
72
74
  | 'fontVariant'
73
- | 'fontWeight';
75
+ | 'fontWeight'
76
+ | 'color';
74
77
 
75
- type TypographyPropsWithoutFontStyleProps = Except<InternalTypographyProps, TypographyExcludedFontStyleProps>;
78
+ type TypographyPropsWithoutFontStyleProps = Except<InternalTypographyProps, TypographyExcludedFontStyleProps> & {
79
+ color: ColorTokens;
80
+ };
76
81
 
77
82
  export interface BodyProps extends TypographyPropsWithoutFontStyleProps {
78
83
  variant?: BodyFontVariants;
@@ -93,9 +98,10 @@ export type TypographyTextProps =
93
98
  | OverrideTamaguiComponentProps<ContentCapsProps>;
94
99
 
95
100
  const TypographyBase = InternalTypography.styleable<TypographyTextProps, TypographyTextProps>((props, ref) => {
96
- const typographyVariantAncestorValue = useContext(TypographyVariantContext);
97
- const typographyWeightAncestorValue = useContext(TypographyWeightContext);
98
- const typographyColorAncestorValue = useContext(TypograhyColorContext);
101
+ const typographyVariantAncestorValue = useTypographyVariant();
102
+ const typographyWeightAncestorValue = useTypographyWeight();
103
+ const typographyColorAncestorValue = useTypographyColor();
104
+ const typographyContext = useTypographyContext();
99
105
 
100
106
  const { variant, weight } = getVariantAndWeightValues(
101
107
  props.weight,
@@ -115,6 +121,8 @@ const TypographyBase = InternalTypography.styleable<TypographyTextProps, Typogra
115
121
  />
116
122
  );
117
123
 
124
+ content = typographyContext ? content : <TypographyContext.Provider value>{content}</TypographyContext.Provider>;
125
+
118
126
  // If a variant is provided, we set it in the context for children to be able to inherit variant value
119
127
  content = props.variant ? (
120
128
  <TypographyVariantContext.Provider value={props.variant}>{content}</TypographyVariantContext.Provider>
@@ -153,4 +161,5 @@ export const Typography = {
153
161
  Header4: createHeading(4),
154
162
  Header5: createHeading(5),
155
163
  Header6: createHeading(6),
164
+ Icon: TypographyIcon,
156
165
  };
@@ -0,0 +1,163 @@
1
+ import {
2
+ CheckCircleRegularIcon,
3
+ InfoRegularIcon,
4
+ StarRegularIcon,
5
+ WarningRegularIcon,
6
+ } from '@ornikar/kitt-icons/phosphor';
7
+ import type { Meta, StoryObj } from '@storybook/react';
8
+ import { HStack, VStack } from '../../core/primitives/Stack';
9
+ import { Typography } from './Typography';
10
+ import { TypographyIcon } from './TypographyIcon';
11
+
12
+ const meta: Meta<typeof TypographyIcon> = {
13
+ title: 'Bumper/Content/TypographyIcon/Features',
14
+ component: TypographyIcon,
15
+ };
16
+
17
+ export default meta;
18
+ type Story = StoryObj<typeof meta>;
19
+
20
+ export const WithExplicitColor: Story = {
21
+ render: () => (
22
+ <HStack gap="$space.16" alignItems="center">
23
+ <VStack alignItems="center" gap="$space.8">
24
+ <TypographyIcon icon={<StarRegularIcon />} size="$size.24" color="$content.accent" />
25
+ <Typography.Text variant="body-xs" color="$content.base.mid">
26
+ Explicit accent
27
+ </Typography.Text>
28
+ </VStack>
29
+ <VStack alignItems="center" gap="$space.8">
30
+ <TypographyIcon icon={<CheckCircleRegularIcon />} size="$size.24" color="$content.success" />
31
+ <Typography.Text variant="body-xs" color="$content.base.mid">
32
+ Explicit success
33
+ </Typography.Text>
34
+ </VStack>
35
+ <VStack alignItems="center" gap="$space.8">
36
+ <TypographyIcon icon={<WarningRegularIcon />} size="$size.24" color="$content.warning" />
37
+ <Typography.Text variant="body-xs" color="$content.base.mid">
38
+ Explicit warning
39
+ </Typography.Text>
40
+ </VStack>
41
+ <VStack alignItems="center" gap="$space.8">
42
+ <TypographyIcon icon={<WarningRegularIcon />} size="$size.24" color="$content.danger" />
43
+ <Typography.Text variant="body-xs" color="$content.base.mid">
44
+ Explicit danger
45
+ </Typography.Text>
46
+ </VStack>
47
+ </HStack>
48
+ ),
49
+ };
50
+
51
+ export const InheritFromTypography: Story = {
52
+ render: () => (
53
+ <VStack gap="$space.24">
54
+ <VStack gap="$space.8">
55
+ <Typography.Text variant="body-s" color="$content.base.mid">
56
+ Icon inherits accent color from Typography
57
+ </Typography.Text>
58
+ <Typography.Text variant="body-m" color="$content.accent">
59
+ <TypographyIcon icon={<StarRegularIcon />} size="$size.20" /> This icon inherits the accent color
60
+ </Typography.Text>
61
+ </VStack>
62
+
63
+ <VStack gap="$space.8">
64
+ <Typography.Text variant="body-s" color="$content.base.mid">
65
+ Icon inherits success color from Typography
66
+ </Typography.Text>
67
+ <Typography.Text variant="body-m" color="$content.success">
68
+ <TypographyIcon icon={<CheckCircleRegularIcon />} size="$size.20" /> Operation completed successfully
69
+ </Typography.Text>
70
+ </VStack>
71
+
72
+ <VStack gap="$space.8">
73
+ <Typography.Text variant="body-s" color="$content.base.mid">
74
+ Icon inherits danger color from Typography
75
+ </Typography.Text>
76
+ <Typography.Text variant="body-m" color="$content.danger">
77
+ <TypographyIcon icon={<WarningRegularIcon />} size="$size.20" /> Error: Something went wrong
78
+ </Typography.Text>
79
+ </VStack>
80
+
81
+ <VStack gap="$space.8">
82
+ <Typography.Text variant="body-s" color="$content.base.mid">
83
+ Icon inherits warning color from Typography
84
+ </Typography.Text>
85
+ <Typography.Text variant="body-m" color="$content.warning">
86
+ <TypographyIcon icon={<InfoRegularIcon />} size="$size.20" /> Warning: Please review this item
87
+ </Typography.Text>
88
+ </VStack>
89
+ </VStack>
90
+ ),
91
+ };
92
+
93
+ export const OverrideInheritedColor: Story = {
94
+ render: () => (
95
+ <VStack gap="$space.24">
96
+ <VStack gap="$space.8">
97
+ <Typography.Text variant="body-s" color="$content.base.mid">
98
+ Typography is accent, but icon explicitly uses success color
99
+ </Typography.Text>
100
+ <Typography.Text variant="body-m" color="$content.accent">
101
+ <TypographyIcon icon={<CheckCircleRegularIcon />} size="$size.20" color="$content.success" /> Icon overrides
102
+ inherited color
103
+ </Typography.Text>
104
+ </VStack>
105
+
106
+ <VStack gap="$space.8">
107
+ <Typography.Text variant="body-s" color="$content.base.mid">
108
+ Typography is success, but icon explicitly uses danger color
109
+ </Typography.Text>
110
+ <Typography.Text variant="body-m" color="$content.success">
111
+ <TypographyIcon icon={<WarningRegularIcon />} size="$size.20" color="$content.danger" /> Mixed color scenario
112
+ </Typography.Text>
113
+ </VStack>
114
+ </VStack>
115
+ ),
116
+ };
117
+
118
+ export const DifferentSizes: Story = {
119
+ render: () => (
120
+ <VStack gap="$space.16">
121
+ <Typography.Text variant="heading-l" color="$content.accent">
122
+ <TypographyIcon icon={<StarRegularIcon />} size="$size.32" /> Large heading with size 32 icon
123
+ </Typography.Text>
124
+ <Typography.Text variant="body-m" color="$content.accent">
125
+ <TypographyIcon icon={<StarRegularIcon />} size="$size.20" /> Body text with size 20 icon
126
+ </Typography.Text>
127
+ <Typography.Text variant="body-s" color="$content.accent">
128
+ <TypographyIcon icon={<StarRegularIcon />} size="$size.16" /> Small text with size 16 icon
129
+ </Typography.Text>
130
+ </VStack>
131
+ ),
132
+ };
133
+
134
+ export const NestedTypographyInheritance: Story = {
135
+ render: () => (
136
+ <VStack gap="$space.24">
137
+ <VStack gap="$space.8">
138
+ <Typography.Text variant="body-s" color="$content.base.mid">
139
+ Nested Typography components - icon inherits from parent
140
+ </Typography.Text>
141
+ <Typography.Text variant="body-l" color="$content.accent">
142
+ <TypographyIcon icon={<StarRegularIcon />} size="$size.20" /> Parent text with icon
143
+ <Typography.Text variant="body-m">
144
+ <TypographyIcon icon={<CheckCircleRegularIcon />} size="$size.16" /> Nested text - icon inherits parent
145
+ color
146
+ </Typography.Text>
147
+ </Typography.Text>
148
+ </VStack>
149
+
150
+ <VStack gap="$space.8">
151
+ <Typography.Text variant="body-s" color="$content.base.mid">
152
+ Nested with override - child overrides parent color
153
+ </Typography.Text>
154
+ <Typography.Text variant="body-l" color="$content.accent">
155
+ <TypographyIcon icon={<StarRegularIcon />} size="$size.20" /> Parent accent color
156
+ <Typography.Text variant="body-m" color="$content.success">
157
+ <TypographyIcon icon={<CheckCircleRegularIcon />} size="$size.16" /> Child overrides to success
158
+ </Typography.Text>
159
+ </Typography.Text>
160
+ </VStack>
161
+ </VStack>
162
+ ),
163
+ };
@@ -0,0 +1,52 @@
1
+ import { StarRegularIcon } from '@ornikar/kitt-icons/phosphor';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import { TypographyIcon } from './TypographyIcon';
4
+
5
+ const meta: Meta<typeof TypographyIcon> = {
6
+ title: 'Bumper/Content/TypographyIcon',
7
+ component: TypographyIcon,
8
+ tags: ['autodocs'],
9
+ argTypes: {
10
+ icon: {
11
+ control: false,
12
+ description: 'The icon element to render',
13
+ },
14
+ size: {
15
+ control: 'select',
16
+ options: ['$size.16', '$size.20', '$size.24', '$size.32', '$size.48', '$size.64', '$size.80', '$size.96'],
17
+ description: 'Icon size (uses size tokens)',
18
+ },
19
+ color: {
20
+ control: 'select',
21
+ options: [
22
+ '$content.base.low',
23
+ '$content.base.mid',
24
+ '$content.base.hi',
25
+ '$content.base.onContrasted.low',
26
+ '$content.base.onContrasted.mid',
27
+ '$content.base.onContrasted.hi',
28
+ '$content.accent',
29
+ '$content.promo',
30
+ '$content.promo.onContrasted',
31
+ '$content.info',
32
+ '$content.success',
33
+ '$content.warning',
34
+ '$content.danger',
35
+ '$content.muted',
36
+ '$content.disabled',
37
+ '$content.disabled.onContrasted',
38
+ ],
39
+ description: 'Icon color (semantic theme token). When omitted, inherits from parent Typography context.',
40
+ },
41
+ },
42
+ };
43
+
44
+ export default meta;
45
+ type Story = StoryObj<typeof meta>;
46
+
47
+ export const Default: Story = {
48
+ args: {
49
+ icon: <StarRegularIcon />,
50
+ size: '$size.20',
51
+ },
52
+ };
@@ -0,0 +1,33 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { Except } from 'type-fest';
3
+ import type { IconProps } from '../icon/Icon';
4
+ import { Icon } from '../icon/Icon';
5
+ import type { TypographyTextProps } from './Typography';
6
+ import { TypographyView } from './TypographyView';
7
+ import { useTypographyColor } from './utils/typographyContext';
8
+
9
+ export interface TypographyIconProps extends Except<IconProps, 'color'> {
10
+ color?: TypographyTextProps['color'];
11
+ }
12
+
13
+ function TypographyIconInternal(props: TypographyIconProps): ReactNode {
14
+ return (
15
+ <TypographyView>
16
+ <Icon {...props} />
17
+ </TypographyView>
18
+ );
19
+ }
20
+
21
+ function TypographyIconInheritColor(props: TypographyIconProps): ReactNode {
22
+ const typographyColorAncestorValue = useTypographyColor();
23
+
24
+ return <TypographyIconInternal color={typographyColorAncestorValue || undefined} {...props} />;
25
+ }
26
+
27
+ export function TypographyIcon({ color, ...props }: TypographyIconProps): ReactNode {
28
+ if (color) {
29
+ return <TypographyIconInternal color={color} {...props} />;
30
+ }
31
+
32
+ return <TypographyIconInheritColor {...props} />;
33
+ }
@@ -0,0 +1,34 @@
1
+ import type { GetProps } from '@tamagui/core';
2
+ import { View, styled } from '@tamagui/core';
3
+ import type { ReactNode } from 'react';
4
+ import { useTypographyContext } from './utils/typographyContext';
5
+
6
+ const InternalTypographyView = styled(View, {
7
+ name: 'TypographyView',
8
+ });
9
+
10
+ type TypographyViewProps = GetProps<typeof InternalTypographyView>;
11
+
12
+ /**
13
+ *
14
+ * A wrapper component that applies typography styles to its children in order to maintain consistent style between web and native
15
+ * In native, it simply renders a View as it renders correctly by default
16
+ * In web, it ensures that the display is set to inline-flex when inside a Typography context
17
+ *
18
+ * React Native Web includes this implementation in its codebase
19
+ * but Tamagui does not use React Native Webview, we need to implement it ourselves
20
+ *
21
+ * Inside a Typography component, always use TypographyView to wrap external components like Icon or Svg
22
+ */
23
+ export function TypographyView(props: TypographyViewProps): ReactNode {
24
+ const isInTypographyContext = useTypographyContext();
25
+
26
+ return (
27
+ <InternalTypographyView
28
+ {...props}
29
+ $platform-web={
30
+ isInTypographyContext ? { ...props['$platform-web'], display: 'inline-flex' } : props['$platform-web']
31
+ }
32
+ />
33
+ );
34
+ }