native-variants 0.1.63 → 0.1.69

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 (37) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +125 -125
  3. package/dist/example.js +1 -0
  4. package/dist/index.d.ts +17 -8
  5. package/dist/index.js +72 -22
  6. package/dist/index.js.map +1 -1
  7. package/dist/lib/cn.d.ts +82 -2
  8. package/dist/lib/cn.js +138 -8
  9. package/dist/lib/cn.js.map +1 -1
  10. package/dist/lib/create-nva.d.ts +209 -6
  11. package/dist/lib/create-nva.js +460 -47
  12. package/dist/lib/create-nva.js.map +1 -1
  13. package/dist/lib/media-query.d.ts +84 -2
  14. package/dist/lib/media-query.js +103 -9
  15. package/dist/lib/media-query.js.map +1 -1
  16. package/dist/provider/create-provider.d.ts +44 -4
  17. package/dist/provider/create-provider.js +1 -1
  18. package/dist/provider/create-provider.jsx +110 -9
  19. package/dist/provider/create-provider.jsx.map +1 -1
  20. package/dist/provider/theme-provider.d.ts +266 -0
  21. package/dist/provider/theme-provider.js +1 -0
  22. package/dist/provider/theme-provider.jsx +328 -0
  23. package/dist/provider/theme-provider.jsx.map +1 -0
  24. package/dist/tokens/default-tokens.d.ts +2737 -0
  25. package/dist/tokens/default-tokens.js +1067 -0
  26. package/dist/tokens/default-tokens.js.map +1 -0
  27. package/dist/types.d.ts +318 -3
  28. package/dist/utils/alpha.d.ts +68 -0
  29. package/dist/utils/alpha.js +147 -4
  30. package/dist/utils/alpha.js.map +1 -1
  31. package/dist/utils/compose-text.d.ts +64 -2
  32. package/dist/utils/compose-text.js +103 -3
  33. package/dist/utils/compose-text.js.map +1 -1
  34. package/package.json +1 -1
  35. package/dist/utils/compose-refs.d.ts +0 -4
  36. package/dist/utils/compose-refs.js +0 -39
  37. package/dist/utils/compose-refs.js.map +0 -1
@@ -1,2 +1,84 @@
1
- export declare const wq: (widthPercent: number | string) => number;
2
- export declare const hq: (heightPercent: number | string) => number;
1
+ /**
2
+ * Width Query - Calculates a width value based on screen percentage.
3
+ * Returns a pixel-rounded value proportional to screen width.
4
+ *
5
+ * @param widthPercent - Percentage of screen width (0-100) as number or string
6
+ * @returns Pixel value rounded to nearest pixel ratio
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * // Get 50% of screen width
11
+ * const halfWidth = wq(50);
12
+ *
13
+ * // Using string percentage
14
+ * const quarterWidth = wq("25");
15
+ *
16
+ * // In styles
17
+ * const styles = {
18
+ * container: {
19
+ * width: wq(80), // 80% of screen width
20
+ * marginHorizontal: wq(10), // 10% margin on each side
21
+ * }
22
+ * };
23
+ * ```
24
+ */
25
+ export declare function wq(widthPercent: number | string): number;
26
+ /**
27
+ * Height Query - Calculates a height value based on screen percentage.
28
+ * Returns a pixel-rounded value proportional to screen height.
29
+ *
30
+ * @param heightPercent - Percentage of screen height (0-100) as number or string
31
+ * @returns Pixel value rounded to nearest pixel ratio
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * // Get 50% of screen height
36
+ * const halfHeight = hq(50);
37
+ *
38
+ * // Using string percentage
39
+ * const quarterHeight = hq("25");
40
+ *
41
+ * // In styles
42
+ * const styles = {
43
+ * hero: {
44
+ * height: hq(40), // 40% of screen height
45
+ * minHeight: hq(30), // Minimum 30% of screen height
46
+ * }
47
+ * };
48
+ * ```
49
+ */
50
+ export declare function hq(heightPercent: number | string): number;
51
+ /**
52
+ * Gets the current screen dimensions.
53
+ * Useful for calculations that need both width and height.
54
+ *
55
+ * @returns Object containing screen width and height in pixels
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * const { width, height } = getScreenDimensions();
60
+ * const isLandscape = width > height;
61
+ * ```
62
+ */
63
+ export declare function getScreenDimensions(): {
64
+ width: number;
65
+ height: number;
66
+ };
67
+ /**
68
+ * Calculates a responsive font size based on screen width.
69
+ * Ensures text scales appropriately across different device sizes.
70
+ *
71
+ * @param baseFontSize - The base font size in pixels
72
+ * @param scaleFactor - Optional scale factor (default: 0.5, meaning 50% responsive)
73
+ * @returns Scaled font size rounded to nearest pixel
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * // Responsive font that scales with screen size
78
+ * const titleSize = responsiveFontSize(24);
79
+ *
80
+ * // Less responsive (only 30% scaling)
81
+ * const subtitleSize = responsiveFontSize(18, 0.3);
82
+ * ```
83
+ */
84
+ export declare function responsiveFontSize(baseFontSize: number, scaleFactor?: number): number;
@@ -1,19 +1,113 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hq = exports.wq = void 0;
3
+ exports.wq = wq;
4
+ exports.hq = hq;
5
+ exports.getScreenDimensions = getScreenDimensions;
6
+ exports.responsiveFontSize = responsiveFontSize;
4
7
  const react_native_1 = require("react-native");
5
- let screenWidth = react_native_1.Dimensions.get("window").width;
6
- let screenHeight = react_native_1.Dimensions.get("window").height;
7
- const wq = (widthPercent) => {
8
+ /**
9
+ * Current screen dimensions.
10
+ * These values are captured at module load time.
11
+ * For responsive updates, consider using useWindowDimensions hook instead.
12
+ */
13
+ const screenWidth = react_native_1.Dimensions.get("window").width;
14
+ const screenHeight = react_native_1.Dimensions.get("window").height;
15
+ /**
16
+ * Width Query - Calculates a width value based on screen percentage.
17
+ * Returns a pixel-rounded value proportional to screen width.
18
+ *
19
+ * @param widthPercent - Percentage of screen width (0-100) as number or string
20
+ * @returns Pixel value rounded to nearest pixel ratio
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * // Get 50% of screen width
25
+ * const halfWidth = wq(50);
26
+ *
27
+ * // Using string percentage
28
+ * const quarterWidth = wq("25");
29
+ *
30
+ * // In styles
31
+ * const styles = {
32
+ * container: {
33
+ * width: wq(80), // 80% of screen width
34
+ * marginHorizontal: wq(10), // 10% margin on each side
35
+ * }
36
+ * };
37
+ * ```
38
+ */
39
+ function wq(widthPercent) {
8
40
  const elemWidth = typeof widthPercent === "number" ? widthPercent : parseFloat(widthPercent);
9
41
  return react_native_1.PixelRatio.roundToNearestPixel((screenWidth * elemWidth) / 100);
10
- };
11
- exports.wq = wq;
12
- const hq = (heightPercent) => {
42
+ }
43
+ /**
44
+ * Height Query - Calculates a height value based on screen percentage.
45
+ * Returns a pixel-rounded value proportional to screen height.
46
+ *
47
+ * @param heightPercent - Percentage of screen height (0-100) as number or string
48
+ * @returns Pixel value rounded to nearest pixel ratio
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * // Get 50% of screen height
53
+ * const halfHeight = hq(50);
54
+ *
55
+ * // Using string percentage
56
+ * const quarterHeight = hq("25");
57
+ *
58
+ * // In styles
59
+ * const styles = {
60
+ * hero: {
61
+ * height: hq(40), // 40% of screen height
62
+ * minHeight: hq(30), // Minimum 30% of screen height
63
+ * }
64
+ * };
65
+ * ```
66
+ */
67
+ function hq(heightPercent) {
13
68
  const elemHeight = typeof heightPercent === "number"
14
69
  ? heightPercent
15
70
  : parseFloat(heightPercent);
16
71
  return react_native_1.PixelRatio.roundToNearestPixel((screenHeight * elemHeight) / 100);
17
- };
18
- exports.hq = hq;
72
+ }
73
+ /**
74
+ * Gets the current screen dimensions.
75
+ * Useful for calculations that need both width and height.
76
+ *
77
+ * @returns Object containing screen width and height in pixels
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * const { width, height } = getScreenDimensions();
82
+ * const isLandscape = width > height;
83
+ * ```
84
+ */
85
+ function getScreenDimensions() {
86
+ return {
87
+ width: screenWidth,
88
+ height: screenHeight,
89
+ };
90
+ }
91
+ /**
92
+ * Calculates a responsive font size based on screen width.
93
+ * Ensures text scales appropriately across different device sizes.
94
+ *
95
+ * @param baseFontSize - The base font size in pixels
96
+ * @param scaleFactor - Optional scale factor (default: 0.5, meaning 50% responsive)
97
+ * @returns Scaled font size rounded to nearest pixel
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * // Responsive font that scales with screen size
102
+ * const titleSize = responsiveFontSize(24);
103
+ *
104
+ * // Less responsive (only 30% scaling)
105
+ * const subtitleSize = responsiveFontSize(18, 0.3);
106
+ * ```
107
+ */
108
+ function responsiveFontSize(baseFontSize, scaleFactor = 0.5) {
109
+ const scale = screenWidth / 375; // Base scale on iPhone 8/SE width
110
+ const newSize = baseFontSize + (baseFontSize * (scale - 1) * scaleFactor);
111
+ return react_native_1.PixelRatio.roundToNearestPixel(newSize);
112
+ }
19
113
  //# sourceMappingURL=media-query.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"media-query.js","sourceRoot":"","sources":["../../src/lib/media-query.ts"],"names":[],"mappings":";;;AAAA,+CAAsD;AAEtD,IAAI,WAAW,GAAG,yBAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC;AACjD,IAAI,YAAY,GAAG,yBAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;AAE5C,MAAM,EAAE,GAAG,CAAC,YAA6B,EAAU,EAAE;IAC1D,MAAM,SAAS,GACb,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAE7E,OAAO,yBAAU,CAAC,mBAAmB,CAAC,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC;AACzE,CAAC,CAAC;AALW,QAAA,EAAE,MAKb;AAEK,MAAM,EAAE,GAAG,CAAC,aAA8B,EAAU,EAAE;IAC3D,MAAM,UAAU,GACd,OAAO,aAAa,KAAK,QAAQ;QAC/B,CAAC,CAAC,aAAa;QACf,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAEhC,OAAO,yBAAU,CAAC,mBAAmB,CAAC,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;AAC3E,CAAC,CAAC;AAPW,QAAA,EAAE,MAOb"}
1
+ {"version":3,"file":"media-query.js","sourceRoot":"","sources":["../../src/lib/media-query.ts"],"names":[],"mappings":";;AAkCA,gBAKC;AA0BD,gBAOC;AAcD,kDAKC;AAmBD,gDAOC;AArHD,+CAAsD;AAEtD;;;;GAIG;AACH,MAAM,WAAW,GAAG,yBAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC;AACnD,MAAM,YAAY,GAAG,yBAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,EAAE,CAAC,YAA6B;IAC9C,MAAM,SAAS,GACb,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAE7E,OAAO,yBAAU,CAAC,mBAAmB,CAAC,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC;AACzE,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,EAAE,CAAC,aAA8B;IAC/C,MAAM,UAAU,GACd,OAAO,aAAa,KAAK,QAAQ;QAC/B,CAAC,CAAC,aAAa;QACf,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAEhC,OAAO,yBAAU,CAAC,mBAAmB,CAAC,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,mBAAmB;IACjC,OAAO;QACL,KAAK,EAAE,WAAW;QAClB,MAAM,EAAE,YAAY;KACrB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,kBAAkB,CAChC,YAAoB,EACpB,cAAsB,GAAG;IAEzB,MAAM,KAAK,GAAG,WAAW,GAAG,GAAG,CAAC,CAAC,kCAAkC;IACnE,MAAM,OAAO,GAAG,YAAY,GAAG,CAAC,YAAY,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC;IAC1E,OAAO,yBAAU,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AACjD,CAAC"}
@@ -1,7 +1,47 @@
1
- import { type PropsWithChildren } from "react";
2
- export declare const createCTX: <T>() => {
3
- CTXProvider: ({ children, props, }: PropsWithChildren & {
1
+ import React from "react";
2
+ /**
3
+ * Creates a type-safe context with provider and hook.
4
+ * Useful for creating component-level contexts for sharing props.
5
+ *
6
+ * @template T - The type of props to share via context
7
+ * @returns Object containing CTXProvider component and useCTX hook
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * // Define props type
12
+ * type ButtonContextProps = {
13
+ * size: "sm" | "md" | "lg";
14
+ * variant: "primary" | "secondary";
15
+ * disabled?: boolean;
16
+ * };
17
+ *
18
+ * // Create context
19
+ * const { CTXProvider: ButtonProvider, useCTX: useButtonContext } =
20
+ * createCTX<ButtonContextProps>();
21
+ *
22
+ * // Use in parent component
23
+ * function ButtonGroup({ children }) {
24
+ * return (
25
+ * <ButtonProvider props={{ size: "md", variant: "primary" }}>
26
+ * {children}
27
+ * </ButtonProvider>
28
+ * );
29
+ * }
30
+ *
31
+ * // Use in child component
32
+ * function ButtonText() {
33
+ * const context = useButtonContext();
34
+ * // context?.size, context?.variant, etc.
35
+ * }
36
+ * ```
37
+ */
38
+ export declare function createCTX<T>(): {
39
+ /** Provider component that makes context available to children */
40
+ CTXProvider: ({ children, props, }: React.PropsWithChildren<{
4
41
  props: T;
5
- }) => import("react").JSX.Element;
42
+ }>) => React.JSX.Element;
43
+ /** Hook to optionally consume context (returns undefined if outside provider) */
6
44
  useCTX: () => T | undefined;
45
+ /** Hook that requires context (throws if outside provider) */
46
+ useRequiredCTX: (componentName?: string) => T;
7
47
  };
@@ -1 +1 @@
1
- import{createContext,useContext,useMemo}from"react";export const createCTX=()=>{const Context=createContext(undefined);const CTXProvider=({children,props})=>{const value=useMemo(()=>({props}),[props]);return React.createElement(Context.Provider,{value:value},children)};const useCTX=()=>{const context=useContext(Context);if(!context){return undefined}return context.props};return{CTXProvider,useCTX}};
1
+ import React,{createContext,useContext,useMemo}from"react";export function createCTX(){const Context=createContext(undefined);function CTXProvider({children,props}){const value=useMemo(()=>({props}),[props]);return React.createElement(Context.Provider,{value:value},children)}function useCTX(){const context=useContext(Context);if(!context){return undefined}return context.props}function useRequiredCTX(componentName="Component"){const context=useContext(Context);if(!context){throw new Error(`${componentName} must be used within a CTXProvider. `+`Make sure to wrap your component tree with the appropriate provider.`)}return context.props}return{CTXProvider,useCTX,useRequiredCTX}}
@@ -1,24 +1,125 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createCTX = void 0;
4
- const react_1 = require("react");
5
- const createCTX = () => {
36
+ exports.createCTX = createCTX;
37
+ const react_1 = __importStar(require("react"));
38
+ /**
39
+ * Creates a type-safe context with provider and hook.
40
+ * Useful for creating component-level contexts for sharing props.
41
+ *
42
+ * @template T - The type of props to share via context
43
+ * @returns Object containing CTXProvider component and useCTX hook
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * // Define props type
48
+ * type ButtonContextProps = {
49
+ * size: "sm" | "md" | "lg";
50
+ * variant: "primary" | "secondary";
51
+ * disabled?: boolean;
52
+ * };
53
+ *
54
+ * // Create context
55
+ * const { CTXProvider: ButtonProvider, useCTX: useButtonContext } =
56
+ * createCTX<ButtonContextProps>();
57
+ *
58
+ * // Use in parent component
59
+ * function ButtonGroup({ children }) {
60
+ * return (
61
+ * <ButtonProvider props={{ size: "md", variant: "primary" }}>
62
+ * {children}
63
+ * </ButtonProvider>
64
+ * );
65
+ * }
66
+ *
67
+ * // Use in child component
68
+ * function ButtonText() {
69
+ * const context = useButtonContext();
70
+ * // context?.size, context?.variant, etc.
71
+ * }
72
+ * ```
73
+ */
74
+ function createCTX() {
6
75
  const Context = (0, react_1.createContext)(undefined);
7
- const CTXProvider = ({ children, props, }) => {
76
+ /**
77
+ * Context Provider component.
78
+ * Wraps children and provides the props value to all descendants.
79
+ *
80
+ * @param children - React children nodes
81
+ * @param props - The props object to provide to context consumers
82
+ */
83
+ function CTXProvider({ children, props, }) {
8
84
  const value = (0, react_1.useMemo)(() => ({ props }), [props]);
9
85
  return <Context.Provider value={value}>{children}</Context.Provider>;
10
- };
11
- const useCTX = () => {
86
+ }
87
+ /**
88
+ * Hook to consume the context value.
89
+ * Returns undefined if used outside of a CTXProvider.
90
+ *
91
+ * @returns The context props or undefined if outside provider
92
+ */
93
+ function useCTX() {
12
94
  const context = (0, react_1.useContext)(Context);
13
95
  if (!context) {
14
96
  return undefined;
15
97
  }
16
98
  return context.props;
17
- };
99
+ }
100
+ /**
101
+ * Hook that requires context to be present.
102
+ * Throws an error if used outside of a CTXProvider.
103
+ *
104
+ * @param componentName - Name of the component using the hook (for error messages)
105
+ * @returns The context props (guaranteed to be defined)
106
+ * @throws Error if used outside of CTXProvider
107
+ */
108
+ function useRequiredCTX(componentName = "Component") {
109
+ const context = (0, react_1.useContext)(Context);
110
+ if (!context) {
111
+ throw new Error(`${componentName} must be used within a CTXProvider. ` +
112
+ `Make sure to wrap your component tree with the appropriate provider.`);
113
+ }
114
+ return context.props;
115
+ }
18
116
  return {
117
+ /** Provider component that makes context available to children */
19
118
  CTXProvider,
119
+ /** Hook to optionally consume context (returns undefined if outside provider) */
20
120
  useCTX,
121
+ /** Hook that requires context (throws if outside provider) */
122
+ useRequiredCTX,
21
123
  };
22
- };
23
- exports.createCTX = createCTX;
124
+ }
24
125
  //# sourceMappingURL=create-provider.jsx.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-provider.jsx","sourceRoot":"","sources":["../../src/provider/create-provider.tsx"],"names":[],"mappings":";;;AAAA,iCAAmF;AAM5E,MAAM,SAAS,GAAG,GAAO,EAAE;IAChC,MAAM,OAAO,GAAG,IAAA,qBAAa,EAAgC,SAAS,CAAC,CAAC;IAExE,MAAM,WAAW,GAAG,CAAC,EACnB,QAAQ,EACR,KAAK,GAGN,EAAE,EAAE;QACH,MAAM,KAAK,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAElD,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvE,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,GAAkB,EAAE;QACjC,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,OAAO,CAAC,CAAC;QAEpC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO,OAAO,CAAC,KAAU,CAAC;IAC5B,CAAC,CAAC;IAEF,OAAO;QACL,WAAW;QACX,MAAM;KACP,CAAC;AACJ,CAAC,CAAC;AA5BW,QAAA,SAAS,aA4BpB"}
1
+ {"version":3,"file":"create-provider.jsx","sourceRoot":"","sources":["../../src/provider/create-provider.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,8BAgEC;AAhHD,+CAAkE;AAYlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,SAAgB,SAAS;IACvB,MAAM,OAAO,GAAG,IAAA,qBAAa,EAAgC,SAAS,CAAC,CAAC;IAExE;;;;;;OAMG;IACH,SAAS,WAAW,CAAC,EACnB,QAAQ,EACR,KAAK,GACiC;QACtC,MAAM,KAAK,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAElD,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvE,CAAC;IAED;;;;;OAKG;IACH,SAAS,MAAM;QACb,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,OAAO,CAAC,CAAC;QAEpC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO,OAAO,CAAC,KAAK,CAAC;IACvB,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,cAAc,CAAC,gBAAwB,WAAW;QACzD,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,OAAO,CAAC,CAAC;QAEpC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,GAAG,aAAa,sCAAsC;gBACtD,sEAAsE,CACvE,CAAC;QACJ,CAAC;QAED,OAAO,OAAO,CAAC,KAAK,CAAC;IACvB,CAAC;IAED,OAAO;QACL,kEAAkE;QAClE,WAAW;QACX,iFAAiF;QACjF,MAAM;QACN,8DAA8D;QAC9D,cAAc;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,266 @@
1
+ import React from "react";
2
+ import type { ColorSchemeConfig } from "../types.js";
3
+ /**
4
+ * Color scheme options for the theme.
5
+ */
6
+ export type ColorScheme = "light" | "dark";
7
+ /**
8
+ * Theme mode options.
9
+ * - "light": Always use light theme
10
+ * - "dark": Always use dark theme
11
+ * - "system": Follow system preference
12
+ */
13
+ export type ThemeMode = ColorScheme | "system";
14
+ /**
15
+ * Theme context value interface.
16
+ *
17
+ * @template T - The colors type
18
+ */
19
+ export interface ThemeContextValue<T extends Record<string, string>> {
20
+ /** Current color scheme (resolved from mode) */
21
+ colorScheme: ColorScheme;
22
+ /** Current theme mode setting */
23
+ mode: ThemeMode;
24
+ /** Whether dark mode is active */
25
+ isDark: boolean;
26
+ /** Current theme colors based on color scheme */
27
+ colors: T;
28
+ /** Set theme mode */
29
+ setMode: (mode: ThemeMode) => void;
30
+ /** Toggle between light and dark (ignores system) */
31
+ toggle: () => void;
32
+ }
33
+ /**
34
+ * Props for ThemeProvider component.
35
+ *
36
+ * @template T - The colors type
37
+ */
38
+ export interface ThemeProviderProps<T extends Record<string, string>> {
39
+ /** Child components */
40
+ children: React.ReactNode;
41
+ /**
42
+ * Color scheme configuration with default (light) and dark colors.
43
+ * Get this from createNVA's colorScheme output.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * const { colorScheme } = createNVA({
48
+ * theme: {
49
+ * colors: {
50
+ * default: { primary: "#000" },
51
+ * dark: { primary: "#fff" },
52
+ * },
53
+ * },
54
+ * });
55
+ *
56
+ * <ThemeProvider colors={colorScheme}>
57
+ * <App />
58
+ * </ThemeProvider>
59
+ * ```
60
+ */
61
+ colors: ColorSchemeConfig<T>;
62
+ /** Initial theme mode (default: "system") */
63
+ defaultMode?: ThemeMode;
64
+ /** Custom storage get function for persisting theme preference */
65
+ onGetStorage?: () => Promise<ThemeMode | null>;
66
+ /** Custom storage set function for persisting theme preference */
67
+ onSetStorage?: (mode: ThemeMode) => Promise<void>;
68
+ }
69
+ /**
70
+ * ThemeProvider component.
71
+ * Provides theme context with dark/light mode support.
72
+ *
73
+ * **Important:** This provider requires colors to be passed explicitly.
74
+ * Get colors from createNVA's colorScheme output.
75
+ *
76
+ * @template T - The colors type
77
+ *
78
+ * @example
79
+ * ```tsx
80
+ * // 1. Create your theme with createNVA
81
+ * const { theme, colorScheme, styled } = createNVA({
82
+ * theme: {
83
+ * colors: {
84
+ * default: {
85
+ * background: "#ffffff",
86
+ * foreground: "#000000",
87
+ * primary: "#3b82f6",
88
+ * },
89
+ * dark: {
90
+ * background: "#0a0a0a",
91
+ * foreground: "#ffffff",
92
+ * primary: "#60a5fa",
93
+ * },
94
+ * },
95
+ * },
96
+ * });
97
+ *
98
+ * // 2. Wrap your app with ThemeProvider
99
+ * function App() {
100
+ * return (
101
+ * <ThemeProvider colors={colorScheme}>
102
+ * <MyApp />
103
+ * </ThemeProvider>
104
+ * );
105
+ * }
106
+ *
107
+ * // 3. Use colors in components
108
+ * function MyComponent() {
109
+ * const { colors, isDark, toggle } = useTheme();
110
+ *
111
+ * return (
112
+ * <View style={{ backgroundColor: colors.background }}>
113
+ * <Text style={{ color: colors.foreground }}>
114
+ * {isDark ? "Dark Mode" : "Light Mode"}
115
+ * </Text>
116
+ * <Button onPress={toggle} title="Toggle" />
117
+ * </View>
118
+ * );
119
+ * }
120
+ *
121
+ * // With AsyncStorage persistence
122
+ * import AsyncStorage from "@react-native-async-storage/async-storage";
123
+ *
124
+ * <ThemeProvider
125
+ * colors={colorScheme}
126
+ * defaultMode="system"
127
+ * onGetStorage={async () => {
128
+ * const mode = await AsyncStorage.getItem("theme-mode");
129
+ * return mode as ThemeMode | null;
130
+ * }}
131
+ * onSetStorage={async (mode) => {
132
+ * await AsyncStorage.setItem("theme-mode", mode);
133
+ * }}
134
+ * >
135
+ * <App />
136
+ * </ThemeProvider>
137
+ * ```
138
+ */
139
+ export declare function ThemeProvider<T extends Record<string, string>>({ children, colors, defaultMode, onGetStorage, onSetStorage, }: ThemeProviderProps<T>): React.JSX.Element | null;
140
+ /**
141
+ * Hook to access theme context.
142
+ * Must be used within a ThemeProvider.
143
+ *
144
+ * @template T - The colors type
145
+ * @returns Theme context value with colors and controls
146
+ * @throws Error if used outside ThemeProvider
147
+ *
148
+ * @example
149
+ * ```tsx
150
+ * function MyComponent() {
151
+ * const { colors, isDark, toggle, setMode } = useTheme<MyColors>();
152
+ *
153
+ * return (
154
+ * <View style={{ backgroundColor: colors.background }}>
155
+ * <Text style={{ color: colors.foreground }}>
156
+ * Current mode: {isDark ? "Dark" : "Light"}
157
+ * </Text>
158
+ * <Button onPress={toggle} title="Toggle Theme" />
159
+ * <Button onPress={() => setMode("system")} title="Use System" />
160
+ * </View>
161
+ * );
162
+ * }
163
+ * ```
164
+ */
165
+ export declare function useTheme<T extends Record<string, string>>(): ThemeContextValue<T>;
166
+ /**
167
+ * Hook to access only theme colors.
168
+ * Convenience wrapper around useTheme that returns just the colors.
169
+ *
170
+ * @template T - The colors type
171
+ * @returns Current theme colors
172
+ *
173
+ * @example
174
+ * ```tsx
175
+ * function MyComponent() {
176
+ * const colors = useThemeColors<MyColors>();
177
+ *
178
+ * return (
179
+ * <View style={{ backgroundColor: colors.background }}>
180
+ * <Text style={{ color: colors.primary }}>Hello</Text>
181
+ * </View>
182
+ * );
183
+ * }
184
+ * ```
185
+ */
186
+ export declare function useThemeColors<T extends Record<string, string>>(): T;
187
+ /**
188
+ * Hook to check if dark mode is active.
189
+ * Convenience wrapper for quick dark mode checks.
190
+ *
191
+ * @returns Boolean indicating if dark mode is active
192
+ *
193
+ * @example
194
+ * ```tsx
195
+ * function MyComponent() {
196
+ * const isDark = useIsDark();
197
+ *
198
+ * return (
199
+ * <Image source={isDark ? darkLogo : lightLogo} />
200
+ * );
201
+ * }
202
+ * ```
203
+ */
204
+ export declare function useIsDark(): boolean;
205
+ /**
206
+ * Hook to get the current color scheme.
207
+ * Returns "light" or "dark" based on current theme.
208
+ *
209
+ * @returns Current color scheme
210
+ *
211
+ * @example
212
+ * ```tsx
213
+ * function MyComponent() {
214
+ * const colorScheme = useColorScheme();
215
+ *
216
+ * return (
217
+ * <StatusBar barStyle={colorScheme === "dark" ? "light-content" : "dark-content"} />
218
+ * );
219
+ * }
220
+ * ```
221
+ */
222
+ export declare function useColorScheme(): ColorScheme;
223
+ /**
224
+ * Creates a themed style helper that automatically uses current theme colors.
225
+ * Useful for creating styled components with theme access.
226
+ *
227
+ * @template T - The colors type
228
+ * @template S - The styles record type
229
+ * @param styleFactory - Function that receives colors and returns styles
230
+ * @returns Hook that returns computed styles
231
+ *
232
+ * @example
233
+ * ```tsx
234
+ * type MyColors = { card: string; border: string; cardForeground: string };
235
+ *
236
+ * const useCardStyles = createThemedStyles<MyColors, {
237
+ * container: ViewStyle;
238
+ * title: TextStyle;
239
+ * }>((colors) => ({
240
+ * container: {
241
+ * backgroundColor: colors.card,
242
+ * borderColor: colors.border,
243
+ * borderWidth: 1,
244
+ * borderRadius: 8,
245
+ * padding: 16,
246
+ * },
247
+ * title: {
248
+ * color: colors.cardForeground,
249
+ * fontSize: 18,
250
+ * fontWeight: "600",
251
+ * },
252
+ * }));
253
+ *
254
+ * function Card({ title, children }) {
255
+ * const styles = useCardStyles();
256
+ *
257
+ * return (
258
+ * <View style={styles.container}>
259
+ * <Text style={styles.title}>{title}</Text>
260
+ * {children}
261
+ * </View>
262
+ * );
263
+ * }
264
+ * ```
265
+ */
266
+ export declare function createThemedStyles<T extends Record<string, string>, S extends Record<string, object>>(styleFactory: (colors: T) => S): () => S;
@@ -0,0 +1 @@
1
+ import React,{createContext,useCallback,useContext,useEffect,useMemo,useState}from"react";import{Appearance}from"react-native";const ThemeContext=createContext(undefined);function resolveColorScheme(mode,systemScheme){if(mode==="system"){return systemScheme==="dark"?"dark":"light"}return mode}export function ThemeProvider({children,colors,defaultMode="system",onGetStorage,onSetStorage}){const[mode,setModeState]=useState(defaultMode);const[systemScheme,setSystemScheme]=useState(Appearance.getColorScheme());const[isHydrated,setIsHydrated]=useState(!onGetStorage);useEffect(()=>{if(onGetStorage){onGetStorage().then(storedMode=>{if(storedMode){setModeState(storedMode)}setIsHydrated(true)})}},[onGetStorage]);useEffect(()=>{const subscription=Appearance.addChangeListener(({colorScheme})=>{setSystemScheme(colorScheme)});return()=>subscription.remove()},[]);const setMode=useCallback(newMode=>{setModeState(newMode);if(onSetStorage){onSetStorage(newMode)}},[onSetStorage]);const toggle=useCallback(()=>{const currentScheme=resolveColorScheme(mode,systemScheme);const newMode=currentScheme==="light"?"dark":"light";setMode(newMode)},[mode,systemScheme,setMode]);const value=useMemo(()=>{const colorScheme=resolveColorScheme(mode,systemScheme);return{colorScheme,mode,isDark:colorScheme==="dark",colors:colorScheme==="dark"?colors.dark:colors.default,setMode,toggle}},[mode,systemScheme,colors,setMode,toggle]);if(!isHydrated){return null}return React.createElement(ThemeContext.Provider,{value:value},children)}export function useTheme(){const context=useContext(ThemeContext);if(!context){throw new Error("useTheme must be used within a ThemeProvider. "+"Make sure to wrap your app with <ThemeProvider colors={colorScheme}>.")}return context}export function useThemeColors(){const{colors}=useTheme();return colors}export function useIsDark(){const{isDark}=useTheme();return isDark}export function useColorScheme(){const{colorScheme}=useTheme();return colorScheme}export function createThemedStyles(styleFactory){return function useThemedStyles(){const{colors}=useTheme();return useMemo(()=>styleFactory(colors),[colors])}}