radix-native 0.0.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 (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -0
  3. package/dist/index.cjs +4323 -0
  4. package/dist/index.d.cts +861 -0
  5. package/dist/index.d.mts +861 -0
  6. package/dist/index.d.ts +861 -0
  7. package/dist/index.mjs +4285 -0
  8. package/package.json +51 -0
  9. package/src/components/actions/Button.tsx +337 -0
  10. package/src/components/actions/Checkbox.tsx +216 -0
  11. package/src/components/actions/CheckboxCards.tsx +257 -0
  12. package/src/components/actions/CheckboxGroup.tsx +249 -0
  13. package/src/components/actions/index.ts +4 -0
  14. package/src/components/layout/Box.tsx +108 -0
  15. package/src/components/layout/Flex.tsx +149 -0
  16. package/src/components/layout/Grid.tsx +224 -0
  17. package/src/components/layout/index.ts +9 -0
  18. package/src/components/playground/ThemeControls.tsx +456 -0
  19. package/src/components/playground/index.ts +1 -0
  20. package/src/components/typography/Blockquote.tsx +137 -0
  21. package/src/components/typography/Code.tsx +164 -0
  22. package/src/components/typography/Em.tsx +68 -0
  23. package/src/components/typography/Heading.tsx +136 -0
  24. package/src/components/typography/Kbd.tsx +162 -0
  25. package/src/components/typography/Link.tsx +173 -0
  26. package/src/components/typography/Quote.tsx +71 -0
  27. package/src/components/typography/Strong.tsx +70 -0
  28. package/src/components/typography/Text.tsx +140 -0
  29. package/src/components/typography/index.ts +9 -0
  30. package/src/hooks/useResolveColor.ts +24 -0
  31. package/src/hooks/useThemeContext.ts +11 -0
  32. package/src/index.ts +63 -0
  33. package/src/theme/Theme.tsx +12 -0
  34. package/src/theme/ThemeContext.ts +4 -0
  35. package/src/theme/ThemeImpl.tsx +54 -0
  36. package/src/theme/ThemeRoot.tsx +65 -0
  37. package/src/theme/createTheme.tsx +17 -0
  38. package/src/theme/resolveGrayColor.ts +38 -0
  39. package/src/theme/theme.types.ts +95 -0
  40. package/src/tokens/colors/amber.ts +28 -0
  41. package/src/tokens/colors/blue.ts +28 -0
  42. package/src/tokens/colors/bronze.ts +28 -0
  43. package/src/tokens/colors/brown.ts +28 -0
  44. package/src/tokens/colors/crimson.ts +28 -0
  45. package/src/tokens/colors/cyan.ts +28 -0
  46. package/src/tokens/colors/gold.ts +28 -0
  47. package/src/tokens/colors/grass.ts +28 -0
  48. package/src/tokens/colors/gray.ts +28 -0
  49. package/src/tokens/colors/green.ts +28 -0
  50. package/src/tokens/colors/index.ts +36 -0
  51. package/src/tokens/colors/indigo.ts +28 -0
  52. package/src/tokens/colors/iris.ts +28 -0
  53. package/src/tokens/colors/jade.ts +28 -0
  54. package/src/tokens/colors/lime.ts +28 -0
  55. package/src/tokens/colors/mauve.ts +28 -0
  56. package/src/tokens/colors/mint.ts +28 -0
  57. package/src/tokens/colors/olive.ts +28 -0
  58. package/src/tokens/colors/orange.ts +28 -0
  59. package/src/tokens/colors/pink.ts +28 -0
  60. package/src/tokens/colors/plum.ts +28 -0
  61. package/src/tokens/colors/purple.ts +28 -0
  62. package/src/tokens/colors/red.ts +28 -0
  63. package/src/tokens/colors/ruby.ts +28 -0
  64. package/src/tokens/colors/sage.ts +28 -0
  65. package/src/tokens/colors/sand.ts +28 -0
  66. package/src/tokens/colors/sky.ts +28 -0
  67. package/src/tokens/colors/slate.ts +28 -0
  68. package/src/tokens/colors/teal.ts +28 -0
  69. package/src/tokens/colors/tomato.ts +28 -0
  70. package/src/tokens/colors/types.ts +69 -0
  71. package/src/tokens/colors/violet.ts +28 -0
  72. package/src/tokens/colors/yellow.ts +28 -0
  73. package/src/tokens/index.ts +5 -0
  74. package/src/tokens/radius.ts +56 -0
  75. package/src/tokens/scaling.ts +10 -0
  76. package/src/tokens/spacing.ts +21 -0
  77. package/src/tokens/typography.ts +60 -0
  78. package/src/utils/applyScaling.ts +6 -0
  79. package/src/utils/classicEffect.ts +46 -0
  80. package/src/utils/resolveColor.ts +69 -0
  81. package/src/utils/resolveSpace.ts +13 -0
@@ -0,0 +1,149 @@
1
+ import React from 'react'
2
+ import { View } from 'react-native'
3
+ import type { ViewProps, ViewStyle } from 'react-native'
4
+ import { useThemeContext } from '../../hooks/useThemeContext'
5
+ import { useResolveColor } from '../../hooks/useResolveColor'
6
+ import { resolveSpace } from '../../utils/resolveSpace'
7
+ import { getRadius, getFullRadius } from '../../tokens/radius'
8
+ import type { SpaceToken, MarginToken } from '../../tokens/spacing'
9
+ import type { ThemeColor, RadiusToken } from '../../theme/theme.types'
10
+
11
+ // ─── Flex-specific value types ────────────────────────────────────────────────
12
+
13
+ export type FlexDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse'
14
+ export type FlexAlign = 'start' | 'center' | 'end' | 'baseline' | 'stretch'
15
+ export type FlexJustify = 'start' | 'center' | 'end' | 'between'
16
+ export type FlexWrap = 'nowrap' | 'wrap' | 'wrap-reverse'
17
+
18
+ // ─── Alignment helpers ────────────────────────────────────────────────────────
19
+
20
+ const ALIGN_MAP: Record<FlexAlign, ViewStyle['alignItems']> = {
21
+ start: 'flex-start',
22
+ center: 'center',
23
+ end: 'flex-end',
24
+ baseline: 'baseline',
25
+ stretch: 'stretch',
26
+ }
27
+
28
+ const JUSTIFY_MAP: Record<FlexJustify, ViewStyle['justifyContent']> = {
29
+ start: 'flex-start',
30
+ center: 'center',
31
+ end: 'flex-end',
32
+ between: 'space-between',
33
+ }
34
+
35
+ // ─── Props ────────────────────────────────────────────────────────────────────
36
+
37
+ export interface FlexProps extends ViewProps {
38
+ // ─── Flex-specific ────────────────────────────────────────────────
39
+ direction?: FlexDirection
40
+ align?: FlexAlign
41
+ justify?: FlexJustify
42
+ wrap?: FlexWrap
43
+ gap?: SpaceToken
44
+ gapX?: SpaceToken
45
+ gapY?: SpaceToken
46
+ // ─── Padding ──────────────────────────────────────────────────────
47
+ p?: SpaceToken
48
+ px?: SpaceToken
49
+ py?: SpaceToken
50
+ pt?: SpaceToken
51
+ pr?: SpaceToken
52
+ pb?: SpaceToken
53
+ pl?: SpaceToken
54
+ // ─── Margin ───────────────────────────────────────────────────────
55
+ m?: MarginToken
56
+ mx?: MarginToken
57
+ my?: MarginToken
58
+ mt?: MarginToken
59
+ mr?: MarginToken
60
+ mb?: MarginToken
61
+ ml?: MarginToken
62
+ // ─── Size ─────────────────────────────────────────────────────────
63
+ width?: number | string
64
+ minWidth?: number | string
65
+ maxWidth?: number | string
66
+ height?: number | string
67
+ minHeight?: number | string
68
+ maxHeight?: number | string
69
+ // ─── Position ─────────────────────────────────────────────────────
70
+ position?: 'relative' | 'absolute'
71
+ top?: number | string
72
+ right?: number | string
73
+ bottom?: number | string
74
+ left?: number | string
75
+ // ─── Layout ───────────────────────────────────────────────────────
76
+ overflow?: 'hidden' | 'visible' | 'scroll'
77
+ flexBasis?: number | string
78
+ flexShrink?: number
79
+ flexGrow?: number
80
+ // ─── RN-only theme props ──────────────────────────────────────────
81
+ bg?: ThemeColor
82
+ radius?: RadiusToken
83
+ }
84
+
85
+ /** Flexbox layout primitive. Renders as a View with display: flex (the RN default). */
86
+ export function Flex({
87
+ direction, align, justify, wrap,
88
+ gap, gapX, gapY,
89
+ p, px, py, pt, pr, pb, pl,
90
+ m, mx, my, mt, mr, mb, ml,
91
+ width, minWidth, maxWidth,
92
+ height, minHeight, maxHeight,
93
+ position,
94
+ top, right, bottom, left,
95
+ overflow,
96
+ flexBasis, flexShrink, flexGrow,
97
+ bg,
98
+ radius,
99
+ style,
100
+ ...rest
101
+ }: FlexProps) {
102
+ const { scaling } = useThemeContext()
103
+ const rc = useResolveColor()
104
+
105
+ const sp = (token: MarginToken | SpaceToken | undefined): number | undefined =>
106
+ token !== undefined ? resolveSpace(token, scaling) : undefined
107
+
108
+ const flexStyle: ViewStyle = {
109
+ // Flex-specific
110
+ flexDirection: direction,
111
+ alignItems: align ? ALIGN_MAP[align] : undefined,
112
+ justifyContent: justify ? JUSTIFY_MAP[justify] : undefined,
113
+ flexWrap: wrap,
114
+ rowGap: sp(gapY ?? gap),
115
+ columnGap: sp(gapX ?? gap),
116
+ // Padding — specific > axis > all
117
+ paddingTop: sp(pt ?? py ?? p),
118
+ paddingBottom: sp(pb ?? py ?? p),
119
+ paddingLeft: sp(pl ?? px ?? p),
120
+ paddingRight: sp(pr ?? px ?? p),
121
+ // Margin — specific > axis > all
122
+ marginTop: sp(mt ?? my ?? m),
123
+ marginBottom: sp(mb ?? my ?? m),
124
+ marginLeft: sp(ml ?? mx ?? m),
125
+ marginRight: sp(mr ?? mx ?? m),
126
+ // Size
127
+ width: width as ViewStyle['width'],
128
+ minWidth: minWidth as ViewStyle['minWidth'],
129
+ maxWidth: maxWidth as ViewStyle['maxWidth'],
130
+ height: height as ViewStyle['height'],
131
+ minHeight: minHeight as ViewStyle['minHeight'],
132
+ maxHeight: maxHeight as ViewStyle['maxHeight'],
133
+ // Position
134
+ position, top: top as ViewStyle['top'], right: right as ViewStyle['right'],
135
+ bottom: bottom as ViewStyle['bottom'], left: left as ViewStyle['left'],
136
+ // Layout
137
+ overflow: overflow as ViewStyle['overflow'],
138
+ flexBasis: flexBasis as ViewStyle['flexBasis'],
139
+ flexShrink, flexGrow,
140
+ // Theme
141
+ backgroundColor: bg ? rc(bg) : undefined,
142
+ borderRadius: radius
143
+ ? (radius === 'full' ? getFullRadius(radius) : getRadius(radius, 4))
144
+ : undefined,
145
+ }
146
+
147
+ return <View style={[flexStyle, style]} {...rest} />
148
+ }
149
+ Flex.displayName = 'Flex'
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Grid — CSS-Grid-inspired layout component for React Native.
3
+ *
4
+ * Renders a plain View with `flexDirection: 'row'` and `flexWrap: 'wrap'`.
5
+ * Each direct child is automatically wrapped in a cell whose width is
6
+ * calculated from the number of `columns` so items flow into a uniform grid.
7
+ *
8
+ * ─── What it CAN do ────────────────────────────────────────────────────────────
9
+ * - Equal-width column grids: `<Grid columns={3} gap={3}>…</Grid>`
10
+ * - Theme-aware gap, padding, margin, background, and radius tokens
11
+ * - Consistent spacing via `gap` / `gapX` / `gapY` (mapped to space tokens)
12
+ * - Alignment of items within the grid via `align` / `justify`
13
+ *
14
+ * ─── What it CANNOT do (CSS Grid limitations in RN) ────────────────────────────
15
+ * - Mixed-width column templates (e.g. `"1fr 2fr"`, `"200px 1fr"`)
16
+ * - Row templates (`grid-template-rows`)
17
+ * - `grid-auto-flow: column`
18
+ * - Children spanning multiple columns/rows (`grid-column: span 2`)
19
+ * - Named grid areas (`grid-template-areas`)
20
+ * - Responsive breakpoint objects — use platform-specific logic instead
21
+ *
22
+ * ─── For scrolling & virtualization ────────────────────────────────────────────
23
+ * Grid is a layout container (View), NOT a scrollable list.
24
+ * If you need scrolling or virtualized rendering, use one of:
25
+ * - `<FlatList numColumns={N} />` (React Native built-in)
26
+ * - `<FlashList numColumns={N} />` (@shopify/flash-list)
27
+ * - `<LegendList numColumns={N} />` (@legendapp/list)
28
+ * These support virtualization out of the box and are the right choice for
29
+ * long or dynamic lists rendered in a grid.
30
+ */
31
+ import React, { useState, useCallback } from 'react'
32
+ import { View } from 'react-native'
33
+ import type { ViewProps, ViewStyle, LayoutChangeEvent } from 'react-native'
34
+ import { useThemeContext } from '../../hooks/useThemeContext'
35
+ import { useResolveColor } from '../../hooks/useResolveColor'
36
+ import { resolveSpace } from '../../utils/resolveSpace'
37
+ import { getRadius, getFullRadius } from '../../tokens/radius'
38
+ import type { SpaceToken, MarginToken } from '../../tokens/spacing'
39
+ import type { ThemeColor, RadiusToken } from '../../theme/theme.types'
40
+
41
+ // ─── Types ────────────────────────────────────────────────────────────────────
42
+
43
+ export type GridAlign = 'start' | 'center' | 'end' | 'stretch'
44
+ export type GridJustify = 'start' | 'center' | 'end' | 'between'
45
+
46
+ export interface GridProps extends Omit<ViewProps, 'style'> {
47
+ /** Number of equal-width columns. Default: 1. */
48
+ columns?: number
49
+ /** Space token applied to both row and column gaps. */
50
+ gap?: SpaceToken
51
+ /** Space token for column (horizontal) gaps only. Overrides `gap`. */
52
+ gapX?: SpaceToken
53
+ /** Space token for row (vertical) gaps only. Overrides `gap`. */
54
+ gapY?: SpaceToken
55
+ /** Cross-axis alignment of items within their cells. */
56
+ align?: GridAlign
57
+ /** Main-axis justification of items within their cells. */
58
+ justify?: GridJustify
59
+ // ─── Padding ──────────────────────────────────────────────────────
60
+ p?: SpaceToken
61
+ px?: SpaceToken
62
+ py?: SpaceToken
63
+ pt?: SpaceToken
64
+ pr?: SpaceToken
65
+ pb?: SpaceToken
66
+ pl?: SpaceToken
67
+ // ─── Margin ───────────────────────────────────────────────────────
68
+ m?: MarginToken
69
+ mx?: MarginToken
70
+ my?: MarginToken
71
+ mt?: MarginToken
72
+ mr?: MarginToken
73
+ mb?: MarginToken
74
+ ml?: MarginToken
75
+ // ─── Size ─────────────────────────────────────────────────────────
76
+ width?: number | string
77
+ minWidth?: number | string
78
+ maxWidth?: number | string
79
+ height?: number | string
80
+ minHeight?: number | string
81
+ maxHeight?: number | string
82
+ // ─── Position ─────────────────────────────────────────────────────
83
+ position?: 'relative' | 'absolute'
84
+ top?: number | string
85
+ right?: number | string
86
+ bottom?: number | string
87
+ left?: number | string
88
+ // ─── Layout ───────────────────────────────────────────────────────
89
+ overflow?: 'hidden' | 'visible' | 'scroll'
90
+ flexBasis?: number | string
91
+ flexShrink?: number
92
+ flexGrow?: number
93
+ // ─── Theme ────────────────────────────────────────────────────────
94
+ bg?: ThemeColor
95
+ radius?: RadiusToken
96
+ style?: ViewProps['style']
97
+ }
98
+
99
+ // ─── Alignment helpers ────────────────────────────────────────────────────────
100
+
101
+ const ALIGN_MAP: Record<GridAlign, ViewStyle['alignItems']> = {
102
+ start: 'flex-start',
103
+ center: 'center',
104
+ end: 'flex-end',
105
+ stretch: 'stretch',
106
+ }
107
+
108
+ const JUSTIFY_MAP: Record<GridJustify, ViewStyle['justifyContent']> = {
109
+ start: 'flex-start',
110
+ center: 'center',
111
+ end: 'flex-end',
112
+ between: 'space-between',
113
+ }
114
+
115
+ // ─── Component ────────────────────────────────────────────────────────────────
116
+
117
+ export function Grid({
118
+ columns = 1,
119
+ gap,
120
+ gapX,
121
+ gapY,
122
+ align,
123
+ justify,
124
+ p, px, py, pt, pr, pb, pl,
125
+ m, mx, my, mt, mr, mb, ml,
126
+ width, minWidth, maxWidth,
127
+ height, minHeight, maxHeight,
128
+ position,
129
+ top, right, bottom, left,
130
+ overflow,
131
+ flexBasis, flexShrink, flexGrow,
132
+ bg,
133
+ radius,
134
+ style,
135
+ children,
136
+ onLayout: onLayoutProp,
137
+ ...rest
138
+ }: GridProps) {
139
+ const { scaling } = useThemeContext()
140
+ const rc = useResolveColor()
141
+
142
+ const sp = (token: MarginToken | SpaceToken | undefined): number | undefined =>
143
+ token !== undefined ? resolveSpace(token, scaling) : undefined
144
+
145
+ const columnGap = sp(gapX ?? gap) ?? 0
146
+ const rowGap = sp(gapY ?? gap) ?? 0
147
+
148
+ // ─── Container width measurement ──────────────────────────────────────────
149
+ const [containerWidth, setContainerWidth] = useState<number>(0)
150
+
151
+ const handleLayout = useCallback(
152
+ (e: LayoutChangeEvent) => {
153
+ setContainerWidth(e.nativeEvent.layout.width)
154
+ onLayoutProp?.(e)
155
+ },
156
+ [onLayoutProp],
157
+ )
158
+
159
+ // ─── Cell width calculation ───────────────────────────────────────────────
160
+ // totalGapWidth = (columns - 1) * columnGap
161
+ // cellWidth = (containerWidth - totalGapWidth) / columns
162
+ const cols = Math.max(1, Math.round(columns))
163
+ const cellWidth =
164
+ containerWidth > 0
165
+ ? (containerWidth - (cols - 1) * columnGap) / cols
166
+ : undefined
167
+
168
+ // ─── Container style ─────────────────────────────────────────────────────
169
+ const containerStyle: ViewStyle = {
170
+ flexDirection: 'row',
171
+ flexWrap: 'wrap',
172
+ alignItems: ALIGN_MAP[align ?? 'stretch'],
173
+ justifyContent: justify ? JUSTIFY_MAP[justify] : undefined,
174
+ rowGap,
175
+ columnGap,
176
+ // Padding
177
+ paddingTop: sp(pt ?? py ?? p),
178
+ paddingBottom: sp(pb ?? py ?? p),
179
+ paddingLeft: sp(pl ?? px ?? p),
180
+ paddingRight: sp(pr ?? px ?? p),
181
+ // Margin
182
+ marginTop: sp(mt ?? my ?? m),
183
+ marginBottom: sp(mb ?? my ?? m),
184
+ marginLeft: sp(ml ?? mx ?? m),
185
+ marginRight: sp(mr ?? mx ?? m),
186
+ // Size
187
+ width: width as ViewStyle['width'],
188
+ minWidth: minWidth as ViewStyle['minWidth'],
189
+ maxWidth: maxWidth as ViewStyle['maxWidth'],
190
+ height: height as ViewStyle['height'],
191
+ minHeight: minHeight as ViewStyle['minHeight'],
192
+ maxHeight: maxHeight as ViewStyle['maxHeight'],
193
+ // Position
194
+ position,
195
+ top: top as ViewStyle['top'],
196
+ right: right as ViewStyle['right'],
197
+ bottom: bottom as ViewStyle['bottom'],
198
+ left: left as ViewStyle['left'],
199
+ // Layout
200
+ overflow: overflow as ViewStyle['overflow'],
201
+ flexBasis: flexBasis as ViewStyle['flexBasis'],
202
+ flexShrink,
203
+ flexGrow,
204
+ // Theme
205
+ backgroundColor: bg ? rc(bg) : undefined,
206
+ borderRadius: radius
207
+ ? (radius === 'full' ? getFullRadius(radius) : getRadius(radius, 4))
208
+ : undefined,
209
+ }
210
+
211
+ // ─── Render ──────────────────────────────────────────────────────────────
212
+ const items = React.Children.toArray(children)
213
+
214
+ return (
215
+ <View style={[containerStyle, style]} onLayout={handleLayout} {...rest}>
216
+ {items.map((child, i) => (
217
+ <View key={i} style={{ width: cellWidth }}>
218
+ {child}
219
+ </View>
220
+ ))}
221
+ </View>
222
+ )
223
+ }
224
+ Grid.displayName = 'Grid'
@@ -0,0 +1,9 @@
1
+ export { Box, type BoxProps } from './Box'
2
+ export {
3
+ Flex, type FlexProps,
4
+ type FlexDirection, type FlexAlign, type FlexJustify, type FlexWrap,
5
+ } from './Flex'
6
+ export {
7
+ Grid, type GridProps,
8
+ type GridAlign, type GridJustify,
9
+ } from './Grid'