@scalewing/react-native 0.5.0 → 0.6.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,19 @@
1
1
  # @scalewing/react-native
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ebbbd43: Add a controlled native Accordion with optional separate title navigation,
8
+ leading/metadata slots, expanded accessibility state, and theme-owned chrome.
9
+
10
+ ### Patch Changes
11
+
12
+ - ebbbd43: Make native segmented selection visible with paired accent/onAccent colors
13
+ and a larger minimum touch height. Existing component props are unchanged.
14
+ - Updated dependencies
15
+ - @scalewing/tokens@0.6.0
16
+
3
17
  ## 0.5.0
4
18
 
5
19
  ### Minor Changes
package/README.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  React Native / Expo primitives that consume the same Scalewing tokens as the DOM package.
4
4
 
5
+ Native `Accordion` is controlled by `open` / `onOpenChange`. Provide a title,
6
+ localized disclosure `accessibilityLabel`, and content. Optional `leading`
7
+ and `metadata` slots support marks and counts. With `onTitlePress`, the title
8
+ is a separate action (named by `titleAccessibilityLabel` or `title`) and only
9
+ the trailing control toggles. Otherwise the entire header toggles. Collapsed
10
+ content unmounts and is absent from the accessibility tree.
11
+
5
12
  ```ts
6
13
  import { Button, Card, Field, SegmentedControl, Stack, TabBar, Text, ThemeProvider } from '@scalewing/react-native';
7
14
 
@@ -23,4 +30,8 @@ except styling and controlled semantics owned by the component. `colorScheme`
23
30
  is `"light"`, `"dark"`, or `"system"`. Named palettes include both schemes;
24
31
  `colors` may be `{ light, dark }`.
25
32
 
33
+ `SegmentedControl` uses the active palette's accent/onAccent pair for the
34
+ selected section, with a 44-point minimum touch height. Labels grow with
35
+ system text size. The native example demonstrates switching sections.
36
+
26
37
  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,13 @@
1
+ import { type ReactNode } from 'react';
2
+ export type AccordionProps = {
3
+ accessibilityLabel: string;
4
+ children: ReactNode;
5
+ leading?: ReactNode;
6
+ metadata?: ReactNode;
7
+ onOpenChange: (open: boolean) => void;
8
+ onTitlePress?: () => void;
9
+ open: boolean;
10
+ title: string;
11
+ titleAccessibilityLabel?: string;
12
+ };
13
+ export declare function Accordion({ accessibilityLabel, children, leading, metadata, onOpenChange, onTitlePress, open, title, titleAccessibilityLabel, }: AccordionProps): import("react").JSX.Element;
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Pressable } from 'react-native';
3
+ import { mapAccordionChevronStyle, mapAccordionHeaderStyle, mapAccordionPressStyle, mapAccordionStyle, } from '../map-accordion-style.js';
4
+ import { useTheme } from '../theme/ThemeProvider.js';
5
+ import { Box } from './Box.js';
6
+ import { Text } from './Text.js';
7
+ export function Accordion({ accessibilityLabel, children, leading, metadata, onOpenChange, onTitlePress, open, title, titleAccessibilityLabel, }) {
8
+ const theme = useTheme();
9
+ const toggle = () => onOpenChange(!open);
10
+ const chevron = (_jsx(Box, { accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", style: mapAccordionChevronStyle(theme, open) }));
11
+ return (_jsxs(Box, { style: mapAccordionStyle(theme), children: [_jsxs(Box, { style: mapAccordionHeaderStyle(theme), children: [_jsxs(Pressable, { accessibilityRole: "button", accessibilityLabel: onTitlePress
12
+ ? (titleAccessibilityLabel ?? title)
13
+ : accessibilityLabel, accessibilityState: onTitlePress ? undefined : { expanded: open }, onPress: onTitlePress ?? toggle, style: ({ pressed }) => [
14
+ mapAccordionPressStyle(theme, pressed),
15
+ { flex: 1, minWidth: 0 },
16
+ ], children: [leading, _jsx(Text, { variant: "label", style: { flex: 1, minWidth: 0 }, children: title }), !onTitlePress ? (_jsxs(_Fragment, { children: [metadata, chevron] })) : null] }), onTitlePress ? (_jsxs(Pressable, { accessibilityRole: "button", accessibilityLabel: accessibilityLabel, accessibilityState: { expanded: open }, onPress: toggle, style: ({ pressed }) => mapAccordionPressStyle(theme, pressed), children: [metadata, chevron] })) : null] }), open ? (_jsx(Box, { paddingX: 1, paddingBottom: 1, children: children })) : null] }));
17
+ }
package/dist/index.d.ts CHANGED
@@ -10,3 +10,4 @@ export { TabBar, TabBarTrailing, type TabBarItem, type TabBarProps, type TabBarT
10
10
  export { Table, TableBody, TableCell, TableHeader, TableRow, type TableBodyProps, type TableCellProps, type TableDensity, type TableHeaderProps, type TableProps, type TableRowProps, } from './components/Table.js';
11
11
  export { Text, type TextProps } from './components/Text.js';
12
12
  export { ThemeProvider, useTheme, type ThemeProviderProps, } from './theme/ThemeProvider.js';
13
+ export { Accordion, type AccordionProps } from './components/Accordion.js';
package/dist/index.js CHANGED
@@ -9,3 +9,4 @@ export { TabBar, TabBarTrailing, } from './components/TabBar.js';
9
9
  export { Table, TableBody, TableCell, TableHeader, TableRow, } from './components/Table.js';
10
10
  export { Text } from './components/Text.js';
11
11
  export { ThemeProvider, useTheme, } from './theme/ThemeProvider.js';
12
+ export { Accordion } from './components/Accordion.js';
@@ -0,0 +1,6 @@
1
+ import { type Theme } from '@scalewing/tokens';
2
+ import { type ViewStyle } from 'react-native';
3
+ export declare function mapAccordionStyle(theme: Theme): ViewStyle;
4
+ export declare function mapAccordionHeaderStyle(theme: Theme): ViewStyle;
5
+ export declare function mapAccordionPressStyle(theme: Theme, pressed: boolean): ViewStyle;
6
+ export declare function mapAccordionChevronStyle(theme: Theme, open: boolean): ViewStyle;
@@ -0,0 +1,39 @@
1
+ import { focusRing } from '@scalewing/tokens';
2
+ export function mapAccordionStyle(theme) {
3
+ return {
4
+ backgroundColor: theme.colors.surface,
5
+ borderColor: theme.colors.border,
6
+ borderWidth: 1,
7
+ borderRadius: theme.radius.lg,
8
+ overflow: 'hidden',
9
+ };
10
+ }
11
+ export function mapAccordionHeaderStyle(theme) {
12
+ return {
13
+ flexDirection: 'row',
14
+ alignItems: 'stretch',
15
+ backgroundColor: theme.glass.fill,
16
+ };
17
+ }
18
+ export function mapAccordionPressStyle(theme, pressed) {
19
+ return {
20
+ alignItems: 'center',
21
+ flexDirection: 'row',
22
+ gap: theme.space[3],
23
+ minHeight: theme.control.md.minHeight + theme.space[3],
24
+ minWidth: theme.control.md.minHeight,
25
+ paddingHorizontal: theme.space[4],
26
+ paddingVertical: theme.space[3],
27
+ opacity: pressed ? theme.disabledOpacity : 1,
28
+ };
29
+ }
30
+ export function mapAccordionChevronStyle(theme, open) {
31
+ return {
32
+ width: theme.space[2],
33
+ height: theme.space[2],
34
+ borderBottomWidth: focusRing.width,
35
+ borderRightWidth: focusRing.width,
36
+ borderColor: theme.colors.muted,
37
+ transform: [{ rotate: open ? '225deg' : '45deg' }],
38
+ };
39
+ }
@@ -13,14 +13,14 @@ export function mapSegmentedControlStyle(theme) {
13
13
  export function mapSegmentedItemStyle(theme, selected) {
14
14
  return {
15
15
  alignItems: 'center',
16
- backgroundColor: selected ? theme.colors.surface : 'transparent',
16
+ backgroundColor: selected ? theme.colors.accent : 'transparent',
17
17
  borderRadius: theme.radius.pill,
18
18
  flex: 1,
19
19
  justifyContent: 'center',
20
- minHeight: theme.control.xs.minHeight,
20
+ minHeight: theme.control.md.minHeight,
21
21
  paddingHorizontal: theme.control.xs.paddingInline,
22
22
  };
23
23
  }
24
24
  export function segmentedItemColor(selected) {
25
- return selected ? 'text' : 'muted';
25
+ return selected ? 'onAccent' : 'muted';
26
26
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalewing/react-native",
3
- "version": "0.5.0",
3
+ "version": "0.6.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.5.0"
31
+ "@scalewing/tokens": "0.6.0"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "react": "^19.0.0",
@@ -36,8 +36,10 @@
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/react": "^19.2.2",
39
+ "@types/react-test-renderer": "^19.3.0",
39
40
  "react": "19.2.3",
40
- "react-native": "0.86.3"
41
+ "react-native": "0.86.3",
42
+ "react-test-renderer": "19.2.3"
41
43
  },
42
44
  "publishConfig": {
43
45
  "access": "public"