@boostdev/design-system-components 2.4.2 → 2.5.1

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 (201) hide show
  1. package/AGENTS.md +4 -20
  2. package/README.md +3 -23
  3. package/dist/client.cjs +115 -61
  4. package/dist/client.css +537 -537
  5. package/dist/client.d.cts +11 -1
  6. package/dist/client.d.ts +11 -1
  7. package/dist/client.js +115 -61
  8. package/dist/index.cjs +115 -61
  9. package/dist/index.css +537 -537
  10. package/dist/index.d.cts +11 -1
  11. package/dist/index.d.ts +11 -1
  12. package/dist/index.js +115 -61
  13. package/dist/web-components/index.js +23 -3
  14. package/package.json +2 -10
  15. package/src/components/layout/Grid/Grid.mdx +20 -2
  16. package/src/components/layout/Grid/Grid.spec.tsx +194 -4
  17. package/src/components/layout/Grid/Grid.tsx +15 -1
  18. package/src/components/layout/Grid/masonry.ts +127 -9
  19. package/dist/native/index.cjs +0 -4337
  20. package/dist/native/index.d.cts +0 -574
  21. package/dist/native/index.d.ts +0 -574
  22. package/dist/native/index.js +0 -4421
  23. package/src/components/interaction/Button/Button.native.mdx +0 -91
  24. package/src/components/interaction/Button/Button.native.spec.tsx +0 -55
  25. package/src/components/interaction/Button/Button.native.stories.tsx +0 -141
  26. package/src/components/interaction/Button/Button.native.tsx +0 -105
  27. package/src/components/interaction/Dialog/Dialog.native.mdx +0 -61
  28. package/src/components/interaction/Dialog/Dialog.native.spec.tsx +0 -73
  29. package/src/components/interaction/Dialog/Dialog.native.stories.tsx +0 -53
  30. package/src/components/interaction/Dialog/Dialog.native.tsx +0 -128
  31. package/src/components/interaction/Drawer/Drawer.native.mdx +0 -58
  32. package/src/components/interaction/Drawer/Drawer.native.spec.tsx +0 -81
  33. package/src/components/interaction/Drawer/Drawer.native.stories.tsx +0 -33
  34. package/src/components/interaction/Drawer/Drawer.native.tsx +0 -175
  35. package/src/components/interaction/DropdownMenu/DropdownMenu.native.mdx +0 -74
  36. package/src/components/interaction/DropdownMenu/DropdownMenu.native.spec.tsx +0 -78
  37. package/src/components/interaction/DropdownMenu/DropdownMenu.native.stories.tsx +0 -51
  38. package/src/components/interaction/DropdownMenu/DropdownMenu.native.tsx +0 -254
  39. package/src/components/interaction/Popover/Popover.native.mdx +0 -61
  40. package/src/components/interaction/Popover/Popover.native.spec.tsx +0 -73
  41. package/src/components/interaction/Popover/Popover.native.stories.tsx +0 -44
  42. package/src/components/interaction/Popover/Popover.native.tsx +0 -87
  43. package/src/components/interaction/Rating/Rating.native.mdx +0 -55
  44. package/src/components/interaction/Rating/Rating.native.spec.tsx +0 -38
  45. package/src/components/interaction/Rating/Rating.native.stories.tsx +0 -37
  46. package/src/components/interaction/Rating/Rating.native.tsx +0 -50
  47. package/src/components/interaction/Toast/Toast.native.mdx +0 -81
  48. package/src/components/interaction/Toast/Toast.native.spec.tsx +0 -80
  49. package/src/components/interaction/Toast/Toast.native.stories.tsx +0 -47
  50. package/src/components/interaction/Toast/Toast.native.tsx +0 -202
  51. package/src/components/interaction/form/Checkbox/Checkbox.native.mdx +0 -74
  52. package/src/components/interaction/form/Checkbox/Checkbox.native.spec.tsx +0 -42
  53. package/src/components/interaction/form/Checkbox/Checkbox.native.stories.tsx +0 -34
  54. package/src/components/interaction/form/Checkbox/Checkbox.native.tsx +0 -80
  55. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.native.mdx +0 -78
  56. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.native.spec.tsx +0 -57
  57. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.native.stories.tsx +0 -96
  58. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.native.tsx +0 -61
  59. package/src/components/interaction/form/Combobox/Combobox.native.mdx +0 -86
  60. package/src/components/interaction/form/Combobox/Combobox.native.spec.tsx +0 -60
  61. package/src/components/interaction/form/Combobox/Combobox.native.stories.tsx +0 -99
  62. package/src/components/interaction/form/Combobox/Combobox.native.tsx +0 -211
  63. package/src/components/interaction/form/FileInput/FileInput.native.mdx +0 -86
  64. package/src/components/interaction/form/FileInput/FileInput.native.spec.tsx +0 -73
  65. package/src/components/interaction/form/FileInput/FileInput.native.stories.tsx +0 -69
  66. package/src/components/interaction/form/FileInput/FileInput.native.tsx +0 -129
  67. package/src/components/interaction/form/FormInput/FormInput.native.mdx +0 -81
  68. package/src/components/interaction/form/FormInput/FormInput.native.spec.tsx +0 -51
  69. package/src/components/interaction/form/FormInput/FormInput.native.stories.tsx +0 -54
  70. package/src/components/interaction/form/FormInput/FormInput.native.tsx +0 -122
  71. package/src/components/interaction/form/NumberInput/NumberInput.native.mdx +0 -87
  72. package/src/components/interaction/form/NumberInput/NumberInput.native.spec.tsx +0 -63
  73. package/src/components/interaction/form/NumberInput/NumberInput.native.stories.tsx +0 -63
  74. package/src/components/interaction/form/NumberInput/NumberInput.native.tsx +0 -198
  75. package/src/components/interaction/form/Radio/Radio.native.spec.tsx +0 -79
  76. package/src/components/interaction/form/Radio/Radio.native.stories.tsx +0 -44
  77. package/src/components/interaction/form/Radio/Radio.native.tsx +0 -79
  78. package/src/components/interaction/form/RadioGroup/RadioGroup.native.mdx +0 -79
  79. package/src/components/interaction/form/RadioGroup/RadioGroup.native.spec.tsx +0 -66
  80. package/src/components/interaction/form/RadioGroup/RadioGroup.native.stories.tsx +0 -96
  81. package/src/components/interaction/form/RadioGroup/RadioGroup.native.tsx +0 -61
  82. package/src/components/interaction/form/SegmentedControl/SegmentedControl.native.mdx +0 -78
  83. package/src/components/interaction/form/SegmentedControl/SegmentedControl.native.spec.tsx +0 -82
  84. package/src/components/interaction/form/SegmentedControl/SegmentedControl.native.stories.tsx +0 -99
  85. package/src/components/interaction/form/SegmentedControl/SegmentedControl.native.tsx +0 -121
  86. package/src/components/interaction/form/Select/Select.native.mdx +0 -85
  87. package/src/components/interaction/form/Select/Select.native.spec.tsx +0 -64
  88. package/src/components/interaction/form/Select/Select.native.stories.tsx +0 -75
  89. package/src/components/interaction/form/Select/Select.native.tsx +0 -252
  90. package/src/components/interaction/form/Slider/Slider.native.mdx +0 -83
  91. package/src/components/interaction/form/Slider/Slider.native.spec.tsx +0 -51
  92. package/src/components/interaction/form/Slider/Slider.native.stories.tsx +0 -58
  93. package/src/components/interaction/form/Slider/Slider.native.tsx +0 -188
  94. package/src/components/interaction/form/Switch/Switch.native.spec.tsx +0 -60
  95. package/src/components/interaction/form/Switch/Switch.native.stories.tsx +0 -33
  96. package/src/components/interaction/form/Switch/Switch.native.tsx +0 -59
  97. package/src/components/interaction/form/Textarea/Textarea.native.mdx +0 -76
  98. package/src/components/interaction/form/Textarea/Textarea.native.spec.tsx +0 -50
  99. package/src/components/interaction/form/Textarea/Textarea.native.stories.tsx +0 -50
  100. package/src/components/interaction/form/Textarea/Textarea.native.tsx +0 -108
  101. package/src/components/interaction/form/atoms/Label.native.spec.tsx +0 -39
  102. package/src/components/interaction/form/atoms/Label.native.stories.tsx +0 -18
  103. package/src/components/interaction/form/atoms/Label.native.tsx +0 -29
  104. package/src/components/interaction/form/atoms/Message.native.spec.tsx +0 -30
  105. package/src/components/interaction/form/atoms/Message.native.stories.tsx +0 -22
  106. package/src/components/interaction/form/atoms/Message.native.tsx +0 -34
  107. package/src/components/layout/ButtonGroup/ButtonGroup.native.spec.tsx +0 -83
  108. package/src/components/layout/ButtonGroup/ButtonGroup.native.stories.tsx +0 -44
  109. package/src/components/layout/ButtonGroup/ButtonGroup.native.tsx +0 -44
  110. package/src/components/layout/Card/Card.native.spec.tsx +0 -102
  111. package/src/components/layout/Card/Card.native.stories.tsx +0 -51
  112. package/src/components/layout/Card/Card.native.tsx +0 -89
  113. package/src/components/layout/IconWrapper/IconWrapper.native.spec.tsx +0 -39
  114. package/src/components/layout/IconWrapper/IconWrapper.native.stories.tsx +0 -37
  115. package/src/components/layout/IconWrapper/IconWrapper.native.tsx +0 -20
  116. package/src/components/layout/SectionHeader/SectionHeader.native.spec.tsx +0 -51
  117. package/src/components/layout/SectionHeader/SectionHeader.native.stories.tsx +0 -36
  118. package/src/components/layout/SectionHeader/SectionHeader.native.tsx +0 -79
  119. package/src/components/ui/Accordion/Accordion.native.mdx +0 -65
  120. package/src/components/ui/Accordion/Accordion.native.spec.tsx +0 -69
  121. package/src/components/ui/Accordion/Accordion.native.stories.tsx +0 -52
  122. package/src/components/ui/Accordion/Accordion.native.tsx +0 -141
  123. package/src/components/ui/Alert/Alert.native.mdx +0 -62
  124. package/src/components/ui/Alert/Alert.native.spec.tsx +0 -76
  125. package/src/components/ui/Alert/Alert.native.stories.tsx +0 -41
  126. package/src/components/ui/Alert/Alert.native.tsx +0 -94
  127. package/src/components/ui/Avatar/Avatar.native.mdx +0 -50
  128. package/src/components/ui/Avatar/Avatar.native.spec.tsx +0 -47
  129. package/src/components/ui/Avatar/Avatar.native.stories.tsx +0 -32
  130. package/src/components/ui/Avatar/Avatar.native.tsx +0 -85
  131. package/src/components/ui/Badge/Badge.native.mdx +0 -54
  132. package/src/components/ui/Badge/Badge.native.spec.tsx +0 -45
  133. package/src/components/ui/Badge/Badge.native.stories.tsx +0 -34
  134. package/src/components/ui/Badge/Badge.native.tsx +0 -50
  135. package/src/components/ui/Breadcrumb/Breadcrumb.native.mdx +0 -52
  136. package/src/components/ui/Breadcrumb/Breadcrumb.native.spec.tsx +0 -49
  137. package/src/components/ui/Breadcrumb/Breadcrumb.native.stories.tsx +0 -46
  138. package/src/components/ui/Breadcrumb/Breadcrumb.native.tsx +0 -83
  139. package/src/components/ui/Calendar/Calendar.native.mdx +0 -58
  140. package/src/components/ui/Calendar/Calendar.native.spec.tsx +0 -92
  141. package/src/components/ui/Calendar/Calendar.native.stories.tsx +0 -45
  142. package/src/components/ui/Calendar/Calendar.native.tsx +0 -294
  143. package/src/components/ui/Carousel/Carousel.native.mdx +0 -55
  144. package/src/components/ui/Carousel/Carousel.native.spec.tsx +0 -55
  145. package/src/components/ui/Carousel/Carousel.native.stories.tsx +0 -59
  146. package/src/components/ui/Carousel/Carousel.native.tsx +0 -184
  147. package/src/components/ui/Collapsible/Collapsible.native.mdx +0 -53
  148. package/src/components/ui/Collapsible/Collapsible.native.spec.tsx +0 -68
  149. package/src/components/ui/Collapsible/Collapsible.native.stories.tsx +0 -48
  150. package/src/components/ui/Collapsible/Collapsible.native.tsx +0 -139
  151. package/src/components/ui/DescriptionList/DescriptionList.native.mdx +0 -50
  152. package/src/components/ui/DescriptionList/DescriptionList.native.spec.tsx +0 -37
  153. package/src/components/ui/DescriptionList/DescriptionList.native.stories.tsx +0 -48
  154. package/src/components/ui/DescriptionList/DescriptionList.native.tsx +0 -54
  155. package/src/components/ui/Link/Link.native.mdx +0 -53
  156. package/src/components/ui/Link/Link.native.spec.tsx +0 -35
  157. package/src/components/ui/Link/Link.native.stories.tsx +0 -46
  158. package/src/components/ui/Link/Link.native.tsx +0 -48
  159. package/src/components/ui/Loading/Loading.native.spec.tsx +0 -24
  160. package/src/components/ui/Loading/Loading.native.stories.tsx +0 -31
  161. package/src/components/ui/Loading/Loading.native.tsx +0 -29
  162. package/src/components/ui/NotificationBanner/NotificationBanner.native.spec.tsx +0 -85
  163. package/src/components/ui/NotificationBanner/NotificationBanner.native.stories.tsx +0 -37
  164. package/src/components/ui/NotificationBanner/NotificationBanner.native.tsx +0 -76
  165. package/src/components/ui/Pagination/Pagination.native.mdx +0 -62
  166. package/src/components/ui/Pagination/Pagination.native.spec.tsx +0 -86
  167. package/src/components/ui/Pagination/Pagination.native.stories.tsx +0 -47
  168. package/src/components/ui/Pagination/Pagination.native.tsx +0 -157
  169. package/src/components/ui/Progress/Progress.native.spec.tsx +0 -56
  170. package/src/components/ui/Progress/Progress.native.stories.tsx +0 -34
  171. package/src/components/ui/Progress/Progress.native.tsx +0 -84
  172. package/src/components/ui/ProgressCircle/ProgressCircle.native.mdx +0 -63
  173. package/src/components/ui/ProgressCircle/ProgressCircle.native.spec.tsx +0 -39
  174. package/src/components/ui/ProgressCircle/ProgressCircle.native.stories.tsx +0 -36
  175. package/src/components/ui/ProgressCircle/ProgressCircle.native.tsx +0 -176
  176. package/src/components/ui/Separator/Separator.native.spec.tsx +0 -39
  177. package/src/components/ui/Separator/Separator.native.stories.tsx +0 -38
  178. package/src/components/ui/Separator/Separator.native.tsx +0 -32
  179. package/src/components/ui/Skeleton/Skeleton.native.spec.tsx +0 -39
  180. package/src/components/ui/Skeleton/Skeleton.native.stories.tsx +0 -31
  181. package/src/components/ui/Skeleton/Skeleton.native.tsx +0 -42
  182. package/src/components/ui/Table/Table.native.mdx +0 -72
  183. package/src/components/ui/Table/Table.native.spec.tsx +0 -83
  184. package/src/components/ui/Table/Table.native.stories.tsx +0 -55
  185. package/src/components/ui/Table/Table.native.tsx +0 -196
  186. package/src/components/ui/Tabs/Tabs.native.mdx +0 -65
  187. package/src/components/ui/Tabs/Tabs.native.spec.tsx +0 -65
  188. package/src/components/ui/Tabs/Tabs.native.stories.tsx +0 -57
  189. package/src/components/ui/Tabs/Tabs.native.tsx +0 -133
  190. package/src/components/ui/Tooltip/Tooltip.native.mdx +0 -47
  191. package/src/components/ui/Tooltip/Tooltip.native.spec.tsx +0 -37
  192. package/src/components/ui/Tooltip/Tooltip.native.stories.tsx +0 -38
  193. package/src/components/ui/Tooltip/Tooltip.native.tsx +0 -57
  194. package/src/components/ui/Typography/Typography.native.mdx +0 -56
  195. package/src/components/ui/Typography/Typography.native.spec.tsx +0 -49
  196. package/src/components/ui/Typography/Typography.native.stories.tsx +0 -36
  197. package/src/components/ui/Typography/Typography.native.tsx +0 -65
  198. package/src/native/ThemeContext.tsx +0 -28
  199. package/src/native/tokens.ts +0 -13
  200. package/src/native.ts +0 -76
  201. package/src/stories/ReactNative.mdx +0 -156
@@ -1,133 +0,0 @@
1
- import { ReactNode, useState } from 'react';
2
- import {
3
- AccessibilityRole,
4
- StyleSheet,
5
- View,
6
- Text,
7
- Pressable,
8
- ScrollView,
9
- StyleProp,
10
- ViewStyle,
11
- } from 'react-native';
12
- import { spacing, font, lineHeight } from '../../../native/tokens';
13
- import { useTheme } from '../../../native/ThemeContext';
14
-
15
- export interface TabItem {
16
- id: string;
17
- label: ReactNode;
18
- content: ReactNode;
19
- disabled?: boolean;
20
- }
21
-
22
- interface TabsProps {
23
- tabs: TabItem[];
24
- defaultTab?: string;
25
- style?: StyleProp<ViewStyle>;
26
- }
27
-
28
- const styles = StyleSheet.create({
29
- container: {
30
- overflow: 'hidden',
31
- },
32
- tabList: {
33
- flexDirection: 'row',
34
- borderBottomWidth: 2,
35
- },
36
- tabButton: {
37
- minHeight: 44,
38
- paddingHorizontal: spacing.m,
39
- paddingVertical: spacing.s,
40
- alignItems: 'center',
41
- justifyContent: 'center',
42
- borderBottomWidth: 2,
43
- marginBottom: -2,
44
- },
45
- tabLabel: {
46
- fontSize: font.size.body,
47
- fontFamily: font.family.body,
48
- lineHeight: lineHeight.body,
49
- },
50
- panel: {
51
- paddingVertical: spacing.m,
52
- },
53
- pressed: {
54
- opacity: 0.75,
55
- },
56
- disabled: {
57
- opacity: 0.4,
58
- },
59
- });
60
-
61
- export function Tabs({
62
- tabs,
63
- defaultTab,
64
- style,
65
- }: Readonly<TabsProps>) {
66
- const { colors } = useTheme();
67
- const [activeTab, setActiveTab] = useState(defaultTab ?? tabs[0]?.id);
68
-
69
- return (
70
- <View style={[styles.container, style]}>
71
- <ScrollView
72
- horizontal
73
- showsHorizontalScrollIndicator={false}
74
- contentContainerStyle={[styles.tabList, { borderBottomColor: colors.colorBgSubtle }]}
75
- accessibilityRole="tabbar"
76
- >
77
- {tabs.map(tab => {
78
- const isActive = activeTab === tab.id;
79
-
80
- return (
81
- <Pressable
82
- key={tab.id}
83
- onPress={() => setActiveTab(tab.id)}
84
- disabled={tab.disabled}
85
- accessibilityRole="tab"
86
- accessibilityState={{
87
- selected: isActive,
88
- disabled: tab.disabled,
89
- }}
90
- accessibilityLabel={typeof tab.label === 'string' ? tab.label : undefined}
91
- style={({ pressed }) => [
92
- styles.tabButton,
93
- {
94
- borderBottomColor: isActive
95
- ? colors.colorInteractive
96
- : 'transparent',
97
- },
98
- tab.disabled && styles.disabled,
99
- pressed && !tab.disabled && styles.pressed,
100
- ]}
101
- >
102
- <Text
103
- style={[
104
- styles.tabLabel,
105
- {
106
- color: isActive
107
- ? colors.colorInteractive
108
- : colors.colorOnBgSubtle,
109
- fontWeight: isActive ? font.weight.semibold : font.weight.body,
110
- },
111
- ]}
112
- >
113
- {tab.label}
114
- </Text>
115
- </Pressable>
116
- );
117
- })}
118
- </ScrollView>
119
-
120
- {tabs.map(tab => {
121
- const isActive = activeTab === tab.id;
122
-
123
- if (!isActive) return null;
124
-
125
- return (
126
- <View key={tab.id} style={styles.panel} accessibilityRole={'tabpanel' as AccessibilityRole}>
127
- {tab.content}
128
- </View>
129
- );
130
- })}
131
- </View>
132
- );
133
- }
@@ -1,47 +0,0 @@
1
- import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
- import * as Stories from './Tooltip.native.stories';
3
-
4
- <Meta of={Stories} />
5
-
6
- # Tooltip (React Native)
7
-
8
- React Native tooltip that appears on long press. Wraps children in a `Pressable` and shows the tooltip content above the trigger element.
9
-
10
- > **Status: alpha** — API may change before stable release.
11
-
12
- ## Usage
13
-
14
- ```tsx
15
- import { Tooltip } from '@boostdev/design-system-components';
16
- import { Text } from 'react-native';
17
-
18
- <Tooltip content="Helpful information">
19
- <Text>Long press me</Text>
20
- </Tooltip>
21
- ```
22
-
23
- ## Examples
24
-
25
- ### Default
26
- <Canvas of={Stories.Default} />
27
-
28
- ### Long content
29
- <Canvas of={Stories.LongContent} />
30
-
31
- ## Props
32
-
33
- <ArgTypes of={Stories} />
34
-
35
- ## Props reference
36
-
37
- | Prop | Type | Default | Description |
38
- |------|------|---------|-------------|
39
- | `content` | `string` | — | Tooltip text |
40
- | `children` | `ReactNode` | — | Trigger element |
41
- | `style` | `StyleProp<ViewStyle>` | — | Override wrapper styles |
42
-
43
- ## Accessibility
44
-
45
- - Tooltip content is exposed via `accessibilityHint` on the pressable trigger
46
- - When visible, the tooltip view has `accessibilityRole="text"` and `accessibilityLabel`
47
- - Tooltip appears on long press and dismisses on press out
@@ -1,37 +0,0 @@
1
- import { render, screen } from '@testing-library/react';
2
- import { ThemeProvider } from '../../../native/ThemeContext';
3
- import { Tooltip } from './Tooltip.native';
4
- import { Text } from 'react-native';
5
-
6
- function renderWithTheme(ui: React.ReactElement) {
7
- return render(<ThemeProvider>{ui}</ThemeProvider>);
8
- }
9
-
10
- describe('Tooltip (native)', () => {
11
- it('renders children', () => {
12
- renderWithTheme(
13
- <Tooltip content="Helpful info">
14
- <Text>Trigger</Text>
15
- </Tooltip>,
16
- );
17
- expect(screen.getByText('Trigger')).toBeInTheDocument();
18
- });
19
-
20
- it('does not show tooltip content by default', () => {
21
- renderWithTheme(
22
- <Tooltip content="Helpful info">
23
- <Text>Trigger</Text>
24
- </Tooltip>,
25
- );
26
- expect(screen.queryByText('Helpful info')).not.toBeInTheDocument();
27
- });
28
-
29
- it('renders a wrapper element', () => {
30
- const { container } = renderWithTheme(
31
- <Tooltip content="Helpful info">
32
- <Text>Trigger</Text>
33
- </Tooltip>,
34
- );
35
- expect(container.firstChild).toBeInTheDocument();
36
- });
37
- });
@@ -1,38 +0,0 @@
1
- import React from 'react';
2
- import { Text } from 'react-native';
3
- import type { Meta, StoryObj } from '@storybook/react';
4
- import { ThemeProvider } from '../../../native/ThemeContext';
5
- import { Tooltip } from './Tooltip.native';
6
-
7
- const meta = {
8
- tags: ['!stable', 'alpha'],
9
- title: 'React Native/UI/Tooltip',
10
- component: Tooltip,
11
- decorators: [
12
- (Story) => (
13
- <ThemeProvider colorScheme="light">
14
- <div style={{ padding: '60px 20px 20px' }}>
15
- <Story />
16
- </div>
17
- </ThemeProvider>
18
- ),
19
- ],
20
- parameters: { layout: 'padded' },
21
- } satisfies Meta<typeof Tooltip>;
22
-
23
- export default meta;
24
- type Story = StoryObj<typeof meta>;
25
-
26
- export const Default: Story = {
27
- args: {
28
- content: 'Helpful tooltip text',
29
- children: <Text>Long press me</Text>,
30
- },
31
- };
32
-
33
- export const LongContent: Story = {
34
- args: {
35
- content: 'This is a longer tooltip that provides more detailed information about the element.',
36
- children: <Text>Long press for details</Text>,
37
- },
38
- };
@@ -1,57 +0,0 @@
1
- import { ReactNode, useState } from 'react';
2
- import { StyleSheet, View, Text, Pressable, StyleProp, ViewStyle } from 'react-native';
3
- import { spacing, font, border } from '../../../native/tokens';
4
- import { useTheme } from '../../../native/ThemeContext';
5
-
6
- interface TooltipProps {
7
- content: string;
8
- children: ReactNode;
9
- style?: StyleProp<ViewStyle>;
10
- }
11
-
12
- const styles = StyleSheet.create({
13
- wrapper: {
14
- position: 'relative',
15
- },
16
- tooltip: {
17
- position: 'absolute',
18
- bottom: '100%',
19
- start: 0,
20
- marginBottom: spacing.xxs,
21
- paddingVertical: spacing.xxs,
22
- paddingHorizontal: spacing.xs,
23
- borderRadius: border.radius.full,
24
- zIndex: 10,
25
- alignSelf: 'flex-start',
26
- },
27
- text: {
28
- fontSize: font.size.bodyS,
29
- fontFamily: font.family.body,
30
- },
31
- });
32
-
33
- export function Tooltip({ content, children, style }: Readonly<TooltipProps>) {
34
- const { colors } = useTheme();
35
- const [visible, setVisible] = useState(false);
36
-
37
- return (
38
- <View style={[styles.wrapper, style]}>
39
- <Pressable
40
- onLongPress={() => setVisible(true)}
41
- onPressOut={() => setVisible(false)}
42
- accessibilityHint={content}
43
- >
44
- {children}
45
- </Pressable>
46
- {visible && (
47
- <View
48
- style={[styles.tooltip, { backgroundColor: colors.colorOnBg }]}
49
- accessibilityRole="text"
50
- accessibilityLabel={content}
51
- >
52
- <Text style={[styles.text, { color: colors.colorBg }]}>{content}</Text>
53
- </View>
54
- )}
55
- </View>
56
- );
57
- }
@@ -1,56 +0,0 @@
1
- import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
- import * as Stories from './Typography.native.stories';
3
-
4
- <Meta of={Stories} />
5
-
6
- # Typography (React Native)
7
-
8
- React Native typography component wrapping `Text` with semantic variants. Use instead of bare `<Text>` to ensure consistent sizing, weight, and line-height from the design token scale.
9
-
10
- > **Status: alpha** — API may change before stable release.
11
-
12
- ## Usage
13
-
14
- ```tsx
15
- import { Typography } from '@boostdev/design-system-components';
16
-
17
- <Typography variant="h1">Page title</Typography>
18
- <Typography variant="body">Body copy text.</Typography>
19
- ```
20
-
21
- ## Examples
22
-
23
- ### All variants
24
- <Canvas of={Stories.AllVariants} />
25
-
26
- ### Heading 1
27
- <Canvas of={Stories.Heading1} />
28
-
29
- ### Heading 2
30
- <Canvas of={Stories.Heading2} />
31
-
32
- ### Heading 3
33
- <Canvas of={Stories.Heading3} />
34
-
35
- ### Body
36
- <Canvas of={Stories.Body} />
37
-
38
- ### Body small
39
- <Canvas of={Stories.BodySmall} />
40
-
41
- ## Props
42
-
43
- <ArgTypes of={Stories} />
44
-
45
- ## Props reference
46
-
47
- | Prop | Type | Default | Description |
48
- |------|------|---------|-------------|
49
- | `variant` | `"h1" \| "h2" \| "h3" \| "body" \| "body_s"` | `"body"` | Typographic scale |
50
- | `children` | `ReactNode` | — | Text content |
51
- | `style` | `StyleProp<TextStyle>` | — | Override text styles |
52
-
53
- ## Accessibility
54
-
55
- - `h1`/`h2`/`h3` variants set `accessibilityRole="header"` automatically
56
- - Override with the `accessibilityRole` prop if the visual hierarchy doesn't match the semantic hierarchy
@@ -1,49 +0,0 @@
1
- import { render, screen } from '@testing-library/react';
2
- import { ThemeProvider } from '../../../native/ThemeContext';
3
- import { Typography } from './Typography.native';
4
-
5
- function renderWithTheme(ui: React.ReactElement) {
6
- return render(<ThemeProvider>{ui}</ThemeProvider>);
7
- }
8
-
9
- describe('Typography (native)', () => {
10
- it('renders children text', () => {
11
- renderWithTheme(<Typography>Hello world</Typography>);
12
- expect(screen.getByText('Hello world')).toBeInTheDocument();
13
- });
14
-
15
- it('defaults to body variant without heading role', () => {
16
- renderWithTheme(<Typography>Body text</Typography>);
17
- expect(screen.getByText('Body text')).toBeInTheDocument();
18
- expect(screen.queryByRole('heading')).not.toBeInTheDocument();
19
- });
20
-
21
- it('has heading role for h1 variant', () => {
22
- renderWithTheme(<Typography variant="h1">Heading 1</Typography>);
23
- expect(screen.getByRole('heading')).toBeInTheDocument();
24
- expect(screen.getByText('Heading 1')).toBeInTheDocument();
25
- });
26
-
27
- it('has heading role for h2 variant', () => {
28
- renderWithTheme(<Typography variant="h2">Heading 2</Typography>);
29
- expect(screen.getByRole('heading')).toBeInTheDocument();
30
- expect(screen.getByText('Heading 2')).toBeInTheDocument();
31
- });
32
-
33
- it('has heading role for h3 variant', () => {
34
- renderWithTheme(<Typography variant="h3">Heading 3</Typography>);
35
- expect(screen.getByRole('heading')).toBeInTheDocument();
36
- expect(screen.getByText('Heading 3')).toBeInTheDocument();
37
- });
38
-
39
- it('does not have heading role for body_s variant', () => {
40
- renderWithTheme(<Typography variant="body_s">Small body</Typography>);
41
- expect(screen.getByText('Small body')).toBeInTheDocument();
42
- expect(screen.queryByRole('heading')).not.toBeInTheDocument();
43
- });
44
-
45
- it('accepts custom style', () => {
46
- renderWithTheme(<Typography style={{ marginTop: 10 }}>Styled</Typography>);
47
- expect(screen.getByText('Styled')).toBeInTheDocument();
48
- });
49
- });
@@ -1,36 +0,0 @@
1
- import React from 'react';
2
- import type { Meta, StoryObj } from '@storybook/react';
3
- import { ThemeProvider } from '../../../native/ThemeContext';
4
- import { Typography } from './Typography.native';
5
-
6
- const meta = {
7
- tags: ['!stable', 'alpha'],
8
- title: 'React Native/UI/Typography',
9
- component: Typography,
10
- decorators: [(Story) => <ThemeProvider colorScheme="light"><Story /></ThemeProvider>],
11
- parameters: { layout: 'padded' },
12
- argTypes: {
13
- variant: { control: 'select', options: ['h1', 'h2', 'h3', 'body', 'body_s'] },
14
- },
15
- } satisfies Meta<typeof Typography>;
16
-
17
- export default meta;
18
- type Story = StoryObj<typeof meta>;
19
-
20
- export const Heading1: Story = { args: { children: 'Heading 1', variant: 'h1' } };
21
- export const Heading2: Story = { args: { children: 'Heading 2', variant: 'h2' } };
22
- export const Heading3: Story = { args: { children: 'Heading 3', variant: 'h3' } };
23
- export const Body: Story = { args: { children: 'The quick brown fox jumps over the lazy dog.', variant: 'body' } };
24
- export const BodySmall: Story = { args: { children: 'The quick brown fox jumps over the lazy dog.', variant: 'body_s' } };
25
- export const AllVariants: Story = {
26
- args: { children: '' },
27
- render: () => (
28
- <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
29
- <Typography variant="h1">Heading 1</Typography>
30
- <Typography variant="h2">Heading 2</Typography>
31
- <Typography variant="h3">Heading 3</Typography>
32
- <Typography variant="body">Body — The quick brown fox jumps over the lazy dog.</Typography>
33
- <Typography variant="body_s">Body Small — The quick brown fox jumps over the lazy dog.</Typography>
34
- </div>
35
- ),
36
- };
@@ -1,65 +0,0 @@
1
- import { ReactNode } from 'react';
2
- import { StyleSheet, Text, StyleProp, TextStyle } from 'react-native';
3
- import { font, lineHeight } from '../../../native/tokens';
4
- import { useTheme } from '../../../native/ThemeContext';
5
-
6
- type TypographyVariant = 'h1' | 'h2' | 'h3' | 'body' | 'body_s';
7
-
8
- interface TypographyProps {
9
- variant?: TypographyVariant;
10
- children: ReactNode;
11
- style?: StyleProp<TextStyle>;
12
- }
13
-
14
- const styles = StyleSheet.create({
15
- base: {
16
- fontFamily: font.family.body,
17
- fontWeight: font.weight.body,
18
- },
19
- h1: {
20
- fontSize: font.size.heading1,
21
- fontFamily: font.family.heading,
22
- fontWeight: font.weight.heading,
23
- lineHeight: lineHeight.heading1,
24
- },
25
- h2: {
26
- fontSize: font.size.heading2,
27
- fontFamily: font.family.heading,
28
- fontWeight: font.weight.heading,
29
- lineHeight: lineHeight.heading2,
30
- },
31
- h3: {
32
- fontSize: font.size.heading3,
33
- fontFamily: font.family.heading,
34
- fontWeight: font.weight.heading,
35
- lineHeight: lineHeight.heading3,
36
- },
37
- body: {
38
- fontSize: font.size.body,
39
- lineHeight: lineHeight.body,
40
- },
41
- body_s: {
42
- fontSize: font.size.bodyS,
43
- lineHeight: lineHeight.bodyS,
44
- },
45
- });
46
-
47
- const accessibilityRoles: Record<TypographyVariant, 'header' | 'text'> = {
48
- h1: 'header',
49
- h2: 'header',
50
- h3: 'header',
51
- body: 'text',
52
- body_s: 'text',
53
- };
54
-
55
- export function Typography({ variant = 'body', children, style }: TypographyProps) {
56
- const { colors } = useTheme();
57
- return (
58
- <Text
59
- accessibilityRole={accessibilityRoles[variant]}
60
- style={[styles.base, styles[variant], { color: colors.colorOnBg }, style]}
61
- >
62
- {children}
63
- </Text>
64
- );
65
- }
@@ -1,28 +0,0 @@
1
- import { createContext, ReactNode, useContext, useMemo } from 'react';
2
- import { useColorScheme } from 'react-native';
3
- import { colors } from './tokens';
4
-
5
- type ThemeColors = typeof colors.light | typeof colors.dark;
6
-
7
- interface ThemeContextValue {
8
- colors: ThemeColors;
9
- isDark: boolean;
10
- }
11
-
12
- const ThemeContext = createContext<ThemeContextValue | null>(null);
13
-
14
- export function ThemeProvider({ children, colorScheme }: { children: ReactNode; colorScheme?: 'light' | 'dark' }) {
15
- const systemScheme = useColorScheme();
16
- const isDark = (colorScheme ?? systemScheme) === 'dark';
17
- const value = useMemo<ThemeContextValue>(
18
- () => ({ colors: isDark ? colors.dark : colors.light, isDark }),
19
- [isDark],
20
- );
21
- return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
22
- }
23
-
24
- export function useTheme(): ThemeContextValue {
25
- const ctx = useContext(ThemeContext);
26
- if (!ctx) throw new Error('useTheme must be used within ThemeProvider');
27
- return ctx;
28
- }
@@ -1,13 +0,0 @@
1
- import { colors, spacing, font, border, zIndex, animation } from '@boostdev/design-system-foundation/native';
2
-
3
- export { colors, spacing, font, border, zIndex, animation };
4
-
5
- /** Absolute lineHeight values for React Native (ratio × fontSize). */
6
- export const lineHeight = {
7
- display: Math.round(font.size.display * font.lineHeight.display),
8
- heading1: Math.round(font.size.heading1 * font.lineHeight.heading),
9
- heading2: Math.round(font.size.heading2 * font.lineHeight.heading),
10
- heading3: Math.round(font.size.heading3 * font.lineHeight.heading),
11
- body: Math.round(font.size.body * font.lineHeight.body),
12
- bodyS: Math.round(font.size.bodyS * font.lineHeight.body),
13
- } as const;
package/src/native.ts DELETED
@@ -1,76 +0,0 @@
1
- // React Native component barrel
2
- // Explicitly imports *.native.tsx variants so tsup compiles them into dist/native/index.js.
3
- // Metro resolves this via the "react-native" export condition in package.json.
4
-
5
- // Infrastructure
6
- export { ThemeProvider, useTheme } from './native/ThemeContext';
7
-
8
- // UI
9
- export { Typography } from './components/ui/Typography/Typography.native';
10
- export { Badge } from './components/ui/Badge/Badge.native';
11
- export { Avatar } from './components/ui/Avatar/Avatar.native';
12
- export { Separator } from './components/ui/Separator/Separator.native';
13
- export { Loading } from './components/ui/Loading/Loading.native';
14
- export { Progress } from './components/ui/Progress/Progress.native';
15
- export { Skeleton } from './components/ui/Skeleton/Skeleton.native';
16
- export { Alert } from './components/ui/Alert/Alert.native';
17
- export { NotificationBanner } from './components/ui/NotificationBanner/NotificationBanner.native';
18
- export { Link } from './components/ui/Link/Link.native';
19
- export { DescriptionList } from './components/ui/DescriptionList/DescriptionList.native';
20
- export type { DescriptionItem } from './components/ui/DescriptionList/DescriptionList.native';
21
- export { Breadcrumb } from './components/ui/Breadcrumb/Breadcrumb.native';
22
- export type { BreadcrumbItem } from './components/ui/Breadcrumb/Breadcrumb.native';
23
- export { ProgressCircle } from './components/ui/ProgressCircle/ProgressCircle.native';
24
- export { Tooltip } from './components/ui/Tooltip/Tooltip.native';
25
- export { Pagination } from './components/ui/Pagination/Pagination.native';
26
- export { Collapsible } from './components/ui/Collapsible/Collapsible.native';
27
- export type { CollapsibleProps } from './components/ui/Collapsible/Collapsible.native';
28
- export { Accordion } from './components/ui/Accordion/Accordion.native';
29
- export type { AccordionItem } from './components/ui/Accordion/Accordion.native';
30
- export { Tabs } from './components/ui/Tabs/Tabs.native';
31
- export type { TabItem } from './components/ui/Tabs/Tabs.native';
32
- export { Table } from './components/ui/Table/Table.native';
33
- export type { TableColumn } from './components/ui/Table/Table.native';
34
- export { Calendar } from './components/ui/Calendar/Calendar.native';
35
- export { Carousel } from './components/ui/Carousel/Carousel.native';
36
-
37
- // Layout
38
- export { Card } from './components/layout/Card/Card.native';
39
- export { SectionHeader } from './components/layout/SectionHeader/SectionHeader.native';
40
- export { IconWrapper } from './components/layout/IconWrapper/IconWrapper.native';
41
- export type { IconWrapperProps } from './components/layout/IconWrapper/IconWrapper.native';
42
- export { ButtonContainer, ButtonGroup } from './components/layout/ButtonGroup/ButtonGroup.native';
43
- export type { ButtonContainerProps, ButtonGroupProps } from './components/layout/ButtonGroup/ButtonGroup.native';
44
-
45
- // Interaction
46
- export { Button } from './components/interaction/Button/Button.native';
47
- export { Rating } from './components/interaction/Rating/Rating.native';
48
- export type { ButtonProps } from './components/interaction/Button/Button.native';
49
- export { Switch } from './components/interaction/form/Switch/Switch.native';
50
- export { Checkbox } from './components/interaction/form/Checkbox/Checkbox.native';
51
- export { CheckboxGroup } from './components/interaction/form/CheckboxGroup/CheckboxGroup.native';
52
- export { Radio } from './components/interaction/form/Radio/Radio.native';
53
- export { RadioGroup } from './components/interaction/form/RadioGroup/RadioGroup.native';
54
- export { FileInput } from './components/interaction/form/FileInput/FileInput.native';
55
- export { Combobox } from './components/interaction/form/Combobox/Combobox.native';
56
- export type { ComboboxOption } from './components/interaction/form/Combobox/Combobox.native';
57
- export { SegmentedControl } from './components/interaction/form/SegmentedControl/SegmentedControl.native';
58
- export { FormInput } from './components/interaction/form/FormInput/FormInput.native';
59
- export { Textarea } from './components/interaction/form/Textarea/Textarea.native';
60
- export { Select } from './components/interaction/form/Select/Select.native';
61
- export type { SelectOption } from './components/interaction/form/Select/Select.native';
62
- export { Slider } from './components/interaction/form/Slider/Slider.native';
63
- export { NumberInput } from './components/interaction/form/NumberInput/NumberInput.native';
64
- export { Dialog } from './components/interaction/Dialog/Dialog.native';
65
- export { Drawer } from './components/interaction/Drawer/Drawer.native';
66
- export { ToastProvider, useToast } from './components/interaction/Toast/Toast.native';
67
- export { DropdownMenu } from './components/interaction/DropdownMenu/DropdownMenu.native';
68
- export type { DropdownMenuItem } from './components/interaction/DropdownMenu/DropdownMenu.native';
69
- export { Popover } from './components/interaction/Popover/Popover.native';
70
-
71
- // Atoms
72
- export { Label } from './components/interaction/form/atoms/Label.native';
73
- export { Message } from './components/interaction/form/atoms/Message.native';
74
-
75
- // Tokens (re-exported for convenience)
76
- export { colors, spacing, font, border, zIndex, animation, lineHeight } from './native/tokens';