@helpwave/hightide-native 0.1.1 → 0.3.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/package.json +2 -2
- package/src/components/chat/ChatAttachmentMessageBubble.tsx +3 -0
- package/src/components/chat/ChatConversationRow.tsx +127 -27
- package/src/components/chat/ChatQuickReplyChip.tsx +7 -1
- package/src/components/chat/ChatThreadHeader.tsx +88 -48
- package/src/components/list/ListActionItem.tsx +60 -11
- package/src/components/list/ListItem.tsx +47 -21
- package/src/components/list/ListItemAccessory.tsx +34 -0
- package/src/components/list/ListItemTextContent.tsx +53 -0
- package/src/components/list/ListNavigationItem.tsx +60 -16
- package/src/components/list/index.ts +2 -0
- package/src/components/user-interaction/Button.tsx +6 -15
- package/src/components/user-interaction/IconButton.tsx +5 -7
- package/src/components/user-interaction/MultiSelect.tsx +72 -46
- package/src/components/user-interaction/Select.tsx +5 -1
- package/src/components/user-interaction/ThemedPressable.tsx +9 -4
- package/src/components/visualization-and-display/Chip.tsx +12 -5
- package/src/components/visualization-and-display/ThemedIcon.tsx +12 -8
- package/src/components/visualization-and-display/ThemedText.tsx +6 -2
- package/src/global-contexts/HightideProvider.tsx +9 -17
- package/src/global-contexts/content-theme/ContentThemeContext.ts +5 -2
- package/src/global-contexts/content-theme/ContentThemeProvider.tsx +64 -10
- package/src/global-contexts/theme/ThemeProvider.tsx +9 -4
- package/src/theme/adapters/index.ts +1 -4
- package/src/theme/adapters/style-adapter-utils.ts +433 -0
- package/src/theme/resolvers/avatar.ts +9 -10
- package/src/theme/resolvers/button.ts +6 -7
- package/src/theme/resolvers/card.ts +3 -2
- package/src/theme/resolvers/chat/attachment-message-bubble.ts +25 -37
- package/src/theme/resolvers/chat/conversation-list.ts +5 -4
- package/src/theme/resolvers/chat/conversation-row.ts +114 -14
- package/src/theme/resolvers/chat/date-divider.ts +4 -4
- package/src/theme/resolvers/chat/message-bubble.ts +9 -10
- package/src/theme/resolvers/chat/message-composer.ts +5 -6
- package/src/theme/resolvers/chat/message-list.ts +3 -2
- package/src/theme/resolvers/chat/quick-reply-chip.ts +12 -20
- package/src/theme/resolvers/chat/system-line.ts +5 -6
- package/src/theme/resolvers/chat/thread-header.ts +60 -12
- package/src/theme/resolvers/checkbox.ts +6 -6
- package/src/theme/resolvers/chip.ts +9 -4
- package/src/theme/resolvers/divider.ts +3 -3
- package/src/theme/resolvers/iconButton.ts +5 -10
- package/src/theme/resolvers/input.ts +12 -7
- package/src/theme/resolvers/listItem.ts +19 -16
- package/src/theme/resolvers/multiSelect.ts +23 -16
- package/src/theme/resolvers/searchBar.ts +14 -7
- package/src/theme/resolvers/select.ts +22 -15
- package/src/theme/resolvers/switch.ts +5 -4
- package/src/theme/resolvers/themedPressable.ts +10 -5
- package/src/theme/themes/createHightideTheme.ts +13 -4
- package/src/theme/types/components/chat.ts +63 -3
- package/src/theme/types/components/chip.ts +4 -0
- package/src/theme/types/components/iconButton.ts +1 -7
- package/src/theme/types/components/listItem.ts +5 -0
- package/src/theme/types/components/multiSelect.ts +1 -0
- package/src/theme/types/components/select.ts +1 -0
- package/src/theme/types/components/themedPressable.ts +4 -0
- package/src/theme/types/layout.ts +13 -7
- package/src/theme/types/semantics.ts +2 -1
- package/src/theme/types/theme.ts +40 -12
- package/src/theme/types/typography.ts +9 -4
- package/src/theme/adapters/container-adapter.ts +0 -323
- package/src/theme/adapters/defined.ts +0 -11
- package/src/theme/adapters/icon-style-adapter.ts +0 -10
- package/src/theme/adapters/text-style-adapter.ts +0 -16
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
import type { ColorPairToken } from '@helpwave/hightide-design/theme-tokens'
|
|
13
13
|
|
|
14
14
|
import { useTheme } from '../../global-contexts/theme/ThemeContext'
|
|
15
|
-
import { ThemedText } from '../visualization-and-display/ThemedText'
|
|
16
15
|
import type {
|
|
17
16
|
ListItemDescriptionStyle,
|
|
18
17
|
ListItemState,
|
|
@@ -20,29 +19,38 @@ import type {
|
|
|
20
19
|
ListItemTitleStyle
|
|
21
20
|
} from '../../theme/types/components/listItem'
|
|
22
21
|
import type { StyleOverwrite } from '../../theme/types/resolver'
|
|
22
|
+
import { ListItemAccessory } from './ListItemAccessory'
|
|
23
|
+
import {
|
|
24
|
+
ListItemTextContent,
|
|
25
|
+
type ListItemContentOrder
|
|
26
|
+
} from './ListItemTextContent'
|
|
23
27
|
|
|
24
28
|
export type ListItemProps = Omit<ViewProps, 'style'> & {
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
title?: string,
|
|
30
|
+
subtitle?: string,
|
|
31
|
+
content?: ReactNode,
|
|
32
|
+
contentOrder?: ListItemContentOrder,
|
|
27
33
|
leading?: ReactNode,
|
|
28
34
|
trailing?: ReactNode,
|
|
29
35
|
color?: ColorPairToken,
|
|
30
36
|
style?: StyleProp<ViewStyle>,
|
|
31
37
|
itemStyle?: StyleOverwrite<ListItemState, ListItemStyle>,
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
titleStyle?: StyleOverwrite<ListItemState, ListItemTitleStyle>,
|
|
39
|
+
subtitleStyle?: StyleOverwrite<ListItemState, ListItemDescriptionStyle>,
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
export const ListItem = ({
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
title,
|
|
44
|
+
subtitle,
|
|
45
|
+
content,
|
|
46
|
+
contentOrder = 'subtitleFirst',
|
|
39
47
|
leading,
|
|
40
48
|
trailing,
|
|
41
49
|
color,
|
|
42
50
|
style,
|
|
43
51
|
itemStyle,
|
|
44
|
-
|
|
45
|
-
|
|
52
|
+
titleStyle,
|
|
53
|
+
subtitleStyle,
|
|
46
54
|
...props
|
|
47
55
|
}: ListItemProps) => {
|
|
48
56
|
const { theme } = useTheme()
|
|
@@ -66,30 +74,48 @@ export const ListItem = ({
|
|
|
66
74
|
() => theme.components.listItem.default.trailingItemContainer(state),
|
|
67
75
|
[theme, state]
|
|
68
76
|
)
|
|
69
|
-
const
|
|
70
|
-
() => theme.components.listItem.default.
|
|
71
|
-
[theme, state,
|
|
77
|
+
const resolvedTitleStyle = useMemo(
|
|
78
|
+
() => theme.components.listItem.default.titleText(state, titleStyle),
|
|
79
|
+
[theme, state, titleStyle]
|
|
80
|
+
)
|
|
81
|
+
const resolvedSubtitleStyle = useMemo(
|
|
82
|
+
() => theme.components.listItem.default.descriptionText(state, subtitleStyle),
|
|
83
|
+
[theme, state, subtitleStyle]
|
|
72
84
|
)
|
|
73
|
-
const
|
|
74
|
-
() => theme.components.listItem.default.
|
|
75
|
-
[theme, state
|
|
85
|
+
const resolvedIconStyle = useMemo(
|
|
86
|
+
() => theme.components.listItem.default.icon(state),
|
|
87
|
+
[theme, state]
|
|
76
88
|
)
|
|
77
89
|
|
|
78
90
|
return (
|
|
79
91
|
<View {...props} style={[resolvedItemStyle, style]}>
|
|
80
92
|
{leading != null && (
|
|
81
|
-
<
|
|
93
|
+
<ListItemAccessory
|
|
94
|
+
style={resolvedLeadingItemContainerStyle}
|
|
95
|
+
foreground={color?.onColor}
|
|
96
|
+
iconStyle={resolvedIconStyle}
|
|
97
|
+
>
|
|
82
98
|
{leading}
|
|
83
|
-
</
|
|
99
|
+
</ListItemAccessory>
|
|
84
100
|
)}
|
|
85
101
|
<View style={resolvedContentStyle}>
|
|
86
|
-
<
|
|
87
|
-
|
|
102
|
+
<ListItemTextContent
|
|
103
|
+
title={title}
|
|
104
|
+
subtitle={subtitle}
|
|
105
|
+
content={content}
|
|
106
|
+
contentOrder={contentOrder}
|
|
107
|
+
titleStyle={resolvedTitleStyle}
|
|
108
|
+
subtitleStyle={resolvedSubtitleStyle}
|
|
109
|
+
/>
|
|
88
110
|
</View>
|
|
89
111
|
{trailing != null && (
|
|
90
|
-
<
|
|
112
|
+
<ListItemAccessory
|
|
113
|
+
style={resolvedTrailingItemContainerStyle}
|
|
114
|
+
foreground={color?.onColor}
|
|
115
|
+
iconStyle={resolvedIconStyle}
|
|
116
|
+
>
|
|
91
117
|
{trailing}
|
|
92
|
-
</
|
|
118
|
+
</ListItemAccessory>
|
|
93
119
|
)}
|
|
94
120
|
</View>
|
|
95
121
|
)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
type StyleProp,
|
|
5
|
+
type ViewStyle
|
|
6
|
+
} from 'react-native'
|
|
7
|
+
|
|
8
|
+
import type { HexColorToken } from '@helpwave/hightide-design/primitive-tokens'
|
|
9
|
+
|
|
10
|
+
import { ContentThemeOverrideProvider } from '../../global-contexts/content-theme/ContentThemeProvider'
|
|
11
|
+
import type { IconStyle } from '../../icons'
|
|
12
|
+
|
|
13
|
+
export type ListItemAccessoryProps = {
|
|
14
|
+
children: ReactNode,
|
|
15
|
+
style?: StyleProp<ViewStyle>,
|
|
16
|
+
foreground?: HexColorToken,
|
|
17
|
+
iconStyle: IconStyle,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const ListItemAccessory = ({
|
|
21
|
+
children,
|
|
22
|
+
style,
|
|
23
|
+
foreground,
|
|
24
|
+
iconStyle,
|
|
25
|
+
}: ListItemAccessoryProps) => (
|
|
26
|
+
<View style={style}>
|
|
27
|
+
<ContentThemeOverrideProvider
|
|
28
|
+
foreground={foreground}
|
|
29
|
+
iconStyle={iconStyle}
|
|
30
|
+
>
|
|
31
|
+
{children}
|
|
32
|
+
</ContentThemeOverrideProvider>
|
|
33
|
+
</View>
|
|
34
|
+
)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
import { Fragment } from 'react'
|
|
3
|
+
import type { StyleProp, TextStyle } from 'react-native'
|
|
4
|
+
|
|
5
|
+
import { ThemedText } from '../visualization-and-display/ThemedText'
|
|
6
|
+
|
|
7
|
+
export type ListItemContentOrder = 'titleFirst' | 'subtitleFirst'
|
|
8
|
+
|
|
9
|
+
export type ListItemTextContentProps = {
|
|
10
|
+
title?: string,
|
|
11
|
+
subtitle?: string,
|
|
12
|
+
content?: ReactNode,
|
|
13
|
+
contentOrder?: ListItemContentOrder,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const ListItemTextContent = ({
|
|
17
|
+
title,
|
|
18
|
+
subtitle,
|
|
19
|
+
content,
|
|
20
|
+
contentOrder = 'titleFirst',
|
|
21
|
+
titleStyle,
|
|
22
|
+
subtitleStyle,
|
|
23
|
+
}: ListItemTextContentProps & {
|
|
24
|
+
titleStyle?: StyleProp<TextStyle>,
|
|
25
|
+
subtitleStyle?: StyleProp<TextStyle>,
|
|
26
|
+
}) => {
|
|
27
|
+
if (content != null) {
|
|
28
|
+
return <>{content}</>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const titleNode = title != null
|
|
32
|
+
? <ThemedText style={titleStyle}>{title}</ThemedText>
|
|
33
|
+
: null
|
|
34
|
+
const subtitleNode = subtitle != null
|
|
35
|
+
? <ThemedText style={subtitleStyle}>{subtitle}</ThemedText>
|
|
36
|
+
: null
|
|
37
|
+
|
|
38
|
+
if (contentOrder === 'subtitleFirst') {
|
|
39
|
+
return (
|
|
40
|
+
<Fragment>
|
|
41
|
+
{subtitleNode}
|
|
42
|
+
{titleNode}
|
|
43
|
+
</Fragment>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Fragment>
|
|
49
|
+
{titleNode}
|
|
50
|
+
{subtitleNode}
|
|
51
|
+
</Fragment>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
@@ -14,22 +14,34 @@ import type { ColorPairToken } from '@helpwave/hightide-design/theme-tokens'
|
|
|
14
14
|
|
|
15
15
|
import { HightideIconRegistry } from '../../icons/HightideIconRegistry'
|
|
16
16
|
import { ThemedIcon } from '../visualization-and-display/ThemedIcon'
|
|
17
|
-
import {
|
|
17
|
+
import { useDebugContext } from '../../global-contexts/debug'
|
|
18
18
|
import { useTheme } from '../../global-contexts/theme/ThemeContext'
|
|
19
19
|
import type {
|
|
20
|
+
ListNavigationItemDescriptionStyle,
|
|
20
21
|
ListNavigationItemState,
|
|
21
22
|
ListNavigationItemStyle,
|
|
22
23
|
ListNavigationItemTitleStyle
|
|
23
24
|
} from '../../theme/types/components/listItem'
|
|
24
25
|
import type { StyleOverwrite } from '../../theme/types/resolver'
|
|
26
|
+
import { createHitBoxOverlayStyle } from '../../utils/hitBoxOverlay'
|
|
27
|
+
import { useMinimumTouchTargetHitSlop } from '../../utils/minimumTouchTargetHitSlop'
|
|
28
|
+
import { ListItemAccessory } from './ListItemAccessory'
|
|
29
|
+
import {
|
|
30
|
+
ListItemTextContent,
|
|
31
|
+
type ListItemContentOrder
|
|
32
|
+
} from './ListItemTextContent'
|
|
25
33
|
|
|
26
34
|
export type ListNavigationItemProps = Omit<PressableProps, 'children' | 'style'> & {
|
|
27
|
-
|
|
35
|
+
title?: string,
|
|
36
|
+
subtitle?: string,
|
|
37
|
+
content?: ReactNode,
|
|
38
|
+
contentOrder?: ListItemContentOrder,
|
|
28
39
|
leading?: ReactNode,
|
|
29
40
|
color?: ColorPairToken,
|
|
30
41
|
style?: StyleProp<ViewStyle>,
|
|
31
42
|
itemStyle?: StyleOverwrite<ListNavigationItemState, ListNavigationItemStyle>,
|
|
32
|
-
|
|
43
|
+
titleStyle?: StyleOverwrite<ListNavigationItemState, ListNavigationItemTitleStyle>,
|
|
44
|
+
subtitleStyle?: StyleOverwrite<ListNavigationItemState, ListNavigationItemDescriptionStyle>,
|
|
33
45
|
}
|
|
34
46
|
|
|
35
47
|
type PressableInteraction = {
|
|
@@ -40,16 +52,28 @@ type PressableInteraction = {
|
|
|
40
52
|
}
|
|
41
53
|
|
|
42
54
|
export const ListNavigationItem = ({
|
|
43
|
-
|
|
55
|
+
title,
|
|
56
|
+
subtitle,
|
|
57
|
+
content,
|
|
58
|
+
contentOrder = 'titleFirst',
|
|
44
59
|
leading,
|
|
45
60
|
color,
|
|
46
61
|
disabled,
|
|
47
62
|
style,
|
|
48
63
|
itemStyle,
|
|
49
|
-
|
|
64
|
+
titleStyle,
|
|
65
|
+
subtitleStyle,
|
|
66
|
+
hitSlop: providedHitSlop,
|
|
67
|
+
onLayout: providedOnLayout,
|
|
50
68
|
...props
|
|
51
69
|
}: ListNavigationItemProps) => {
|
|
52
70
|
const { theme } = useTheme()
|
|
71
|
+
const { hitBox } = useDebugContext()
|
|
72
|
+
const { hitSlop, onLayout } = useMinimumTouchTargetHitSlop({
|
|
73
|
+
touchTargetSize: theme.semantics.touchTargetSize({}),
|
|
74
|
+
hitSlop: providedHitSlop,
|
|
75
|
+
onLayout: providedOnLayout,
|
|
76
|
+
})
|
|
53
77
|
|
|
54
78
|
const resolveState = (interaction: PressableInteraction): ListNavigationItemState => ({
|
|
55
79
|
color,
|
|
@@ -64,6 +88,8 @@ export const ListNavigationItem = ({
|
|
|
64
88
|
<Pressable
|
|
65
89
|
{...props}
|
|
66
90
|
disabled={disabled}
|
|
91
|
+
hitSlop={hitSlop}
|
|
92
|
+
onLayout={onLayout}
|
|
67
93
|
style={(pressableState) => {
|
|
68
94
|
const state = resolveState(pressableState as PressableInteraction)
|
|
69
95
|
return [theme.components.listItem.navigation.container(state, itemStyle), style]
|
|
@@ -74,26 +100,44 @@ export const ListNavigationItem = ({
|
|
|
74
100
|
const resolvedLeadingItemContainerStyle = theme.components.listItem.navigation.leadingItemContainer(state)
|
|
75
101
|
const resolvedContentStyle = theme.components.listItem.navigation.content(state)
|
|
76
102
|
const resolvedTrailingItemContainerStyle = theme.components.listItem.navigation.trailingItemContainer(state)
|
|
77
|
-
const
|
|
78
|
-
const
|
|
103
|
+
const resolvedTitleStyle = theme.components.listItem.navigation.titleText(state, titleStyle)
|
|
104
|
+
const resolvedSubtitleStyle = theme.components.listItem.navigation.descriptionText(state, subtitleStyle)
|
|
105
|
+
const resolvedIconStyle = theme.components.listItem.navigation.icon(state)
|
|
79
106
|
|
|
80
107
|
return (
|
|
81
108
|
<Fragment>
|
|
109
|
+
{hitBox.isVisualizing && (
|
|
110
|
+
<View
|
|
111
|
+
pointerEvents="none"
|
|
112
|
+
style={createHitBoxOverlayStyle(hitSlop, hitBox.color)}
|
|
113
|
+
/>
|
|
114
|
+
)}
|
|
82
115
|
{leading != null && (
|
|
83
|
-
<
|
|
116
|
+
<ListItemAccessory
|
|
117
|
+
style={resolvedLeadingItemContainerStyle}
|
|
118
|
+
foreground={color?.onColor}
|
|
119
|
+
iconStyle={resolvedIconStyle}
|
|
120
|
+
>
|
|
84
121
|
{leading}
|
|
85
|
-
</
|
|
122
|
+
</ListItemAccessory>
|
|
86
123
|
)}
|
|
87
124
|
<View style={resolvedContentStyle}>
|
|
88
|
-
<
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
125
|
+
<ListItemTextContent
|
|
126
|
+
title={title}
|
|
127
|
+
subtitle={subtitle}
|
|
128
|
+
content={content}
|
|
129
|
+
contentOrder={contentOrder}
|
|
130
|
+
titleStyle={resolvedTitleStyle}
|
|
131
|
+
subtitleStyle={resolvedSubtitleStyle}
|
|
95
132
|
/>
|
|
96
133
|
</View>
|
|
134
|
+
<ListItemAccessory
|
|
135
|
+
style={resolvedTrailingItemContainerStyle}
|
|
136
|
+
foreground={color?.onColor}
|
|
137
|
+
iconStyle={resolvedIconStyle}
|
|
138
|
+
>
|
|
139
|
+
<ThemedIcon icon={HightideIconRegistry.ChevronRight} />
|
|
140
|
+
</ListItemAccessory>
|
|
97
141
|
</Fragment>
|
|
98
142
|
)
|
|
99
143
|
}}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import type { ColorPairToken } from '@helpwave/hightide-design/theme-tokens'
|
|
11
11
|
import type { ComponentSize, ButtonVariant } from '@helpwave/hightide-design/semantic-token-resolvers'
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import { ContentThemeOverrideProvider } from '../../global-contexts/content-theme/ContentThemeProvider'
|
|
14
14
|
import { useDebugContext } from '../../global-contexts/debug'
|
|
15
15
|
import { useTheme } from '../../global-contexts/theme/ThemeContext'
|
|
16
16
|
import type { IconComponent } from '../../icons/types'
|
|
@@ -20,7 +20,6 @@ import type {
|
|
|
20
20
|
ButtonTextStyle
|
|
21
21
|
} from '../../theme/types/components/button'
|
|
22
22
|
import type { StyleOverwrite } from '../../theme/types/resolver'
|
|
23
|
-
import type { Color } from '../../theme/types/color'
|
|
24
23
|
import { createHitBoxOverlayStyle } from '../../utils/hitBoxOverlay'
|
|
25
24
|
import { useMinimumTouchTargetHitSlop } from '../../utils/minimumTouchTargetHitSlop'
|
|
26
25
|
import { ThemedIcon } from '../visualization-and-display/ThemedIcon'
|
|
@@ -122,26 +121,18 @@ export const Button = forwardRef<React.ComponentRef<typeof Pressable>, ButtonPro
|
|
|
122
121
|
pointerEvents="none"
|
|
123
122
|
style={theme.components.button.stateLayer(state, stateLayerStyle)}
|
|
124
123
|
/>
|
|
125
|
-
<
|
|
126
|
-
foregroundColor={resolvedText.color as Color}
|
|
124
|
+
<ContentThemeOverrideProvider
|
|
127
125
|
textStyle={resolvedText}
|
|
126
|
+
iconStyle={resolvedIcon}
|
|
128
127
|
>
|
|
129
128
|
{leadingIcon !== undefined && (
|
|
130
|
-
<ThemedIcon
|
|
131
|
-
icon={leadingIcon}
|
|
132
|
-
size={resolvedIcon.size}
|
|
133
|
-
strokeWidth={resolvedIcon.strokeWidth}
|
|
134
|
-
/>
|
|
129
|
+
<ThemedIcon icon={leadingIcon} />
|
|
135
130
|
)}
|
|
136
131
|
<ThemedText>{children}</ThemedText>
|
|
137
132
|
{trailingIcon !== undefined && (
|
|
138
|
-
<ThemedIcon
|
|
139
|
-
icon={trailingIcon}
|
|
140
|
-
size={resolvedIcon.size}
|
|
141
|
-
strokeWidth={resolvedIcon.strokeWidth}
|
|
142
|
-
/>
|
|
133
|
+
<ThemedIcon icon={trailingIcon} />
|
|
143
134
|
)}
|
|
144
|
-
</
|
|
135
|
+
</ContentThemeOverrideProvider>
|
|
145
136
|
</Fragment>
|
|
146
137
|
)
|
|
147
138
|
}}
|
|
@@ -12,7 +12,7 @@ import type {
|
|
|
12
12
|
IconButtonVariant
|
|
13
13
|
} from '@helpwave/hightide-design/semantic-token-resolvers'
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import { ContentThemeOverrideProvider } from '../../global-contexts/content-theme/ContentThemeProvider'
|
|
16
16
|
import { useDebugContext } from '../../global-contexts/debug'
|
|
17
17
|
import { useTheme } from '../../global-contexts/theme/ThemeContext'
|
|
18
18
|
import type {
|
|
@@ -105,7 +105,6 @@ export const IconButton = forwardRef<React.ComponentRef<typeof Pressable>, IconB
|
|
|
105
105
|
{(pressableState) => {
|
|
106
106
|
const state = resolveState(pressableState as PressableInteraction)
|
|
107
107
|
const resolvedIcon = theme.components.iconButton.icon(state)
|
|
108
|
-
const resolvedText = theme.components.iconButton.text(state)
|
|
109
108
|
|
|
110
109
|
return (
|
|
111
110
|
<Fragment>
|
|
@@ -119,12 +118,11 @@ export const IconButton = forwardRef<React.ComponentRef<typeof Pressable>, IconB
|
|
|
119
118
|
pointerEvents="none"
|
|
120
119
|
style={theme.components.iconButton.stateLayer(state, stateLayerStyle)}
|
|
121
120
|
/>
|
|
122
|
-
<
|
|
123
|
-
|
|
124
|
-
textStyle={resolvedText}
|
|
121
|
+
<ContentThemeOverrideProvider
|
|
122
|
+
iconStyle={resolvedIcon}
|
|
125
123
|
>
|
|
126
|
-
<ThemedIcon icon={IconComponent}
|
|
127
|
-
</
|
|
124
|
+
<ThemedIcon icon={IconComponent} />
|
|
125
|
+
</ContentThemeOverrideProvider>
|
|
128
126
|
</Fragment>
|
|
129
127
|
)
|
|
130
128
|
}}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useMemo } from 'react'
|
|
1
|
+
import { Fragment, useMemo } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
FlatList,
|
|
4
4
|
Modal,
|
|
@@ -128,44 +128,72 @@ export const MultiSelect = ({
|
|
|
128
128
|
})
|
|
129
129
|
}}
|
|
130
130
|
>
|
|
131
|
-
{
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
131
|
+
{(pressableState) => {
|
|
132
|
+
const interaction = pressableState as {
|
|
133
|
+
pressed: boolean,
|
|
134
|
+
hovered?: boolean,
|
|
135
|
+
focused?: boolean,
|
|
136
|
+
focusVisible?: boolean,
|
|
137
|
+
}
|
|
138
|
+
const triggerState = {
|
|
139
|
+
...state,
|
|
140
|
+
isPressed: interaction.pressed,
|
|
141
|
+
isHovered: !!interaction.hovered,
|
|
142
|
+
isFocused: !!interaction.focused,
|
|
143
|
+
isFocusVisible: !!interaction.focusVisible,
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
<Fragment>
|
|
148
|
+
<View
|
|
149
|
+
pointerEvents="none"
|
|
150
|
+
style={multiSelectTheme.stateLayer(triggerState)}
|
|
151
|
+
/>
|
|
152
|
+
{selectedOptions.length > 0
|
|
153
|
+
? (
|
|
154
|
+
<View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 6, flex: 1 }}>
|
|
155
|
+
{selectedOptions.map((option) => (
|
|
156
|
+
<Chip key={option.id} size="md" color={color} variant="tonal">
|
|
157
|
+
<ThemedText>{option.label ?? option.id}</ThemedText>
|
|
158
|
+
{!state.isReadonly && (
|
|
159
|
+
<View
|
|
160
|
+
style={{
|
|
161
|
+
position: 'relative',
|
|
162
|
+
width: theme.icongraphy.sizes.sm,
|
|
163
|
+
}}
|
|
164
|
+
>
|
|
165
|
+
<IconButton
|
|
166
|
+
accessibilityLabel={translation('remove')}
|
|
167
|
+
size="sm"
|
|
168
|
+
color={theme.colors.negative}
|
|
169
|
+
variant="foreground"
|
|
170
|
+
disabled={!interactive}
|
|
171
|
+
onPress={() => multiSelect.toggleSelection(option.id, false)}
|
|
172
|
+
style={{
|
|
173
|
+
position: 'absolute',
|
|
174
|
+
left: '50%',
|
|
175
|
+
top: '50%',
|
|
176
|
+
transform: [
|
|
177
|
+
{ translateX: '-50%' },
|
|
178
|
+
{ translateY: '-50%' },
|
|
179
|
+
],
|
|
180
|
+
}}
|
|
181
|
+
icon={HightideIconRegistry.X}
|
|
182
|
+
/>
|
|
183
|
+
</View>
|
|
184
|
+
)}
|
|
185
|
+
</Chip>
|
|
186
|
+
))}
|
|
187
|
+
</View>
|
|
188
|
+
)
|
|
189
|
+
: (
|
|
190
|
+
<ThemedText style={multiSelectTheme.triggerText(triggerState)}>
|
|
191
|
+
{placeholder}
|
|
192
|
+
</ThemedText>
|
|
193
|
+
)}
|
|
194
|
+
</Fragment>
|
|
167
195
|
)
|
|
168
|
-
|
|
196
|
+
}}
|
|
169
197
|
</Pressable>
|
|
170
198
|
|
|
171
199
|
<Modal
|
|
@@ -224,19 +252,17 @@ export const MultiSelect = ({
|
|
|
224
252
|
|
|
225
253
|
return (
|
|
226
254
|
<ListActionItem
|
|
227
|
-
|
|
255
|
+
title={item.label ?? item.id}
|
|
228
256
|
color={optionColor}
|
|
229
257
|
disabled={item.disabled}
|
|
230
258
|
onPress={() => multiSelect.toggleSelection(item.id)}
|
|
231
259
|
leading={(
|
|
232
260
|
<View style={multiSelectTheme.checkbox(optionState)}>
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
/>
|
|
239
|
-
)}
|
|
261
|
+
<ThemedIcon
|
|
262
|
+
icon={HightideIconRegistry.Check}
|
|
263
|
+
size="sm"
|
|
264
|
+
color={checkboxIcon.color}
|
|
265
|
+
/>
|
|
240
266
|
</View>
|
|
241
267
|
)}
|
|
242
268
|
/>
|
|
@@ -149,6 +149,10 @@ export const Select = ({
|
|
|
149
149
|
|
|
150
150
|
return (
|
|
151
151
|
<Fragment>
|
|
152
|
+
<View
|
|
153
|
+
pointerEvents="none"
|
|
154
|
+
style={selectTheme.stateLayer(triggerState)}
|
|
155
|
+
/>
|
|
152
156
|
<ThemedText style={[selectTheme.triggerText(triggerState), { flex: 1 }]}>
|
|
153
157
|
{selectedLabel}
|
|
154
158
|
</ThemedText>
|
|
@@ -212,7 +216,7 @@ export const Select = ({
|
|
|
212
216
|
|
|
213
217
|
return (
|
|
214
218
|
<ListActionItem
|
|
215
|
-
|
|
219
|
+
title={item.label ?? item.id}
|
|
216
220
|
color={optionColor}
|
|
217
221
|
disabled={item.disabled}
|
|
218
222
|
onPress={() => select.selectValue(item.id)}
|
|
@@ -12,10 +12,11 @@ import type {
|
|
|
12
12
|
} from '@helpwave/hightide-design/semantic-token-resolvers'
|
|
13
13
|
import type { ColorPairToken } from '@helpwave/hightide-design/theme-tokens'
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import { ContentThemeOverrideProvider } from '../../global-contexts/content-theme/ContentThemeProvider'
|
|
16
16
|
import { useDebugContext } from '../../global-contexts/debug'
|
|
17
17
|
import { useTheme } from '../../global-contexts/theme/ThemeContext'
|
|
18
18
|
import type {
|
|
19
|
+
ThemedPressableIconStyle,
|
|
19
20
|
ThemedPressableState,
|
|
20
21
|
ThemedPressableStyle,
|
|
21
22
|
ThemedPressableTextStyle
|
|
@@ -40,6 +41,7 @@ export type ThemedPressableProps = PressableProps & {
|
|
|
40
41
|
hasAdditionalHorizontalPadding?: boolean,
|
|
41
42
|
containerStyle?: StyleOverwrite<ThemedPressableState, ThemedPressableStyle>,
|
|
42
43
|
stateLayerStyle?: StyleOverwrite<ThemedPressableState, ThemedPressableStyle>,
|
|
44
|
+
iconStyle?: StyleOverwrite<ThemedPressableState, ThemedPressableIconStyle>,
|
|
43
45
|
textStyle?: StyleOverwrite<ThemedPressableState, ThemedPressableTextStyle>,
|
|
44
46
|
}
|
|
45
47
|
|
|
@@ -61,6 +63,7 @@ export const ThemedPressable = forwardRef<React.ComponentRef<typeof Pressable>,
|
|
|
61
63
|
style,
|
|
62
64
|
containerStyle,
|
|
63
65
|
stateLayerStyle,
|
|
66
|
+
iconStyle,
|
|
64
67
|
textStyle,
|
|
65
68
|
hitSlop: providedHitSlop,
|
|
66
69
|
onLayout: providedOnLayout,
|
|
@@ -106,6 +109,7 @@ export const ThemedPressable = forwardRef<React.ComponentRef<typeof Pressable>,
|
|
|
106
109
|
{(pressableState) => {
|
|
107
110
|
const state = resolveState(pressableState as PressableInteraction)
|
|
108
111
|
const resolvedText = theme.components.themedPressable.text(state, textStyle)
|
|
112
|
+
const resolvedIcon = theme.components.themedPressable.icon(state, iconStyle)
|
|
109
113
|
const resolvedChildren = typeof children === 'function'
|
|
110
114
|
? children(pressableState)
|
|
111
115
|
: children
|
|
@@ -122,12 +126,13 @@ export const ThemedPressable = forwardRef<React.ComponentRef<typeof Pressable>,
|
|
|
122
126
|
pointerEvents="none"
|
|
123
127
|
style={theme.components.themedPressable.stateLayer(state, stateLayerStyle)}
|
|
124
128
|
/>
|
|
125
|
-
<
|
|
126
|
-
|
|
129
|
+
<ContentThemeOverrideProvider
|
|
130
|
+
foreground={resolvedText.color}
|
|
127
131
|
textStyle={resolvedText}
|
|
132
|
+
iconStyle={resolvedIcon}
|
|
128
133
|
>
|
|
129
134
|
{resolvedChildren}
|
|
130
|
-
</
|
|
135
|
+
</ContentThemeOverrideProvider>
|
|
131
136
|
</Fragment>
|
|
132
137
|
)
|
|
133
138
|
}}
|