mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 10:27:33 +00:00
* feat(mobile): give every corner one of three shapes Corners had drifted to 17 different radii, so a screen mixed 6 pt buttons, 14 pt cards, 12 pt groups and 4 pt badges. Every corner now comes from the shape of what it is: - control (12): anything you tap — buttons, icon buttons, fields, pickers, segmented controls, key caps. - surface (16): anything that holds content — cards, groups, sheets, banners, code boxes. Dialogs and the composer box use floating (24). - pill: badges, chips, status pills, dots, avatars and the composer's own round buttons. - tile (10) for icon squares and mark (4) for inline code and check squares; nested shapes take the parent's radius minus the gap. Every rounded style also asks for the continuous (squircle) corner curve; iOS draws it, Android and the web ignore it. * fix(mobile): keep circles and pills on the circular corner curve The continuous curve squares off a corner radius that reaches half the element's size, so the FAB, dots, avatars and the composer's round buttons stopped being round on iOS. * fix(mobile): put the anchored detail card on the surface radius * fix(mobile): keep the circular curve on unclipped bordered styles React Native strokes an unclipped visible border on a circular path while it fills the background with the continuous curve, so the two edges drifted apart at the corners.
113 lines
2.7 KiB
TypeScript
113 lines
2.7 KiB
TypeScript
import { Pressable, View } from 'react-native'
|
|
import { Monitor, Smartphone, type LucideIcon } from 'lucide-react-native'
|
|
import type { Translate } from '../i18n/mobile-i18n'
|
|
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
|
import { colors, radii } from '../theme/mobile-theme'
|
|
import { themedStyleSheet } from '../theme/themed-styles'
|
|
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
|
|
import type { MobileBrowserViewMode } from './browser-screencast-request'
|
|
|
|
type Props = {
|
|
disabled: boolean
|
|
value: MobileBrowserViewMode
|
|
onChange: (mode: MobileBrowserViewMode) => void
|
|
}
|
|
|
|
function viewModes(t: Translate): { id: MobileBrowserViewMode; label: string; icon: LucideIcon }[] {
|
|
return [
|
|
{
|
|
id: 'web',
|
|
label: t('browser.viewModeSwitch.webView', 'Show web website view'),
|
|
icon: Monitor
|
|
},
|
|
{
|
|
id: 'mobile',
|
|
label: t('browser.viewModeSwitch.mobileView', 'Show mobile website view'),
|
|
icon: Smartphone
|
|
}
|
|
]
|
|
}
|
|
|
|
export function MobileBrowserViewModeSwitch({
|
|
disabled,
|
|
value,
|
|
onChange
|
|
}: Props): React.JSX.Element {
|
|
const t = useMobileTranslation()
|
|
useMobileColorScheme()
|
|
return (
|
|
<View style={styles.switch}>
|
|
{viewModes(t).map((mode) => (
|
|
<ViewModeButton
|
|
key={mode.id}
|
|
Icon={mode.icon}
|
|
label={mode.label}
|
|
selected={value === mode.id}
|
|
disabled={disabled}
|
|
onPress={() => onChange(mode.id)}
|
|
/>
|
|
))}
|
|
</View>
|
|
)
|
|
}
|
|
|
|
function ViewModeButton({
|
|
Icon,
|
|
disabled,
|
|
label,
|
|
onPress,
|
|
selected
|
|
}: {
|
|
Icon: LucideIcon
|
|
disabled?: boolean
|
|
label: string
|
|
onPress: () => void
|
|
selected: boolean
|
|
}) {
|
|
useMobileColorScheme()
|
|
return (
|
|
<Pressable
|
|
style={({ pressed }) => [
|
|
styles.button,
|
|
selected && styles.buttonSelected,
|
|
pressed && !disabled && !selected && styles.buttonPressed,
|
|
disabled && styles.disabled
|
|
]}
|
|
disabled={disabled}
|
|
onPress={onPress}
|
|
accessibilityRole="button"
|
|
accessibilityState={{ selected, disabled }}
|
|
accessibilityLabel={label}
|
|
>
|
|
<Icon size={14} color={selected ? colors.bgBase : colors.textSecondary} />
|
|
</Pressable>
|
|
)
|
|
}
|
|
|
|
const styles = themedStyleSheet(() => ({
|
|
switch: {
|
|
minHeight: 28,
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
borderRadius: radii.control,
|
|
backgroundColor: colors.bgRaised,
|
|
padding: 2
|
|
},
|
|
button: {
|
|
minHeight: 24,
|
|
width: 32,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
borderRadius: radii.control
|
|
},
|
|
buttonPressed: {
|
|
backgroundColor: colors.borderSubtle
|
|
},
|
|
buttonSelected: {
|
|
backgroundColor: colors.textPrimary
|
|
},
|
|
disabled: {
|
|
opacity: 0.35
|
|
}
|
|
}))
|