ki integration
This commit is contained in:
1 parent
82d98bd8cf
commit
9ecb292c26
78 files changed
+12055
-55
No files matched your search
@@ -0,0 +1,75 @@
|
||||
import { Pressable, StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
import { colors, radius, space, text } from '@/theme/tokens';
|
||||
|
||||
type Option<T extends string> = { wert: T; titel: string; erklaerung: string };
|
||||
|
||||
type Props<T extends string> = {
|
||||
label: string;
|
||||
optionen: Option<T>[];
|
||||
wert: T;
|
||||
aufWahl: (w: T) => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* Auswahl mit Erklärung je Option statt eines nackten Schalters.
|
||||
*
|
||||
* Bewusst so: „Zweck" und „Startwerte" beim Ordner entscheiden darüber, woraus
|
||||
* später generiert wird – wer sie nicht versteht, baut sich einen Ordner, der
|
||||
* nicht das tut, was er erwartet (konzept-bilder-feed.md §9).
|
||||
*/
|
||||
export function Wahl<T extends string>({ label, optionen, wert, aufWahl }: Props<T>) {
|
||||
return (
|
||||
<View style={s.block}>
|
||||
<Text style={s.label}>{label}</Text>
|
||||
<View style={s.optionen}>
|
||||
{optionen.map((o) => {
|
||||
const aktiv = o.wert === wert;
|
||||
return (
|
||||
<Pressable
|
||||
key={o.wert}
|
||||
onPress={() => aufWahl(o.wert)}
|
||||
accessibilityRole="radio"
|
||||
accessibilityState={{ selected: aktiv }}
|
||||
style={({ pressed }) => [s.opt, aktiv ? s.optAktiv : null, pressed ? s.gedrueckt : null]}>
|
||||
<View style={s.kopf}>
|
||||
<View style={[s.punkt, aktiv ? s.punktAktiv : null]}>
|
||||
{aktiv ? <View style={s.punktKern} /> : null}
|
||||
</View>
|
||||
<Text style={[s.titel, aktiv ? s.titelAktiv : null]}>{o.titel}</Text>
|
||||
</View>
|
||||
<Text style={s.erklaerung}>{o.erklaerung}</Text>
|
||||
</Pressable>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const s = StyleSheet.create({
|
||||
block: { gap: space.sm },
|
||||
label: { ...text.label, color: colors.mut },
|
||||
optionen: { gap: space.sm },
|
||||
opt: {
|
||||
backgroundColor: colors.surface,
|
||||
borderColor: colors.border,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderRadius: radius.md,
|
||||
padding: space.lg,
|
||||
gap: space.sm,
|
||||
},
|
||||
optAktiv: { borderColor: colors.accent, backgroundColor: 'rgba(255,92,57,0.08)' },
|
||||
gedrueckt: { opacity: 0.8 },
|
||||
kopf: { flexDirection: 'row', alignItems: 'center', gap: space.md },
|
||||
punkt: {
|
||||
width: 18, height: 18, borderRadius: 9,
|
||||
borderColor: colors.borderStrong, borderWidth: 1.5,
|
||||
alignItems: 'center', justifyContent: 'center',
|
||||
},
|
||||
punktAktiv: { borderColor: colors.accent },
|
||||
punktKern: { width: 9, height: 9, borderRadius: 5, backgroundColor: colors.accent },
|
||||
titel: { ...text.body, fontWeight: '600', color: colors.txt },
|
||||
titelAktiv: { color: colors.txt },
|
||||
erklaerung: { ...text.label, color: colors.mut, lineHeight: 18 },
|
||||
});
|
||||
Reference in new issue
Block a user