@munchi_oy/native-ui 0.1.0

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 (83) hide show
  1. package/dist/index.d.mts +568 -0
  2. package/dist/index.d.ts +568 -0
  3. package/dist/index.js +1 -0
  4. package/dist/index.mjs +1 -0
  5. package/global.css +53 -0
  6. package/nativewind-env.d.ts +2 -0
  7. package/package.json +88 -0
  8. package/src/MAlert.tsx +38 -0
  9. package/src/MAnimation.tsx +55 -0
  10. package/src/MAvatar.tsx +111 -0
  11. package/src/MBadge.tsx +72 -0
  12. package/src/MButton.tsx +90 -0
  13. package/src/MCard.tsx +15 -0
  14. package/src/MChevron.tsx +47 -0
  15. package/src/MConfirmation.tsx +68 -0
  16. package/src/MCountDown.tsx +120 -0
  17. package/src/MDateTimePicker.tsx +124 -0
  18. package/src/MDivider.tsx +69 -0
  19. package/src/MDrawerRightPanel.tsx +187 -0
  20. package/src/MDropdown.tsx +277 -0
  21. package/src/MInput.tsx +162 -0
  22. package/src/MLabel.tsx +3 -0
  23. package/src/MLucideIcon.tsx +21 -0
  24. package/src/MModal.tsx +287 -0
  25. package/src/MNativeAlert.tsx +33 -0
  26. package/src/MNumpad.tsx +520 -0
  27. package/src/MPicker.tsx +150 -0
  28. package/src/MPinPadKeys.tsx +104 -0
  29. package/src/MPortal.tsx +4 -0
  30. package/src/MProgressBar.tsx +74 -0
  31. package/src/MRadioGroup.tsx +4 -0
  32. package/src/MRequiredLabel.tsx +21 -0
  33. package/src/MResponsiveContainer.tsx +74 -0
  34. package/src/MSearch.tsx +138 -0
  35. package/src/MSelector.tsx +48 -0
  36. package/src/MSkeleton.tsx +3 -0
  37. package/src/MSwitch.tsx +13 -0
  38. package/src/MTable.tsx +17 -0
  39. package/src/MTabs.tsx +198 -0
  40. package/src/MText.tsx +51 -0
  41. package/src/MTimerUp.tsx +88 -0
  42. package/src/MToggle.tsx +51 -0
  43. package/src/constants.ts +19 -0
  44. package/src/hooks/useColorScheme.tsx +12 -0
  45. package/src/hooks/useIconColors.ts +19 -0
  46. package/src/index.ts +124 -0
  47. package/src/primitives/accordion.tsx +143 -0
  48. package/src/primitives/alert-dialog.tsx +181 -0
  49. package/src/primitives/alert.tsx +94 -0
  50. package/src/primitives/aspect-ratio.tsx +5 -0
  51. package/src/primitives/avatar.tsx +47 -0
  52. package/src/primitives/badge.tsx +57 -0
  53. package/src/primitives/button.tsx +92 -0
  54. package/src/primitives/card.tsx +86 -0
  55. package/src/primitives/checkbox.tsx +35 -0
  56. package/src/primitives/collapsible.tsx +9 -0
  57. package/src/primitives/context-menu.tsx +255 -0
  58. package/src/primitives/dialog.tsx +166 -0
  59. package/src/primitives/dropdown-menu.tsx +264 -0
  60. package/src/primitives/hover-card.tsx +45 -0
  61. package/src/primitives/input.tsx +25 -0
  62. package/src/primitives/label.tsx +33 -0
  63. package/src/primitives/menubar.tsx +266 -0
  64. package/src/primitives/navigation-menu.tsx +192 -0
  65. package/src/primitives/popover.tsx +46 -0
  66. package/src/primitives/progress.tsx +82 -0
  67. package/src/primitives/radio-group.tsx +42 -0
  68. package/src/primitives/select.tsx +192 -0
  69. package/src/primitives/separator.tsx +28 -0
  70. package/src/primitives/skeleton.tsx +39 -0
  71. package/src/primitives/switch.tsx +102 -0
  72. package/src/primitives/table.tsx +107 -0
  73. package/src/primitives/tabs.tsx +66 -0
  74. package/src/primitives/text.tsx +28 -0
  75. package/src/primitives/textarea.tsx +39 -0
  76. package/src/primitives/toggle-group.tsx +89 -0
  77. package/src/primitives/toggle.tsx +91 -0
  78. package/src/primitives/tooltip.tsx +40 -0
  79. package/src/primitives/typography.tsx +214 -0
  80. package/src/theme.ts +43 -0
  81. package/src/tokens.ts +7 -0
  82. package/src/utils.ts +14 -0
  83. package/tailwind.config.ts +112 -0
@@ -0,0 +1,91 @@
1
+ import * as TogglePrimitive from "@rn-primitives/toggle";
2
+ import { type VariantProps, cva } from "class-variance-authority";
3
+ import type { LucideIcon } from "lucide-react-native";
4
+ import * as React from "react";
5
+ import { cn } from "../utils";
6
+ import { TextClassContext } from "./text";
7
+
8
+ const toggleVariants = cva(
9
+ "web:group web:inline-flex items-center justify-center rounded-md web:ring-offset-background web:transition-colors web:hover:bg-muted active:bg-muted web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2",
10
+ {
11
+ variants: {
12
+ variant: {
13
+ default: "bg-transparent",
14
+ outline:
15
+ "border border-input bg-transparent web:hover:bg-accent active:bg-accent active:bg-accent"
16
+ },
17
+ size: {
18
+ default: "h-10 px-3 native:h-12 native:px-[12]",
19
+ sm: "h-9 px-2.5 native:h-10 native:px-[9]",
20
+ lg: "h-11 px-5 native:h-14 native:px-6"
21
+ }
22
+ },
23
+ defaultVariants: {
24
+ variant: "default",
25
+ size: "default"
26
+ }
27
+ }
28
+ );
29
+
30
+ const toggleTextVariants = cva(
31
+ "text-sm native:text-base text-foreground font-medium",
32
+ {
33
+ variants: {
34
+ variant: {
35
+ default: "",
36
+ outline:
37
+ "web:group-hover:text-accent-foreground web:group-active:text-accent-foreground"
38
+ },
39
+ size: {
40
+ default: "",
41
+ sm: "",
42
+ lg: ""
43
+ }
44
+ },
45
+ defaultVariants: {
46
+ variant: "default",
47
+ size: "default"
48
+ }
49
+ }
50
+ );
51
+
52
+ const Toggle = React.forwardRef<
53
+ TogglePrimitive.RootRef,
54
+ TogglePrimitive.RootProps & VariantProps<typeof toggleVariants>
55
+ >(({ className, variant, size, ...props }, ref) => (
56
+ <TextClassContext.Provider
57
+ value={cn(
58
+ toggleTextVariants({ variant, size }),
59
+ props.pressed
60
+ ? "text-accent-foreground"
61
+ : "web:group-hover:text-muted-foreground",
62
+ className
63
+ )}
64
+ >
65
+ <TogglePrimitive.Root
66
+ ref={ref}
67
+ className={cn(
68
+ toggleVariants({ variant, size }),
69
+ props.disabled && "web:pointer-events-none opacity-50",
70
+ props.pressed && "bg-accent",
71
+ className
72
+ )}
73
+ {...props}
74
+ />
75
+ </TextClassContext.Provider>
76
+ ));
77
+
78
+ Toggle.displayName = TogglePrimitive.Root.displayName;
79
+
80
+ function ToggleIcon({
81
+ className,
82
+ icon: Icon,
83
+ ...props
84
+ }: React.ComponentPropsWithoutRef<LucideIcon> & {
85
+ icon: LucideIcon;
86
+ }) {
87
+ const textClass = React.useContext(TextClassContext);
88
+ return <Icon className={cn(textClass, className)} {...props} />;
89
+ }
90
+
91
+ export { Toggle, ToggleIcon, toggleTextVariants, toggleVariants };
@@ -0,0 +1,40 @@
1
+ import * as TooltipPrimitive from "@rn-primitives/tooltip";
2
+ import * as React from "react";
3
+ import { Platform, StyleSheet } from "react-native";
4
+ import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
5
+ import { cn } from "../utils";
6
+ import { TextClassContext } from "./text";
7
+
8
+ const Tooltip = TooltipPrimitive.Root;
9
+ const TooltipTrigger = TooltipPrimitive.Trigger;
10
+
11
+ const TooltipContent = React.forwardRef<
12
+ TooltipPrimitive.ContentRef,
13
+ TooltipPrimitive.ContentProps & { portalHost?: string }
14
+ >(({ className, sideOffset = 4, portalHost, ...props }, ref) => (
15
+ <TooltipPrimitive.Portal hostName={portalHost}>
16
+ <TooltipPrimitive.Overlay
17
+ style={Platform.OS !== "web" ? StyleSheet.absoluteFill : undefined}
18
+ >
19
+ <Animated.View
20
+ entering={Platform.select({ web: undefined, default: FadeIn })}
21
+ exiting={Platform.select({ web: undefined, default: FadeOut })}
22
+ >
23
+ <TextClassContext.Provider value="text-sm native:text-base text-popover-foreground">
24
+ <TooltipPrimitive.Content
25
+ ref={ref}
26
+ sideOffset={sideOffset}
27
+ className={cn(
28
+ "z-50 overflow-hidden rounded-md border border-border bg-popover px-3 py-1.5 shadow-md shadow-foreground/5 web:animate-in web:fade-in-0 web:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
29
+ className
30
+ )}
31
+ {...props}
32
+ />
33
+ </TextClassContext.Provider>
34
+ </Animated.View>
35
+ </TooltipPrimitive.Overlay>
36
+ </TooltipPrimitive.Portal>
37
+ ));
38
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
39
+
40
+ export { Tooltip, TooltipContent, TooltipTrigger };
@@ -0,0 +1,214 @@
1
+ import * as Slot from "@rn-primitives/slot";
2
+ import type { SlottableTextProps, TextRef } from "@rn-primitives/types";
3
+ import * as React from "react";
4
+ import { Platform, Text as RNText } from "react-native";
5
+ import { cn } from "../utils";
6
+
7
+ const H1 = React.forwardRef<TextRef, SlottableTextProps>(
8
+ ({ className, asChild = false, ...props }, ref) => {
9
+ const Component = asChild ? Slot.Text : RNText;
10
+ return (
11
+ <Component
12
+ role="heading"
13
+ aria-level="1"
14
+ className={cn(
15
+ "web:scroll-m-20 text-4xl text-foreground font-extrabold tracking-tight lg:text-5xl web:select-text",
16
+ className
17
+ )}
18
+ ref={ref}
19
+ {...props}
20
+ />
21
+ );
22
+ }
23
+ );
24
+
25
+ H1.displayName = "H1";
26
+
27
+ const H2 = React.forwardRef<TextRef, SlottableTextProps>(
28
+ ({ className, asChild = false, ...props }, ref) => {
29
+ const Component = asChild ? Slot.Text : RNText;
30
+ return (
31
+ <Component
32
+ role="heading"
33
+ aria-level="2"
34
+ className={cn(
35
+ "web:scroll-m-20 border-b border-border pb-2 text-3xl text-foreground font-semibold tracking-tight first:mt-0 web:select-text",
36
+ className
37
+ )}
38
+ ref={ref}
39
+ {...props}
40
+ />
41
+ );
42
+ }
43
+ );
44
+
45
+ H2.displayName = "H2";
46
+
47
+ const H3 = React.forwardRef<TextRef, SlottableTextProps>(
48
+ ({ className, asChild = false, ...props }, ref) => {
49
+ const Component = asChild ? Slot.Text : RNText;
50
+ return (
51
+ <Component
52
+ role="heading"
53
+ aria-level="3"
54
+ className={cn(
55
+ "web:scroll-m-20 text-2xl text-foreground font-semibold tracking-tight web:select-text",
56
+ className
57
+ )}
58
+ ref={ref}
59
+ {...props}
60
+ />
61
+ );
62
+ }
63
+ );
64
+
65
+ H3.displayName = "H3";
66
+
67
+ const H4 = React.forwardRef<TextRef, SlottableTextProps>(
68
+ ({ className, asChild = false, ...props }, ref) => {
69
+ const Component = asChild ? Slot.Text : RNText;
70
+ return (
71
+ <Component
72
+ role="heading"
73
+ aria-level="4"
74
+ className={cn(
75
+ "web:scroll-m-20 text-xl text-foreground font-semibold tracking-tight web:select-text",
76
+ className
77
+ )}
78
+ ref={ref}
79
+ {...props}
80
+ />
81
+ );
82
+ }
83
+ );
84
+
85
+ H4.displayName = "H4";
86
+
87
+ const P = React.forwardRef<TextRef, SlottableTextProps>(
88
+ ({ className, asChild = false, ...props }, ref) => {
89
+ const Component = asChild ? Slot.Text : RNText;
90
+ return (
91
+ <Component
92
+ className={cn("text-base text-foreground web:select-text", className)}
93
+ ref={ref}
94
+ {...props}
95
+ />
96
+ );
97
+ }
98
+ );
99
+
100
+ P.displayName = "P";
101
+
102
+ const BlockQuote = React.forwardRef<TextRef, SlottableTextProps>(
103
+ ({ className, asChild = false, ...props }, ref) => {
104
+ const Component = asChild ? Slot.Text : RNText;
105
+ return (
106
+ <Component
107
+ // @ts-ignore - role of blockquote renders blockquote element on the web
108
+ role={Platform.OS === "web" ? "blockquote" : undefined}
109
+ className={cn(
110
+ "mt-6 native:mt-4 border-l-2 border-border pl-6 native:pl-3 text-base text-foreground italic web:select-text",
111
+ className
112
+ )}
113
+ ref={ref}
114
+ {...props}
115
+ />
116
+ );
117
+ }
118
+ );
119
+
120
+ BlockQuote.displayName = "BlockQuote";
121
+
122
+ const Code = React.forwardRef<TextRef, SlottableTextProps>(
123
+ ({ className, asChild = false, ...props }, ref) => {
124
+ const Component = asChild ? Slot.Text : RNText;
125
+ return (
126
+ <Component
127
+ // @ts-ignore - role of code renders code element on the web
128
+ role={Platform.OS === "web" ? "code" : undefined}
129
+ className={cn(
130
+ "relative rounded-md bg-muted px-[0.3rem] py-[0.2rem] text-sm text-foreground font-semibold web:select-text",
131
+ className
132
+ )}
133
+ ref={ref}
134
+ {...props}
135
+ />
136
+ );
137
+ }
138
+ );
139
+
140
+ Code.displayName = "Code";
141
+
142
+ const Lead = React.forwardRef<TextRef, SlottableTextProps>(
143
+ ({ className, asChild = false, ...props }, ref) => {
144
+ const Component = asChild ? Slot.Text : RNText;
145
+ return (
146
+ <Component
147
+ className={cn(
148
+ "text-xl text-muted-foreground web:select-text",
149
+ className
150
+ )}
151
+ ref={ref}
152
+ {...props}
153
+ />
154
+ );
155
+ }
156
+ );
157
+
158
+ Lead.displayName = "Lead";
159
+
160
+ const Large = React.forwardRef<TextRef, SlottableTextProps>(
161
+ ({ className, asChild = false, ...props }, ref) => {
162
+ const Component = asChild ? Slot.Text : RNText;
163
+ return (
164
+ <Component
165
+ className={cn(
166
+ "text-xl text-foreground font-semibold web:select-text",
167
+ className
168
+ )}
169
+ ref={ref}
170
+ {...props}
171
+ />
172
+ );
173
+ }
174
+ );
175
+
176
+ Large.displayName = "Large";
177
+
178
+ const Small = React.forwardRef<TextRef, SlottableTextProps>(
179
+ ({ className, asChild = false, ...props }, ref) => {
180
+ const Component = asChild ? Slot.Text : RNText;
181
+ return (
182
+ <Component
183
+ className={cn(
184
+ "text-sm text-foreground font-medium leading-none web:select-text",
185
+ className
186
+ )}
187
+ ref={ref}
188
+ {...props}
189
+ />
190
+ );
191
+ }
192
+ );
193
+
194
+ Small.displayName = "Small";
195
+
196
+ const Muted = React.forwardRef<TextRef, SlottableTextProps>(
197
+ ({ className, asChild = false, ...props }, ref) => {
198
+ const Component = asChild ? Slot.Text : RNText;
199
+ return (
200
+ <Component
201
+ className={cn(
202
+ "text-sm text-muted-foreground web:select-text",
203
+ className
204
+ )}
205
+ ref={ref}
206
+ {...props}
207
+ />
208
+ );
209
+ }
210
+ );
211
+
212
+ Muted.displayName = "Muted";
213
+
214
+ export { BlockQuote, Code, H1, H2, H3, H4, Large, Lead, Muted, P, Small };
package/src/theme.ts ADDED
@@ -0,0 +1,43 @@
1
+ export const lightVars = {
2
+ "--background": "0 0% 95.7%",
3
+ "--foreground": "0 0% 7.8%",
4
+ "--card": "0 0% 100%",
5
+ "--card-foreground": "0 0% 7.8%",
6
+ "--popover": "0 0% 100%",
7
+ "--popover-foreground": "0 0% 7.8%",
8
+ "--primary": "0 0% 7.8%",
9
+ "--primary-foreground": "0 0% 100%",
10
+ "--secondary": "0 0% 93%",
11
+ "--secondary-foreground": "0 0% 7.8%",
12
+ "--muted": "0 0% 93%",
13
+ "--muted-foreground": "0 0% 45%",
14
+ "--accent": "0 0% 89.4%",
15
+ "--accent-foreground": "0 0% 7.8%",
16
+ "--destructive": "0 84.2% 60.2%",
17
+ "--destructive-foreground": "0 0% 100%",
18
+ "--border": "0 0% 78%",
19
+ "--input": "0 0% 78%",
20
+ "--ring": "0 0% 7.8%"
21
+ } as const;
22
+
23
+ export const darkVars = {
24
+ "--background": "0 0% 7.8%",
25
+ "--foreground": "0 0% 100%",
26
+ "--card": "0 0% 14.5%",
27
+ "--card-foreground": "0 0% 100%",
28
+ "--popover": "0 0% 14.5%",
29
+ "--popover-foreground": "0 0% 100%",
30
+ "--primary": "0 0% 100%",
31
+ "--primary-foreground": "0 0% 7.8%",
32
+ "--secondary": "0 0% 18%",
33
+ "--secondary-foreground": "0 0% 100%",
34
+ "--muted": "0 0% 11%",
35
+ "--muted-foreground": "0 0% 60%",
36
+ "--accent": "0 0% 21.2%",
37
+ "--accent-foreground": "0 0% 100%",
38
+ "--destructive": "0 72% 51%",
39
+ "--destructive-foreground": "0 0% 100%",
40
+ "--border": "0 0% 28%",
41
+ "--input": "0 0% 28%",
42
+ "--ring": "0 0% 60%"
43
+ } as const;
package/src/tokens.ts ADDED
@@ -0,0 +1,7 @@
1
+ export const typography = {
2
+ regular: "DMSans_400Regular",
3
+ medium: "DMSans_500Medium",
4
+ bold: "DMSans_700Bold"
5
+ } as const;
6
+
7
+ export type TypographyToken = keyof typeof typography;
package/src/utils.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { type ClassValue, clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
7
+
8
+ export function padNumber(
9
+ number: number | string,
10
+ length = 4,
11
+ padChar = "0"
12
+ ): string {
13
+ return number.toString().padStart(length, padChar);
14
+ }
@@ -0,0 +1,112 @@
1
+ import { hairlineWidth } from "nativewind/theme";
2
+ import type { Config } from "tailwindcss";
3
+ import { darkVars, lightVars } from "./src/theme";
4
+
5
+ const config: Config = {
6
+ darkMode: "class",
7
+ content: ["./src/**/*.{ts,tsx}"],
8
+ presets: [require("nativewind/preset")],
9
+ theme: {
10
+ // Mobile + tablet only — no desktop xl/2xl. Height queries: POS split layouts.
11
+ screens: {
12
+ sm: "640px",
13
+ md: "768px",
14
+ lg: "1024px",
15
+ "h-sm": { raw: "(min-height: 600px)" },
16
+ "h-md": { raw: "(min-height: 768px)" }
17
+ },
18
+ extend: {
19
+ fontFamily: {
20
+ munchi: ["DMSans_400Regular"],
21
+ "munchi-medium": ["DMSans_400Regular"],
22
+ "munchi-semibold": ["DMSans_500Medium"],
23
+ "munchi-bold": ["DMSans_700Bold"]
24
+ },
25
+ colors: {
26
+ border: "hsl(var(--border))",
27
+ input: "hsl(var(--input))",
28
+ ring: "hsl(var(--ring))",
29
+ background: "hsl(var(--background))",
30
+ foreground: "hsl(var(--foreground))",
31
+ primary: {
32
+ DEFAULT: "hsl(var(--primary))",
33
+ foreground: "hsl(var(--primary-foreground))"
34
+ },
35
+ secondary: {
36
+ DEFAULT: "hsl(var(--secondary))",
37
+ foreground: "hsl(var(--secondary-foreground))"
38
+ },
39
+ destructive: {
40
+ DEFAULT: "hsl(var(--destructive))",
41
+ foreground: "hsl(var(--destructive-foreground))"
42
+ },
43
+ muted: {
44
+ DEFAULT: "hsl(var(--muted))",
45
+ foreground: "hsl(var(--muted-foreground))"
46
+ },
47
+ accent: {
48
+ DEFAULT: "hsl(var(--accent))",
49
+ foreground: "hsl(var(--accent-foreground))"
50
+ },
51
+ popover: {
52
+ DEFAULT: "hsl(var(--popover))",
53
+ foreground: "hsl(var(--popover-foreground))"
54
+ },
55
+ card: {
56
+ DEFAULT: "hsl(var(--card))",
57
+ foreground: "hsl(var(--card-foreground))"
58
+ }
59
+ },
60
+ borderWidth: {
61
+ hairline: hairlineWidth()
62
+ },
63
+ keyframes: {
64
+ "accordion-down": {
65
+ from: { height: "0" },
66
+ to: { height: "var(--radix-accordion-content-height)" }
67
+ },
68
+ "accordion-up": {
69
+ from: { height: "var(--radix-accordion-content-height)" },
70
+ to: { height: "0" }
71
+ }
72
+ },
73
+ animation: {
74
+ "accordion-down": "accordion-down 0.2s ease-out",
75
+ "accordion-up": "accordion-up 0.2s ease-out"
76
+ },
77
+ flex: {
78
+ 2: "2",
79
+ 3: "3"
80
+ },
81
+ spacing: {
82
+ 18: "4.5rem",
83
+ 88: "22rem",
84
+ 128: "32rem"
85
+ },
86
+ fontSize: {
87
+ xs: ["0.75rem", { lineHeight: "1rem" }],
88
+ sm: ["0.875rem", { lineHeight: "1.25rem" }],
89
+ base: ["1rem", { lineHeight: "1.5rem" }],
90
+ lg: ["1.125rem", { lineHeight: "1.75rem" }],
91
+ xl: ["1.25rem", { lineHeight: "1.75rem" }],
92
+ "2xl": ["1.5rem", { lineHeight: "2rem" }],
93
+ "3xl": ["1.875rem", { lineHeight: "2.25rem" }],
94
+ "4xl": ["2.25rem", { lineHeight: "2.5rem" }],
95
+ "5xl": ["3rem", { lineHeight: "1" }],
96
+ "6xl": ["3.75rem", { lineHeight: "1" }]
97
+ }
98
+ }
99
+ },
100
+ plugins: [
101
+ require("tailwindcss-animate"),
102
+ ({
103
+ addBase
104
+ }: { addBase: (base: Record<string, Record<string, string>>) => void }) =>
105
+ addBase({
106
+ ":root": lightVars,
107
+ ".dark": darkVars
108
+ })
109
+ ]
110
+ };
111
+
112
+ export default config;