@korsolutions/ui 0.0.23 → 0.0.25

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.
package/README.md CHANGED
@@ -1,2 +1,5 @@
1
1
  # TODO
2
- - [ ] Line height
2
+ - [ ] Line height
3
+ - [ ] Letter spacing
4
+ - [ ] Custom safe area insets
5
+ - [ ] Custom portal host container
@@ -1,4 +1,4 @@
1
- import { Et as InputStyles, K as AvatarStyles, L as BadgeStyles, M as TextareaPrimitiveBaseProps, P as TextareaStyles, T as DropdownMenuStyles, V as ToastStyles, Z as EmptyStyles, _ as PopoverStyles, a as CalendarStyles, ft as SelectStyles, kt as FieldStyles, rt as CardStyles, ut as SelectRootBaseProps, wt as InputPrimitiveBaseProps, x as PopoverTriggerRef, xt as ButtonStyles, yt as ButtonPrimitiveRootProps } from "../index-CCYJiglk.mjs";
1
+ import { Et as InputStyles, K as AvatarStyles, L as BadgeStyles, M as TextareaPrimitiveBaseProps, P as TextareaStyles, T as DropdownMenuStyles, V as ToastStyles, Z as EmptyStyles, _ as PopoverStyles, a as CalendarStyles, ft as SelectStyles, kt as FieldStyles, r as CalendarRootProps, rt as CardStyles, ut as SelectRootBaseProps, wt as InputPrimitiveBaseProps, x as PopoverTriggerRef, xt as ButtonStyles, yt as ButtonPrimitiveRootProps } from "../index-DLFYQx-P.mjs";
2
2
  import "../use-relative-position-DBzhrBU7.mjs";
3
3
  import { t as NumericMaskFormat } from "../use-numeric-mask-B9WZG25o.mjs";
4
4
  import React from "react";
@@ -301,13 +301,13 @@ declare const CalendarVariants: {
301
301
  //#endregion
302
302
  //#region src/components/calendar/calendar.d.ts
303
303
  interface CalendarProps {
304
- value?: Date;
305
- onChange?: (date: Date | undefined) => void;
306
- defaultMonth?: Date;
307
- minDate?: Date;
308
- maxDate?: Date;
309
- variant?: keyof typeof CalendarVariants;
304
+ value?: CalendarRootProps["value"];
305
+ onChange?: CalendarRootProps["onChange"];
306
+ defaultMonth?: CalendarRootProps["defaultMonth"];
307
+ minDate?: CalendarRootProps["minDate"];
308
+ maxDate?: CalendarRootProps["maxDate"];
310
309
  weekDays?: string[];
310
+ variant?: keyof typeof CalendarVariants;
311
311
  }
312
312
  declare function Calendar(props: CalendarProps): React.JSX.Element;
313
313
  //#endregion
@@ -1,5 +1,5 @@
1
- import { i as useThemedStyles, r as ToastComponent, t as ToastAPI } from "../toast-manager-Cdhl1ep0.mjs";
2
- import { a as TextareaPrimitive, c as AvatarPrimitive, d as SelectPrimitive, f as ButtonPrimitive, i as DropdownMenuPrimitive, l as EmptyPrimitive, m as FieldPrimitive, n as PopoverPrimitive, o as BadgePrimitive, p as InputPrimitive, r as usePopover, t as CalendarPrimitive, u as CardPrimitive } from "../primitives-ApsPS0vU.mjs";
1
+ import { i as useThemedStyles, r as ToastComponent, t as ToastAPI } from "../toast-manager-BCt2uAJl.mjs";
2
+ import { a as TextareaPrimitive, c as AvatarPrimitive, d as SelectPrimitive, f as ButtonPrimitive, i as DropdownMenuPrimitive, l as EmptyPrimitive, m as FieldPrimitive, n as PopoverPrimitive, o as BadgePrimitive, p as InputPrimitive, r as usePopover, t as CalendarPrimitive, u as CardPrimitive } from "../primitives-1609Y7eP.mjs";
3
3
  import "../use-relative-position-BTKEyT1F.mjs";
4
4
  import { t as useNumericMask } from "../use-numeric-mask-BQlz1Pus.mjs";
5
5
  import React, { forwardRef, useEffect, useState } from "react";
@@ -282,7 +282,7 @@ function Field(props) {
282
282
  styles: variantStyles,
283
283
  children: [
284
284
  props.label && /* @__PURE__ */ jsx(FieldPrimitive.Label, {
285
- htmlFor: props.id,
285
+ for: props.id,
286
286
  children: props.label
287
287
  }),
288
288
  props.description && /* @__PURE__ */ jsx(FieldPrimitive.Description, { children: props.description }),
@@ -1,12 +1,12 @@
1
1
  import { r as LayoutPosition } from "./use-relative-position-DBzhrBU7.mjs";
2
- import * as react8 from "react";
2
+ import * as react7 from "react";
3
3
  import React$1, { Dispatch, RefAttributes } from "react";
4
- import { ImageSource, ImageStyle, LayoutRectangle, PressableProps, StyleProp, TextInputProps, TextProps, TextStyle, View, ViewProps, ViewStyle } from "react-native";
4
+ import { ImageSource, ImageStyle, LayoutRectangle, PressableProps, StyleProp, TextInput, TextInputProps, TextProps, TextStyle, View, ViewProps, ViewStyle } from "react-native";
5
5
 
6
6
  //#region src/primitives/field/field-label.d.ts
7
7
  interface FieldLabelProps {
8
8
  children: string;
9
- htmlFor?: string;
9
+ for?: string;
10
10
  render?: (props: FieldLabelProps) => React$1.ReactNode;
11
11
  style?: TextProps["style"];
12
12
  }
@@ -59,6 +59,7 @@ type InputStyles = Partial<Record<InputState, InputPrimitiveBaseProps>>;
59
59
  //#endregion
60
60
  //#region src/primitives/input/input.d.ts
61
61
  type InputPrimitiveBaseProps = Omit<TextInputProps, "onChange"> & {
62
+ ref?: React.Ref<TextInput>;
62
63
  onChange?: TextInputProps["onChangeText"];
63
64
  isDisabled?: boolean;
64
65
  };
@@ -66,7 +67,7 @@ interface InputPrimitiveProps extends InputPrimitiveBaseProps {
66
67
  render?: (props: InputPrimitiveProps) => React.ReactNode;
67
68
  styles?: InputStyles;
68
69
  }
69
- declare function InputPrimitive(props: InputPrimitiveProps): react8.JSX.Element;
70
+ declare const InputPrimitive: react7.ForwardRefExoticComponent<Omit<InputPrimitiveProps, "ref"> & react7.RefAttributes<TextInput>>;
70
71
  //#endregion
71
72
  //#region src/primitives/button/button-label.d.ts
72
73
  interface ButtonPrimitiveLabelProps {
@@ -152,7 +153,7 @@ interface SelectOptionProps {
152
153
  render?: (props: SelectOptionProps) => React.ReactElement;
153
154
  style?: StyleProp<TextStyle>;
154
155
  }
155
- declare function SelectOption(props: SelectOptionProps): react8.JSX.Element;
156
+ declare function SelectOption(props: SelectOptionProps): react7.JSX.Element;
156
157
  //#endregion
157
158
  //#region src/primitives/select/types.d.ts
158
159
  type SelectState = "default" | "disabled";
@@ -433,7 +434,7 @@ interface TextareaPrimitiveProps extends TextareaPrimitiveBaseProps {
433
434
  render?: (props: TextareaPrimitiveProps) => React.ReactNode;
434
435
  styles?: TextareaStyles;
435
436
  }
436
- declare function TextareaPrimitive(props: TextareaPrimitiveProps): react8.JSX.Element;
437
+ declare function TextareaPrimitive(props: TextareaPrimitiveProps): react7.JSX.Element;
437
438
  //#endregion
438
439
  //#region src/primitives/dropdown-menu/dropdown-menu-trigger.d.ts
439
440
  interface DropdownMenuTriggerProps extends PressableProps {
@@ -504,7 +505,7 @@ declare function DropdownMenuPortal(props: DropdownMenuPortalProps): React$1.JSX
504
505
  //#region src/primitives/dropdown-menu/index.d.ts
505
506
  declare const DropdownMenuPrimitive: {
506
507
  Root: typeof DropdownMenuRoot;
507
- Trigger: react8.ForwardRefExoticComponent<DropdownMenuTriggerProps & react8.RefAttributes<DropdownMenuTriggerRef>>;
508
+ Trigger: react7.ForwardRefExoticComponent<DropdownMenuTriggerProps & react7.RefAttributes<DropdownMenuTriggerRef>>;
508
509
  Portal: typeof DropdownMenuPortal;
509
510
  Overlay: typeof DropdownMenuOverlay;
510
511
  Content: typeof DropdownMenuContent;
@@ -578,13 +579,13 @@ interface PopoverContext {
578
579
  setTriggerPosition: Dispatch<React.SetStateAction<LayoutPosition>>;
579
580
  styles?: PopoverStyles;
580
581
  }
581
- declare const PopoverContext: react8.Context<PopoverContext | undefined>;
582
+ declare const PopoverContext: react7.Context<PopoverContext | undefined>;
582
583
  declare const usePopover: () => PopoverContext;
583
584
  //#endregion
584
585
  //#region src/primitives/popover/index.d.ts
585
586
  declare const PopoverPrimitive: {
586
587
  Root: typeof PopoverRoot;
587
- Trigger: react8.ForwardRefExoticComponent<PopoverTriggerProps & react8.RefAttributes<PopoverTriggerRef>>;
588
+ Trigger: react7.ForwardRefExoticComponent<PopoverTriggerProps & react7.RefAttributes<PopoverTriggerRef>>;
588
589
  Portal: typeof PopoverPortal;
589
590
  Overlay: typeof PopoverOverlay;
590
591
  Content: typeof PopoverContent;
package/dist/index.d.mts CHANGED
@@ -1,5 +1,14 @@
1
- import * as react4 from "react";
1
+ import * as react5 from "react";
2
2
 
3
+ //#region src/primitives/portal/portal.constants.d.ts
4
+ interface PortalHostProps {
5
+ name?: string;
6
+ container?: {
7
+ ios?: React.ComponentType<React.PropsWithChildren>;
8
+ android?: React.ComponentType<React.PropsWithChildren>;
9
+ };
10
+ }
11
+ //#endregion
3
12
  //#region src/themes/types.d.ts
4
13
  type ThemeName = "default";
5
14
  type ColorScheme = "light" | "dark";
@@ -37,14 +46,17 @@ interface ThemeContext {
37
46
  setTheme: (themeName: ThemeName) => void;
38
47
  themeName: ThemeName;
39
48
  }
40
- declare const ThemeContext: react4.Context<ThemeContext | null>;
49
+ declare const ThemeContext: react5.Context<ThemeContext | null>;
41
50
  declare const useTheme: () => ThemeContext;
42
51
  //#endregion
43
52
  //#region src/index.d.ts
44
- declare const UniversalUIProvider: ({
45
- children
46
- }: {
53
+ interface ProviderProps {
47
54
  children: React.ReactNode;
48
- }) => react4.JSX.Element;
55
+ portalContainer?: PortalHostProps["container"];
56
+ }
57
+ declare const UniversalUIProvider: ({
58
+ children,
59
+ portalContainer
60
+ }: ProviderProps) => react5.JSX.Element;
49
61
  //#endregion
50
- export { UniversalUIProvider, useTheme };
62
+ export { ProviderProps, UniversalUIProvider, useTheme };
package/dist/index.mjs CHANGED
@@ -1,14 +1,14 @@
1
- import { a as ThemeProvider, n as ToastContainer, o as useTheme } from "./toast-manager-Cdhl1ep0.mjs";
2
- import { h as PortalHost } from "./primitives-ApsPS0vU.mjs";
1
+ import { a as ThemeProvider, n as ToastContainer, o as useTheme } from "./toast-manager-BCt2uAJl.mjs";
2
+ import { g as PortalHost } from "./primitives-1609Y7eP.mjs";
3
3
  import "./use-relative-position-BTKEyT1F.mjs";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
 
6
6
  //#region src/index.tsx
7
- const UniversalUIProvider = ({ children }) => {
7
+ const UniversalUIProvider = ({ children, portalContainer }) => {
8
8
  return /* @__PURE__ */ jsxs(ThemeProvider, { children: [
9
+ /* @__PURE__ */ jsx(ToastContainer, {}),
9
10
  children,
10
- /* @__PURE__ */ jsx(PortalHost, {}),
11
- /* @__PURE__ */ jsx(ToastContainer, {})
11
+ /* @__PURE__ */ jsx(PortalHost, { container: portalContainer })
12
12
  ] });
13
13
  };
14
14
 
@@ -1,3 +1,3 @@
1
- import { $ as EmptyMediaProps, A as DropdownMenuTriggerProps, At as FieldErrorProps, B as ToastRootProps, C as DropdownMenuPortalProps, Ct as InputPrimitive, D as DropdownMenuDividerProps, Dt as FieldPrimitive, E as DropdownMenuOverlayProps, Et as InputStyles, F as BadgePrimitive, G as AvatarRootProps, H as ToastDescriptionProps, I as BadgeRootProps, J as AvatarFallbackProps, K as AvatarStyles, L as BadgeStyles, M as TextareaPrimitiveBaseProps, Mt as FieldLabelProps, N as TextareaPrimitiveProps, O as DropdownMenuButtonProps, Ot as FieldPrimitiveRootProps, P as TextareaStyles, Q as EmptyTitleProps, R as BadgeLabelProps, S as DropdownMenuPrimitive, St as ButtonPrimitiveLabelProps, T as DropdownMenuStyles, Tt as InputPrimitiveProps, U as ToastTitleProps, V as ToastStyles, W as AvatarPrimitive, X as EmptyRootProps, Y as EmptyPrimitive, Z as EmptyStyles, _t as SelectTriggerProps, a as CalendarStyles, at as CardBodyProps, b as PopoverTriggerProps, bt as ButtonState, c as CalendarDayProps, ct as SelectPrimitive, d as PopoverPrimitive, dt as SelectRootProps, et as EmptyDescriptionProps, f as PopoverContext, ft as SelectStyles, g as PopoverRootProps, gt as SelectValueProps, h as PopoverPortalProps, ht as SelectOverlayProps, i as CalendarDayState, it as CardFooterProps, j as TextareaPrimitive, jt as FieldDescriptionProps, k as DropdownMenuContentProps, kt as FieldStyles, l as CalendarWeekLabelsProps, lt as SelectPortalProps, m as PopoverCloseProps, mt as SelectContentProps, n as CalendarNavButtonProps, nt as CardRootProps, o as CalendarTitleProps, ot as CardTitleProps, p as usePopover, pt as SelectOptionProps, q as AvatarImageProps, r as CalendarRootProps, rt as CardStyles, s as CalendarHeaderProps, st as CardHeaderProps, t as CalendarPrimitive, tt as CardPrimitive, u as CalendarWeeksProps, ut as SelectRootBaseProps, v as PopoverOverlayProps, vt as ButtonPrimitive, w as DropdownMenuRootProps, wt as InputPrimitiveBaseProps, x as PopoverTriggerRef, xt as ButtonStyles, y as PopoverContentProps, yt as ButtonPrimitiveRootProps, z as ToastPrimitive } from "../index-CCYJiglk.mjs";
1
+ import { $ as EmptyMediaProps, A as DropdownMenuTriggerProps, At as FieldErrorProps, B as ToastRootProps, C as DropdownMenuPortalProps, Ct as InputPrimitive, D as DropdownMenuDividerProps, Dt as FieldPrimitive, E as DropdownMenuOverlayProps, Et as InputStyles, F as BadgePrimitive, G as AvatarRootProps, H as ToastDescriptionProps, I as BadgeRootProps, J as AvatarFallbackProps, K as AvatarStyles, L as BadgeStyles, M as TextareaPrimitiveBaseProps, Mt as FieldLabelProps, N as TextareaPrimitiveProps, O as DropdownMenuButtonProps, Ot as FieldPrimitiveRootProps, P as TextareaStyles, Q as EmptyTitleProps, R as BadgeLabelProps, S as DropdownMenuPrimitive, St as ButtonPrimitiveLabelProps, T as DropdownMenuStyles, Tt as InputPrimitiveProps, U as ToastTitleProps, V as ToastStyles, W as AvatarPrimitive, X as EmptyRootProps, Y as EmptyPrimitive, Z as EmptyStyles, _t as SelectTriggerProps, a as CalendarStyles, at as CardBodyProps, b as PopoverTriggerProps, bt as ButtonState, c as CalendarDayProps, ct as SelectPrimitive, d as PopoverPrimitive, dt as SelectRootProps, et as EmptyDescriptionProps, f as PopoverContext, ft as SelectStyles, g as PopoverRootProps, gt as SelectValueProps, h as PopoverPortalProps, ht as SelectOverlayProps, i as CalendarDayState, it as CardFooterProps, j as TextareaPrimitive, jt as FieldDescriptionProps, k as DropdownMenuContentProps, kt as FieldStyles, l as CalendarWeekLabelsProps, lt as SelectPortalProps, m as PopoverCloseProps, mt as SelectContentProps, n as CalendarNavButtonProps, nt as CardRootProps, o as CalendarTitleProps, ot as CardTitleProps, p as usePopover, pt as SelectOptionProps, q as AvatarImageProps, r as CalendarRootProps, rt as CardStyles, s as CalendarHeaderProps, st as CardHeaderProps, t as CalendarPrimitive, tt as CardPrimitive, u as CalendarWeeksProps, ut as SelectRootBaseProps, v as PopoverOverlayProps, vt as ButtonPrimitive, w as DropdownMenuRootProps, wt as InputPrimitiveBaseProps, x as PopoverTriggerRef, xt as ButtonStyles, y as PopoverContentProps, yt as ButtonPrimitiveRootProps, z as ToastPrimitive } from "../index-DLFYQx-P.mjs";
2
2
  import "../use-relative-position-DBzhrBU7.mjs";
3
3
  export { AvatarFallbackProps, AvatarImageProps, AvatarPrimitive, AvatarRootProps, AvatarStyles, BadgeLabelProps, BadgePrimitive, BadgeRootProps, BadgeStyles, ButtonPrimitive, ButtonPrimitiveLabelProps, ButtonPrimitiveRootProps, ButtonState, ButtonStyles, CalendarDayProps, CalendarDayState, CalendarHeaderProps, CalendarNavButtonProps, CalendarPrimitive, CalendarRootProps, CalendarStyles, CalendarTitleProps, CalendarWeekLabelsProps, CalendarWeeksProps, CardBodyProps, CardFooterProps, CardHeaderProps, CardPrimitive, CardRootProps, CardStyles, CardTitleProps, DropdownMenuButtonProps, DropdownMenuContentProps, DropdownMenuDividerProps, DropdownMenuOverlayProps, DropdownMenuPortalProps, DropdownMenuPrimitive, DropdownMenuRootProps, DropdownMenuStyles, DropdownMenuTriggerProps, EmptyDescriptionProps, EmptyMediaProps, EmptyPrimitive, EmptyRootProps, EmptyStyles, EmptyTitleProps, FieldDescriptionProps, FieldErrorProps, FieldLabelProps, FieldPrimitive, FieldPrimitiveRootProps, FieldStyles, InputPrimitive, InputPrimitiveBaseProps, InputPrimitiveProps, InputStyles, PopoverCloseProps, PopoverContentProps, PopoverContext, PopoverOverlayProps, PopoverPortalProps, PopoverPrimitive, PopoverRootProps, PopoverTriggerProps, PopoverTriggerRef, SelectContentProps, SelectOptionProps, SelectOverlayProps, SelectPortalProps, SelectPrimitive, SelectRootBaseProps, SelectRootProps, SelectStyles, SelectTriggerProps, SelectValueProps, TextareaPrimitive, TextareaPrimitiveBaseProps, TextareaPrimitiveProps, TextareaStyles, ToastDescriptionProps, ToastPrimitive, ToastRootProps, ToastStyles, ToastTitleProps, usePopover };
@@ -1,4 +1,4 @@
1
- import { a as TextareaPrimitive, c as AvatarPrimitive, d as SelectPrimitive, f as ButtonPrimitive, i as DropdownMenuPrimitive, l as EmptyPrimitive, m as FieldPrimitive, n as PopoverPrimitive, o as BadgePrimitive, p as InputPrimitive, r as usePopover, s as ToastPrimitive, t as CalendarPrimitive, u as CardPrimitive } from "../primitives-ApsPS0vU.mjs";
1
+ import { a as TextareaPrimitive, c as AvatarPrimitive, d as SelectPrimitive, f as ButtonPrimitive, i as DropdownMenuPrimitive, l as EmptyPrimitive, m as FieldPrimitive, n as PopoverPrimitive, o as BadgePrimitive, p as InputPrimitive, r as usePopover, s as ToastPrimitive, t as CalendarPrimitive, u as CardPrimitive } from "../primitives-1609Y7eP.mjs";
2
2
  import "../use-relative-position-BTKEyT1F.mjs";
3
3
 
4
4
  export { AvatarPrimitive, BadgePrimitive, ButtonPrimitive, CalendarPrimitive, CardPrimitive, DropdownMenuPrimitive, EmptyPrimitive, FieldPrimitive, InputPrimitive, PopoverPrimitive, SelectPrimitive, TextareaPrimitive, ToastPrimitive, usePopover };
@@ -1,10 +1,13 @@
1
1
  import { n as DEFAULT_POSITION, r as useRelativePosition, t as DEFAULT_LAYOUT } from "./use-relative-position-BTKEyT1F.mjs";
2
- import React, { createContext, forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState, useSyncExternalStore } from "react";
3
- import { ActivityIndicator, Image, Pressable, StyleSheet, Text, TextInput, View } from "react-native";
4
- import { Fragment, jsx } from "react/jsx-runtime";
2
+ import React, { createContext, forwardRef, useCallback, useContext, useEffect, useId, useImperativeHandle, useMemo, useRef, useState, useSyncExternalStore } from "react";
3
+ import { ActivityIndicator, Image, Platform, Pressable, StyleSheet, Text, TextInput, View } from "react-native";
4
+ import { jsx } from "react/jsx-runtime";
5
5
 
6
+ //#region src/primitives/portal/portal.constants.tsx
7
+ const DEFAULT_PORTAL_HOST = "__KOR_PORTAL_HOST__";
8
+
9
+ //#endregion
6
10
  //#region src/primitives/portal/portal.tsx
7
- const DEFAULT_PORTAL_HOST = "KOR_NATIVE_DEFAULT_HOST_NAME";
8
11
  const store = {
9
12
  map: (/* @__PURE__ */ new Map()).set(DEFAULT_PORTAL_HOST, /* @__PURE__ */ new Map()),
10
13
  listeners: /* @__PURE__ */ new Set()
@@ -37,10 +40,26 @@ function removePortal(hostName, name) {
37
40
  store.map = next;
38
41
  emit();
39
42
  }
40
- function PortalHost({ name = DEFAULT_PORTAL_HOST }) {
43
+ function PortalHost({ name = DEFAULT_PORTAL_HOST, container }) {
41
44
  const portalMap = useSyncExternalStore(subscribe, getSnapshot, getSnapshot).get(name) ?? /* @__PURE__ */ new Map();
42
45
  if (portalMap.size === 0) return null;
43
- return /* @__PURE__ */ jsx(Fragment, { children: Array.from(portalMap.values()) });
46
+ return /* @__PURE__ */ jsx(Platform.select({
47
+ default: (props) => /* @__PURE__ */ jsx(View, {
48
+ ...props,
49
+ style: {
50
+ position: "absolute",
51
+ top: 0,
52
+ left: 0,
53
+ right: 0,
54
+ bottom: 0,
55
+ elevation: 999,
56
+ zIndex: 999,
57
+ pointerEvents: "box-none"
58
+ }
59
+ }),
60
+ ios: container?.ios,
61
+ android: container?.android
62
+ }), { children: Array.from(portalMap.values()) });
44
63
  }
45
64
  function Portal({ name, hostName = DEFAULT_PORTAL_HOST, children }) {
46
65
  useEffect(() => {
@@ -66,14 +85,21 @@ const useField = () => {
66
85
  if (!context) throw new Error("useField must be used within a FieldProvider");
67
86
  return context;
68
87
  };
88
+ const useFieldOptional = () => {
89
+ return useContext(FieldContext);
90
+ };
69
91
 
70
92
  //#endregion
71
93
  //#region src/primitives/field/field-root.tsx
72
94
  function FieldRoot(props) {
95
+ const id = useId();
73
96
  const composedStyles = [props.styles?.root, props.style];
74
97
  const Component = props.render ?? View;
75
98
  return /* @__PURE__ */ jsx(FieldContext.Provider, {
76
- value: { styles: props.styles },
99
+ value: {
100
+ styles: props.styles,
101
+ id
102
+ },
77
103
  children: /* @__PURE__ */ jsx(Component, {
78
104
  ...props,
79
105
  style: composedStyles
@@ -87,7 +113,7 @@ function FieldLabel(props) {
87
113
  const field = useField();
88
114
  return /* @__PURE__ */ jsx(props.render ?? Text, {
89
115
  ...props,
90
- htmlFor: props.htmlFor,
116
+ for: props.for ?? field.id,
91
117
  style: [field.styles?.label, props.style]
92
118
  });
93
119
  }
@@ -128,9 +154,10 @@ const calculateState$7 = (props, isFocused) => {
128
154
  if (isFocused) return "focused";
129
155
  return "default";
130
156
  };
131
- function InputPrimitive(props) {
157
+ const InputPrimitive = forwardRef((props, ref) => {
132
158
  const [isFocused, setIsFocused] = useState(false);
133
159
  const state = calculateState$7(props, isFocused);
160
+ const field = useFieldOptional();
134
161
  const composedStyles = [
135
162
  props.styles?.default?.style,
136
163
  props.styles?.[state]?.style,
@@ -143,6 +170,8 @@ function InputPrimitive(props) {
143
170
  };
144
171
  return /* @__PURE__ */ jsx(props.render ?? TextInput, {
145
172
  ...composedProps,
173
+ ref,
174
+ id: field?.id,
146
175
  onChange: void 0,
147
176
  onChangeText: props.onChange,
148
177
  onFocus: (e) => {
@@ -156,7 +185,8 @@ function InputPrimitive(props) {
156
185
  readOnly: props.isDisabled || props.readOnly,
157
186
  style: composedStyles
158
187
  });
159
- }
188
+ });
189
+ InputPrimitive.displayName = "InputPrimitive";
160
190
 
161
191
  //#endregion
162
192
  //#region src/primitives/button/button-context.tsx
@@ -1380,4 +1410,4 @@ const CalendarPrimitive = {
1380
1410
  };
1381
1411
 
1382
1412
  //#endregion
1383
- export { TextareaPrimitive as a, AvatarPrimitive as c, SelectPrimitive as d, ButtonPrimitive as f, PortalHost as h, DropdownMenuPrimitive as i, EmptyPrimitive as l, FieldPrimitive as m, PopoverPrimitive as n, BadgePrimitive as o, InputPrimitive as p, usePopover as r, ToastPrimitive as s, CalendarPrimitive as t, CardPrimitive as u };
1413
+ export { TextareaPrimitive as a, AvatarPrimitive as c, SelectPrimitive as d, ButtonPrimitive as f, PortalHost as g, Portal as h, DropdownMenuPrimitive as i, EmptyPrimitive as l, FieldPrimitive as m, PopoverPrimitive as n, BadgePrimitive as o, InputPrimitive as p, usePopover as r, ToastPrimitive as s, CalendarPrimitive as t, CardPrimitive as u };
@@ -1,4 +1,4 @@
1
- import { s as ToastPrimitive } from "./primitives-ApsPS0vU.mjs";
1
+ import { h as Portal, s as ToastPrimitive } from "./primitives-1609Y7eP.mjs";
2
2
  import React, { createContext, useContext, useEffect, useState, useSyncExternalStore } from "react";
3
3
  import { StyleSheet, View, useColorScheme } from "react-native";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -198,15 +198,16 @@ const ToastVariants = {
198
198
  //#region src/components/toast/toast.tsx
199
199
  function ToastComponent(props) {
200
200
  const useVariantStyles = ToastVariants[props.variant || "default"];
201
- const styles$1 = useVariantStyles();
201
+ const styles = useVariantStyles();
202
202
  return /* @__PURE__ */ jsxs(ToastPrimitive.Root, {
203
- styles: styles$1,
203
+ styles,
204
204
  children: [/* @__PURE__ */ jsx(ToastPrimitive.Title, { children: props.title }), !!props.description && /* @__PURE__ */ jsx(ToastPrimitive.Description, { children: props.description })]
205
205
  });
206
206
  }
207
207
 
208
208
  //#endregion
209
209
  //#region src/components/toast/toast-manager.tsx
210
+ const TOAST_PORTAL_NAME = "toast-portal";
210
211
  const store = {
211
212
  toasts: [],
212
213
  listeners: /* @__PURE__ */ new Set()
@@ -248,11 +249,10 @@ const ToastAPI = {
248
249
  function ToastContainer() {
249
250
  const toasts = useSyncExternalStore(subscribe, getSnapshot);
250
251
  if (!toasts.length) return null;
251
- return /* @__PURE__ */ jsx(View, {
252
- style: styles.container,
253
- pointerEvents: "box-none",
252
+ return /* @__PURE__ */ jsx(Portal, {
253
+ name: TOAST_PORTAL_NAME,
254
254
  children: toasts.map((toast) => /* @__PURE__ */ jsx(View, {
255
- style: styles.toastWrapper,
255
+ style: s.wrapper,
256
256
  children: /* @__PURE__ */ jsx(ToastComponent, {
257
257
  title: toast.title,
258
258
  description: toast.description,
@@ -261,21 +261,10 @@ function ToastContainer() {
261
261
  }, toast.id))
262
262
  });
263
263
  }
264
- const styles = StyleSheet.create({
265
- container: {
266
- position: "absolute",
267
- top: 50,
268
- left: 0,
269
- right: 0,
270
- alignItems: "center",
271
- gap: 12,
272
- zIndex: 9999
273
- },
274
- toastWrapper: {
275
- width: "100%",
276
- alignItems: "center"
277
- }
278
- });
264
+ const s = StyleSheet.create({ wrapper: {
265
+ width: "100%",
266
+ alignItems: "center"
267
+ } });
279
268
 
280
269
  //#endregion
281
270
  export { ThemeProvider as a, useThemedStyles as i, ToastContainer as n, useTheme as o, ToastComponent as r, ToastAPI as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@korsolutions/ui",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.mjs",
6
6
  "module": "dist/index.mjs",
@@ -27,19 +27,15 @@
27
27
  "dev-source": "./src/hooks/index.ts"
28
28
  }
29
29
  },
30
- "scripts": {
31
- "build": "tsdown",
32
- "prepublish": "tsdown",
33
- "publish": "npm publish --access public",
34
- "ts-check": "tsc --noEmit"
35
- },
36
30
  "peerDependencies": {
37
31
  "react": "*",
32
+ "react-dom": "*",
38
33
  "react-native": "*",
39
34
  "react-native-web": "*"
40
35
  },
41
36
  "devDependencies": {
42
37
  "@types/react": "^19.2.3",
38
+ "@types/react-dom": "^19.2.3",
43
39
  "tsdown": "0.17.0-beta.4"
44
40
  },
45
41
  "repository": {
@@ -48,5 +44,10 @@
48
44
  },
49
45
  "bugs": {
50
46
  "url": "https://github.com/KorSoftwareSolutions/ui/issues"
47
+ },
48
+ "scripts": {
49
+ "build": "tsdown",
50
+ "prepublish": "tsdown",
51
+ "ts-check": "tsc --noEmit"
51
52
  }
52
- }
53
+ }
@@ -1,15 +1,16 @@
1
1
  import React from "react";
2
- import { CalendarPrimitive } from "@/primitives";
2
+ import { CalendarPrimitive, CalendarRootProps } from "@/primitives";
3
3
  import { CalendarVariants } from "./variants";
4
4
 
5
5
  export interface CalendarProps {
6
- value?: Date;
7
- onChange?: (date: Date | undefined) => void;
8
- defaultMonth?: Date;
9
- minDate?: Date;
10
- maxDate?: Date;
11
- variant?: keyof typeof CalendarVariants;
6
+ value?: CalendarRootProps["value"];
7
+ onChange?: CalendarRootProps["onChange"];
8
+ defaultMonth?: CalendarRootProps["defaultMonth"];
9
+ minDate?: CalendarRootProps["minDate"];
10
+ maxDate?: CalendarRootProps["maxDate"];
12
11
  weekDays?: string[];
12
+
13
+ variant?: keyof typeof CalendarVariants;
13
14
  }
14
15
 
15
16
  export function Calendar(props: CalendarProps) {
@@ -18,7 +18,7 @@ export function Field(props: FieldProps) {
18
18
 
19
19
  return (
20
20
  <FieldPrimitive.Root styles={variantStyles}>
21
- {props.label && <FieldPrimitive.Label htmlFor={props.id}>{props.label}</FieldPrimitive.Label>}
21
+ {props.label && <FieldPrimitive.Label for={props.id}>{props.label}</FieldPrimitive.Label>}
22
22
  {props.description && <FieldPrimitive.Description>{props.description}</FieldPrimitive.Description>}
23
23
  {props.children}
24
24
  {props.error && <FieldPrimitive.Error>{props.error}</FieldPrimitive.Error>}
@@ -2,6 +2,9 @@ import React, { useSyncExternalStore } from "react";
2
2
  import { View, StyleSheet } from "react-native";
3
3
  import { ToastComponent } from "./toast";
4
4
  import { ToastVariants } from "./variants";
5
+ import { Portal } from "@/primitives/portal";
6
+
7
+ export const TOAST_PORTAL_NAME = "toast-portal";
5
8
 
6
9
  export interface ToastConfig {
7
10
  id: string;
@@ -77,27 +80,18 @@ export function ToastContainer() {
77
80
  if (!toasts.length) return null;
78
81
 
79
82
  return (
80
- <View style={styles.container} pointerEvents="box-none">
83
+ <Portal name={TOAST_PORTAL_NAME}>
81
84
  {toasts.map((toast) => (
82
- <View key={toast.id} style={styles.toastWrapper}>
85
+ <View key={toast.id} style={s.wrapper}>
83
86
  <ToastComponent title={toast.title} description={toast.description} variant={toast.variant} />
84
87
  </View>
85
88
  ))}
86
- </View>
89
+ </Portal>
87
90
  );
88
91
  }
89
92
 
90
- const styles = StyleSheet.create({
91
- container: {
92
- position: "absolute",
93
- top: 50,
94
- left: 0,
95
- right: 0,
96
- alignItems: "center",
97
- gap: 12,
98
- zIndex: 9999,
99
- },
100
- toastWrapper: {
93
+ const s = StyleSheet.create({
94
+ wrapper: {
101
95
  width: "100%",
102
96
  alignItems: "center",
103
97
  },
package/src/index.tsx CHANGED
@@ -1,13 +1,20 @@
1
1
  import { ThemeProvider } from "@/themes";
2
2
  import { PortalHost } from "./primitives/portal";
3
3
  import { ToastContainer } from "./components/toast/toast-manager";
4
+ import { PortalHostProps } from "./primitives/portal/portal.constants";
4
5
 
5
- export const UniversalUIProvider = ({ children }: { children: React.ReactNode }) => {
6
+ export interface ProviderProps {
7
+ children: React.ReactNode;
8
+
9
+ portalContainer?: PortalHostProps["container"];
10
+ }
11
+
12
+ export const UniversalUIProvider = ({ children, portalContainer }: ProviderProps) => {
6
13
  return (
7
14
  <ThemeProvider>
8
- {children}
9
- <PortalHost />
10
15
  <ToastContainer />
16
+ {children}
17
+ <PortalHost container={portalContainer} />
11
18
  </ThemeProvider>
12
19
  );
13
20
  };
@@ -3,6 +3,7 @@ import { FieldStyles } from "./types";
3
3
 
4
4
  export interface FieldContext {
5
5
  styles?: FieldStyles;
6
+ id: string;
6
7
  }
7
8
 
8
9
  export const FieldContext = createContext<FieldContext | undefined>(undefined);
@@ -14,3 +15,7 @@ export const useField = () => {
14
15
  }
15
16
  return context;
16
17
  };
18
+
19
+ export const useFieldOptional = () => {
20
+ return useContext(FieldContext);
21
+ };
@@ -5,7 +5,7 @@ import { Text, TextProps } from "react-native";
5
5
  export interface FieldLabelProps {
6
6
  children: string;
7
7
 
8
- htmlFor?: string;
8
+ for?: string;
9
9
 
10
10
  render?: (props: FieldLabelProps) => React.ReactNode;
11
11
 
@@ -16,5 +16,5 @@ export function FieldLabel(props: FieldLabelProps) {
16
16
  const field = useField();
17
17
 
18
18
  const Component = props.render ?? Text;
19
- return <Component {...props} htmlFor={props.htmlFor} style={[field.styles?.label, props.style]} />;
19
+ return <Component {...props} for={props.for ?? field.id} style={[field.styles?.label, props.style]} />;
20
20
  }
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { useId } from "react";
2
2
  import { StyleProp, View, ViewStyle } from "react-native";
3
3
  import { FieldContext } from "./context";
4
4
  import { FieldStyles } from "./types";
@@ -13,10 +13,11 @@ export interface FieldPrimitiveRootProps {
13
13
  }
14
14
 
15
15
  export function FieldRoot(props: FieldPrimitiveRootProps) {
16
+ const id = useId();
16
17
  const composedStyles = [props.styles?.root, props.style];
17
18
  const Component = props.render ?? View;
18
19
  return (
19
- <FieldContext.Provider value={{ styles: props.styles }}>
20
+ <FieldContext.Provider value={{ styles: props.styles, id }}>
20
21
  <Component {...props} style={composedStyles} />
21
22
  </FieldContext.Provider>
22
23
  );
@@ -1,10 +1,11 @@
1
1
  import { TextInput, TextInputProps } from "react-native";
2
2
  import { InputState, InputStyles } from "./types";
3
- import { useState } from "react";
3
+ import { useState, forwardRef } from "react";
4
+ import { useFieldOptional } from "../field/context";
4
5
 
5
6
  export type InputPrimitiveBaseProps = Omit<TextInputProps, "onChange"> & {
7
+ ref?: React.Ref<TextInput>;
6
8
  onChange?: TextInputProps["onChangeText"];
7
-
8
9
  isDisabled?: boolean;
9
10
  };
10
11
 
@@ -24,9 +25,10 @@ const calculateState = (props: InputPrimitiveProps, isFocused: boolean): InputSt
24
25
  return "default";
25
26
  };
26
27
 
27
- export function InputPrimitive(props: InputPrimitiveProps) {
28
+ export const InputPrimitive = forwardRef<TextInput, InputPrimitiveProps>((props, ref) => {
28
29
  const [isFocused, setIsFocused] = useState(false);
29
30
  const state = calculateState(props, isFocused);
31
+ const field = useFieldOptional();
30
32
 
31
33
  const composedStyles = [props.styles?.default?.style, props.styles?.[state]?.style, props.style];
32
34
  const composedProps = {
@@ -35,9 +37,12 @@ export function InputPrimitive(props: InputPrimitiveProps) {
35
37
  ...props,
36
38
  };
37
39
  const Component = props.render ?? TextInput;
40
+
38
41
  return (
39
42
  <Component
40
43
  {...composedProps}
44
+ ref={ref}
45
+ id={field?.id}
41
46
  onChange={undefined}
42
47
  onChangeText={props.onChange}
43
48
  onFocus={(e) => {
@@ -52,4 +57,6 @@ export function InputPrimitive(props: InputPrimitiveProps) {
52
57
  style={composedStyles}
53
58
  />
54
59
  );
55
- }
60
+ });
61
+
62
+ InputPrimitive.displayName = "InputPrimitive";
@@ -0,0 +1,15 @@
1
+ export const DEFAULT_PORTAL_HOST = "__KOR_PORTAL_HOST__";
2
+
3
+ export interface PortalHostProps {
4
+ name?: string;
5
+ container?: {
6
+ ios?: React.ComponentType<React.PropsWithChildren>;
7
+ android?: React.ComponentType<React.PropsWithChildren>;
8
+ };
9
+ }
10
+
11
+ export interface PortalProps {
12
+ name: string;
13
+ hostName?: string;
14
+ children: React.ReactNode;
15
+ }
@@ -1,8 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from "react";
3
- import { Platform, type View, type ViewStyle } from "react-native";
4
-
5
- const DEFAULT_PORTAL_HOST = "KOR_NATIVE_DEFAULT_HOST_NAME";
3
+ import { Platform, View, type ViewStyle } from "react-native";
4
+ import { DEFAULT_PORTAL_HOST, PortalHostProps, PortalProps } from "./portal.constants";
6
5
 
7
6
  type PortalMap = Map<string, React.ReactNode>;
8
7
  type PortalHostMap = Map<string, PortalMap>;
@@ -50,14 +49,35 @@ function removePortal(hostName: string, name: string) {
50
49
  emit();
51
50
  }
52
51
 
53
- export function PortalHost({ name = DEFAULT_PORTAL_HOST }: { name?: string }) {
52
+ export function PortalHost({ name = DEFAULT_PORTAL_HOST, container }: PortalHostProps) {
54
53
  const map = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
55
54
  const portalMap = map.get(name) ?? new Map<string, React.ReactNode>();
56
55
  if (portalMap.size === 0) return null;
57
- return <>{Array.from(portalMap.values())}</>;
56
+
57
+ const Container = Platform.select({
58
+ default: (props: React.PropsWithChildren) => (
59
+ <View
60
+ {...props}
61
+ style={{
62
+ position: "absolute",
63
+ top: 0,
64
+ left: 0,
65
+ right: 0,
66
+ bottom: 0,
67
+ elevation: 999,
68
+ zIndex: 999,
69
+ pointerEvents: "box-none",
70
+ }}
71
+ />
72
+ ),
73
+ ios: container?.ios,
74
+ android: container?.android,
75
+ });
76
+
77
+ return <Container>{Array.from(portalMap.values())}</Container>;
58
78
  }
59
79
 
60
- export function Portal({ name, hostName = DEFAULT_PORTAL_HOST, children }: { name: string; hostName?: string; children: React.ReactNode }) {
80
+ export function Portal({ name, hostName = DEFAULT_PORTAL_HOST, children }: PortalProps) {
61
81
  useEffect(() => {
62
82
  updatePortal(hostName, name, children);
63
83
  }, [hostName, name, children]);
@@ -0,0 +1,21 @@
1
+ import { createPortal } from "react-dom";
2
+ import { DEFAULT_PORTAL_HOST, PortalHostProps, PortalProps } from "./portal.constants";
3
+
4
+ function getPortalContainer(containerId: string) {
5
+ let container = document.getElementById(containerId);
6
+ if (!container) {
7
+ container = document.createElement("div");
8
+ container.id = containerId;
9
+ document.body.appendChild(container);
10
+ }
11
+ return container;
12
+ }
13
+
14
+ export function PortalHost({ name = DEFAULT_PORTAL_HOST }: PortalHostProps) {
15
+ return <div id={name} />;
16
+ }
17
+
18
+ export function Portal({ name, hostName = DEFAULT_PORTAL_HOST, children }: PortalProps) {
19
+ const container = getPortalContainer(hostName);
20
+ return <>{createPortal(children, container, name)}</>;
21
+ }