@innovui/react-native 0.0.0-stage → 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 (204) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -2
  3. package/dist/components/_shared/anchored-overlay.js +74 -0
  4. package/dist/components/_shared/anchored-overlay.js.map +1 -0
  5. package/dist/components/_shared/backdrop.js +25 -0
  6. package/dist/components/_shared/backdrop.js.map +1 -0
  7. package/dist/components/_shared/overlay-anchor.js +31 -0
  8. package/dist/components/_shared/overlay-anchor.js.map +1 -0
  9. package/dist/components/_shared/overlay-state.js +31 -0
  10. package/dist/components/_shared/overlay-state.js.map +1 -0
  11. package/dist/components/_shared/status.d.ts +5 -0
  12. package/dist/components/_shared/status.js +98 -0
  13. package/dist/components/_shared/status.js.map +1 -0
  14. package/dist/components/_shared/use-token.js +15 -0
  15. package/dist/components/_shared/use-token.js.map +1 -0
  16. package/dist/components/accordion/accordion.d.ts +43 -0
  17. package/dist/components/accordion/accordion.js +90 -0
  18. package/dist/components/accordion/accordion.js.map +1 -0
  19. package/dist/components/accordion/index.d.ts +2 -0
  20. package/dist/components/alert/alert.d.ts +25 -0
  21. package/dist/components/alert/alert.js +61 -0
  22. package/dist/components/alert/alert.js.map +1 -0
  23. package/dist/components/alert/index.d.ts +2 -0
  24. package/dist/components/avatar/avatar.d.ts +17 -0
  25. package/dist/components/avatar/avatar.js +51 -0
  26. package/dist/components/avatar/avatar.js.map +1 -0
  27. package/dist/components/avatar/index.d.ts +2 -0
  28. package/dist/components/badge/badge.d.ts +16 -0
  29. package/dist/components/badge/badge.js +57 -0
  30. package/dist/components/badge/badge.js.map +1 -0
  31. package/dist/components/badge/index.d.ts +2 -0
  32. package/dist/components/banner/banner.d.ts +23 -0
  33. package/dist/components/banner/banner.js +50 -0
  34. package/dist/components/banner/banner.js.map +1 -0
  35. package/dist/components/banner/index.d.ts +2 -0
  36. package/dist/components/breadcrumb/breadcrumb.d.ts +22 -0
  37. package/dist/components/breadcrumb/breadcrumb.js +54 -0
  38. package/dist/components/breadcrumb/breadcrumb.js.map +1 -0
  39. package/dist/components/breadcrumb/index.d.ts +2 -0
  40. package/dist/components/button/button.d.ts +21 -0
  41. package/dist/components/button/button.js +89 -0
  42. package/dist/components/button/button.js.map +1 -0
  43. package/dist/components/button/index.d.ts +2 -0
  44. package/dist/components/card/card.d.ts +17 -0
  45. package/dist/components/card/card.js +28 -0
  46. package/dist/components/card/card.js.map +1 -0
  47. package/dist/components/card/index.d.ts +2 -0
  48. package/dist/components/checkbox/checkbox.d.ts +18 -0
  49. package/dist/components/checkbox/checkbox.js +64 -0
  50. package/dist/components/checkbox/checkbox.js.map +1 -0
  51. package/dist/components/checkbox/index.d.ts +2 -0
  52. package/dist/components/combobox/combobox.d.ts +40 -0
  53. package/dist/components/combobox/combobox.js +101 -0
  54. package/dist/components/combobox/combobox.js.map +1 -0
  55. package/dist/components/combobox/index.d.ts +2 -0
  56. package/dist/components/container/container.d.ts +17 -0
  57. package/dist/components/container/container.js +42 -0
  58. package/dist/components/container/container.js.map +1 -0
  59. package/dist/components/container/index.d.ts +2 -0
  60. package/dist/components/date-picker/calendar.d.ts +38 -0
  61. package/dist/components/date-picker/calendar.js +137 -0
  62. package/dist/components/date-picker/calendar.js.map +1 -0
  63. package/dist/components/date-picker/date-picker.d.ts +24 -0
  64. package/dist/components/date-picker/date-picker.js +52 -0
  65. package/dist/components/date-picker/date-picker.js.map +1 -0
  66. package/dist/components/date-picker/date-presets.d.ts +15 -0
  67. package/dist/components/date-picker/date-presets.js +52 -0
  68. package/dist/components/date-picker/date-presets.js.map +1 -0
  69. package/dist/components/date-picker/date-range-picker.d.ts +24 -0
  70. package/dist/components/date-picker/date-range-picker.js +78 -0
  71. package/dist/components/date-picker/date-range-picker.js.map +1 -0
  72. package/dist/components/date-picker/date-sheet.js +33 -0
  73. package/dist/components/date-picker/date-sheet.js.map +1 -0
  74. package/dist/components/date-picker/date-trigger.js +14 -0
  75. package/dist/components/date-picker/date-trigger.js.map +1 -0
  76. package/dist/components/date-picker/dates.d.ts +8 -0
  77. package/dist/components/date-picker/dates.js +40 -0
  78. package/dist/components/date-picker/dates.js.map +1 -0
  79. package/dist/components/date-picker/index.d.ts +6 -0
  80. package/dist/components/divider/divider.d.ts +11 -0
  81. package/dist/components/divider/divider.js +16 -0
  82. package/dist/components/divider/divider.js.map +1 -0
  83. package/dist/components/divider/index.d.ts +2 -0
  84. package/dist/components/drawer/drawer.d.ts +34 -0
  85. package/dist/components/drawer/drawer.js +144 -0
  86. package/dist/components/drawer/drawer.js.map +1 -0
  87. package/dist/components/drawer/index.d.ts +2 -0
  88. package/dist/components/field/field.d.ts +31 -0
  89. package/dist/components/field/field.js +52 -0
  90. package/dist/components/field/field.js.map +1 -0
  91. package/dist/components/field/index.d.ts +2 -0
  92. package/dist/components/grid/grid.d.ts +35 -0
  93. package/dist/components/grid/grid.js +64 -0
  94. package/dist/components/grid/grid.js.map +1 -0
  95. package/dist/components/grid/index.d.ts +2 -0
  96. package/dist/components/icon-button/icon-button.d.ts +23 -0
  97. package/dist/components/icon-button/icon-button.js +48 -0
  98. package/dist/components/icon-button/icon-button.js.map +1 -0
  99. package/dist/components/icon-button/index.d.ts +2 -0
  100. package/dist/components/input/index.d.ts +2 -0
  101. package/dist/components/input/input.d.ts +22 -0
  102. package/dist/components/input/input.js +86 -0
  103. package/dist/components/input/input.js.map +1 -0
  104. package/dist/components/link/index.d.ts +2 -0
  105. package/dist/components/link/link.d.ts +13 -0
  106. package/dist/components/link/link.js +20 -0
  107. package/dist/components/link/link.js.map +1 -0
  108. package/dist/components/list/index.d.ts +2 -0
  109. package/dist/components/list/list.d.ts +26 -0
  110. package/dist/components/list/list.js +45 -0
  111. package/dist/components/list/list.js.map +1 -0
  112. package/dist/components/menu/index.d.ts +2 -0
  113. package/dist/components/menu/menu.d.ts +47 -0
  114. package/dist/components/menu/menu.js +81 -0
  115. package/dist/components/menu/menu.js.map +1 -0
  116. package/dist/components/modal/index.d.ts +2 -0
  117. package/dist/components/modal/modal.d.ts +41 -0
  118. package/dist/components/modal/modal.js +92 -0
  119. package/dist/components/modal/modal.js.map +1 -0
  120. package/dist/components/pagination/index.d.ts +2 -0
  121. package/dist/components/pagination/pagination.d.ts +21 -0
  122. package/dist/components/pagination/pagination.js +99 -0
  123. package/dist/components/pagination/pagination.js.map +1 -0
  124. package/dist/components/popover/index.d.ts +2 -0
  125. package/dist/components/popover/popover.d.ts +29 -0
  126. package/dist/components/popover/popover.js +54 -0
  127. package/dist/components/popover/popover.js.map +1 -0
  128. package/dist/components/radio/index.d.ts +2 -0
  129. package/dist/components/radio/radio.d.ts +16 -0
  130. package/dist/components/radio/radio.js +37 -0
  131. package/dist/components/radio/radio.js.map +1 -0
  132. package/dist/components/segmented-control/index.d.ts +2 -0
  133. package/dist/components/segmented-control/segmented-control.d.ts +23 -0
  134. package/dist/components/segmented-control/segmented-control.js +53 -0
  135. package/dist/components/segmented-control/segmented-control.js.map +1 -0
  136. package/dist/components/select/field-trigger.d.ts +6 -0
  137. package/dist/components/select/field-trigger.js +90 -0
  138. package/dist/components/select/field-trigger.js.map +1 -0
  139. package/dist/components/select/index.d.ts +2 -0
  140. package/dist/components/select/select.d.ts +35 -0
  141. package/dist/components/select/select.js +98 -0
  142. package/dist/components/select/select.js.map +1 -0
  143. package/dist/components/skeleton/index.d.ts +2 -0
  144. package/dist/components/skeleton/skeleton.d.ts +17 -0
  145. package/dist/components/skeleton/skeleton.js +53 -0
  146. package/dist/components/skeleton/skeleton.js.map +1 -0
  147. package/dist/components/slider/index.d.ts +2 -0
  148. package/dist/components/slider/slider.d.ts +26 -0
  149. package/dist/components/slider/slider.js +102 -0
  150. package/dist/components/slider/slider.js.map +1 -0
  151. package/dist/components/spinner/index.d.ts +2 -0
  152. package/dist/components/spinner/spinner.d.ts +13 -0
  153. package/dist/components/spinner/spinner.js +47 -0
  154. package/dist/components/spinner/spinner.js.map +1 -0
  155. package/dist/components/stack/index.d.ts +2 -0
  156. package/dist/components/stack/stack.d.ts +17 -0
  157. package/dist/components/stack/stack.js +60 -0
  158. package/dist/components/stack/stack.js.map +1 -0
  159. package/dist/components/stepper/index.d.ts +2 -0
  160. package/dist/components/stepper/stepper.d.ts +20 -0
  161. package/dist/components/stepper/stepper.js +61 -0
  162. package/dist/components/stepper/stepper.js.map +1 -0
  163. package/dist/components/switch/index.d.ts +2 -0
  164. package/dist/components/switch/switch.d.ts +15 -0
  165. package/dist/components/switch/switch.js +51 -0
  166. package/dist/components/switch/switch.js.map +1 -0
  167. package/dist/components/table/index.d.ts +2 -0
  168. package/dist/components/table/table.d.ts +42 -0
  169. package/dist/components/table/table.js +83 -0
  170. package/dist/components/table/table.js.map +1 -0
  171. package/dist/components/tabs/index.d.ts +2 -0
  172. package/dist/components/tabs/tabs.d.ts +35 -0
  173. package/dist/components/tabs/tabs.js +82 -0
  174. package/dist/components/tabs/tabs.js.map +1 -0
  175. package/dist/components/tag/index.d.ts +2 -0
  176. package/dist/components/tag/tag.d.ts +18 -0
  177. package/dist/components/tag/tag.js +37 -0
  178. package/dist/components/tag/tag.js.map +1 -0
  179. package/dist/components/textarea/index.d.ts +2 -0
  180. package/dist/components/textarea/textarea.d.ts +16 -0
  181. package/dist/components/textarea/textarea.js +46 -0
  182. package/dist/components/textarea/textarea.js.map +1 -0
  183. package/dist/components/toast/index.d.ts +2 -0
  184. package/dist/components/toast/toast.d.ts +41 -0
  185. package/dist/components/toast/toast.js +167 -0
  186. package/dist/components/toast/toast.js.map +1 -0
  187. package/dist/components/tooltip/index.d.ts +2 -0
  188. package/dist/components/tooltip/tooltip.d.ts +28 -0
  189. package/dist/components/tooltip/tooltip.js +62 -0
  190. package/dist/components/tooltip/tooltip.js.map +1 -0
  191. package/dist/components/upload/index.d.ts +2 -0
  192. package/dist/components/upload/upload.d.ts +65 -0
  193. package/dist/components/upload/upload.js +130 -0
  194. package/dist/components/upload/upload.js.map +1 -0
  195. package/dist/index.d.ts +87 -0
  196. package/dist/index.js +46 -0
  197. package/dist/tokens/generated.d.ts +371 -0
  198. package/dist/tokens/generated.js +373 -0
  199. package/dist/tokens/generated.js.map +1 -0
  200. package/dist/utils/cn.d.ts +6 -0
  201. package/dist/utils/cn.js +11 -0
  202. package/dist/utils/cn.js.map +1 -0
  203. package/package.json +61 -3
  204. package/theme.css +191 -0
@@ -0,0 +1,60 @@
1
+ import { cn } from "../../utils/cn.js";
2
+ import { View } from "react-native";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { cva } from "class-variance-authority";
5
+ //#region src/components/stack/stack.tsx
6
+ const stackVariants = cva("", {
7
+ variants: {
8
+ direction: {
9
+ column: "flex-col",
10
+ row: "flex-row"
11
+ },
12
+ gap: {
13
+ 0: "gap-0",
14
+ 1: "gap-1",
15
+ 2: "gap-2",
16
+ 3: "gap-3",
17
+ 4: "gap-4",
18
+ 6: "gap-6",
19
+ 8: "gap-8"
20
+ },
21
+ align: {
22
+ start: "items-start",
23
+ center: "items-center",
24
+ end: "items-end",
25
+ stretch: "items-stretch"
26
+ },
27
+ justify: {
28
+ start: "justify-start",
29
+ center: "justify-center",
30
+ end: "justify-end",
31
+ between: "justify-between"
32
+ },
33
+ wrap: {
34
+ true: "flex-wrap",
35
+ false: ""
36
+ }
37
+ },
38
+ defaultVariants: {
39
+ direction: "column",
40
+ gap: 4,
41
+ wrap: false
42
+ }
43
+ });
44
+ /** Empilha filhos numa direção com espaçamento uniforme (flexbox + a escala de gap do DS). */
45
+ function Stack({ className, direction, gap, align, justify, wrap, ...props }) {
46
+ return /* @__PURE__ */ jsx(View, {
47
+ className: cn(stackVariants({
48
+ direction,
49
+ gap,
50
+ align,
51
+ justify,
52
+ wrap
53
+ }), className),
54
+ ...props
55
+ });
56
+ }
57
+ //#endregion
58
+ export { Stack };
59
+
60
+ //# sourceMappingURL=stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.js","names":[],"sources":["../../../src/components/stack/stack.tsx"],"sourcesContent":["/// <reference types=\"uniwind/types\" />\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { View, type ViewProps } from 'react-native'\nimport { cn } from '../../utils/cn'\n\n// gap segue a escala de espaçamento do DS (base 4): 1=4px … 8=32px\nconst stackVariants = cva('', {\n variants: {\n direction: { column: 'flex-col', row: 'flex-row' },\n gap: {\n 0: 'gap-0',\n 1: 'gap-1',\n 2: 'gap-2',\n 3: 'gap-3',\n 4: 'gap-4',\n 6: 'gap-6',\n 8: 'gap-8',\n },\n align: {\n start: 'items-start',\n center: 'items-center',\n end: 'items-end',\n stretch: 'items-stretch',\n },\n justify: {\n start: 'justify-start',\n center: 'justify-center',\n end: 'justify-end',\n between: 'justify-between',\n },\n wrap: { true: 'flex-wrap', false: '' },\n },\n defaultVariants: { direction: 'column', gap: 4, wrap: false },\n})\n\nexport type StackProps = ViewProps & VariantProps<typeof stackVariants> & { className?: string }\n\n/** Empilha filhos numa direção com espaçamento uniforme (flexbox + a escala de gap do DS). */\nexport function Stack({ className, direction, gap, align, justify, wrap, ...props }: StackProps) {\n return (\n <View\n className={cn(stackVariants({ direction, gap, align, justify, wrap }), className)}\n {...props}\n />\n )\n}\n"],"mappings":";;;;;AAOA,MAAM,gBAAgB,IAAI,IAAI;CAC5B,UAAU;EACR,WAAW;GAAE,QAAQ;GAAY,KAAK;EAAW;EACjD,KAAK;GACH,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG;EACL;EACA,OAAO;GACL,OAAO;GACP,QAAQ;GACR,KAAK;GACL,SAAS;EACX;EACA,SAAS;GACP,OAAO;GACP,QAAQ;GACR,KAAK;GACL,SAAS;EACX;EACA,MAAM;GAAE,MAAM;GAAa,OAAO;EAAG;CACvC;CACA,iBAAiB;EAAE,WAAW;EAAU,KAAK;EAAG,MAAM;CAAM;AAC9D,CAAC;;AAKD,SAAgB,MAAM,EAAE,WAAW,WAAW,KAAK,OAAO,SAAS,MAAM,GAAG,SAAqB;CAC/F,OACE,oBAAC,MAAD;EACE,WAAW,GAAG,cAAc;GAAE;GAAW;GAAK;GAAO;GAAS;EAAK,CAAC,GAAG,SAAS;EAChF,GAAI;CACL,CAAA;AAEL"}
@@ -0,0 +1,2 @@
1
+ import { Step, StepProps, Stepper, StepperProps } from "./stepper.js";
2
+ export { Step, type StepProps, Stepper, type StepperProps };
@@ -0,0 +1,20 @@
1
+ import { ReactNode } from "react";
2
+ import { ViewProps } from "react-native";
3
+ //#region src/components/stepper/stepper.d.ts
4
+ export type StepperProps = ViewProps & {
5
+ className?: string;
6
+ /** Índice (a partir de 0) do passo atual: os anteriores ficam concluídos, os seguintes pendentes. */
7
+ current: number;
8
+ };
9
+ /** Progresso de um fluxo de 2–7 etapas (checkout, onboarding). O estado de cada `Step` vem de `current`. */
10
+ export declare function Stepper({ className, current, children, ...props }: StepperProps): import("react").JSX.Element;
11
+ export type StepProps = ViewProps & {
12
+ className?: string;
13
+ /** Complemento lido em passos concluídos (o web usa texto só para leitor de tela). */
14
+ completedLabel?: string;
15
+ children?: ReactNode;
16
+ };
17
+ /** Um passo do `Stepper`: o rótulo vai como `children`; o número vem da posição. */
18
+ export declare function Step({ className, completedLabel, children, accessibilityLabel, accessibilityState, ...props }: StepProps): import("react").JSX.Element;
19
+ //#endregion
20
+ //# sourceMappingURL=stepper.d.ts.map
@@ -0,0 +1,61 @@
1
+ import { cn } from "../../utils/cn.js";
2
+ import { CheckIcon } from "../_shared/status.js";
3
+ import { useToken } from "../_shared/use-token.js";
4
+ import { Children, createContext, useContext } from "react";
5
+ import { Text, View } from "react-native";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ //#region src/components/stepper/stepper.tsx
8
+ const StepContext = createContext({
9
+ state: "upcoming",
10
+ number: 1
11
+ });
12
+ /** Progresso de um fluxo de 2–7 etapas (checkout, onboarding). O estado de cada `Step` vem de `current`. */
13
+ function Stepper({ className, current, children, ...props }) {
14
+ return /* @__PURE__ */ jsx(View, {
15
+ className: cn("flex-row flex-wrap items-center gap-8", className),
16
+ ...props,
17
+ children: Children.toArray(children).map((child, index) => /* @__PURE__ */ jsx(StepContext.Provider, {
18
+ value: {
19
+ number: index + 1,
20
+ state: index < current ? "completed" : index === current ? "active" : "upcoming"
21
+ },
22
+ children: child
23
+ }, index))
24
+ });
25
+ }
26
+ const indicator = {
27
+ completed: "bg-bg-success-emphasis",
28
+ active: "bg-interactive-primary",
29
+ upcoming: "bg-interactive-disabled"
30
+ };
31
+ /** Um passo do `Stepper`: o rótulo vai como `children`; o número vem da posição. */
32
+ function Step({ className, completedLabel = "concluído", children, accessibilityLabel, accessibilityState, ...props }) {
33
+ const { state, number } = useContext(StepContext);
34
+ const checkColor = useToken("--color-text-inverse");
35
+ const label = accessibilityLabel ?? (typeof children === "string" && state === "completed" ? `${children} (${completedLabel})` : void 0);
36
+ return /* @__PURE__ */ jsxs(View, {
37
+ accessible: true,
38
+ accessibilityLabel: label,
39
+ accessibilityState: {
40
+ ...accessibilityState,
41
+ selected: state === "active"
42
+ },
43
+ className: cn("flex-row items-center gap-2", className),
44
+ ...props,
45
+ children: [/* @__PURE__ */ jsx(View, {
46
+ importantForAccessibility: "no-hide-descendants",
47
+ className: cn("size-7 shrink-0 items-center justify-center rounded-full", indicator[state]),
48
+ children: state === "completed" ? /* @__PURE__ */ jsx(CheckIcon, { color: checkColor }) : /* @__PURE__ */ jsx(Text, {
49
+ className: "text-[13px] font-bold text-text-inverse",
50
+ children: number
51
+ })
52
+ }), typeof children === "string" ? /* @__PURE__ */ jsx(Text, {
53
+ className: cn("text-sm font-medium", state === "upcoming" ? "text-text-tertiary" : "text-text-primary"),
54
+ children
55
+ }) : children]
56
+ });
57
+ }
58
+ //#endregion
59
+ export { Step, Stepper };
60
+
61
+ //# sourceMappingURL=stepper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stepper.js","names":[],"sources":["../../../src/components/stepper/stepper.tsx"],"sourcesContent":["/// <reference types=\"uniwind/types\" />\n\nimport { Children, createContext, type ReactNode, useContext } from 'react'\nimport { Text, View, type ViewProps } from 'react-native'\nimport { cn } from '../../utils/cn'\nimport { CheckIcon } from '../_shared/status'\nimport { useToken } from '../_shared/use-token'\n\ntype StepState = 'completed' | 'active' | 'upcoming'\n\nconst StepContext = createContext<{ state: StepState; number: number }>({\n state: 'upcoming',\n number: 1,\n})\n\nexport type StepperProps = ViewProps & {\n className?: string\n /** Índice (a partir de 0) do passo atual: os anteriores ficam concluídos, os seguintes pendentes. */\n current: number\n}\n\n/** Progresso de um fluxo de 2–7 etapas (checkout, onboarding). O estado de cada `Step` vem de `current`. */\nexport function Stepper({ className, current, children, ...props }: StepperProps) {\n return (\n <View className={cn('flex-row flex-wrap items-center gap-8', className)} {...props}>\n {Children.toArray(children).map((child, index) => (\n <StepContext.Provider\n // biome-ignore lint/suspicious/noArrayIndexKey: a posição do passo é a identidade dele\n key={index}\n value={{\n number: index + 1,\n state: index < current ? 'completed' : index === current ? 'active' : 'upcoming',\n }}\n >\n {child}\n </StepContext.Provider>\n ))}\n </View>\n )\n}\n\nconst indicator: Record<StepState, string> = {\n completed: 'bg-bg-success-emphasis',\n active: 'bg-interactive-primary',\n upcoming: 'bg-interactive-disabled',\n}\n\nexport type StepProps = ViewProps & {\n className?: string\n /** Complemento lido em passos concluídos (o web usa texto só para leitor de tela). */\n completedLabel?: string\n children?: ReactNode\n}\n\n/** Um passo do `Stepper`: o rótulo vai como `children`; o número vem da posição. */\nexport function Step({\n className,\n completedLabel = 'concluído',\n children,\n accessibilityLabel,\n accessibilityState,\n ...props\n}: StepProps) {\n const { state, number } = useContext(StepContext)\n const checkColor = useToken('--color-text-inverse')\n // Um único elemento acessível por passo; o label só é montado quando o rótulo é texto.\n const label =\n accessibilityLabel ??\n (typeof children === 'string' && state === 'completed'\n ? `${children} (${completedLabel})`\n : undefined)\n\n return (\n <View\n accessible\n accessibilityLabel={label}\n // RN não tem aria-current: o passo atual vai como `selected`.\n accessibilityState={{ ...accessibilityState, selected: state === 'active' }}\n className={cn('flex-row items-center gap-2', className)}\n {...props}\n >\n <View\n importantForAccessibility=\"no-hide-descendants\"\n className={cn('size-7 shrink-0 items-center justify-center rounded-full', indicator[state])}\n >\n {state === 'completed' ? (\n <CheckIcon color={checkColor} />\n ) : (\n <Text className=\"text-[13px] font-bold text-text-inverse\">{number}</Text>\n )}\n </View>\n {typeof children === 'string' ? (\n <Text\n className={cn(\n 'text-sm font-medium',\n state === 'upcoming' ? 'text-text-tertiary' : 'text-text-primary',\n )}\n >\n {children}\n </Text>\n ) : (\n children\n )}\n </View>\n )\n}\n"],"mappings":";;;;;;;AAUA,MAAM,cAAc,cAAoD;CACtE,OAAO;CACP,QAAQ;AACV,CAAC;;AASD,SAAgB,QAAQ,EAAE,WAAW,SAAS,UAAU,GAAG,SAAuB;CAChF,OACE,oBAAC,MAAD;EAAM,WAAW,GAAG,yCAAyC,SAAS;EAAG,GAAI;EAC1E,UAAA,SAAS,QAAQ,QAAQ,CAAC,CAAC,KAAK,OAAO,UACtC,oBAAC,YAAY,UAAb;GAGE,OAAO;IACL,QAAQ,QAAQ;IAChB,OAAO,QAAQ,UAAU,cAAc,UAAU,UAAU,WAAW;GACxE;GAEC,UAAA;EACmB,GAPf,KAOe,CACvB;CACG,CAAA;AAEV;AAEA,MAAM,YAAuC;CAC3C,WAAW;CACX,QAAQ;CACR,UAAU;AACZ;;AAUA,SAAgB,KAAK,EACnB,WACA,iBAAiB,aACjB,UACA,oBACA,oBACA,GAAG,SACS;CACZ,MAAM,EAAE,OAAO,WAAW,WAAW,WAAW;CAChD,MAAM,aAAa,SAAS,sBAAsB;CAElD,MAAM,QACJ,uBACC,OAAO,aAAa,YAAY,UAAU,cACvC,GAAG,SAAS,IAAI,eAAe,KAC/B,KAAA;CAEN,OACE,qBAAC,MAAD;EACE,YAAA;EACA,oBAAoB;EAEpB,oBAAoB;GAAE,GAAG;GAAoB,UAAU,UAAU;EAAS;EAC1E,WAAW,GAAG,+BAA+B,SAAS;EACtD,GAAI;EANN,UAAA,CAQE,oBAAC,MAAD;GACE,2BAA0B;GAC1B,WAAW,GAAG,4DAA4D,UAAU,MAAM;GAEzF,UAAA,UAAU,cACT,oBAAC,WAAD,EAAW,OAAO,WAAa,CAAA,IAE/B,oBAAC,MAAD;IAAM,WAAU;IAA2C,UAAA;GAAa,CAAA;EAEtE,CAAA,GACL,OAAO,aAAa,WACnB,oBAAC,MAAD;GACE,WAAW,GACT,uBACA,UAAU,aAAa,uBAAuB,mBAChD;GAEC;EACG,CAAA,IAEN,QAEE;;AAEV"}
@@ -0,0 +1,2 @@
1
+ import { Switch, SwitchProps } from "./switch.js";
2
+ export { Switch, type SwitchProps };
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from "react";
2
+ import { PressableProps } from "react-native";
3
+ //#region src/components/switch/switch.d.ts
4
+ export type SwitchProps = Omit<PressableProps, 'children' | 'style' | 'onPress'> & {
5
+ className?: string;
6
+ label?: ReactNode;
7
+ /** Controlado. Sem ele, o componente guarda o próprio estado (começa em `defaultChecked`). */
8
+ checked?: boolean;
9
+ defaultChecked?: boolean;
10
+ /** Chamado com o novo valor a cada toque, com efeito imediato (sem submit). */
11
+ onCheckedChange?: (checked: boolean) => void;
12
+ };
13
+ export declare function Switch({ label, checked, defaultChecked, onCheckedChange, disabled, className, accessibilityState, ...props }: SwitchProps): import("react").JSX.Element;
14
+ //#endregion
15
+ //# sourceMappingURL=switch.d.ts.map
@@ -0,0 +1,51 @@
1
+ import { cn } from "../../utils/cn.js";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { Animated, Pressable, Text, View } from "react-native";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/components/switch/switch.tsx
6
+ const TRAVEL = 20;
7
+ function Switch({ label, checked, defaultChecked = false, onCheckedChange, disabled, className, accessibilityState, ...props }) {
8
+ const [uncontrolled, setUncontrolled] = useState(defaultChecked);
9
+ const isChecked = checked ?? uncontrolled;
10
+ const isDisabled = Boolean(disabled);
11
+ const position = useRef(new Animated.Value(isChecked ? TRAVEL : 0)).current;
12
+ useEffect(() => {
13
+ Animated.timing(position, {
14
+ toValue: isChecked ? TRAVEL : 0,
15
+ duration: 150,
16
+ useNativeDriver: true
17
+ }).start();
18
+ }, [isChecked, position]);
19
+ return /* @__PURE__ */ jsxs(Pressable, {
20
+ accessibilityRole: "switch",
21
+ accessibilityState: {
22
+ ...accessibilityState,
23
+ checked: isChecked,
24
+ disabled: isDisabled
25
+ },
26
+ disabled: isDisabled,
27
+ onPress: () => {
28
+ setUncontrolled(!isChecked);
29
+ onCheckedChange?.(!isChecked);
30
+ },
31
+ className: cn("min-h-11 flex-row items-center gap-2.5 self-start", className),
32
+ ...props,
33
+ children: [/* @__PURE__ */ jsx(View, {
34
+ className: cn("h-6 w-11 justify-center rounded-full bg-selection-toggle-track-off", isChecked && "bg-selection-bg-selected", isDisabled && "bg-selection-bg-disabled"),
35
+ children: /* @__PURE__ */ jsx(Animated.View, {
36
+ style: {
37
+ marginLeft: 2,
38
+ transform: [{ translateX: position }]
39
+ },
40
+ children: /* @__PURE__ */ jsx(View, { className: "size-5 rounded-full bg-selection-indicator-selected" })
41
+ })
42
+ }), typeof label === "string" ? /* @__PURE__ */ jsx(Text, {
43
+ className: cn("text-sm font-medium text-selection-text-label", isDisabled && "text-selection-text-disabled"),
44
+ children: label
45
+ }) : label]
46
+ });
47
+ }
48
+ //#endregion
49
+ export { Switch };
50
+
51
+ //# sourceMappingURL=switch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switch.js","names":[],"sources":["../../../src/components/switch/switch.tsx"],"sourcesContent":["/// <reference types=\"uniwind/types\" />\n\nimport { type ReactNode, useEffect, useRef, useState } from 'react'\nimport { Animated, Pressable, type PressableProps, Text, View } from 'react-native'\nimport { cn } from '../../utils/cn'\n\nexport type SwitchProps = Omit<PressableProps, 'children' | 'style' | 'onPress'> & {\n className?: string\n label?: ReactNode\n /** Controlado. Sem ele, o componente guarda o próprio estado (começa em `defaultChecked`). */\n checked?: boolean\n defaultChecked?: boolean\n /** Chamado com o novo valor a cada toque, com efeito imediato (sem submit). */\n onCheckedChange?: (checked: boolean) => void\n}\n\n// Trilho de 44x24 e polegar de 20 com 2 de folga: curso de 20px.\nconst TRAVEL = 20\n\nexport function Switch({\n label,\n checked,\n defaultChecked = false,\n onCheckedChange,\n disabled,\n className,\n accessibilityState,\n ...props\n}: SwitchProps) {\n const [uncontrolled, setUncontrolled] = useState(defaultChecked)\n const isChecked = checked ?? uncontrolled\n const isDisabled = Boolean(disabled)\n const position = useRef(new Animated.Value(isChecked ? TRAVEL : 0)).current\n\n useEffect(() => {\n Animated.timing(position, {\n toValue: isChecked ? TRAVEL : 0,\n duration: 150,\n useNativeDriver: true,\n }).start()\n }, [isChecked, position])\n\n return (\n <Pressable\n accessibilityRole=\"switch\"\n accessibilityState={{ ...accessibilityState, checked: isChecked, disabled: isDisabled }}\n disabled={isDisabled}\n onPress={() => {\n setUncontrolled(!isChecked)\n onCheckedChange?.(!isChecked)\n }}\n className={cn('min-h-11 flex-row items-center gap-2.5 self-start', className)}\n {...props}\n >\n <View\n className={cn(\n 'h-6 w-11 justify-center rounded-full bg-selection-toggle-track-off',\n isChecked && 'bg-selection-bg-selected',\n isDisabled && 'bg-selection-bg-disabled',\n )}\n >\n <Animated.View style={{ marginLeft: 2, transform: [{ translateX: position }] }}>\n <View className=\"size-5 rounded-full bg-selection-indicator-selected\" />\n </Animated.View>\n </View>\n {typeof label === 'string' ? (\n <Text\n className={cn(\n 'text-sm font-medium text-selection-text-label',\n isDisabled && 'text-selection-text-disabled',\n )}\n >\n {label}\n </Text>\n ) : (\n label\n )}\n </Pressable>\n )\n}\n"],"mappings":";;;;;AAiBA,MAAM,SAAS;AAEf,SAAgB,OAAO,EACrB,OACA,SACA,iBAAiB,OACjB,iBACA,UACA,WACA,oBACA,GAAG,SACW;CACd,MAAM,CAAC,cAAc,mBAAmB,SAAS,cAAc;CAC/D,MAAM,YAAY,WAAW;CAC7B,MAAM,aAAa,QAAQ,QAAQ;CACnC,MAAM,WAAW,OAAO,IAAI,SAAS,MAAM,YAAY,SAAS,CAAC,CAAC,CAAC,CAAC;CAEpE,gBAAgB;EACd,SAAS,OAAO,UAAU;GACxB,SAAS,YAAY,SAAS;GAC9B,UAAU;GACV,iBAAiB;EACnB,CAAC,CAAC,CAAC,MAAM;CACX,GAAG,CAAC,WAAW,QAAQ,CAAC;CAExB,OACE,qBAAC,WAAD;EACE,mBAAkB;EAClB,oBAAoB;GAAE,GAAG;GAAoB,SAAS;GAAW,UAAU;EAAW;EACtF,UAAU;EACV,eAAe;GACb,gBAAgB,CAAC,SAAS;GAC1B,kBAAkB,CAAC,SAAS;EAC9B;EACA,WAAW,GAAG,qDAAqD,SAAS;EAC5E,GAAI;EATN,UAAA,CAWE,oBAAC,MAAD;GACE,WAAW,GACT,sEACA,aAAa,4BACb,cAAc,0BAChB;GAEA,UAAA,oBAAC,SAAS,MAAV;IAAe,OAAO;KAAE,YAAY;KAAG,WAAW,CAAC,EAAE,YAAY,SAAS,CAAC;IAAE;IAC3E,UAAA,oBAAC,MAAD,EAAM,WAAU,sDAAuD,CAAA;GAC1D,CAAA;EACX,CAAA,GACL,OAAO,UAAU,WAChB,oBAAC,MAAD;GACE,WAAW,GACT,iDACA,cAAc,8BAChB;GAEC,UAAA;EACG,CAAA,IAEN,KAEO;;AAEf"}
@@ -0,0 +1,2 @@
1
+ import { Table, TableBody, TableBodyProps, TableCaption, TableCaptionProps, TableCell, TableCellProps, TableHead, TableHeadProps, TableHeader, TableHeaderProps, TableProps, TableRow, TableRowProps } from "./table.js";
2
+ export { Table, TableBody, type TableBodyProps, TableCaption, type TableCaptionProps, TableCell, type TableCellProps, TableHead, type TableHeadProps, TableHeader, type TableHeaderProps, type TableProps, TableRow, type TableRowProps };
@@ -0,0 +1,42 @@
1
+ import { ReactNode } from "react";
2
+ import { ViewProps } from "react-native";
3
+ //#region src/components/table/table.d.ts
4
+ export type TableProps = ViewProps & {
5
+ className?: string;
6
+ };
7
+ /**
8
+ * Tabela de dados. Em telas estreitas a tabela rola na horizontal, sem estourar o layout.
9
+ * Dê um `TableCaption` (ou `accessibilityLabel`) para nomear a tabela.
10
+ */
11
+ export declare function Table({ className, ...props }: TableProps): import("react").JSX.Element;
12
+ export type TableCaptionProps = Omit<ViewProps, 'children'> & {
13
+ className?: string;
14
+ children?: ReactNode;
15
+ };
16
+ /** Nome e descrição da tabela, lidos antes do conteúdo por leitores de tela. */
17
+ export declare function TableCaption({ className, children, ...props }: TableCaptionProps): import("react").JSX.Element;
18
+ export type TableHeaderProps = ViewProps & {
19
+ className?: string;
20
+ };
21
+ export declare function TableHeader({ className, ...props }: TableHeaderProps): import("react").JSX.Element;
22
+ export type TableBodyProps = ViewProps & {
23
+ className?: string;
24
+ };
25
+ export declare function TableBody({ className, ...props }: TableBodyProps): import("react").JSX.Element;
26
+ export type TableRowProps = ViewProps & {
27
+ className?: string;
28
+ };
29
+ export declare function TableRow({ className, ...props }: TableRowProps): import("react").JSX.Element;
30
+ export type TableHeadProps = Omit<ViewProps, 'children'> & {
31
+ className?: string;
32
+ children?: ReactNode;
33
+ };
34
+ /** Célula de cabeçalho. RN não tem `aria-sort`: indique a ordenação no próprio conteúdo. */
35
+ export declare function TableHead({ className, children, ...props }: TableHeadProps): import("react").JSX.Element;
36
+ export type TableCellProps = Omit<ViewProps, 'children'> & {
37
+ className?: string;
38
+ children?: ReactNode;
39
+ };
40
+ export declare function TableCell({ className, children, ...props }: TableCellProps): import("react").JSX.Element;
41
+ //#endregion
42
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1,83 @@
1
+ import { cn } from "../../utils/cn.js";
2
+ import { ScrollView, Text, View } from "react-native";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/components/table/table.tsx
5
+ /** Texto puro vira `Text` estilizado; qualquer outro nó é renderizado como veio. */
6
+ function CellContent({ children, className }) {
7
+ return typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx(Text, {
8
+ className,
9
+ children
10
+ }) : children;
11
+ }
12
+ /**
13
+ * Tabela de dados. Em telas estreitas a tabela rola na horizontal, sem estourar o layout.
14
+ * Dê um `TableCaption` (ou `accessibilityLabel`) para nomear a tabela.
15
+ */
16
+ function Table({ className, ...props }) {
17
+ return /* @__PURE__ */ jsx(ScrollView, {
18
+ horizontal: true,
19
+ showsHorizontalScrollIndicator: false,
20
+ className: "w-full grow-0",
21
+ children: /* @__PURE__ */ jsx(View, {
22
+ role: "grid",
23
+ className: cn("min-w-full", className),
24
+ ...props
25
+ })
26
+ });
27
+ }
28
+ /** Nome e descrição da tabela, lidos antes do conteúdo por leitores de tela. */
29
+ function TableCaption({ className, children, ...props }) {
30
+ return /* @__PURE__ */ jsx(View, {
31
+ className: cn("pb-3", className),
32
+ ...props,
33
+ children: /* @__PURE__ */ jsx(CellContent, {
34
+ className: "text-sm text-text-secondary",
35
+ children
36
+ })
37
+ });
38
+ }
39
+ function TableHeader({ className, ...props }) {
40
+ return /* @__PURE__ */ jsx(View, {
41
+ className: cn("bg-bg-secondary", className),
42
+ ...props
43
+ });
44
+ }
45
+ function TableBody({ className, ...props }) {
46
+ return /* @__PURE__ */ jsx(View, {
47
+ className,
48
+ ...props
49
+ });
50
+ }
51
+ function TableRow({ className, ...props }) {
52
+ return /* @__PURE__ */ jsx(View, {
53
+ className: cn("flex-row border-b border-border-default", className),
54
+ ...props
55
+ });
56
+ }
57
+ /** Célula de cabeçalho. RN não tem `aria-sort`: indique a ordenação no próprio conteúdo. */
58
+ function TableHead({ className, children, ...props }) {
59
+ return /* @__PURE__ */ jsx(View, {
60
+ accessible: true,
61
+ accessibilityRole: "header",
62
+ className: cn("min-w-24 flex-1 px-4 py-3", className),
63
+ ...props,
64
+ children: /* @__PURE__ */ jsx(CellContent, {
65
+ className: "text-xs font-medium text-text-secondary",
66
+ children
67
+ })
68
+ });
69
+ }
70
+ function TableCell({ className, children, ...props }) {
71
+ return /* @__PURE__ */ jsx(View, {
72
+ className: cn("min-w-24 flex-1 px-4 py-3", className),
73
+ ...props,
74
+ children: /* @__PURE__ */ jsx(CellContent, {
75
+ className: "text-sm text-text-primary",
76
+ children
77
+ })
78
+ });
79
+ }
80
+ //#endregion
81
+ export { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow };
82
+
83
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.js","names":[],"sources":["../../../src/components/table/table.tsx"],"sourcesContent":["/// <reference types=\"uniwind/types\" />\n\nimport type { ReactNode } from 'react'\nimport { ScrollView, Text, View, type ViewProps } from 'react-native'\nimport { cn } from '../../utils/cn'\n\n// RN não tem colunas automáticas: cada célula é `flex-1` com largura mínima, e a tabela rola na\n// horizontal quando as colunas não cabem. Ajuste a largura de uma coluna com `className`\n// (ex.: `w-40 flex-none`) em TODAS as células dela.\n\n/** Texto puro vira `Text` estilizado; qualquer outro nó é renderizado como veio. */\nfunction CellContent({ children, className }: { children: ReactNode; className: string }) {\n return typeof children === 'string' || typeof children === 'number' ? (\n <Text className={className}>{children}</Text>\n ) : (\n children\n )\n}\n\nexport type TableProps = ViewProps & {\n className?: string\n}\n\n/**\n * Tabela de dados. Em telas estreitas a tabela rola na horizontal, sem estourar o layout.\n * Dê um `TableCaption` (ou `accessibilityLabel`) para nomear a tabela.\n */\nexport function Table({ className, ...props }: TableProps) {\n return (\n <ScrollView horizontal showsHorizontalScrollIndicator={false} className=\"w-full grow-0\">\n <View role=\"grid\" className={cn('min-w-full', className)} {...props} />\n </ScrollView>\n )\n}\n\nexport type TableCaptionProps = Omit<ViewProps, 'children'> & {\n className?: string\n children?: ReactNode\n}\n\n/** Nome e descrição da tabela, lidos antes do conteúdo por leitores de tela. */\nexport function TableCaption({ className, children, ...props }: TableCaptionProps) {\n return (\n <View className={cn('pb-3', className)} {...props}>\n <CellContent className=\"text-sm text-text-secondary\">{children}</CellContent>\n </View>\n )\n}\n\nexport type TableHeaderProps = ViewProps & { className?: string }\n\nexport function TableHeader({ className, ...props }: TableHeaderProps) {\n return <View className={cn('bg-bg-secondary', className)} {...props} />\n}\n\nexport type TableBodyProps = ViewProps & { className?: string }\n\nexport function TableBody({ className, ...props }: TableBodyProps) {\n return <View className={className} {...props} />\n}\n\nexport type TableRowProps = ViewProps & { className?: string }\n\nexport function TableRow({ className, ...props }: TableRowProps) {\n return <View className={cn('flex-row border-b border-border-default', className)} {...props} />\n}\n\nexport type TableHeadProps = Omit<ViewProps, 'children'> & {\n className?: string\n children?: ReactNode\n}\n\n/** Célula de cabeçalho. RN não tem `aria-sort`: indique a ordenação no próprio conteúdo. */\nexport function TableHead({ className, children, ...props }: TableHeadProps) {\n return (\n <View\n accessible\n accessibilityRole=\"header\"\n className={cn('min-w-24 flex-1 px-4 py-3', className)}\n {...props}\n >\n <CellContent className=\"text-xs font-medium text-text-secondary\">{children}</CellContent>\n </View>\n )\n}\n\nexport type TableCellProps = Omit<ViewProps, 'children'> & {\n className?: string\n children?: ReactNode\n}\n\nexport function TableCell({ className, children, ...props }: TableCellProps) {\n return (\n <View className={cn('min-w-24 flex-1 px-4 py-3', className)} {...props}>\n <CellContent className=\"text-sm text-text-primary\">{children}</CellContent>\n </View>\n )\n}\n"],"mappings":";;;;;AAWA,SAAS,YAAY,EAAE,UAAU,aAAyD;CACxF,OAAO,OAAO,aAAa,YAAY,OAAO,aAAa,WACzD,oBAAC,MAAD;EAAiB;EAAY;CAAe,CAAA,IAE5C;AAEJ;;;;;AAUA,SAAgB,MAAM,EAAE,WAAW,GAAG,SAAqB;CACzD,OACE,oBAAC,YAAD;EAAY,YAAA;EAAW,gCAAgC;EAAO,WAAU;EACtE,UAAA,oBAAC,MAAD;GAAM,MAAK;GAAO,WAAW,GAAG,cAAc,SAAS;GAAG,GAAI;EAAQ,CAAA;CAC5D,CAAA;AAEhB;;AAQA,SAAgB,aAAa,EAAE,WAAW,UAAU,GAAG,SAA4B;CACjF,OACE,oBAAC,MAAD;EAAM,WAAW,GAAG,QAAQ,SAAS;EAAG,GAAI;EAC1C,UAAA,oBAAC,aAAD;GAAa,WAAU;GAA+B;EAAsB,CAAA;CACxE,CAAA;AAEV;AAIA,SAAgB,YAAY,EAAE,WAAW,GAAG,SAA2B;CACrE,OAAO,oBAAC,MAAD;EAAM,WAAW,GAAG,mBAAmB,SAAS;EAAG,GAAI;CAAQ,CAAA;AACxE;AAIA,SAAgB,UAAU,EAAE,WAAW,GAAG,SAAyB;CACjE,OAAO,oBAAC,MAAD;EAAiB;EAAW,GAAI;CAAQ,CAAA;AACjD;AAIA,SAAgB,SAAS,EAAE,WAAW,GAAG,SAAwB;CAC/D,OAAO,oBAAC,MAAD;EAAM,WAAW,GAAG,2CAA2C,SAAS;EAAG,GAAI;CAAQ,CAAA;AAChG;;AAQA,SAAgB,UAAU,EAAE,WAAW,UAAU,GAAG,SAAyB;CAC3E,OACE,oBAAC,MAAD;EACE,YAAA;EACA,mBAAkB;EAClB,WAAW,GAAG,6BAA6B,SAAS;EACpD,GAAI;EAEJ,UAAA,oBAAC,aAAD;GAAa,WAAU;GAA2C;EAAsB,CAAA;CACpF,CAAA;AAEV;AAOA,SAAgB,UAAU,EAAE,WAAW,UAAU,GAAG,SAAyB;CAC3E,OACE,oBAAC,MAAD;EAAM,WAAW,GAAG,6BAA6B,SAAS;EAAG,GAAI;EAC/D,UAAA,oBAAC,aAAD;GAAa,WAAU;GAA6B;EAAsB,CAAA;CACtE,CAAA;AAEV"}
@@ -0,0 +1,2 @@
1
+ import { Tab, TabList, TabListProps, TabPanel, TabPanelProps, TabProps, Tabs, TabsProps } from "./tabs.js";
2
+ export { Tab, TabList, type TabListProps, TabPanel, type TabPanelProps, type TabProps, Tabs, type TabsProps };
@@ -0,0 +1,35 @@
1
+ import { ReactNode } from "react";
2
+ import { PressableProps, ScrollViewProps, ViewProps } from "react-native";
3
+ //#region src/components/tabs/tabs.d.ts
4
+ export type TabsProps = ViewProps & {
5
+ className?: string;
6
+ /** Aba ativa (controlado). */
7
+ value?: string;
8
+ /** Aba ativa inicial (não controlado). */
9
+ defaultValue?: string;
10
+ onValueChange?: (value: string) => void;
11
+ };
12
+ /** Raiz das abas: controla qual `Tab` está ativa (`value`/`defaultValue`/`onValueChange`). */
13
+ export declare function Tabs({ className, value, defaultValue, onValueChange, ...props }: TabsProps): import("react").JSX.Element;
14
+ export type TabListProps = Omit<ScrollViewProps, 'horizontal' | 'style'> & {
15
+ className?: string;
16
+ };
17
+ /** Lista de gatilhos. Rola na horizontal quando as abas não cabem na tela. */
18
+ export declare function TabList({ className, ...props }: TabListProps): import("react").JSX.Element;
19
+ export type TabProps = Omit<PressableProps, 'children' | 'style'> & {
20
+ className?: string;
21
+ /** Valor que liga a aba ao `TabPanel` de mesmo `value`. */
22
+ value: string;
23
+ /** Ícone à esquerda do rótulo (ex.: um ícone SVG de 24px). */
24
+ icon?: ReactNode;
25
+ children?: ReactNode;
26
+ };
27
+ export declare function Tab({ className, value, icon, children, disabled, onPress, accessibilityState, ...props }: TabProps): import("react").JSX.Element;
28
+ export type TabPanelProps = ViewProps & {
29
+ className?: string;
30
+ value: string;
31
+ };
32
+ /** Painel da aba: só é montado enquanto a aba de mesmo `value` está ativa (igual ao web). */
33
+ export declare function TabPanel({ className, value, ...props }: TabPanelProps): import("react").JSX.Element | null;
34
+ //#endregion
35
+ //# sourceMappingURL=tabs.d.ts.map
@@ -0,0 +1,82 @@
1
+ import { cn } from "../../utils/cn.js";
2
+ import { createContext, useContext, useMemo, useState } from "react";
3
+ import { Pressable, ScrollView, Text, View } from "react-native";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/components/tabs/tabs.tsx
6
+ const TabsContext = createContext({
7
+ value: void 0,
8
+ setValue: () => {}
9
+ });
10
+ /** Raiz das abas: controla qual `Tab` está ativa (`value`/`defaultValue`/`onValueChange`). */
11
+ function Tabs({ className, value, defaultValue, onValueChange, ...props }) {
12
+ const [internal, setInternal] = useState(defaultValue);
13
+ const current = value !== void 0 ? value : internal;
14
+ const context = useMemo(() => ({
15
+ value: current,
16
+ setValue: (next) => {
17
+ if (value === void 0) setInternal(next);
18
+ onValueChange?.(next);
19
+ }
20
+ }), [
21
+ current,
22
+ value,
23
+ onValueChange
24
+ ]);
25
+ return /* @__PURE__ */ jsx(TabsContext.Provider, {
26
+ value: context,
27
+ children: /* @__PURE__ */ jsx(View, {
28
+ className,
29
+ ...props
30
+ })
31
+ });
32
+ }
33
+ /** Lista de gatilhos. Rola na horizontal quando as abas não cabem na tela. */
34
+ function TabList({ className, ...props }) {
35
+ return /* @__PURE__ */ jsx(ScrollView, {
36
+ horizontal: true,
37
+ showsHorizontalScrollIndicator: false,
38
+ accessibilityRole: "tablist",
39
+ className: cn("grow-0", className),
40
+ contentContainerClassName: "items-start",
41
+ ...props
42
+ });
43
+ }
44
+ function Tab({ className, value, icon, children, disabled, onPress, accessibilityState, ...props }) {
45
+ const { value: active, setValue } = useContext(TabsContext);
46
+ const selected = active === value;
47
+ return /* @__PURE__ */ jsxs(Pressable, {
48
+ accessibilityRole: "tab",
49
+ accessibilityState: {
50
+ ...accessibilityState,
51
+ selected,
52
+ disabled: Boolean(disabled)
53
+ },
54
+ disabled,
55
+ onPress: (event) => {
56
+ setValue(value);
57
+ onPress?.(event);
58
+ },
59
+ className: cn("items-start gap-[6px] px-3 pt-2", className),
60
+ ...props,
61
+ children: [/* @__PURE__ */ jsxs(View, {
62
+ className: "flex-row items-center gap-1",
63
+ children: [icon, typeof children === "string" ? /* @__PURE__ */ jsx(Text, {
64
+ className: cn("text-sm text-text-secondary", selected && "font-medium text-text-brand", disabled && "text-text-disabled"),
65
+ children
66
+ }) : children]
67
+ }), /* @__PURE__ */ jsx(View, { className: cn("h-0.5 self-stretch bg-transparent", selected && "bg-interactive-primary") })]
68
+ });
69
+ }
70
+ /** Painel da aba: só é montado enquanto a aba de mesmo `value` está ativa (igual ao web). */
71
+ function TabPanel({ className, value, ...props }) {
72
+ const { value: active } = useContext(TabsContext);
73
+ if (active !== value) return null;
74
+ return /* @__PURE__ */ jsx(View, {
75
+ className,
76
+ ...props
77
+ });
78
+ }
79
+ //#endregion
80
+ export { Tab, TabList, TabPanel, Tabs };
81
+
82
+ //# sourceMappingURL=tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.js","names":[],"sources":["../../../src/components/tabs/tabs.tsx"],"sourcesContent":["/// <reference types=\"uniwind/types\" />\n\nimport { createContext, type ReactNode, useContext, useMemo, useState } from 'react'\nimport {\n Pressable,\n type PressableProps,\n ScrollView,\n type ScrollViewProps,\n Text,\n View,\n type ViewProps,\n} from 'react-native'\nimport { cn } from '../../utils/cn'\n\ntype TabsContextValue = { value: string | undefined; setValue: (value: string) => void }\n\nconst TabsContext = createContext<TabsContextValue>({ value: undefined, setValue: () => {} })\n\nexport type TabsProps = ViewProps & {\n className?: string\n /** Aba ativa (controlado). */\n value?: string\n /** Aba ativa inicial (não controlado). */\n defaultValue?: string\n onValueChange?: (value: string) => void\n}\n\n/** Raiz das abas: controla qual `Tab` está ativa (`value`/`defaultValue`/`onValueChange`). */\nexport function Tabs({ className, value, defaultValue, onValueChange, ...props }: TabsProps) {\n const [internal, setInternal] = useState(defaultValue)\n const current = value !== undefined ? value : internal\n\n const context = useMemo(\n () => ({\n value: current,\n setValue: (next: string) => {\n if (value === undefined) setInternal(next)\n onValueChange?.(next)\n },\n }),\n [current, value, onValueChange],\n )\n\n return (\n <TabsContext.Provider value={context}>\n <View className={className} {...props} />\n </TabsContext.Provider>\n )\n}\n\nexport type TabListProps = Omit<ScrollViewProps, 'horizontal' | 'style'> & {\n className?: string\n}\n\n/** Lista de gatilhos. Rola na horizontal quando as abas não cabem na tela. */\nexport function TabList({ className, ...props }: TabListProps) {\n return (\n <ScrollView\n horizontal\n showsHorizontalScrollIndicator={false}\n accessibilityRole=\"tablist\"\n className={cn('grow-0', className)}\n contentContainerClassName=\"items-start\"\n {...props}\n />\n )\n}\n\nexport type TabProps = Omit<PressableProps, 'children' | 'style'> & {\n className?: string\n /** Valor que liga a aba ao `TabPanel` de mesmo `value`. */\n value: string\n /** Ícone à esquerda do rótulo (ex.: um ícone SVG de 24px). */\n icon?: ReactNode\n children?: ReactNode\n}\n\nexport function Tab({\n className,\n value,\n icon,\n children,\n disabled,\n onPress,\n accessibilityState,\n ...props\n}: TabProps) {\n const { value: active, setValue } = useContext(TabsContext)\n const selected = active === value\n\n return (\n <Pressable\n accessibilityRole=\"tab\"\n accessibilityState={{ ...accessibilityState, selected, disabled: Boolean(disabled) }}\n disabled={disabled}\n onPress={(event) => {\n setValue(value)\n onPress?.(event)\n }}\n className={cn('items-start gap-[6px] px-3 pt-2', className)}\n {...props}\n >\n <View className=\"flex-row items-center gap-1\">\n {icon}\n {typeof children === 'string' ? (\n <Text\n className={cn(\n 'text-sm text-text-secondary',\n selected && 'font-medium text-text-brand',\n disabled && 'text-text-disabled',\n )}\n >\n {children}\n </Text>\n ) : (\n children\n )}\n </View>\n <View\n className={cn('h-0.5 self-stretch bg-transparent', selected && 'bg-interactive-primary')}\n />\n </Pressable>\n )\n}\n\nexport type TabPanelProps = ViewProps & {\n className?: string\n value: string\n}\n\n/** Painel da aba: só é montado enquanto a aba de mesmo `value` está ativa (igual ao web). */\nexport function TabPanel({ className, value, ...props }: TabPanelProps) {\n const { value: active } = useContext(TabsContext)\n if (active !== value) return null\n return <View className={className} {...props} />\n}\n"],"mappings":";;;;;AAgBA,MAAM,cAAc,cAAgC;CAAE,OAAO,KAAA;CAAW,gBAAgB,CAAC;AAAE,CAAC;;AAY5F,SAAgB,KAAK,EAAE,WAAW,OAAO,cAAc,eAAe,GAAG,SAAoB;CAC3F,MAAM,CAAC,UAAU,eAAe,SAAS,YAAY;CACrD,MAAM,UAAU,UAAU,KAAA,IAAY,QAAQ;CAE9C,MAAM,UAAU,eACP;EACL,OAAO;EACP,WAAW,SAAiB;GAC1B,IAAI,UAAU,KAAA,GAAW,YAAY,IAAI;GACzC,gBAAgB,IAAI;EACtB;CACF,IACA;EAAC;EAAS;EAAO;CAAa,CAChC;CAEA,OACE,oBAAC,YAAY,UAAb;EAAsB,OAAO;EAC3B,UAAA,oBAAC,MAAD;GAAiB;GAAW,GAAI;EAAQ,CAAA;CACpB,CAAA;AAE1B;;AAOA,SAAgB,QAAQ,EAAE,WAAW,GAAG,SAAuB;CAC7D,OACE,oBAAC,YAAD;EACE,YAAA;EACA,gCAAgC;EAChC,mBAAkB;EAClB,WAAW,GAAG,UAAU,SAAS;EACjC,2BAA0B;EAC1B,GAAI;CACL,CAAA;AAEL;AAWA,SAAgB,IAAI,EAClB,WACA,OACA,MACA,UACA,UACA,SACA,oBACA,GAAG,SACQ;CACX,MAAM,EAAE,OAAO,QAAQ,aAAa,WAAW,WAAW;CAC1D,MAAM,WAAW,WAAW;CAE5B,OACE,qBAAC,WAAD;EACE,mBAAkB;EAClB,oBAAoB;GAAE,GAAG;GAAoB;GAAU,UAAU,QAAQ,QAAQ;EAAE;EACzE;EACV,UAAU,UAAU;GAClB,SAAS,KAAK;GACd,UAAU,KAAK;EACjB;EACA,WAAW,GAAG,mCAAmC,SAAS;EAC1D,GAAI;EATN,UAAA,CAWE,qBAAC,MAAD;GAAM,WAAU;GAAhB,UAAA,CACG,MACA,OAAO,aAAa,WACnB,oBAAC,MAAD;IACE,WAAW,GACT,+BACA,YAAY,+BACZ,YAAY,oBACd;IAEC;GACG,CAAA,IAEN,QAEE;EACN,CAAA,GAAA,oBAAC,MAAD,EACE,WAAW,GAAG,qCAAqC,YAAY,wBAAwB,EACxF,CAAA,CACQ;;AAEf;;AAQA,SAAgB,SAAS,EAAE,WAAW,OAAO,GAAG,SAAwB;CACtE,MAAM,EAAE,OAAO,WAAW,WAAW,WAAW;CAChD,IAAI,WAAW,OAAO,OAAO;CAC7B,OAAO,oBAAC,MAAD;EAAiB;EAAW,GAAI;CAAQ,CAAA;AACjD"}
@@ -0,0 +1,2 @@
1
+ import { Tag, TagProps } from "./tag.js";
2
+ export { Tag, type TagProps };
@@ -0,0 +1,18 @@
1
+ import { ViewProps } from "react-native";
2
+ import { VariantProps } from "class-variance-authority";
3
+ //#region src/components/tag/tag.d.ts
4
+ declare const tagVariants: (props?: ({
5
+ variant?: "filled" | "outline" | null | undefined;
6
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
+ export type TagProps = Omit<ViewProps, 'children'> & VariantProps<typeof tagVariants> & {
8
+ className?: string;
9
+ children: string;
10
+ /** Mostra o botão de remoção (×) e o chama ao tocar. Sem ele, a Tag não é removível. */
11
+ onDismiss?: () => void;
12
+ /** Nome acessível do botão de remoção. */
13
+ dismissLabel?: string;
14
+ };
15
+ /** Rótulo de categoria ou filtro, opcionalmente removível. Para status, use Badge. */
16
+ export declare function Tag({ className, variant, onDismiss, dismissLabel, children, ...props }: TagProps): import("react").JSX.Element;
17
+ //#endregion
18
+ //# sourceMappingURL=tag.d.ts.map
@@ -0,0 +1,37 @@
1
+ import { cn } from "../../utils/cn.js";
2
+ import { CloseIcon } from "../_shared/status.js";
3
+ import { useToken } from "../_shared/use-token.js";
4
+ import { Pressable, Text, View } from "react-native";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { cva } from "class-variance-authority";
7
+ //#region src/components/tag/tag.tsx
8
+ const tagVariants = cva("flex-row items-center gap-1 self-start rounded-sm px-2 py-0.5", {
9
+ variants: { variant: {
10
+ filled: "bg-bg-secondary",
11
+ outline: "border border-border-default"
12
+ } },
13
+ defaultVariants: { variant: "filled" }
14
+ });
15
+ /** Rótulo de categoria ou filtro, opcionalmente removível. Para status, use Badge. */
16
+ function Tag({ className, variant, onDismiss, dismissLabel = "Remover", children, ...props }) {
17
+ const iconColor = useToken("--color-text-secondary");
18
+ return /* @__PURE__ */ jsxs(View, {
19
+ className: cn(tagVariants({ variant }), className),
20
+ ...props,
21
+ children: [/* @__PURE__ */ jsx(Text, {
22
+ className: "text-xs font-medium leading-4 text-text-primary",
23
+ children
24
+ }), onDismiss && /* @__PURE__ */ jsx(Pressable, {
25
+ accessibilityRole: "button",
26
+ accessibilityLabel: dismissLabel,
27
+ onPress: onDismiss,
28
+ hitSlop: 8,
29
+ className: "size-4 shrink-0 items-center justify-center rounded-sm",
30
+ children: /* @__PURE__ */ jsx(CloseIcon, { color: iconColor })
31
+ })]
32
+ });
33
+ }
34
+ //#endregion
35
+ export { Tag };
36
+
37
+ //# sourceMappingURL=tag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tag.js","names":[],"sources":["../../../src/components/tag/tag.tsx"],"sourcesContent":["/// <reference types=\"uniwind/types\" />\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { Pressable, Text, View, type ViewProps } from 'react-native'\nimport { cn } from '../../utils/cn'\nimport { CloseIcon } from '../_shared/status'\nimport { useToken } from '../_shared/use-token'\n\nconst tagVariants = cva('flex-row items-center gap-1 self-start rounded-sm px-2 py-0.5', {\n variants: {\n variant: {\n filled: 'bg-bg-secondary',\n outline: 'border border-border-default',\n },\n },\n defaultVariants: { variant: 'filled' },\n})\n\nexport type TagProps = Omit<ViewProps, 'children'> &\n VariantProps<typeof tagVariants> & {\n className?: string\n children: string\n /** Mostra o botão de remoção (×) e o chama ao tocar. Sem ele, a Tag não é removível. */\n onDismiss?: () => void\n /** Nome acessível do botão de remoção. */\n dismissLabel?: string\n }\n\n/** Rótulo de categoria ou filtro, opcionalmente removível. Para status, use Badge. */\nexport function Tag({\n className,\n variant,\n onDismiss,\n dismissLabel = 'Remover',\n children,\n ...props\n}: TagProps) {\n const iconColor = useToken('--color-text-secondary')\n\n return (\n <View className={cn(tagVariants({ variant }), className)} {...props}>\n <Text className=\"text-xs font-medium leading-4 text-text-primary\">{children}</Text>\n {onDismiss && (\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel={dismissLabel}\n onPress={onDismiss}\n hitSlop={8}\n className=\"size-4 shrink-0 items-center justify-center rounded-sm\"\n >\n <CloseIcon color={iconColor} />\n </Pressable>\n )}\n </View>\n )\n}\n"],"mappings":";;;;;;;AAQA,MAAM,cAAc,IAAI,iEAAiE;CACvF,UAAU,EACR,SAAS;EACP,QAAQ;EACR,SAAS;CACX,EACF;CACA,iBAAiB,EAAE,SAAS,SAAS;AACvC,CAAC;;AAaD,SAAgB,IAAI,EAClB,WACA,SACA,WACA,eAAe,WACf,UACA,GAAG,SACQ;CACX,MAAM,YAAY,SAAS,wBAAwB;CAEnD,OACE,qBAAC,MAAD;EAAM,WAAW,GAAG,YAAY,EAAE,QAAQ,CAAC,GAAG,SAAS;EAAG,GAAI;EAA9D,UAAA,CACE,oBAAC,MAAD;GAAM,WAAU;GAAmD;EAAe,CAAA,GACjF,aACC,oBAAC,WAAD;GACE,mBAAkB;GAClB,oBAAoB;GACpB,SAAS;GACT,SAAS;GACT,WAAU;GAEV,UAAA,oBAAC,WAAD,EAAW,OAAO,UAAY,CAAA;EACrB,CAAA,CAET;;AAEV"}
@@ -0,0 +1,2 @@
1
+ import { Textarea, TextareaProps } from "./textarea.js";
2
+ export { Textarea, type TextareaProps };
@@ -0,0 +1,16 @@
1
+ import { TextInputProps } from "react-native";
2
+ import { VariantProps } from "class-variance-authority";
3
+ //#region src/components/textarea/textarea.d.ts
4
+ declare const textareaVariants: (props?: ({
5
+ size?: "lg" | "md" | "sm" | null | undefined;
6
+ error?: boolean | null | undefined;
7
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
+ export type TextareaProps = Omit<TextInputProps, 'style' | 'editable' | 'multiline'> & Omit<VariantProps<typeof textareaVariants>, 'error'> & {
9
+ className?: string;
10
+ /** Borda e foco em vermelho. */
11
+ error?: boolean;
12
+ disabled?: boolean;
13
+ };
14
+ export declare function Textarea({ className, size, error, disabled, readOnly, accessibilityState, ...props }: TextareaProps): import("react").JSX.Element;
15
+ //#endregion
16
+ //# sourceMappingURL=textarea.d.ts.map