@ankhorage/surface 1.4.0 → 2.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.
- package/CHANGELOG.md +33 -0
- package/dist/components/action-sheet/ActionSheet.d.ts +4 -0
- package/dist/components/action-sheet/ActionSheet.d.ts.map +1 -0
- package/dist/components/action-sheet/ActionSheet.js +71 -0
- package/dist/components/action-sheet/ActionSheet.js.map +1 -0
- package/dist/components/action-sheet/ActionSheetItem.d.ts +4 -0
- package/dist/components/action-sheet/ActionSheetItem.d.ts.map +1 -0
- package/dist/components/action-sheet/ActionSheetItem.js +27 -0
- package/dist/components/action-sheet/ActionSheetItem.js.map +1 -0
- package/dist/components/action-sheet/index.d.ts +4 -0
- package/dist/components/action-sheet/index.d.ts.map +1 -0
- package/dist/components/action-sheet/index.js +3 -0
- package/dist/components/action-sheet/index.js.map +1 -0
- package/dist/components/action-sheet/types.d.ts +24 -0
- package/dist/components/action-sheet/types.d.ts.map +1 -0
- package/dist/components/action-sheet/types.js +2 -0
- package/dist/components/action-sheet/types.js.map +1 -0
- package/dist/components/badge/Badge.d.ts +1 -1
- package/dist/components/badge/Badge.d.ts.map +1 -1
- package/dist/components/badge/Badge.js +3 -3
- package/dist/components/badge/Badge.js.map +1 -1
- package/dist/components/badge/types.d.ts +2 -2
- package/dist/components/badge/types.d.ts.map +1 -1
- package/dist/components/badge/types.js.map +1 -1
- package/dist/components/button/Button.d.ts +1 -1
- package/dist/components/button/Button.d.ts.map +1 -1
- package/dist/components/button/Button.js +6 -3
- package/dist/components/button/Button.js.map +1 -1
- package/dist/components/button/types.d.ts +2 -2
- package/dist/components/button/types.d.ts.map +1 -1
- package/dist/components/button/types.js.map +1 -1
- package/dist/components/checkbox/Checkbox.d.ts +1 -1
- package/dist/components/checkbox/Checkbox.d.ts.map +1 -1
- package/dist/components/checkbox/Checkbox.js +7 -4
- package/dist/components/checkbox/Checkbox.js.map +1 -1
- package/dist/components/checkbox/types.d.ts +2 -2
- package/dist/components/checkbox/types.d.ts.map +1 -1
- package/dist/components/checkbox/types.js.map +1 -1
- package/dist/components/field/Field.d.ts.map +1 -1
- package/dist/components/field/Field.js +6 -2
- package/dist/components/field/Field.js.map +1 -1
- package/dist/components/helper-text/HelperText.d.ts +1 -1
- package/dist/components/helper-text/HelperText.d.ts.map +1 -1
- package/dist/components/helper-text/HelperText.js +2 -2
- package/dist/components/helper-text/HelperText.js.map +1 -1
- package/dist/components/helper-text/types.d.ts +3 -2
- package/dist/components/helper-text/types.d.ts.map +1 -1
- package/dist/components/helper-text/types.js.map +1 -1
- package/dist/components/icon-button/IconButton.d.ts +1 -1
- package/dist/components/icon-button/IconButton.d.ts.map +1 -1
- package/dist/components/icon-button/IconButton.js +2 -2
- package/dist/components/icon-button/IconButton.js.map +1 -1
- package/dist/components/icon-button/types.d.ts +2 -2
- package/dist/components/icon-button/types.d.ts.map +1 -1
- package/dist/components/icon-button/types.js.map +1 -1
- package/dist/components/label/Label.d.ts +1 -1
- package/dist/components/label/Label.d.ts.map +1 -1
- package/dist/components/label/Label.js +3 -3
- package/dist/components/label/Label.js.map +1 -1
- package/dist/components/label/types.d.ts +3 -2
- package/dist/components/label/types.d.ts.map +1 -1
- package/dist/components/label/types.js.map +1 -1
- package/dist/components/list-item/ListItem.js +1 -1
- package/dist/components/list-item/ListItem.js.map +1 -1
- package/dist/components/menu/Menu.d.ts.map +1 -1
- package/dist/components/menu/Menu.js +1 -3
- package/dist/components/menu/Menu.js.map +1 -1
- package/dist/components/navigation/NavigationItem.d.ts.map +1 -1
- package/dist/components/navigation/NavigationItem.js +1 -1
- package/dist/components/navigation/NavigationItem.js.map +1 -1
- package/dist/components/navigation/TabBarItem.d.ts.map +1 -1
- package/dist/components/navigation/TabBarItem.js +1 -1
- package/dist/components/navigation/TabBarItem.js.map +1 -1
- package/dist/components/radio/Radio.d.ts +1 -1
- package/dist/components/radio/Radio.d.ts.map +1 -1
- package/dist/components/radio/Radio.js +4 -3
- package/dist/components/radio/Radio.js.map +1 -1
- package/dist/components/radio/types.d.ts +2 -2
- package/dist/components/radio/types.d.ts.map +1 -1
- package/dist/components/radio/types.js.map +1 -1
- package/dist/components/switch/Switch.d.ts +1 -1
- package/dist/components/switch/Switch.d.ts.map +1 -1
- package/dist/components/switch/Switch.js +4 -3
- package/dist/components/switch/Switch.js.map +1 -1
- package/dist/components/switch/types.d.ts +2 -2
- package/dist/components/switch/types.d.ts.map +1 -1
- package/dist/components/switch/types.js.map +1 -1
- package/dist/components/tabs/Tab.d.ts.map +1 -1
- package/dist/components/tabs/Tab.js +1 -1
- package/dist/components/tabs/Tab.js.map +1 -1
- package/dist/components/toast/Toast.d.ts +1 -1
- package/dist/components/toast/Toast.d.ts.map +1 -1
- package/dist/components/toast/Toast.js +34 -9
- package/dist/components/toast/Toast.js.map +1 -1
- package/dist/components/toast/ToastProvider.js +1 -1
- package/dist/components/toast/ToastProvider.js.map +1 -1
- package/dist/components/toast/index.d.ts +1 -1
- package/dist/components/toast/index.d.ts.map +1 -1
- package/dist/components/toast/index.js.map +1 -1
- package/dist/components/toast/types.d.ts +3 -2
- package/dist/components/toast/types.d.ts.map +1 -1
- package/dist/components/toast/types.js.map +1 -1
- package/dist/components/tooltip/Tooltip.js +1 -1
- package/dist/components/tooltip/Tooltip.js.map +1 -1
- package/dist/examples/DocsExamples.js +4 -4
- package/dist/examples/DocsExamples.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/resolvers/index.d.ts +1 -1
- package/dist/internal/resolvers/index.d.ts.map +1 -1
- package/dist/internal/resolvers/index.js +1 -1
- package/dist/internal/resolvers/index.js.map +1 -1
- package/dist/internal/resolvers/resolveFieldPresentation.d.ts +5 -5
- package/dist/internal/resolvers/resolveFieldPresentation.d.ts.map +1 -1
- package/dist/internal/resolvers/resolveFieldPresentation.js +8 -6
- package/dist/internal/resolvers/resolveFieldPresentation.js.map +1 -1
- package/dist/internal/resolvers/resolveInteractiveColors.d.ts +3 -3
- package/dist/internal/resolvers/resolveInteractiveColors.d.ts.map +1 -1
- package/dist/internal/resolvers/resolveInteractiveColors.js +4 -6
- package/dist/internal/resolvers/resolveInteractiveColors.js.map +1 -1
- package/dist/internal/resolvers/resolveSelectionControlColors.d.ts +3 -3
- package/dist/internal/resolvers/resolveSelectionControlColors.d.ts.map +1 -1
- package/dist/internal/resolvers/resolveSelectionControlColors.js +4 -4
- package/dist/internal/resolvers/resolveSelectionControlColors.js.map +1 -1
- package/dist/internal/resolvers/resolveSurfaceColor.d.ts +4 -0
- package/dist/internal/resolvers/resolveSurfaceColor.d.ts.map +1 -0
- package/dist/internal/resolvers/resolveSurfaceColor.js +26 -0
- package/dist/internal/resolvers/resolveSurfaceColor.js.map +1 -0
- package/dist/internal/resolvers/resolveTextColor.d.ts +2 -3
- package/dist/internal/resolvers/resolveTextColor.d.ts.map +1 -1
- package/dist/internal/resolvers/resolveTextColor.js +7 -11
- package/dist/internal/resolvers/resolveTextColor.js.map +1 -1
- package/dist/primitives/heading/Heading.d.ts.map +1 -1
- package/dist/primitives/heading/Heading.js +2 -2
- package/dist/primitives/heading/Heading.js.map +1 -1
- package/dist/primitives/heading/resolveHeadingStyle.d.ts +2 -1
- package/dist/primitives/heading/resolveHeadingStyle.d.ts.map +1 -1
- package/dist/primitives/heading/resolveHeadingStyle.js +2 -2
- package/dist/primitives/heading/resolveHeadingStyle.js.map +1 -1
- package/dist/primitives/heading/types.d.ts +3 -0
- package/dist/primitives/heading/types.d.ts.map +1 -1
- package/dist/primitives/heading/types.js.map +1 -1
- package/dist/primitives/text/Text.d.ts +1 -1
- package/dist/primitives/text/Text.d.ts.map +1 -1
- package/dist/primitives/text/Text.js +2 -2
- package/dist/primitives/text/Text.js.map +1 -1
- package/dist/primitives/text/types.d.ts +3 -3
- package/dist/primitives/text/types.d.ts.map +1 -1
- package/dist/primitives/text/types.js.map +1 -1
- package/dist/surfaceColor.d.ts +9 -0
- package/dist/surfaceColor.d.ts.map +1 -0
- package/dist/surfaceColor.js +15 -0
- package/dist/surfaceColor.js.map +1 -0
- package/dist/theme/colorEngine.d.ts.map +1 -1
- package/dist/theme/colorEngine.js +9 -1
- package/dist/theme/colorEngine.js.map +1 -1
- package/dist/theme/types.d.ts +5 -0
- package/dist/theme/types.d.ts.map +1 -1
- package/dist/theme/types.js.map +1 -1
- package/package.json +2 -2
- package/src/components/action-sheet/ActionSheet.tsx +121 -0
- package/src/components/action-sheet/ActionSheetItem.tsx +57 -0
- package/src/components/action-sheet/index.ts +3 -0
- package/src/components/action-sheet/types.ts +26 -0
- package/src/components/badge/Badge.tsx +8 -3
- package/src/components/badge/types.ts +2 -2
- package/src/components/button/Button.tsx +9 -3
- package/src/components/button/types.ts +2 -2
- package/src/components/checkbox/Checkbox.tsx +13 -4
- package/src/components/checkbox/types.ts +2 -2
- package/src/components/field/Field.tsx +11 -3
- package/src/components/helper-text/HelperText.tsx +2 -2
- package/src/components/helper-text/types.ts +3 -2
- package/src/components/icon-button/IconButton.tsx +2 -2
- package/src/components/icon-button/types.ts +2 -2
- package/src/components/label/Label.tsx +9 -3
- package/src/components/label/types.ts +3 -2
- package/src/components/list-item/ListItem.tsx +1 -1
- package/src/components/menu/Menu.tsx +1 -8
- package/src/components/navigation/NavigationItem.tsx +2 -1
- package/src/components/navigation/TabBarItem.tsx +2 -1
- package/src/components/radio/Radio.tsx +5 -3
- package/src/components/radio/types.ts +2 -2
- package/src/components/switch/Switch.tsx +5 -3
- package/src/components/switch/types.ts +2 -2
- package/src/components/tabs/Tab.tsx +1 -5
- package/src/components/toast/Toast.tsx +38 -10
- package/src/components/toast/ToastProvider.tsx +1 -1
- package/src/components/toast/index.ts +1 -1
- package/src/components/toast/types.ts +4 -2
- package/src/components/tooltip/Tooltip.tsx +1 -1
- package/src/examples/DocsExamples.tsx +4 -4
- package/src/index.test.ts +1 -0
- package/src/index.ts +15 -1
- package/src/internal/resolvers/index.ts +1 -1
- package/src/internal/resolvers/resolveFieldPresentation.test.ts +12 -10
- package/src/internal/resolvers/resolveFieldPresentation.ts +13 -11
- package/src/internal/resolvers/resolveInteractiveColors.test.ts +4 -4
- package/src/internal/resolvers/resolveInteractiveColors.ts +6 -7
- package/src/internal/resolvers/resolveSelectionControlColors.test.ts +8 -8
- package/src/internal/resolvers/resolveSelectionControlColors.ts +6 -5
- package/src/internal/resolvers/resolveSurfaceColor.test.ts +21 -0
- package/src/internal/resolvers/resolveSurfaceColor.ts +31 -0
- package/src/internal/resolvers/resolveTextColor.test.ts +16 -5
- package/src/internal/resolvers/resolveTextColor.ts +10 -22
- package/src/primitives/heading/Heading.tsx +3 -1
- package/src/primitives/heading/resolveHeadingStyle.test.ts +1 -1
- package/src/primitives/heading/resolveHeadingStyle.ts +4 -1
- package/src/primitives/heading/types.ts +4 -0
- package/src/primitives/text/Text.tsx +2 -2
- package/src/primitives/text/types.ts +3 -3
- package/src/surfaceColor.test.ts +46 -0
- package/src/surfaceColor.ts +22 -0
- package/src/theme/colorEngine.test.ts +6 -0
- package/src/theme/colorEngine.ts +9 -1
- package/src/theme/types.ts +5 -0
- package/dist/internal/resolvers/resolveTone.d.ts +0 -4
- package/dist/internal/resolvers/resolveTone.d.ts.map +0 -1
- package/dist/internal/resolvers/resolveTone.js +0 -16
- package/dist/internal/resolvers/resolveTone.js.map +0 -1
- package/src/internal/resolvers/resolveTone.ts +0 -19
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import type { SurfaceColor } from '../../surfaceColor';
|
|
1
2
|
import type { SurfaceTheme } from '../../theme/types';
|
|
2
3
|
import type { FieldState } from './resolveFieldState';
|
|
3
|
-
import {
|
|
4
|
+
import { resolveSurfaceColor } from './resolveSurfaceColor';
|
|
4
5
|
|
|
5
6
|
export interface ResolvedSelectionControlColors {
|
|
6
7
|
backgroundColor: string;
|
|
@@ -15,20 +16,20 @@ export interface ResolvedSelectionControlColors {
|
|
|
15
16
|
export function resolveSelectionControlColors(
|
|
16
17
|
theme: SurfaceTheme,
|
|
17
18
|
{
|
|
18
|
-
|
|
19
|
+
color = 'primary',
|
|
19
20
|
fieldState,
|
|
20
21
|
checked,
|
|
21
22
|
hovered = false,
|
|
22
23
|
pressed = false,
|
|
23
24
|
}: {
|
|
24
|
-
|
|
25
|
+
color?: SurfaceColor;
|
|
25
26
|
fieldState: FieldState;
|
|
26
27
|
checked: boolean;
|
|
27
28
|
hovered?: boolean;
|
|
28
29
|
pressed?: boolean;
|
|
29
30
|
},
|
|
30
31
|
): ResolvedSelectionControlColors {
|
|
31
|
-
const semanticTone =
|
|
32
|
+
const semanticTone = resolveSurfaceColor(theme, fieldState.invalid ? 'error' : color);
|
|
32
33
|
const isMuted = fieldState.disabled;
|
|
33
34
|
const isInteractiveReadOnly = fieldState.readOnly && !fieldState.disabled;
|
|
34
35
|
|
|
@@ -47,7 +48,7 @@ export function resolveSelectionControlColors(
|
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
const uncheckedBorderColor = fieldState.invalid
|
|
50
|
-
? theme.semantics.
|
|
51
|
+
? theme.semantics.error.outline
|
|
51
52
|
: fieldState.focused
|
|
52
53
|
? theme.semantics.border.focus
|
|
53
54
|
: theme.semantics.border.strong;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import { createTheme } from '../../theme/createTheme';
|
|
4
|
+
import { resolveSurfaceColor } from './resolveSurfaceColor';
|
|
5
|
+
|
|
6
|
+
describe('resolveSurfaceColor', () => {
|
|
7
|
+
it('maps every public surface color to a semantic role', () => {
|
|
8
|
+
const theme = createTheme();
|
|
9
|
+
|
|
10
|
+
expect(resolveSurfaceColor(theme, 'primary')).toBe(theme.semantics.action.primary);
|
|
11
|
+
expect(resolveSurfaceColor(theme, 'secondary')).toBe(theme.semantics.secondary);
|
|
12
|
+
expect(resolveSurfaceColor(theme, 'tertiary')).toBe(theme.semantics.accent);
|
|
13
|
+
expect(resolveSurfaceColor(theme, 'quaternary')).toBe(theme.semantics.highlight);
|
|
14
|
+
expect(resolveSurfaceColor(theme, 'neutral')).toBe(theme.semantics.action.neutral);
|
|
15
|
+
expect(resolveSurfaceColor(theme, 'success')).toBe(theme.semantics.success);
|
|
16
|
+
expect(resolveSurfaceColor(theme, 'warning')).toBe(theme.semantics.warning);
|
|
17
|
+
expect(resolveSurfaceColor(theme, 'error')).toBe(theme.semantics.error);
|
|
18
|
+
expect(resolveSurfaceColor(theme, 'info')).toBe(theme.semantics.info);
|
|
19
|
+
expect(resolveSurfaceColor(theme, 'danger')).toBe(theme.semantics.action.danger);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SurfaceColor } from '../../surfaceColor';
|
|
2
|
+
import type { RoleSemantics, SurfaceTheme } from '../../theme/types';
|
|
3
|
+
|
|
4
|
+
export function resolveSurfaceColor(
|
|
5
|
+
theme: SurfaceTheme,
|
|
6
|
+
color: SurfaceColor = 'primary',
|
|
7
|
+
): RoleSemantics {
|
|
8
|
+
switch (color) {
|
|
9
|
+
case 'secondary':
|
|
10
|
+
return theme.semantics.secondary;
|
|
11
|
+
case 'tertiary':
|
|
12
|
+
return theme.semantics.accent;
|
|
13
|
+
case 'quaternary':
|
|
14
|
+
return theme.semantics.highlight;
|
|
15
|
+
case 'neutral':
|
|
16
|
+
return theme.semantics.action.neutral;
|
|
17
|
+
case 'error':
|
|
18
|
+
return theme.semantics.error;
|
|
19
|
+
case 'info':
|
|
20
|
+
return theme.semantics.info;
|
|
21
|
+
case 'danger':
|
|
22
|
+
return theme.semantics.action.danger;
|
|
23
|
+
case 'success':
|
|
24
|
+
return theme.semantics.success;
|
|
25
|
+
case 'warning':
|
|
26
|
+
return theme.semantics.warning;
|
|
27
|
+
case 'primary':
|
|
28
|
+
default:
|
|
29
|
+
return theme.semantics.action.primary;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -4,7 +4,7 @@ import { createTheme } from '../../theme/createTheme';
|
|
|
4
4
|
import { resolveTextColor } from './resolveTextColor';
|
|
5
5
|
|
|
6
6
|
describe('resolveTextColor', () => {
|
|
7
|
-
it('maps semantic text
|
|
7
|
+
it('maps semantic text emphases through content aliases', () => {
|
|
8
8
|
const theme = createTheme();
|
|
9
9
|
|
|
10
10
|
expect(resolveTextColor(theme, 'default')).toBe(theme.semantics.content.default);
|
|
@@ -13,11 +13,22 @@ describe('resolveTextColor', () => {
|
|
|
13
13
|
expect(resolveTextColor(theme, 'inverse')).toBe(theme.semantics.content.inverse);
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
it('supports semantic
|
|
16
|
+
it('supports semantic colors for shared field and messaging copy', () => {
|
|
17
17
|
const theme = createTheme();
|
|
18
18
|
|
|
19
|
-
expect(resolveTextColor(theme, 'danger')).toBe(theme.semantics.danger.base);
|
|
20
|
-
expect(resolveTextColor(theme, 'success')).toBe(theme.semantics.success.base);
|
|
21
|
-
expect(resolveTextColor(theme, 'warning')).toBe(theme.semantics.warning.base);
|
|
19
|
+
expect(resolveTextColor(theme, 'default', 'danger')).toBe(theme.semantics.action.danger.base);
|
|
20
|
+
expect(resolveTextColor(theme, 'default', 'success')).toBe(theme.semantics.success.base);
|
|
21
|
+
expect(resolveTextColor(theme, 'default', 'warning')).toBe(theme.semantics.warning.base);
|
|
22
|
+
expect(resolveTextColor(theme, 'default', 'error')).toBe(theme.semantics.error.base);
|
|
23
|
+
expect(resolveTextColor(theme, 'default', 'info')).toBe(theme.semantics.info.base);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('maps inverse emphasis with a semantic color to role foreground text', () => {
|
|
27
|
+
const theme = createTheme();
|
|
28
|
+
|
|
29
|
+
expect(resolveTextColor(theme, 'inverse', 'primary')).toBe(
|
|
30
|
+
theme.semantics.action.primary.onSolidText,
|
|
31
|
+
);
|
|
32
|
+
expect(resolveTextColor(theme, 'inverse', 'error')).toBe(theme.semantics.error.onSolidText);
|
|
22
33
|
});
|
|
23
34
|
});
|
|
@@ -1,39 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { SurfaceColor, SurfaceEmphasis } from '../../surfaceColor';
|
|
2
2
|
import type { SurfaceTheme } from '../../theme/types';
|
|
3
|
-
|
|
4
|
-
export type TextTone =
|
|
5
|
-
| 'default'
|
|
6
|
-
| 'muted'
|
|
7
|
-
| 'subtle'
|
|
8
|
-
| 'inverse'
|
|
9
|
-
| 'danger'
|
|
10
|
-
| 'success'
|
|
11
|
-
| 'warning';
|
|
12
|
-
export type TextColorValue = keyof SurfaceTheme['colors'] | string;
|
|
3
|
+
import { resolveSurfaceColor } from './resolveSurfaceColor';
|
|
13
4
|
|
|
14
5
|
export function resolveTextColor(
|
|
15
6
|
theme: SurfaceTheme,
|
|
16
|
-
|
|
17
|
-
color?:
|
|
7
|
+
emphasis: SurfaceEmphasis = 'default',
|
|
8
|
+
color?: SurfaceColor,
|
|
18
9
|
): string {
|
|
19
10
|
if (color) {
|
|
20
|
-
|
|
11
|
+
if (emphasis === 'inverse') {
|
|
12
|
+
return resolveSurfaceColor(theme, color).onSolidText;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return resolveSurfaceColor(theme, color).base;
|
|
21
16
|
}
|
|
22
17
|
|
|
23
|
-
switch (
|
|
18
|
+
switch (emphasis) {
|
|
24
19
|
case 'muted':
|
|
25
20
|
return theme.semantics.content.muted;
|
|
26
21
|
case 'subtle':
|
|
27
22
|
return theme.semantics.content.subtle;
|
|
28
23
|
case 'inverse':
|
|
29
24
|
return theme.semantics.content.inverse;
|
|
30
|
-
case 'danger':
|
|
31
|
-
return theme.semantics.danger.base;
|
|
32
|
-
case 'success':
|
|
33
|
-
return theme.semantics.success.base;
|
|
34
|
-
case 'warning':
|
|
35
|
-
return theme.semantics.warning.base;
|
|
36
|
-
case 'default':
|
|
37
25
|
default:
|
|
38
26
|
return theme.semantics.content.default;
|
|
39
27
|
}
|
|
@@ -39,6 +39,8 @@ export const Heading: React.FC<HeadingProps> = ({
|
|
|
39
39
|
children,
|
|
40
40
|
level = 2,
|
|
41
41
|
align,
|
|
42
|
+
color,
|
|
43
|
+
emphasis = 'default',
|
|
42
44
|
numberOfLines,
|
|
43
45
|
i18nKey,
|
|
44
46
|
testID,
|
|
@@ -52,7 +54,7 @@ export const Heading: React.FC<HeadingProps> = ({
|
|
|
52
54
|
accessibilityRole="header"
|
|
53
55
|
testID={testID}
|
|
54
56
|
numberOfLines={numberOfLines}
|
|
55
|
-
style={resolveHeadingTextStyle(theme, level, align)}
|
|
57
|
+
style={resolveHeadingTextStyle(theme, level, align, emphasis, color)}
|
|
56
58
|
>
|
|
57
59
|
{content}
|
|
58
60
|
</Text>
|
|
@@ -22,7 +22,7 @@ describe('resolveHeadingTextStyle', () => {
|
|
|
22
22
|
expect(style.fontFamily).toBe('SpaceGrotesk_700Regular');
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
it('shares the default content
|
|
25
|
+
it('shares the default content emphasis with the text primitive', () => {
|
|
26
26
|
const theme = createTheme();
|
|
27
27
|
const style = resolveHeadingTextStyle(theme, 2);
|
|
28
28
|
|
|
@@ -2,6 +2,7 @@ import type { TextStyle } from 'react-native';
|
|
|
2
2
|
|
|
3
3
|
import { resolveTextColor } from '../../internal/resolvers/resolveTextColor';
|
|
4
4
|
import { resolveTextStyles } from '../../internal/resolvers/resolveTextStyles';
|
|
5
|
+
import type { SurfaceColor, SurfaceEmphasis } from '../../surfaceColor';
|
|
5
6
|
import type { SurfaceTheme } from '../../theme/types';
|
|
6
7
|
import type { HeadingLevel, HeadingProps } from './types';
|
|
7
8
|
|
|
@@ -9,9 +10,11 @@ export function resolveHeadingTextStyle(
|
|
|
9
10
|
theme: SurfaceTheme,
|
|
10
11
|
level: HeadingLevel,
|
|
11
12
|
align?: HeadingProps['align'],
|
|
13
|
+
emphasis: SurfaceEmphasis = 'default',
|
|
14
|
+
color?: SurfaceColor,
|
|
12
15
|
): TextStyle {
|
|
13
16
|
return {
|
|
14
17
|
...resolveTextStyles(theme, { align, level }),
|
|
15
|
-
color: resolveTextColor(theme,
|
|
18
|
+
color: resolveTextColor(theme, emphasis, color),
|
|
16
19
|
};
|
|
17
20
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
|
|
3
|
+
import type { SurfaceColor, SurfaceEmphasis } from '../../surfaceColor';
|
|
4
|
+
|
|
3
5
|
export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
4
6
|
|
|
5
7
|
export interface HeadingProps {
|
|
@@ -7,6 +9,8 @@ export interface HeadingProps {
|
|
|
7
9
|
children?: React.ReactNode;
|
|
8
10
|
level?: HeadingLevel;
|
|
9
11
|
align?: 'auto' | 'left' | 'right' | 'center' | 'justify';
|
|
12
|
+
color?: SurfaceColor;
|
|
13
|
+
emphasis?: SurfaceEmphasis;
|
|
10
14
|
numberOfLines?: number;
|
|
11
15
|
i18nKey?: string;
|
|
12
16
|
testID?: string;
|
|
@@ -32,7 +32,7 @@ export function Text({
|
|
|
32
32
|
children,
|
|
33
33
|
i18nKey,
|
|
34
34
|
variant = 'body',
|
|
35
|
-
|
|
35
|
+
emphasis = 'default',
|
|
36
36
|
color,
|
|
37
37
|
align,
|
|
38
38
|
weight,
|
|
@@ -56,7 +56,7 @@ export function Text({
|
|
|
56
56
|
weight,
|
|
57
57
|
}),
|
|
58
58
|
{
|
|
59
|
-
color: resolveTextColor(theme,
|
|
59
|
+
color: resolveTextColor(theme, emphasis, color),
|
|
60
60
|
},
|
|
61
61
|
]}
|
|
62
62
|
>
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import type { TextStyle } from 'react-native';
|
|
3
3
|
|
|
4
|
-
import type { TextColorValue, TextTone } from '../../internal/resolvers/resolveTextColor';
|
|
5
4
|
import type { TextVariant, TextWeight } from '../../internal/resolvers/resolveTextStyles';
|
|
5
|
+
import type { SurfaceColor, SurfaceEmphasis } from '../../surfaceColor';
|
|
6
6
|
|
|
7
7
|
export interface TextProps {
|
|
8
8
|
children?: React.ReactNode;
|
|
9
9
|
i18nKey?: string;
|
|
10
10
|
variant?: TextVariant;
|
|
11
|
-
|
|
12
|
-
color?:
|
|
11
|
+
emphasis?: SurfaceEmphasis;
|
|
12
|
+
color?: SurfaceColor;
|
|
13
13
|
align?: TextStyle['textAlign'];
|
|
14
14
|
weight?: TextWeight;
|
|
15
15
|
italic?: boolean;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
|
|
3
|
+
import { describe, expect, it } from 'bun:test';
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
SurfaceColor,
|
|
7
|
+
SurfaceEmphasis,
|
|
8
|
+
SurfacePaletteColor,
|
|
9
|
+
SurfaceStatusColor,
|
|
10
|
+
} from './index';
|
|
11
|
+
import {
|
|
12
|
+
SURFACE_COLORS,
|
|
13
|
+
SURFACE_EMPHASES,
|
|
14
|
+
SURFACE_PALETTE_COLORS,
|
|
15
|
+
SURFACE_STATUS_COLORS,
|
|
16
|
+
} from './surfaceColor';
|
|
17
|
+
|
|
18
|
+
describe('surfaceColor public exports', () => {
|
|
19
|
+
it('exports canonical runtime color and emphasis lists from the root entrypoint', () => {
|
|
20
|
+
const indexSource = readFileSync(new URL('./index.ts', import.meta.url), 'utf8');
|
|
21
|
+
|
|
22
|
+
expect(indexSource).toContain("from './surfaceColor';");
|
|
23
|
+
expect(SURFACE_PALETTE_COLORS).toEqual([
|
|
24
|
+
'primary',
|
|
25
|
+
'secondary',
|
|
26
|
+
'tertiary',
|
|
27
|
+
'quaternary',
|
|
28
|
+
'neutral',
|
|
29
|
+
]);
|
|
30
|
+
expect(SURFACE_STATUS_COLORS).toEqual(['success', 'warning', 'error', 'info']);
|
|
31
|
+
expect(SURFACE_COLORS).toEqual([...SURFACE_PALETTE_COLORS, ...SURFACE_STATUS_COLORS, 'danger']);
|
|
32
|
+
expect(SURFACE_EMPHASES).toEqual(['default', 'muted', 'subtle', 'inverse']);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('keeps root-imported type contracts aligned with runtime lists', () => {
|
|
36
|
+
const paletteColor: SurfacePaletteColor = 'neutral';
|
|
37
|
+
const statusColor: SurfaceStatusColor = 'info';
|
|
38
|
+
const color: SurfaceColor = 'danger';
|
|
39
|
+
const emphasis: SurfaceEmphasis = 'muted';
|
|
40
|
+
|
|
41
|
+
expect(SURFACE_PALETTE_COLORS).toContain(paletteColor);
|
|
42
|
+
expect(SURFACE_STATUS_COLORS).toContain(statusColor);
|
|
43
|
+
expect(SURFACE_COLORS).toContain(color);
|
|
44
|
+
expect(SURFACE_EMPHASES).toContain(emphasis);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const SURFACE_PALETTE_COLORS = [
|
|
2
|
+
'primary',
|
|
3
|
+
'secondary',
|
|
4
|
+
'tertiary',
|
|
5
|
+
'quaternary',
|
|
6
|
+
'neutral',
|
|
7
|
+
] as const;
|
|
8
|
+
|
|
9
|
+
export const SURFACE_STATUS_COLORS = ['success', 'warning', 'error', 'info'] as const;
|
|
10
|
+
|
|
11
|
+
export const SURFACE_COLORS = [
|
|
12
|
+
...SURFACE_PALETTE_COLORS,
|
|
13
|
+
...SURFACE_STATUS_COLORS,
|
|
14
|
+
'danger',
|
|
15
|
+
] as const;
|
|
16
|
+
|
|
17
|
+
export const SURFACE_EMPHASES = ['default', 'muted', 'subtle', 'inverse'] as const;
|
|
18
|
+
|
|
19
|
+
export type SurfacePaletteColor = (typeof SURFACE_PALETTE_COLORS)[number];
|
|
20
|
+
export type SurfaceStatusColor = (typeof SURFACE_STATUS_COLORS)[number];
|
|
21
|
+
export type SurfaceColor = (typeof SURFACE_COLORS)[number];
|
|
22
|
+
export type SurfaceEmphasis = (typeof SURFACE_EMPHASES)[number];
|
|
@@ -31,6 +31,8 @@ function expectRequiredSemanticRoles(semantics: ThemeSemantics) {
|
|
|
31
31
|
expect(semantics.danger.base).toBeDefined();
|
|
32
32
|
expect(semantics.success.base).toBeDefined();
|
|
33
33
|
expect(semantics.warning.base).toBeDefined();
|
|
34
|
+
expect(semantics.error.base).toBeDefined();
|
|
35
|
+
expect(semantics.info.base).toBeDefined();
|
|
34
36
|
expect(semantics.surface.default).toBeDefined();
|
|
35
37
|
expect(semantics.content.default).toBeDefined();
|
|
36
38
|
expect(semantics.border.default).toBeDefined();
|
|
@@ -78,10 +80,14 @@ describe('colorEngine', () => {
|
|
|
78
80
|
expect(light.semantics.danger.base).toBe('#ef4444');
|
|
79
81
|
expect(light.semantics.success.base).toBe('#22c55e');
|
|
80
82
|
expect(light.semantics.warning.base).toBe('#f59e0b');
|
|
83
|
+
expect(light.semantics.error.base).toBe(light.semantics.danger.base);
|
|
84
|
+
expect(light.semantics.info.base).toBeDefined();
|
|
81
85
|
|
|
82
86
|
expect(dark.semantics.danger.base).toBe('#ef4444');
|
|
83
87
|
expect(dark.semantics.success.base).toBe('#22c55e');
|
|
84
88
|
expect(dark.semantics.warning.base).toBe('#f59e0b');
|
|
89
|
+
expect(dark.semantics.error.base).toBe(dark.semantics.danger.base);
|
|
90
|
+
expect(dark.semantics.info.base).toBeDefined();
|
|
85
91
|
});
|
|
86
92
|
|
|
87
93
|
it('uses mode-aware role semantics for dark mode soft states', () => {
|
package/src/theme/colorEngine.ts
CHANGED
|
@@ -137,6 +137,9 @@ export function generatePalette(
|
|
|
137
137
|
const danger = buildRoleSemantics(semanticStatusSwatches.danger, isDark);
|
|
138
138
|
const success = buildRoleSemantics(semanticStatusSwatches.success, isDark);
|
|
139
139
|
const warning = buildRoleSemantics(semanticStatusSwatches.warning, isDark);
|
|
140
|
+
// Keep destructive action and feedback error aligned until a dedicated error status swatch is introduced.
|
|
141
|
+
const error = danger;
|
|
142
|
+
const info = buildRoleSemantics(secondarySwatch, isDark);
|
|
140
143
|
|
|
141
144
|
const surfaceSemantics: SurfaceSemantics = {
|
|
142
145
|
default: neutral.surface,
|
|
@@ -168,14 +171,17 @@ export function generatePalette(
|
|
|
168
171
|
secondary: secondarySwatch[500],
|
|
169
172
|
accent: tertiarySwatch[500],
|
|
170
173
|
highlight: quaternarySwatch[500],
|
|
174
|
+
tertiary: tertiarySwatch[500],
|
|
175
|
+
quaternary: quaternarySwatch[500],
|
|
171
176
|
background: neutral.bg,
|
|
172
177
|
surface: neutral.surface,
|
|
173
178
|
text: neutral.text,
|
|
174
179
|
textSecondary: neutral.textMuted,
|
|
175
180
|
border: neutral.border,
|
|
176
|
-
error:
|
|
181
|
+
error: error.base,
|
|
177
182
|
success: success.base,
|
|
178
183
|
warning: warning.base,
|
|
184
|
+
info: info.base,
|
|
179
185
|
};
|
|
180
186
|
|
|
181
187
|
return {
|
|
@@ -190,6 +196,8 @@ export function generatePalette(
|
|
|
190
196
|
danger,
|
|
191
197
|
success,
|
|
192
198
|
warning,
|
|
199
|
+
error,
|
|
200
|
+
info,
|
|
193
201
|
surface: surfaceSemantics,
|
|
194
202
|
content,
|
|
195
203
|
border,
|
package/src/theme/types.ts
CHANGED
|
@@ -73,6 +73,8 @@ export interface ThemeSemantics {
|
|
|
73
73
|
danger: RoleSemantics;
|
|
74
74
|
success: RoleSemantics;
|
|
75
75
|
warning: RoleSemantics;
|
|
76
|
+
error: RoleSemantics;
|
|
77
|
+
info: RoleSemantics;
|
|
76
78
|
surface: SurfaceSemantics;
|
|
77
79
|
content: ContentSemantics;
|
|
78
80
|
border: BorderSemantics;
|
|
@@ -98,6 +100,8 @@ export interface ThemeTokens {
|
|
|
98
100
|
secondary: string;
|
|
99
101
|
accent: string;
|
|
100
102
|
highlight: string;
|
|
103
|
+
tertiary: string;
|
|
104
|
+
quaternary: string;
|
|
101
105
|
background: string;
|
|
102
106
|
surface: string;
|
|
103
107
|
text: string;
|
|
@@ -106,6 +110,7 @@ export interface ThemeTokens {
|
|
|
106
110
|
error: string;
|
|
107
111
|
success: string;
|
|
108
112
|
warning: string;
|
|
113
|
+
info: string;
|
|
109
114
|
[key: string]: string;
|
|
110
115
|
};
|
|
111
116
|
swatches: GeneratedThemeSwatches;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { RoleSemantics, SurfaceTheme } from '../../theme/types';
|
|
2
|
-
export type ComponentTone = 'primary' | 'neutral' | 'danger' | 'success' | 'warning';
|
|
3
|
-
export declare function resolveTone(theme: SurfaceTheme, tone?: ComponentTone): RoleSemantics;
|
|
4
|
-
//# sourceMappingURL=resolveTone.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolveTone.d.ts","sourceRoot":"","sources":["../../../src/internal/resolvers/resolveTone.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAErE,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAErF,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,GAAE,aAAyB,GAAG,aAAa,CAc/F"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export function resolveTone(theme, tone = 'primary') {
|
|
2
|
-
switch (tone) {
|
|
3
|
-
case 'neutral':
|
|
4
|
-
return theme.semantics.action.neutral;
|
|
5
|
-
case 'danger':
|
|
6
|
-
return theme.semantics.action.danger;
|
|
7
|
-
case 'success':
|
|
8
|
-
return theme.semantics.success;
|
|
9
|
-
case 'warning':
|
|
10
|
-
return theme.semantics.warning;
|
|
11
|
-
case 'primary':
|
|
12
|
-
default:
|
|
13
|
-
return theme.semantics.action.primary;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=resolveTone.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolveTone.js","sourceRoot":"","sources":["../../../src/internal/resolvers/resolveTone.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,WAAW,CAAC,KAAmB,EAAE,OAAsB,SAAS;IAC9E,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC;QACxC,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC;QACvC,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC;QACjC,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC;QACjC,KAAK,SAAS,CAAC;QACf;YACE,OAAO,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC;IAC1C,CAAC;AACH,CAAC","sourcesContent":["import type { RoleSemantics, SurfaceTheme } from '../../theme/types';\n\nexport type ComponentTone = 'primary' | 'neutral' | 'danger' | 'success' | 'warning';\n\nexport function resolveTone(theme: SurfaceTheme, tone: ComponentTone = 'primary'): RoleSemantics {\n switch (tone) {\n case 'neutral':\n return theme.semantics.action.neutral;\n case 'danger':\n return theme.semantics.action.danger;\n case 'success':\n return theme.semantics.success;\n case 'warning':\n return theme.semantics.warning;\n case 'primary':\n default:\n return theme.semantics.action.primary;\n }\n}\n"]}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { RoleSemantics, SurfaceTheme } from '../../theme/types';
|
|
2
|
-
|
|
3
|
-
export type ComponentTone = 'primary' | 'neutral' | 'danger' | 'success' | 'warning';
|
|
4
|
-
|
|
5
|
-
export function resolveTone(theme: SurfaceTheme, tone: ComponentTone = 'primary'): RoleSemantics {
|
|
6
|
-
switch (tone) {
|
|
7
|
-
case 'neutral':
|
|
8
|
-
return theme.semantics.action.neutral;
|
|
9
|
-
case 'danger':
|
|
10
|
-
return theme.semantics.action.danger;
|
|
11
|
-
case 'success':
|
|
12
|
-
return theme.semantics.success;
|
|
13
|
-
case 'warning':
|
|
14
|
-
return theme.semantics.warning;
|
|
15
|
-
case 'primary':
|
|
16
|
-
default:
|
|
17
|
-
return theme.semantics.action.primary;
|
|
18
|
-
}
|
|
19
|
-
}
|