@korsolutions/ui 0.0.11 → 0.0.13

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 (58) hide show
  1. package/README.md +2 -0
  2. package/dist/components/index.d.mts +70 -15
  3. package/dist/components/index.mjs +269 -38
  4. package/dist/{index-Cq_-PiOm.d.mts → index-_E4x_kNB.d.mts} +95 -6
  5. package/dist/index.d.mts +5 -3
  6. package/dist/index.mjs +1 -1
  7. package/dist/primitives/index.d.mts +2 -2
  8. package/dist/primitives/index.mjs +2 -2
  9. package/dist/{primitives-C2enZ5Ku.mjs → primitives-DQMWXbuX.mjs} +121 -4
  10. package/dist/{themes-D5iq6sfL.mjs → themes-DXcjBdO2.mjs} +4 -2
  11. package/package.json +7 -4
  12. package/src/components/avatar/avatar.tsx +23 -0
  13. package/src/components/avatar/variants/default.tsx +30 -0
  14. package/src/components/avatar/variants/index.ts +5 -0
  15. package/src/components/button/variants/default.tsx +9 -3
  16. package/src/components/button/variants/index.ts +2 -0
  17. package/src/components/button/variants/secondary.tsx +58 -0
  18. package/src/components/card/variants/default.tsx +2 -2
  19. package/src/components/empty/empty.tsx +26 -0
  20. package/src/components/empty/variants/default.tsx +35 -0
  21. package/src/components/empty/variants/index.ts +5 -0
  22. package/src/components/field/variants/default.tsx +4 -4
  23. package/src/components/index.ts +3 -1
  24. package/src/components/input/variants/default.tsx +2 -1
  25. package/src/components/link/variants/default.tsx +2 -2
  26. package/src/components/select/variants/default.tsx +4 -4
  27. package/src/components/typography/typography.tsx +13 -0
  28. package/src/components/typography/variants/body-lg.tsx +13 -0
  29. package/src/components/{text/variants/default.tsx → typography/variants/body-md.tsx} +3 -3
  30. package/src/components/typography/variants/body-sm.tsx +13 -0
  31. package/src/components/typography/variants/heading-lg.tsx +14 -0
  32. package/src/components/typography/variants/heading-md.tsx +14 -0
  33. package/src/components/typography/variants/heading-sm.tsx +14 -0
  34. package/src/components/typography/variants/index.ts +15 -0
  35. package/src/primitives/avatar/avatar-fallback.tsx +16 -0
  36. package/src/primitives/avatar/avatar-image.tsx +17 -0
  37. package/src/primitives/avatar/avatar-root.tsx +21 -0
  38. package/src/primitives/avatar/context.ts +16 -0
  39. package/src/primitives/avatar/index.ts +14 -0
  40. package/src/primitives/avatar/types.ts +9 -0
  41. package/src/primitives/button/button-root.tsx +9 -4
  42. package/src/primitives/button/types.ts +1 -1
  43. package/src/primitives/empty/context.ts +16 -0
  44. package/src/primitives/empty/empty-description.tsx +16 -0
  45. package/src/primitives/empty/empty-media.tsx +16 -0
  46. package/src/primitives/empty/empty-root.tsx +21 -0
  47. package/src/primitives/empty/empty-title.tsx +16 -0
  48. package/src/primitives/empty/index.ts +17 -0
  49. package/src/primitives/empty/types.ts +11 -0
  50. package/src/primitives/index.ts +2 -0
  51. package/src/themes/default/index.ts +1 -0
  52. package/src/themes/provider.tsx +3 -1
  53. package/src/themes/types.ts +2 -0
  54. package/src/utils/hsla-utils.ts +26 -0
  55. package/src/utils/use-themed-styles.ts +3 -1
  56. package/tsconfig.json +1 -0
  57. package/src/components/text/text.tsx +0 -13
  58. package/src/components/text/variants/index.ts +0 -5
@@ -3,25 +3,25 @@ import { useThemedStyles } from "@/utils/use-themed-styles";
3
3
 
4
4
  export const useFieldVariantDefault = (): FieldStyles => {
5
5
  return useThemedStyles(
6
- ({ colors, fontFamily }): FieldStyles => ({
6
+ ({ colors, fontFamily, fontSize }): FieldStyles => ({
7
7
  root: {
8
8
  flexDirection: "column",
9
9
  gap: 8,
10
10
  },
11
11
  label: {
12
12
  fontFamily,
13
- fontSize: 14,
13
+ fontSize: fontSize * 0.875,
14
14
  fontWeight: "600",
15
15
  color: colors.foreground,
16
16
  },
17
17
  description: {
18
18
  fontFamily,
19
- fontSize: 14,
19
+ fontSize: fontSize * 0.875,
20
20
  color: colors.mutedForeground,
21
21
  },
22
22
  error: {
23
23
  fontFamily,
24
- fontSize: 14,
24
+ fontSize: fontSize * 0.875,
25
25
  color: colors.danger,
26
26
  },
27
27
  })
@@ -3,5 +3,7 @@ export * from "./card/card";
3
3
  export * from "./input/input";
4
4
  export * from "./field/field";
5
5
  export * from "./select/select";
6
- export * from "./text/text";
6
+ export * from "./typography/typography";
7
7
  export * from "./link/link";
8
+ export * from "./empty/empty";
9
+ export * from "./avatar/avatar";
@@ -3,7 +3,7 @@ import { useThemedStyles } from "@/utils/use-themed-styles";
3
3
 
4
4
  export function useInputVariantDefault(): InputStyles {
5
5
  return useThemedStyles(
6
- ({ colors, radius, fontFamily }): InputStyles => ({
6
+ ({ colors, radius, fontFamily, fontSize }): InputStyles => ({
7
7
  default: {
8
8
  placeholderTextColor: colors.mutedForeground,
9
9
  selectionColor: colors.primary,
@@ -16,6 +16,7 @@ export function useInputVariantDefault(): InputStyles {
16
16
  paddingHorizontal: 16,
17
17
  outlineWidth: 0,
18
18
  fontFamily,
19
+ fontSize,
19
20
  height: 48,
20
21
  color: colors.foreground,
21
22
  },
@@ -3,9 +3,9 @@ import { TextStyle } from "react-native";
3
3
 
4
4
  export function useLinkVariantDefault(): TextStyle {
5
5
  return useThemedStyles(
6
- ({ colors, fontFamily, letterSpacing }): TextStyle => ({
6
+ ({ colors, fontFamily, letterSpacing, fontSize }): TextStyle => ({
7
7
  color: colors.primary,
8
- fontSize: 16,
8
+ fontSize,
9
9
  fontFamily,
10
10
  textDecorationLine: "underline",
11
11
  letterSpacing,
@@ -3,7 +3,7 @@ import { useThemedStyles } from "@/utils/use-themed-styles";
3
3
 
4
4
  export function useSelectVariantDefault(): SelectStyles {
5
5
  return useThemedStyles(
6
- ({ colors, radius, fontFamily }): SelectStyles => ({
6
+ ({ colors, radius, fontFamily, fontSize }): SelectStyles => ({
7
7
  root: {
8
8
  default: {},
9
9
  disabled: {},
@@ -25,7 +25,7 @@ export function useSelectVariantDefault(): SelectStyles {
25
25
  value: {
26
26
  default: {
27
27
  fontFamily,
28
- fontSize: 16,
28
+ fontSize,
29
29
  color: colors.foreground,
30
30
  },
31
31
  disabled: {
@@ -35,7 +35,7 @@ export function useSelectVariantDefault(): SelectStyles {
35
35
  placeholder: {
36
36
  default: {
37
37
  fontFamily,
38
- fontSize: 16,
38
+ fontSize,
39
39
  color: colors.mutedForeground,
40
40
  },
41
41
  disabled: {
@@ -62,7 +62,7 @@ export function useSelectVariantDefault(): SelectStyles {
62
62
  paddingVertical: 12,
63
63
  paddingHorizontal: 16,
64
64
  fontFamily,
65
- fontSize: 16,
65
+ fontSize,
66
66
  color: colors.foreground,
67
67
  borderRadius: radius / 2,
68
68
  },
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ import { Text as RnText, TextProps as RnTextProps } from "react-native";
3
+ import { TypographyVariants } from "./variants";
4
+
5
+ export interface TypographyProps extends RnTextProps {
6
+ variant?: keyof typeof TypographyVariants;
7
+ }
8
+
9
+ export function Typography(props: TypographyProps) {
10
+ const useVariantStyles = TypographyVariants[props.variant ?? "body-md"];
11
+ const variantStyles = useVariantStyles();
12
+ return <RnText {...props} style={variantStyles} />;
13
+ }
@@ -0,0 +1,13 @@
1
+ import { useThemedStyles } from "@/utils/use-themed-styles";
2
+ import { TextStyle } from "react-native";
3
+
4
+ export function useTextVariantBodyLg(): TextStyle {
5
+ return useThemedStyles(
6
+ ({ colors, fontFamily, letterSpacing, fontSize }): TextStyle => ({
7
+ color: colors.foreground,
8
+ fontSize: fontSize * 1.25,
9
+ fontFamily,
10
+ letterSpacing,
11
+ })
12
+ );
13
+ }
@@ -1,11 +1,11 @@
1
1
  import { useThemedStyles } from "@/utils/use-themed-styles";
2
2
  import { TextStyle } from "react-native";
3
3
 
4
- export function useInputVariantDefault(): TextStyle {
4
+ export function useTextVariantBodyMd(): TextStyle {
5
5
  return useThemedStyles(
6
- ({ colors, fontFamily, letterSpacing }): TextStyle => ({
6
+ ({ colors, fontFamily, letterSpacing, fontSize }): TextStyle => ({
7
7
  color: colors.foreground,
8
- fontSize: 16,
8
+ fontSize,
9
9
  fontFamily,
10
10
  letterSpacing,
11
11
  })
@@ -0,0 +1,13 @@
1
+ import { useThemedStyles } from "@/utils/use-themed-styles";
2
+ import { TextStyle } from "react-native";
3
+
4
+ export function useTextVariantBodySm(): TextStyle {
5
+ return useThemedStyles(
6
+ ({ colors, fontFamily, letterSpacing, fontSize }): TextStyle => ({
7
+ color: colors.foreground,
8
+ fontSize: fontSize * 0.875,
9
+ fontFamily,
10
+ letterSpacing,
11
+ })
12
+ );
13
+ }
@@ -0,0 +1,14 @@
1
+ import { useThemedStyles } from "@/utils/use-themed-styles";
2
+ import { TextStyle } from "react-native";
3
+
4
+ export function useTextVariantHeadingLg(): TextStyle {
5
+ return useThemedStyles(
6
+ ({ colors, fontFamily, letterSpacing, fontSize }): TextStyle => ({
7
+ color: colors.foreground,
8
+ fontSize: fontSize * 1.5,
9
+ fontFamily,
10
+ letterSpacing,
11
+ fontWeight: "600",
12
+ })
13
+ );
14
+ }
@@ -0,0 +1,14 @@
1
+ import { useThemedStyles } from "@/utils/use-themed-styles";
2
+ import { TextStyle } from "react-native";
3
+
4
+ export function useTextVariantHeadingMd(): TextStyle {
5
+ return useThemedStyles(
6
+ ({ colors, fontFamily, letterSpacing, fontSize }): TextStyle => ({
7
+ color: colors.foreground,
8
+ fontSize: fontSize * 1.25,
9
+ fontFamily,
10
+ letterSpacing,
11
+ fontWeight: "600",
12
+ })
13
+ );
14
+ }
@@ -0,0 +1,14 @@
1
+ import { useThemedStyles } from "@/utils/use-themed-styles";
2
+ import { TextStyle } from "react-native";
3
+
4
+ export function useTextVariantHeadingSm(): TextStyle {
5
+ return useThemedStyles(
6
+ ({ colors, fontFamily, letterSpacing, fontSize }): TextStyle => ({
7
+ color: colors.foreground,
8
+ fontSize,
9
+ fontFamily,
10
+ letterSpacing,
11
+ fontWeight: "600",
12
+ })
13
+ );
14
+ }
@@ -0,0 +1,15 @@
1
+ import { useTextVariantBodyLg } from "./body-lg";
2
+ import { useTextVariantBodyMd } from "./body-md";
3
+ import { useTextVariantBodySm } from "./body-sm";
4
+ import { useTextVariantHeadingLg } from "./heading-lg";
5
+ import { useTextVariantHeadingMd } from "./heading-md";
6
+ import { useTextVariantHeadingSm } from "./heading-sm";
7
+
8
+ export const TypographyVariants = {
9
+ ["body-sm"]: useTextVariantBodySm,
10
+ ["body-md"]: useTextVariantBodyMd,
11
+ ["body-lg"]: useTextVariantBodyLg,
12
+ ["heading-sm"]: useTextVariantHeadingSm,
13
+ ["heading-md"]: useTextVariantHeadingMd,
14
+ ["heading-lg"]: useTextVariantHeadingLg,
15
+ };
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { StyleProp, TextStyle, View } from "react-native";
3
+ import { useAvatar } from "./context";
4
+
5
+ export interface AvatarFallbackProps {
6
+ children: string;
7
+ render?: (props: AvatarFallbackProps) => React.ReactNode;
8
+ style?: StyleProp<TextStyle>;
9
+ }
10
+
11
+ export function AvatarFallback(props: AvatarFallbackProps) {
12
+ const avatar = useAvatar();
13
+ const composedStyles = [avatar.styles?.fallback, props.style];
14
+ const Component = props.render ?? View;
15
+ return <Component {...props} style={composedStyles} />;
16
+ }
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import { Image, ImageSource, ImageStyle, StyleProp } from "react-native";
3
+ import { useAvatar } from "./context";
4
+
5
+ export interface AvatarImageProps {
6
+ source: ImageSource;
7
+ onError: () => void;
8
+ render?: (props: AvatarImageProps) => React.ReactNode;
9
+ style?: StyleProp<ImageStyle>;
10
+ }
11
+
12
+ export function AvatarImage(props: AvatarImageProps) {
13
+ const avatar = useAvatar();
14
+ const composedStyles = [avatar.styles?.image, props.style];
15
+ const Component = props.render ?? Image;
16
+ return <Component {...props} style={composedStyles} />;
17
+ }
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import { StyleProp, View, ViewStyle } from "react-native";
3
+ import { AvatarContext } from "./context";
4
+ import { AvatarStyles } from "./types";
5
+
6
+ export interface AvatarRootProps {
7
+ children: React.ReactNode;
8
+ render?: (props: AvatarRootProps) => React.ReactNode;
9
+ style?: StyleProp<ViewStyle>;
10
+ styles?: AvatarStyles;
11
+ }
12
+
13
+ export function AvatarRoot(props: AvatarRootProps) {
14
+ const composedStyles = [props.styles?.root, props.style];
15
+ const Component = props.render ?? View;
16
+ return (
17
+ <AvatarContext.Provider value={{ styles: props.styles }}>
18
+ <Component {...props} style={composedStyles} />
19
+ </AvatarContext.Provider>
20
+ );
21
+ }
@@ -0,0 +1,16 @@
1
+ import { createContext, useContext } from "react";
2
+ import { AvatarStyles } from "./types";
3
+
4
+ export interface AvatarContext {
5
+ styles?: AvatarStyles;
6
+ }
7
+
8
+ export const AvatarContext = createContext<AvatarContext | undefined>(undefined);
9
+
10
+ export const useAvatar = () => {
11
+ const context = useContext(AvatarContext);
12
+ if (!context) {
13
+ throw new Error("useAvatarContext must be used within a AvatarProvider");
14
+ }
15
+ return context;
16
+ };
@@ -0,0 +1,14 @@
1
+ import { AvatarRoot } from "./avatar-root";
2
+ import { AvatarFallback } from "./avatar-fallback";
3
+ import { AvatarImage } from "./avatar-image";
4
+
5
+ export const AvatarPrimitive = {
6
+ Root: AvatarRoot,
7
+ Image: AvatarImage,
8
+ Fallback: AvatarFallback,
9
+ };
10
+
11
+ export type { AvatarRootProps } from "./avatar-root";
12
+ export type { AvatarFallbackProps } from "./avatar-fallback";
13
+ export type { AvatarImageProps } from "./avatar-image";
14
+ export type { AvatarStyles } from "./types";
@@ -0,0 +1,9 @@
1
+ import { AvatarFallbackProps } from "./avatar-fallback";
2
+ import { AvatarImageProps } from "./avatar-image";
3
+ import { AvatarRootProps } from "./avatar-root";
4
+
5
+ export type AvatarStyles = {
6
+ root?: AvatarRootProps["style"];
7
+ image?: AvatarImageProps["style"];
8
+ fallback?: AvatarFallbackProps["style"];
9
+ };
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { useState } from "react";
2
2
  import { Pressable, StyleProp, ViewStyle } from "react-native";
3
3
  import { ButtonStyles, ButtonState } from "./types";
4
4
  import { ButtonPrimitiveContext } from "./button-context";
@@ -17,25 +17,30 @@ export interface ButtonPrimitiveRootProps {
17
17
  render?: (props: this) => React.ReactElement;
18
18
  }
19
19
 
20
- const calculateState = (props: ButtonPrimitiveRootProps): ButtonState => {
20
+ const calculateState = (props: ButtonPrimitiveRootProps, isHovered: boolean): ButtonState => {
21
21
  if (props.isDisabled) {
22
22
  return "disabled";
23
23
  }
24
24
  if (props.isLoading) {
25
25
  return "loading";
26
26
  }
27
+ if (isHovered) {
28
+ return "hovered";
29
+ }
27
30
  return "default";
28
31
  };
29
32
 
30
33
  export function ButtonRoot(props: ButtonPrimitiveRootProps) {
31
- const state = calculateState(props);
34
+ const [isHovered, setIsHovered] = useState(false);
35
+
36
+ const state = calculateState(props, isHovered);
32
37
 
33
38
  const calculatedStyle = [props.styles?.root?.default, props.styles?.root?.[state], props.style];
34
39
 
35
40
  const Container = props.render ?? Pressable;
36
41
  return (
37
42
  <ButtonPrimitiveContext.Provider value={{ disabled: props.isDisabled, state, styles: props.styles }}>
38
- <Container {...props} style={calculatedStyle} />
43
+ <Container {...props} onHoverIn={() => setIsHovered(true)} onHoverOut={() => setIsHovered(false)} style={calculatedStyle} />
39
44
  </ButtonPrimitiveContext.Provider>
40
45
  );
41
46
  }
@@ -1,7 +1,7 @@
1
1
  import { ButtonPrimitiveRootProps } from "./button-root";
2
2
  import { ButtonPrimitiveLabelProps } from "./button-label";
3
3
 
4
- export type ButtonState = "default" | "disabled" | "loading";
4
+ export type ButtonState = "default" | "disabled" | "loading" | "hovered";
5
5
 
6
6
  export interface ButtonStyles {
7
7
  root?: Partial<Record<ButtonState, ButtonPrimitiveRootProps["style"]>>;
@@ -0,0 +1,16 @@
1
+ import { createContext, useContext } from "react";
2
+ import { EmptyStyles } from "./types";
3
+
4
+ export interface EmptyContext {
5
+ styles?: EmptyStyles;
6
+ }
7
+
8
+ export const EmptyContext = createContext<EmptyContext>({});
9
+
10
+ export const useEmpty = () => {
11
+ const context = useContext(EmptyContext);
12
+ if (!context) {
13
+ throw new Error("useEmptyContext must be used within a EmptyProvider");
14
+ }
15
+ return context;
16
+ };
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { StyleProp, Text, TextStyle } from "react-native";
3
+ import { useEmpty } from "./context";
4
+
5
+ export interface EmptyDescriptionProps {
6
+ children: string;
7
+ render?: (props: EmptyDescriptionProps) => React.ReactNode;
8
+ style?: StyleProp<TextStyle>;
9
+ }
10
+
11
+ export function EmptyDescription(props: EmptyDescriptionProps) {
12
+ const empty = useEmpty();
13
+ const composedStyles = [empty.styles?.description, props.style];
14
+ const Component = props.render ?? Text;
15
+ return <Component {...props} style={composedStyles} />;
16
+ }
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { StyleProp, View, ViewStyle } from "react-native";
3
+ import { useEmpty } from "./context";
4
+
5
+ export interface EmptyMediaProps {
6
+ children: React.ReactNode;
7
+ render?: (props: EmptyMediaProps) => React.ReactNode;
8
+ style?: StyleProp<ViewStyle>;
9
+ }
10
+
11
+ export function EmptyMedia(props: EmptyMediaProps) {
12
+ const empty = useEmpty();
13
+ const composedStyles = [empty.styles?.media, props.style];
14
+ const Component = props.render ?? View;
15
+ return <Component {...props} style={composedStyles} />;
16
+ }
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import { StyleProp, View, ViewStyle } from "react-native";
3
+ import { EmptyContext } from "./context";
4
+ import { EmptyStyles } from "./types";
5
+
6
+ export interface EmptyRootProps {
7
+ children: React.ReactNode;
8
+ render?: (props: EmptyRootProps) => React.ReactNode;
9
+ style?: StyleProp<ViewStyle>;
10
+ styles?: EmptyStyles;
11
+ }
12
+
13
+ export function EmptyRoot(props: EmptyRootProps) {
14
+ const composedStyles = [props.styles?.root, props.style];
15
+ const Component = props.render ?? View;
16
+ return (
17
+ <EmptyContext.Provider value={{ styles: props.styles }}>
18
+ <Component {...props} style={composedStyles} />
19
+ </EmptyContext.Provider>
20
+ );
21
+ }
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { useEmpty } from "./context";
3
+ import { StyleProp, Text, TextStyle } from "react-native";
4
+
5
+ export interface EmptyTitleProps {
6
+ children: string;
7
+ render?: (props: EmptyTitleProps) => React.ReactNode;
8
+ style?: StyleProp<TextStyle>;
9
+ }
10
+
11
+ export function EmptyTitle(props: EmptyTitleProps) {
12
+ const empty = useEmpty();
13
+ const composedStyles = [empty.styles?.title, props.style];
14
+ const Component = props.render ?? Text;
15
+ return <Component {...props} style={composedStyles} />;
16
+ }
@@ -0,0 +1,17 @@
1
+ import { EmptyRoot } from "./empty-root";
2
+ import { EmptyMedia } from "./empty-media";
3
+ import { EmptyTitle } from "./empty-title";
4
+ import { EmptyDescription } from "./empty-description";
5
+
6
+ export const EmptyPrimitive = {
7
+ Root: EmptyRoot,
8
+ Media: EmptyMedia,
9
+ Title: EmptyTitle,
10
+ Description: EmptyDescription,
11
+ };
12
+
13
+ export type { EmptyRootProps } from "./empty-root";
14
+ export type { EmptyMediaProps } from "./empty-media";
15
+ export type { EmptyTitleProps } from "./empty-title";
16
+ export type { EmptyDescriptionProps } from "./empty-description";
17
+ export type { EmptyStyles } from "./types";
@@ -0,0 +1,11 @@
1
+ import { EmptyDescriptionProps } from "./empty-description";
2
+ import { EmptyMediaProps } from "./empty-media";
3
+ import { EmptyRootProps } from "./empty-root";
4
+ import { EmptyTitleProps } from "./empty-title";
5
+
6
+ export type EmptyStyles = {
7
+ root?: EmptyRootProps["style"];
8
+ media?: EmptyMediaProps["style"];
9
+ title?: EmptyTitleProps["style"];
10
+ description?: EmptyDescriptionProps["style"];
11
+ };
@@ -3,3 +3,5 @@ export * from "./input";
3
3
  export * from "./button";
4
4
  export * from "./select";
5
5
  export * from "./card";
6
+ export * from "./empty";
7
+ export * from "./avatar";
@@ -9,4 +9,5 @@ export const defaultThemeAssets: ThemeAssets = {
9
9
  radius: 10,
10
10
  fontFamily: "System",
11
11
  letterSpacing: 0,
12
+ fontSize: 16,
12
13
  };
@@ -1,5 +1,5 @@
1
1
  import { createContext, PropsWithChildren, useContext, useEffect, useState } from "react";
2
- import { Colors, ColorScheme, FontFamily, LetterSpacing, Radius, ThemeName } from "./types";
2
+ import { Colors, ColorScheme, FontFamily, FontSize, LetterSpacing, Radius, ThemeName } from "./types";
3
3
  import { themes } from "./themes";
4
4
  import { useColorScheme } from "react-native";
5
5
 
@@ -9,6 +9,7 @@ interface ThemeContext {
9
9
  fontFamily: FontFamily;
10
10
  colorScheme: ColorScheme;
11
11
  letterSpacing: LetterSpacing;
12
+ fontSize: FontSize;
12
13
  setColorScheme: (scheme: ColorScheme) => void;
13
14
  setTheme: (themeName: ThemeName) => void;
14
15
  themeName: ThemeName;
@@ -42,6 +43,7 @@ export const ThemeProvider = (props: PropsWithChildren) => {
42
43
  radius: themesAssets.radius,
43
44
  fontFamily: themesAssets.fontFamily,
44
45
  letterSpacing: themesAssets.letterSpacing,
46
+ fontSize: themesAssets.fontSize,
45
47
  }}
46
48
  >
47
49
  {props.children}
@@ -23,10 +23,12 @@ export interface Colors {
23
23
  export type Radius = number;
24
24
  export type FontFamily = string;
25
25
  export type LetterSpacing = number;
26
+ export type FontSize = number;
26
27
 
27
28
  export interface ThemeAssets {
28
29
  colors: Record<ColorScheme, Colors>;
29
30
  radius: Radius;
30
31
  fontFamily: FontFamily;
31
32
  letterSpacing: LetterSpacing;
33
+ fontSize: FontSize;
32
34
  }
@@ -8,3 +8,29 @@ export const hslaSetAlpha = (hsla: string, alpha: number): string => {
8
8
  const l = parseInt(parts[2], 10);
9
9
  return `hsla(${h}, ${s}%, ${l}%, ${alpha})`;
10
10
  };
11
+
12
+ export const hslaSetLightness = (hsla: string, lightness: number): string => {
13
+ const parts = hsla.replace(/^hsla?\(|\s+|\)$/g, "").split(",");
14
+ if (parts.length < 3) {
15
+ throw new Error("Invalid HSLA color format");
16
+ }
17
+ const h = parseInt(parts[0], 10);
18
+ const s = parseInt(parts[1], 10);
19
+ return `hsla(${h}, ${s}%, ${lightness}%, ${parts[3] ? parseFloat(parts[3]) : 1})`;
20
+ };
21
+
22
+ export const hslaGetLightness = (hsla: string): number => {
23
+ const parts = hsla.replace(/^hsla?\(|\s+|\)$/g, "").split(",");
24
+ if (parts.length < 3) {
25
+ throw new Error("Invalid HSLA color format");
26
+ }
27
+ return parseInt(parts[2], 10);
28
+ };
29
+
30
+ export const hslaSetRelativeLightness = (hsla: string, delta: number): string => {
31
+ const currentLightness = hslaGetLightness(hsla);
32
+ let newLightness = currentLightness + delta;
33
+ if (newLightness > 100) newLightness = 100;
34
+ if (newLightness < 0) newLightness = 0;
35
+ return hslaSetLightness(hsla, newLightness);
36
+ };
@@ -1,11 +1,12 @@
1
1
  import { useTheme } from "@/themes";
2
- import { Colors, FontFamily, LetterSpacing, Radius } from "@/themes/types";
2
+ import { Colors, FontFamily, FontSize, LetterSpacing, Radius } from "@/themes/types";
3
3
 
4
4
  interface CallbackProps {
5
5
  colors: Colors;
6
6
  radius: Radius;
7
7
  fontFamily: FontFamily;
8
8
  letterSpacing: LetterSpacing;
9
+ fontSize: FontSize;
9
10
  }
10
11
 
11
12
  export const useThemedStyles = <T>(callback: (props: CallbackProps) => T): T => {
@@ -15,5 +16,6 @@ export const useThemedStyles = <T>(callback: (props: CallbackProps) => T): T =>
15
16
  radius: theme.radius,
16
17
  fontFamily: theme.fontFamily,
17
18
  letterSpacing: theme.letterSpacing,
19
+ fontSize: theme.fontSize,
18
20
  });
19
21
  };
package/tsconfig.json CHANGED
@@ -4,6 +4,7 @@
4
4
  "strict": true,
5
5
  "noUnusedLocals": true,
6
6
  "noUnusedParameters": true,
7
+ "customConditions": ["dev-source"],
7
8
  "paths": {
8
9
  "@/*": ["./src/*"]
9
10
  }
@@ -1,13 +0,0 @@
1
- import React from "react";
2
- import { Text as RnText, TextProps as RnTextProps } from "react-native";
3
- import { TextVariants } from "./variants";
4
-
5
- export interface TextProps extends RnTextProps {
6
- variant?: keyof typeof TextVariants;
7
- }
8
-
9
- export function Text(props: TextProps) {
10
- const useVariantStyles = TextVariants[props.variant ?? "default"];
11
- const variantStyles = useVariantStyles();
12
- return <RnText {...props} style={variantStyles} />;
13
- }
@@ -1,5 +0,0 @@
1
- import { useInputVariantDefault } from "./default";
2
-
3
- export const TextVariants = {
4
- default: useInputVariantDefault,
5
- };