@fountain-ui/core 3.0.0-alpha.46 → 3.0.0-alpha.48

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.
Files changed (46) hide show
  1. package/build/commonjs/Chip/Chip.js +4 -2
  2. package/build/commonjs/Chip/Chip.js.map +1 -1
  3. package/build/commonjs/Chip/ChipProps.js +3 -1
  4. package/build/commonjs/Chip/ChipProps.js.map +1 -1
  5. package/build/commonjs/Chip/index.js +6 -0
  6. package/build/commonjs/Chip/index.js.map +1 -1
  7. package/build/commonjs/Chip/useChipStyle.js +12 -5
  8. package/build/commonjs/Chip/useChipStyle.js.map +1 -1
  9. package/build/commonjs/Radio/Radio.js +6 -3
  10. package/build/commonjs/Radio/Radio.js.map +1 -1
  11. package/build/commonjs/TextField/TextField.js +9 -2
  12. package/build/commonjs/TextField/TextField.js.map +1 -1
  13. package/build/commonjs/TextField/TextFieldProps.js +3 -1
  14. package/build/commonjs/TextField/TextFieldProps.js.map +1 -1
  15. package/build/commonjs/TextField/useVariantStyleMap.js +29 -9
  16. package/build/commonjs/TextField/useVariantStyleMap.js.map +1 -1
  17. package/build/module/Chip/Chip.js +4 -2
  18. package/build/module/Chip/Chip.js.map +1 -1
  19. package/build/module/Chip/ChipProps.js +1 -0
  20. package/build/module/Chip/ChipProps.js.map +1 -1
  21. package/build/module/Chip/index.js +1 -1
  22. package/build/module/Chip/index.js.map +1 -1
  23. package/build/module/Chip/useChipStyle.js +12 -5
  24. package/build/module/Chip/useChipStyle.js.map +1 -1
  25. package/build/module/Radio/Radio.js +6 -3
  26. package/build/module/Radio/Radio.js.map +1 -1
  27. package/build/module/TextField/TextField.js +9 -2
  28. package/build/module/TextField/TextField.js.map +1 -1
  29. package/build/module/TextField/TextFieldProps.js +1 -0
  30. package/build/module/TextField/TextFieldProps.js.map +1 -1
  31. package/build/module/TextField/useVariantStyleMap.js +28 -9
  32. package/build/module/TextField/useVariantStyleMap.js.map +1 -1
  33. package/build/typescript/Chip/ChipProps.d.ts +7 -0
  34. package/build/typescript/Chip/index.d.ts +2 -2
  35. package/build/typescript/Chip/useChipStyle.d.ts +2 -2
  36. package/build/typescript/TextField/TextFieldProps.d.ts +13 -0
  37. package/build/typescript/TextField/useVariantStyleMap.d.ts +2 -2
  38. package/package.json +2 -2
  39. package/src/Chip/Chip.tsx +5 -2
  40. package/src/Chip/ChipProps.ts +9 -0
  41. package/src/Chip/index.ts +2 -2
  42. package/src/Chip/useChipStyle.ts +24 -8
  43. package/src/Radio/Radio.tsx +6 -3
  44. package/src/TextField/TextField.tsx +12 -1
  45. package/src/TextField/TextFieldProps.ts +16 -0
  46. package/src/TextField/useVariantStyleMap.ts +36 -11
package/src/Chip/index.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { default } from './Chip';
2
- export type { default as ChipProps } from './ChipProps';
3
- export { chipColors, chipSizes, chipStartElementVariants } from './ChipProps';
2
+ export type { default as ChipProps, ChipVariant } from './ChipProps';
3
+ export { chipColors, chipSizes, chipStartElementVariants, chipVariants } from './ChipProps';
@@ -3,7 +3,7 @@ import type { TextStyle } from 'react-native';
3
3
  import type { FountainUiStyle } from '@fountain-ui/styles';
4
4
  import type { SvgIconProps } from '../SvgIcon';
5
5
  import { createFontStyle, useTheme } from '../styles';
6
- import type { ChipColor, ChipSize, ChipStartElementVariant } from './ChipProps';
6
+ import type { ChipColor, ChipSize, ChipStartElementVariant, ChipVariant } from './ChipProps';
7
7
 
8
8
  interface ChipStyle {
9
9
  container: FountainUiStyle;
@@ -44,30 +44,46 @@ export default function useChipStyle(
44
44
  startElementVariant: ChipStartElementVariant,
45
45
  color: ChipColor,
46
46
  selected: boolean,
47
+ variant: ChipVariant = 'filled',
47
48
  ): ChipStyle {
48
49
  const theme = useTheme();
49
50
 
50
51
  return useMemo<ChipStyle>(() => {
52
+ const isOutlined = variant === 'outlined';
53
+
54
+ const textColor = selected
55
+ ? theme.palette.text.strongInverse
56
+ : isOutlined
57
+ ? theme.palette.text.base
58
+ : theme.palette.text.strong;
59
+
51
60
  const fontStyleMap: Record<ChipSize, TextStyle> = {
52
61
  small: createFontStyle(theme, {
53
62
  selector: (typography) => typography.caption1.medium,
54
- color: selected ? theme.palette.text.strongInverse : theme.palette.text.strong,
63
+ color: textColor,
55
64
  }),
56
65
  large: createFontStyle(theme, {
57
66
  selector: (typography) => typography.body2.medium,
58
- color: selected ? theme.palette.text.strongInverse : theme.palette.text.strong,
67
+ color: textColor,
59
68
  }),
60
69
  };
61
70
 
62
71
  const baseContainerStyle: FountainUiStyle = {
63
72
  alignItems: 'center',
64
- backgroundColor: selected ? theme.palette.fill.base
65
- : color === 'white'
66
- ? theme.palette.surface.base
67
- : theme.palette.fill.weaker,
73
+ backgroundColor: selected
74
+ ? theme.palette.fill.base
75
+ : isOutlined
76
+ ? 'transparent'
77
+ : color === 'white'
78
+ ? theme.palette.surface.base
79
+ : theme.palette.fill.weaker,
68
80
  borderRadius: theme.shape.radius.full,
69
81
  flexDirection: 'row',
70
82
  overflow: 'hidden',
83
+ ...(isOutlined && {
84
+ borderWidth: 1,
85
+ borderColor: theme.palette.border.weak,
86
+ }),
71
87
  };
72
88
 
73
89
  const isLarge = size === 'large';
@@ -145,5 +161,5 @@ export default function useChipStyle(
145
161
  startElement: variantStyleMap[startElementVariant]?.startElement,
146
162
  startElementContainer: variantStyleMap[startElementVariant]?.startElementContainer,
147
163
  };
148
- }, [theme, size, startElementVariant, color, selected]);
164
+ }, [theme, size, startElementVariant, color, selected, variant]);
149
165
  }
@@ -62,14 +62,15 @@ export default function Radio(props: RadioProps) {
62
62
  }
63
63
  };
64
64
 
65
- const isChecked = context?.value === value ?? checked;
65
+ const isChecked = context
66
+ ? context.value === value
67
+ : checked;
66
68
 
67
69
  const defaultCheckedIcon = (
68
70
  <CheckedIcon color={'accent'}/>
69
71
  );
70
72
 
71
73
  const checkedIcon = checkIconProp ?? defaultCheckedIcon;
72
- const icon = isChecked ? checkedIcon : null;
73
74
 
74
75
  const startIcon = cloneElementSafely(startIconProp, {
75
76
  color: 'strong',
@@ -120,7 +121,9 @@ export default function Radio(props: RadioProps) {
120
121
  ) : null}
121
122
  </Column>
122
123
 
123
- {icon}
124
+ <Column style={{ opacity: Number(isChecked) }}>
125
+ {checkedIcon}
126
+ </Column>
124
127
  </ButtonBase>
125
128
  );
126
129
  };
@@ -62,7 +62,9 @@ const TextField = React.forwardRef<TextInput, TextFieldProps>(function TextField
62
62
  multiline,
63
63
  editable = true,
64
64
  hint,
65
+ inputFontSize = 'large',
65
66
  isLoading,
67
+ maxLength,
66
68
  onBlur,
67
69
  onChangeText: onChangeTextProp,
68
70
  onFocus,
@@ -70,6 +72,7 @@ const TextField = React.forwardRef<TextInput, TextFieldProps>(function TextField
70
72
  placeholderTextColor: placeholderTextColorProp,
71
73
  secureTextEntry: secureTextEntryProp,
72
74
  showClearButton: showClearButtonProp,
75
+ showWordCounter = false,
73
76
  status = 'default' as TextFieldStatus,
74
77
  style: styleProp,
75
78
  title,
@@ -98,7 +101,7 @@ const TextField = React.forwardRef<TextInput, TextFieldProps>(function TextField
98
101
  }
99
102
  }, [ref]);
100
103
 
101
- const variantStyles = useVariantStyleMap(variant, status, isFocused);
104
+ const variantStyles = useVariantStyleMap(variant, status, isFocused, inputFontSize);
102
105
 
103
106
  const handleBlur = (event: NativeSyntheticEvent<TextInputFocusEventData>) => {
104
107
  setIsFocused(false);
@@ -206,6 +209,7 @@ const TextField = React.forwardRef<TextInput, TextFieldProps>(function TextField
206
209
  <TextInput
207
210
  autoFocus={autoFocus}
208
211
  editable={!disabled}
212
+ maxLength={maxLength}
209
213
  onBlur={handleBlur}
210
214
  onChangeText={handleChangeText}
211
215
  onFocus={handleFocus}
@@ -256,6 +260,13 @@ const TextField = React.forwardRef<TextInput, TextFieldProps>(function TextField
256
260
  ) : null}
257
261
  </Row>
258
262
 
263
+ {showWordCounter && maxLength && !isSearch ? (
264
+ <Text
265
+ children={`${value?.length ?? 0}/${maxLength}`}
266
+ style={variantStyles.hintStyle}
267
+ />
268
+ ) : null}
269
+
259
270
  {hint && !isSearch ? (
260
271
  <Text
261
272
  children={hint}
@@ -9,6 +9,9 @@ export type TextFieldStatus = typeof textFieldStatus[number];
9
9
  export const textFieldVariants = ['default', 'search'] as const;
10
10
  export type TextFieldVariant = typeof textFieldVariants[number];
11
11
 
12
+ export const textFieldInputFontSizes = ['large', 'small'] as const;
13
+ export type TextFieldInputFontSize = typeof textFieldInputFontSizes[number];
14
+
12
15
  export default interface TextFieldProps extends OverridableComponentProps<TextInputProps, {
13
16
  /**
14
17
  * Determines the style of the container that wraps the input.
@@ -47,4 +50,17 @@ export default interface TextFieldProps extends OverridableComponentProps<TextIn
47
50
  * @default default
48
51
  */
49
52
  variant?: TextFieldVariant;
53
+
54
+ /**
55
+ * Determines the font size of the input.
56
+ * @default large
57
+ */
58
+ inputFontSize?: TextFieldInputFontSize;
59
+
60
+ /**
61
+ * Determines whether to display the word counter below the input.
62
+ * Requires maxLength to be set.
63
+ * @default false
64
+ */
65
+ showWordCounter?: boolean;
50
66
  }> {}
@@ -3,7 +3,32 @@ import type { TextStyle } from 'react-native';
3
3
  import type { FountainUiStyle, Theme } from '@fountain-ui/styles';
4
4
  import { typographyOf } from '@fountain-ui/styles';
5
5
  import { createFontStyle, useTheme } from '../styles';
6
- import type { TextFieldStatus, TextFieldVariant } from './TextFieldProps';
6
+ import type { TextFieldInputFontSize, TextFieldStatus, TextFieldVariant } from './TextFieldProps';
7
+
8
+ const fontSizeStyleMap = {
9
+ large: {
10
+ fontSize: 18,
11
+ lineHeight: 27,
12
+ fontFamily: 'PretendardStd-SemiBold',
13
+ letterSpacing: 0,
14
+ },
15
+ small: {
16
+ fontSize: 14,
17
+ lineHeight: 21,
18
+ fontFamily: 'PretendardStd-Medium',
19
+ letterSpacing: 0,
20
+ },
21
+ } as const;
22
+
23
+ const containerPaddingMap = {
24
+ large: {
25
+ paddingVertical: 14,
26
+ },
27
+ small: {
28
+ paddingTop: 18,
29
+ paddingBottom: 16,
30
+ },
31
+ } as const;
7
32
 
8
33
  interface VariantStyleMap {
9
34
  containerStyle?: FountainUiStyle;
@@ -33,7 +58,12 @@ function useStatusColor(theme: Theme, status: TextFieldStatus): { borderColor: s
33
58
  }
34
59
  }
35
60
 
36
- export default function useVariantStyleMap(variant: TextFieldVariant, status: TextFieldStatus, isFocused: boolean): VariantStyleMap {
61
+ export default function useVariantStyleMap(
62
+ variant: TextFieldVariant,
63
+ status: TextFieldStatus,
64
+ isFocused: boolean,
65
+ inputFontSize: TextFieldInputFontSize = 'large',
66
+ ): VariantStyleMap {
37
67
  const theme = useTheme();
38
68
 
39
69
  const {
@@ -50,19 +80,14 @@ export default function useVariantStyleMap(variant: TextFieldVariant, status: Te
50
80
  borderBottomColor: status === 'default' && isFocused ? theme.palette.border.strong : borderColor,
51
81
  borderBottomWidth: 1,
52
82
  gap: 16,
53
- minHeight: 60,
54
- paddingVertical: 16,
83
+ minHeight: 54,
84
+ ...containerPaddingMap[inputFontSize],
55
85
  },
56
86
  inputStyle: {
57
87
  padding: 0,
58
88
  },
59
89
  inputFontStyle: createFontStyle(theme, {
60
- selector: (_) => typographyOf({
61
- fontSize: 18,
62
- lineHeight: 27,
63
- fontFamily: 'PretendardStd-SemiBold',
64
- letterSpacing: 0,
65
- }),
90
+ selector: (_) => typographyOf(fontSizeStyleMap[inputFontSize]),
66
91
  color: theme.palette.text.strong,
67
92
  }),
68
93
  hintStyle: {
@@ -98,5 +123,5 @@ export default function useVariantStyleMap(variant: TextFieldVariant, status: Te
98
123
  }),
99
124
  };
100
125
  }
101
- }, [theme, borderColor, hintColor, variant, isFocused]);
126
+ }, [theme, borderColor, hintColor, variant, isFocused, inputFontSize]);
102
127
  }