@scalewing/react-native 0.1.0 → 0.2.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @scalewing/react-native
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - f35314a: Add Button (primary, secondary, ghost, danger; sm and md) for DOM and React Native after FutMas and coach-platform requested the same control. Includes onAccent/onDanger, 44px md hit target, focus ring, and disabled opacity tokens.
8
+ - f35314a: Shift the default visual language to a quiet glass canvas: Apple-like neutrals and type, frosted Card, pill buttons, and generated document styles so links and native text controls are not user-agent chrome.
9
+
10
+ ### Patch Changes
11
+
12
+ - Updated dependencies [f35314a]
13
+ - Updated dependencies [f35314a]
14
+ - @scalewing/tokens@0.2.0
15
+
3
16
  ## 0.1.0
4
17
 
5
18
  ### Minor Changes
package/README.md CHANGED
@@ -3,13 +3,16 @@
3
3
  React Native / Expo primitives that consume the same Scalewing tokens as the DOM package.
4
4
 
5
5
  ```ts
6
- import { Card, Stack, Text, ThemeProvider } from '@scalewing/react-native';
6
+ import { Button, Card, Stack, Text, ThemeProvider } from '@scalewing/react-native';
7
7
 
8
8
  <Card padding={4}>
9
- <Text variant="title">Kickoff</Text>
9
+ <Stack gap={3}>
10
+ <Text variant="title">Kickoff</Text>
11
+ <Button onPress={() => undefined}>Save</Button>
12
+ </Stack>
10
13
  </Card>
11
14
  ```
12
15
 
13
- There is no CSS class API. `padding={4}` is spacing step 4, the same step as `sw-padding-4` on web.
16
+ There is no CSS class API. `padding={4}` is spacing step 4, the same step as `sw-padding-4` on web. Field is web-only (`@scalewing/react`).
14
17
 
15
18
  React and React Native are peer dependencies so the host Expo app owns the runtime. Rationale: duplicating React Native inside this package would fight Metro and Expo upgrades.
@@ -0,0 +1,11 @@
1
+ import { type ButtonSize, type ButtonVariant } from '@scalewing/tokens';
2
+ import { type ReactNode } from 'react';
3
+ export type { ButtonSize, ButtonVariant };
4
+ export type ButtonProps = {
5
+ children: ReactNode;
6
+ disabled?: boolean;
7
+ onPress: () => void;
8
+ size?: ButtonSize;
9
+ variant?: ButtonVariant;
10
+ };
11
+ export declare function Button({ children, disabled, onPress, size, variant, }: ButtonProps): import("react").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Pressable } from 'react-native';
3
+ import { buttonLabelColor, mapButtonViewStyle } from '../map-button-style.js';
4
+ import { useTheme } from '../theme/ThemeProvider.js';
5
+ import { Text } from './Text.js';
6
+ export function Button({ children, disabled = false, onPress, size = 'md', variant = 'primary', }) {
7
+ const theme = useTheme();
8
+ const label = typeof children === 'string' ? children : undefined;
9
+ return (_jsx(Pressable, { accessibilityRole: "button", accessibilityState: { disabled }, accessibilityLabel: label, disabled: disabled, onPress: onPress, style: mapButtonViewStyle(theme, { disabled, size, variant }), children: typeof children === 'string' ? (_jsx(Text, { color: buttonLabelColor(variant), variant: "label", children: children })) : (children) }));
10
+ }
@@ -1,6 +1,6 @@
1
- import { type SpacingStep } from '@scalewing/tokens';
1
+ import { type CardVariant, type SpacingStep } from '@scalewing/tokens';
2
2
  import { type BoxProps } from './Box.js';
3
- export type CardVariant = 'outlined' | 'elevated';
3
+ export type { CardVariant };
4
4
  export type CardProps = BoxProps & {
5
5
  padding?: SpacingStep;
6
6
  variant?: CardVariant;
@@ -1,18 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Box } from './Box.js';
3
+ import { mapCardViewStyle } from '../map-card-style.js';
3
4
  import { useTheme } from '../theme/ThemeProvider.js';
4
- export function Card({ padding = 4, style, variant = 'outlined', ...rest }) {
5
+ export function Card({ padding = 4, style, variant = 'glass', ...rest }) {
5
6
  const theme = useTheme();
6
- return (_jsx(Box, { background: "surface", border: variant === 'outlined', padding: padding, radius: "md", style: [
7
- variant === 'elevated'
8
- ? {
9
- shadowColor: theme.colors.text,
10
- shadowOffset: { height: 8, width: 0 },
11
- shadowOpacity: 0.12,
12
- shadowRadius: 16,
13
- elevation: 3,
14
- }
15
- : undefined,
16
- style,
17
- ], ...rest }));
7
+ return (_jsx(Box, { padding: padding, style: [mapCardViewStyle(theme, variant), style], ...rest }));
18
8
  }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { Box, type BoxProps } from './components/Box.js';
2
+ export { Button, type ButtonProps, type ButtonSize, type ButtonVariant, } from './components/Button.js';
2
3
  export { Card, type CardProps, type CardVariant } from './components/Card.js';
3
4
  export { Inline, type InlineProps } from './components/Inline.js';
4
5
  export { Stack, type StackProps } from './components/Stack.js';
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { Box } from './components/Box.js';
2
+ export { Button, } from './components/Button.js';
2
3
  export { Card } from './components/Card.js';
3
4
  export { Inline } from './components/Inline.js';
4
5
  export { Stack } from './components/Stack.js';
@@ -0,0 +1,9 @@
1
+ import { type ButtonSize, type ButtonVariant, type SemanticColorKey, type Theme } from '@scalewing/tokens';
2
+ import { type TextStyle, type ViewStyle } from 'react-native';
3
+ export declare function buttonLabelColor(variant: ButtonVariant): SemanticColorKey;
4
+ export declare function mapButtonViewStyle(theme: Theme, options: {
5
+ disabled: boolean;
6
+ size: ButtonSize;
7
+ variant: ButtonVariant;
8
+ }): ViewStyle;
9
+ export declare function mapButtonLabelStyle(theme: Theme, variant: ButtonVariant): TextStyle;
@@ -0,0 +1,61 @@
1
+ export function buttonLabelColor(variant) {
2
+ switch (variant) {
3
+ case 'primary':
4
+ return 'onAccent';
5
+ case 'secondary':
6
+ return 'text';
7
+ case 'ghost':
8
+ return 'accent';
9
+ case 'danger':
10
+ return 'onDanger';
11
+ }
12
+ }
13
+ export function mapButtonViewStyle(theme, options) {
14
+ const control = theme.control[options.size];
15
+ const fill = buttonFill(theme, options.variant);
16
+ return {
17
+ alignItems: 'center',
18
+ backgroundColor: fill.backgroundColor,
19
+ borderColor: fill.borderColor,
20
+ borderRadius: theme.radius.pill,
21
+ borderWidth: 1,
22
+ justifyContent: 'center',
23
+ minHeight: control.minHeight,
24
+ opacity: options.disabled ? theme.disabledOpacity : 1,
25
+ paddingHorizontal: control.paddingInline,
26
+ };
27
+ }
28
+ export function mapButtonLabelStyle(theme, variant) {
29
+ const type = theme.typography.label;
30
+ return {
31
+ color: theme.colors[buttonLabelColor(variant)],
32
+ fontSize: type.fontSize,
33
+ fontWeight: String(type.fontWeight),
34
+ letterSpacing: type.letterSpacing,
35
+ lineHeight: type.lineHeight,
36
+ };
37
+ }
38
+ function buttonFill(theme, variant) {
39
+ switch (variant) {
40
+ case 'primary':
41
+ return {
42
+ backgroundColor: theme.colors.accent,
43
+ borderColor: 'transparent',
44
+ };
45
+ case 'secondary':
46
+ return {
47
+ backgroundColor: theme.glass.fill,
48
+ borderColor: theme.glass.border,
49
+ };
50
+ case 'ghost':
51
+ return {
52
+ backgroundColor: 'transparent',
53
+ borderColor: 'transparent',
54
+ };
55
+ case 'danger':
56
+ return {
57
+ backgroundColor: theme.colors.danger,
58
+ borderColor: 'transparent',
59
+ };
60
+ }
61
+ }
@@ -0,0 +1,3 @@
1
+ import { type CardVariant, type Theme } from '@scalewing/tokens';
2
+ import { type ViewStyle } from 'react-native';
3
+ export declare function mapCardViewStyle(theme: Theme, variant: CardVariant): ViewStyle;
@@ -0,0 +1,30 @@
1
+ export function mapCardViewStyle(theme, variant) {
2
+ switch (variant) {
3
+ case 'glass':
4
+ return {
5
+ backgroundColor: theme.glass.fill,
6
+ borderColor: theme.glass.border,
7
+ borderRadius: theme.radius.lg,
8
+ borderWidth: 1,
9
+ };
10
+ case 'outlined':
11
+ return {
12
+ backgroundColor: theme.colors.surface,
13
+ borderColor: theme.colors.border,
14
+ borderRadius: theme.radius.lg,
15
+ borderWidth: 1,
16
+ };
17
+ case 'elevated':
18
+ return {
19
+ backgroundColor: theme.colors.surface,
20
+ borderColor: 'transparent',
21
+ borderRadius: theme.radius.lg,
22
+ borderWidth: 0,
23
+ elevation: 3,
24
+ shadowColor: theme.colors.text,
25
+ shadowOffset: { height: 8, width: 0 },
26
+ shadowOpacity: 0.08,
27
+ shadowRadius: 20,
28
+ };
29
+ }
30
+ }
@@ -1,13 +1,13 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createContext, useContext, useMemo } from 'react';
3
- import { useColorScheme } from 'react-native';
3
+ import { useColorScheme, View } from 'react-native';
4
4
  import { createTheme, } from '@scalewing/tokens';
5
5
  const ThemeContext = createContext(null);
6
6
  export function ThemeProvider({ colorScheme = 'system', colors, children, }) {
7
7
  const deviceScheme = useColorScheme() === 'dark' ? 'dark' : 'light';
8
8
  const resolvedScheme = colorScheme === 'system' ? deviceScheme : colorScheme;
9
9
  const theme = useMemo(() => createTheme({ colorScheme: resolvedScheme, colors }), [colors, resolvedScheme]);
10
- return (_jsx(ThemeContext.Provider, { value: theme, children: children }));
10
+ return (_jsx(ThemeContext.Provider, { value: theme, children: _jsx(View, { style: { backgroundColor: theme.colors.background, flex: 1 }, children: children }) }));
11
11
  }
12
12
  export function useTheme() {
13
13
  const theme = useContext(ThemeContext);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalewing/react-native",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Scalewing React Native layout primitives.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -28,7 +28,7 @@
28
28
  "README.md"
29
29
  ],
30
30
  "dependencies": {
31
- "@scalewing/tokens": "0.1.0"
31
+ "@scalewing/tokens": "0.2.0"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "react": "^19.0.0",