@emara/ui 1.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 (218) hide show
  1. package/components/ui/.gitkeep +0 -0
  2. package/components/ui/accordion.stories.tsx +231 -0
  3. package/components/ui/accordion.tsx +250 -0
  4. package/components/ui/app-shell.stories.tsx +270 -0
  5. package/components/ui/app-shell.tsx +491 -0
  6. package/components/ui/avatar.stories.tsx +174 -0
  7. package/components/ui/avatar.tsx +257 -0
  8. package/components/ui/badge.stories.tsx +127 -0
  9. package/components/ui/badge.tsx +146 -0
  10. package/components/ui/breadcrumb.stories.tsx +92 -0
  11. package/components/ui/breadcrumb.tsx +302 -0
  12. package/components/ui/button.stories.tsx +186 -0
  13. package/components/ui/button.tsx +128 -0
  14. package/components/ui/card.stories.tsx +279 -0
  15. package/components/ui/card.tsx +250 -0
  16. package/components/ui/checkbox.stories.tsx +93 -0
  17. package/components/ui/checkbox.tsx +131 -0
  18. package/components/ui/combobox.stories.tsx +489 -0
  19. package/components/ui/combobox.tsx +874 -0
  20. package/components/ui/context-menu.stories.tsx +202 -0
  21. package/components/ui/context-menu.tsx +309 -0
  22. package/components/ui/data-table.stories.tsx +227 -0
  23. package/components/ui/data-table.tsx +539 -0
  24. package/components/ui/date-picker.stories.tsx +225 -0
  25. package/components/ui/date-picker.tsx +597 -0
  26. package/components/ui/dialog.stories.tsx +193 -0
  27. package/components/ui/dialog.tsx +262 -0
  28. package/components/ui/divider.stories.tsx +84 -0
  29. package/components/ui/divider.tsx +135 -0
  30. package/components/ui/drawer.stories.tsx +218 -0
  31. package/components/ui/drawer.tsx +329 -0
  32. package/components/ui/dropdown-menu.stories.tsx +270 -0
  33. package/components/ui/dropdown-menu.tsx +353 -0
  34. package/components/ui/empty-state.stories.tsx +121 -0
  35. package/components/ui/empty-state.tsx +289 -0
  36. package/components/ui/field-group.stories.tsx +201 -0
  37. package/components/ui/field-group.tsx +276 -0
  38. package/components/ui/form.stories.tsx +219 -0
  39. package/components/ui/form.tsx +542 -0
  40. package/components/ui/input.stories.tsx +154 -0
  41. package/components/ui/input.tsx +208 -0
  42. package/components/ui/label.stories.tsx +84 -0
  43. package/components/ui/label.tsx +98 -0
  44. package/components/ui/page-header.stories.tsx +136 -0
  45. package/components/ui/page-header.tsx +315 -0
  46. package/components/ui/pagination.stories.tsx +136 -0
  47. package/components/ui/pagination.tsx +427 -0
  48. package/components/ui/popover.stories.tsx +212 -0
  49. package/components/ui/popover.tsx +167 -0
  50. package/components/ui/radio-group.stories.tsx +96 -0
  51. package/components/ui/radio-group.tsx +250 -0
  52. package/components/ui/select.stories.tsx +203 -0
  53. package/components/ui/select.tsx +318 -0
  54. package/components/ui/sidebar.stories.tsx +186 -0
  55. package/components/ui/sidebar.tsx +623 -0
  56. package/components/ui/skeleton.stories.tsx +131 -0
  57. package/components/ui/skeleton.tsx +311 -0
  58. package/components/ui/switch.stories.tsx +74 -0
  59. package/components/ui/switch.tsx +186 -0
  60. package/components/ui/table.stories.tsx +107 -0
  61. package/components/ui/table.tsx +285 -0
  62. package/components/ui/tabs.stories.tsx +222 -0
  63. package/components/ui/tabs.tsx +287 -0
  64. package/components/ui/textarea.stories.tsx +96 -0
  65. package/components/ui/textarea.tsx +182 -0
  66. package/components/ui/toast.stories.tsx +169 -0
  67. package/components/ui/toast.tsx +250 -0
  68. package/components/ui/tooltip.stories.tsx +146 -0
  69. package/components/ui/tooltip.tsx +156 -0
  70. package/components/ui/top-bar.stories.tsx +182 -0
  71. package/components/ui/top-bar.tsx +155 -0
  72. package/dist/components/ui/accordion.d.ts +45 -0
  73. package/dist/components/ui/accordion.d.ts.map +1 -0
  74. package/dist/components/ui/accordion.js +99 -0
  75. package/dist/components/ui/accordion.js.map +1 -0
  76. package/dist/components/ui/app-shell.d.ts +70 -0
  77. package/dist/components/ui/app-shell.d.ts.map +1 -0
  78. package/dist/components/ui/app-shell.js +199 -0
  79. package/dist/components/ui/app-shell.js.map +1 -0
  80. package/dist/components/ui/avatar.d.ts +41 -0
  81. package/dist/components/ui/avatar.d.ts.map +1 -0
  82. package/dist/components/ui/avatar.js +104 -0
  83. package/dist/components/ui/avatar.js.map +1 -0
  84. package/dist/components/ui/badge.d.ts +27 -0
  85. package/dist/components/ui/badge.d.ts.map +1 -0
  86. package/dist/components/ui/badge.js +65 -0
  87. package/dist/components/ui/badge.js.map +1 -0
  88. package/dist/components/ui/breadcrumb.d.ts +35 -0
  89. package/dist/components/ui/breadcrumb.d.ts.map +1 -0
  90. package/dist/components/ui/breadcrumb.js +88 -0
  91. package/dist/components/ui/breadcrumb.js.map +1 -0
  92. package/dist/components/ui/button.d.ts +26 -0
  93. package/dist/components/ui/button.d.ts.map +1 -0
  94. package/dist/components/ui/button.js +73 -0
  95. package/dist/components/ui/button.js.map +1 -0
  96. package/dist/components/ui/card.d.ts +52 -0
  97. package/dist/components/ui/card.d.ts.map +1 -0
  98. package/dist/components/ui/card.js +96 -0
  99. package/dist/components/ui/card.js.map +1 -0
  100. package/dist/components/ui/checkbox.d.ts +18 -0
  101. package/dist/components/ui/checkbox.d.ts.map +1 -0
  102. package/dist/components/ui/checkbox.js +59 -0
  103. package/dist/components/ui/checkbox.js.map +1 -0
  104. package/dist/components/ui/combobox.d.ts +194 -0
  105. package/dist/components/ui/combobox.d.ts.map +1 -0
  106. package/dist/components/ui/combobox.js +361 -0
  107. package/dist/components/ui/combobox.js.map +1 -0
  108. package/dist/components/ui/context-menu.d.ts +46 -0
  109. package/dist/components/ui/context-menu.d.ts.map +1 -0
  110. package/dist/components/ui/context-menu.js +95 -0
  111. package/dist/components/ui/context-menu.js.map +1 -0
  112. package/dist/components/ui/data-table.d.ts +53 -0
  113. package/dist/components/ui/data-table.d.ts.map +1 -0
  114. package/dist/components/ui/data-table.js +163 -0
  115. package/dist/components/ui/data-table.js.map +1 -0
  116. package/dist/components/ui/date-picker.d.ts +103 -0
  117. package/dist/components/ui/date-picker.d.ts.map +1 -0
  118. package/dist/components/ui/date-picker.js +306 -0
  119. package/dist/components/ui/date-picker.js.map +1 -0
  120. package/dist/components/ui/dialog.d.ts +40 -0
  121. package/dist/components/ui/dialog.d.ts.map +1 -0
  122. package/dist/components/ui/dialog.js +110 -0
  123. package/dist/components/ui/dialog.js.map +1 -0
  124. package/dist/components/ui/divider.d.ts +30 -0
  125. package/dist/components/ui/divider.d.ts.map +1 -0
  126. package/dist/components/ui/divider.js +62 -0
  127. package/dist/components/ui/divider.js.map +1 -0
  128. package/dist/components/ui/drawer.d.ts +56 -0
  129. package/dist/components/ui/drawer.d.ts.map +1 -0
  130. package/dist/components/ui/drawer.js +147 -0
  131. package/dist/components/ui/drawer.js.map +1 -0
  132. package/dist/components/ui/dropdown-menu.d.ts +63 -0
  133. package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
  134. package/dist/components/ui/dropdown-menu.js +116 -0
  135. package/dist/components/ui/dropdown-menu.js.map +1 -0
  136. package/dist/components/ui/empty-state.d.ts +43 -0
  137. package/dist/components/ui/empty-state.d.ts.map +1 -0
  138. package/dist/components/ui/empty-state.js +128 -0
  139. package/dist/components/ui/empty-state.js.map +1 -0
  140. package/dist/components/ui/field-group.d.ts +38 -0
  141. package/dist/components/ui/field-group.d.ts.map +1 -0
  142. package/dist/components/ui/field-group.js +107 -0
  143. package/dist/components/ui/field-group.js.map +1 -0
  144. package/dist/components/ui/form.d.ts +67 -0
  145. package/dist/components/ui/form.d.ts.map +1 -0
  146. package/dist/components/ui/form.js +286 -0
  147. package/dist/components/ui/form.js.map +1 -0
  148. package/dist/components/ui/input.d.ts +36 -0
  149. package/dist/components/ui/input.d.ts.map +1 -0
  150. package/dist/components/ui/input.js +99 -0
  151. package/dist/components/ui/input.js.map +1 -0
  152. package/dist/components/ui/label.d.ts +37 -0
  153. package/dist/components/ui/label.d.ts.map +1 -0
  154. package/dist/components/ui/label.js +34 -0
  155. package/dist/components/ui/label.js.map +1 -0
  156. package/dist/components/ui/page-header.d.ts +65 -0
  157. package/dist/components/ui/page-header.d.ts.map +1 -0
  158. package/dist/components/ui/page-header.js +140 -0
  159. package/dist/components/ui/page-header.js.map +1 -0
  160. package/dist/components/ui/pagination.d.ts +67 -0
  161. package/dist/components/ui/pagination.d.ts.map +1 -0
  162. package/dist/components/ui/pagination.js +109 -0
  163. package/dist/components/ui/pagination.js.map +1 -0
  164. package/dist/components/ui/popover.d.ts +28 -0
  165. package/dist/components/ui/popover.d.ts.map +1 -0
  166. package/dist/components/ui/popover.js +85 -0
  167. package/dist/components/ui/popover.js.map +1 -0
  168. package/dist/components/ui/radio-group.d.ts +35 -0
  169. package/dist/components/ui/radio-group.d.ts.map +1 -0
  170. package/dist/components/ui/radio-group.js +103 -0
  171. package/dist/components/ui/radio-group.js.map +1 -0
  172. package/dist/components/ui/select.d.ts +42 -0
  173. package/dist/components/ui/select.d.ts.map +1 -0
  174. package/dist/components/ui/select.js +86 -0
  175. package/dist/components/ui/select.js.map +1 -0
  176. package/dist/components/ui/sidebar.d.ts +59 -0
  177. package/dist/components/ui/sidebar.d.ts.map +1 -0
  178. package/dist/components/ui/sidebar.js +189 -0
  179. package/dist/components/ui/sidebar.js.map +1 -0
  180. package/dist/components/ui/skeleton.d.ts +77 -0
  181. package/dist/components/ui/skeleton.d.ts.map +1 -0
  182. package/dist/components/ui/skeleton.js +115 -0
  183. package/dist/components/ui/skeleton.js.map +1 -0
  184. package/dist/components/ui/switch.d.ts +26 -0
  185. package/dist/components/ui/switch.d.ts.map +1 -0
  186. package/dist/components/ui/switch.js +84 -0
  187. package/dist/components/ui/switch.js.map +1 -0
  188. package/dist/components/ui/table.d.ts +52 -0
  189. package/dist/components/ui/table.d.ts.map +1 -0
  190. package/dist/components/ui/table.js +109 -0
  191. package/dist/components/ui/table.js.map +1 -0
  192. package/dist/components/ui/tabs.d.ts +42 -0
  193. package/dist/components/ui/tabs.d.ts.map +1 -0
  194. package/dist/components/ui/tabs.js +163 -0
  195. package/dist/components/ui/tabs.js.map +1 -0
  196. package/dist/components/ui/textarea.d.ts +26 -0
  197. package/dist/components/ui/textarea.d.ts.map +1 -0
  198. package/dist/components/ui/textarea.js +96 -0
  199. package/dist/components/ui/textarea.js.map +1 -0
  200. package/dist/components/ui/toast.d.ts +77 -0
  201. package/dist/components/ui/toast.d.ts.map +1 -0
  202. package/dist/components/ui/toast.js +141 -0
  203. package/dist/components/ui/toast.js.map +1 -0
  204. package/dist/components/ui/tooltip.d.ts +31 -0
  205. package/dist/components/ui/tooltip.d.ts.map +1 -0
  206. package/dist/components/ui/tooltip.js +71 -0
  207. package/dist/components/ui/tooltip.js.map +1 -0
  208. package/dist/components/ui/top-bar.d.ts +30 -0
  209. package/dist/components/ui/top-bar.d.ts.map +1 -0
  210. package/dist/components/ui/top-bar.js +64 -0
  211. package/dist/components/ui/top-bar.js.map +1 -0
  212. package/dist/lib/utils.d.ts +3 -0
  213. package/dist/lib/utils.d.ts.map +1 -0
  214. package/dist/lib/utils.js +6 -0
  215. package/dist/lib/utils.js.map +1 -0
  216. package/lib/utils.ts +6 -0
  217. package/package.json +112 -0
  218. package/styles/globals.css +685 -0
@@ -0,0 +1,141 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
4
+ import { RiCheckLine, RiCloseCircleLine, RiErrorWarningLine, RiInformationLine, RiLoader2Line, } from "@remixicon/react";
5
+ import { Toaster as SonnerToaster, toast as sonnerToast, } from "sonner";
6
+ import { cn } from "@/lib/utils";
7
+ const positionToSonner = {
8
+ "top-start": "top-left",
9
+ "top-end": "top-right",
10
+ "top-center": "top-center",
11
+ "bottom-start": "bottom-left",
12
+ "bottom-end": "bottom-right",
13
+ "bottom-center": "bottom-center",
14
+ };
15
+ /**
16
+ * Sonner uses `left`/`right` physical sides for positions. In RTL,
17
+ * `top-start` should mean visually top-right, and `top-end` should mean
18
+ * top-left. We resolve at runtime based on `<html dir>`.
19
+ */
20
+ function resolveDir() {
21
+ if (typeof document === "undefined")
22
+ return "ltr";
23
+ return document.documentElement.dir === "rtl" ? "rtl" : "ltr";
24
+ }
25
+ function resolvePosition(p) {
26
+ const dir = resolveDir();
27
+ if (dir === "rtl") {
28
+ if (p === "top-start")
29
+ return "top-right";
30
+ if (p === "top-end")
31
+ return "top-left";
32
+ if (p === "bottom-start")
33
+ return "bottom-right";
34
+ if (p === "bottom-end")
35
+ return "bottom-left";
36
+ }
37
+ return positionToSonner[p];
38
+ }
39
+ function Toaster({ position = "bottom-end", pauseOnHover = true, closeOnClick = false, swipeToDismiss = true, maxVisible, defaultDuration = 4000, expand, gap, richColors, className, toastOptions, ...rest }) {
40
+ // Sonner already handles pause-on-hover, no-close-on-click, and swipe on
41
+ // touch natively. These props are accepted in the public API for
42
+ // forward-compatibility but currently have no Sonner override. The voids
43
+ // declare intent without leaking the props through `...rest`.
44
+ void pauseOnHover;
45
+ void closeOnClick;
46
+ void swipeToDismiss;
47
+ // Re-resolve position on dir change. Sonner's `position` is set once at
48
+ // mount, but consumers may flip dir at runtime — re-mount the Toaster by
49
+ // keying on the resolved position.
50
+ const [resolved, setResolved] = useState(() => resolvePosition(position));
51
+ useEffect(() => {
52
+ setResolved(resolvePosition(position));
53
+ if (typeof document === "undefined")
54
+ return;
55
+ const obs = new MutationObserver(() => setResolved(resolvePosition(position)));
56
+ obs.observe(document.documentElement, { attributes: true, attributeFilter: ["dir"] });
57
+ return () => obs.disconnect();
58
+ }, [position]);
59
+ // exactOptionalPropertyTypes: don't forward optional props with `undefined`.
60
+ const passthrough = {};
61
+ if (expand !== undefined)
62
+ passthrough.expand = expand;
63
+ if (gap !== undefined)
64
+ passthrough.gap = gap;
65
+ if (richColors !== undefined)
66
+ passthrough.richColors = richColors;
67
+ if (maxVisible !== undefined)
68
+ passthrough.visibleToasts = maxVisible;
69
+ return (_jsx(SonnerToaster, { position: resolved, duration: defaultDuration, closeButton: true,
70
+ // Anchor sonner's stack layer to the design-token --z-toast (1700) so
71
+ // toasts always sit above tooltips, popovers, and modals.
72
+ style: { zIndex: "var(--z-toast)" },
73
+ // Emara-tinted defaults — colors track the active theme.
74
+ toastOptions: {
75
+ ...toastOptions,
76
+ className: cn("border border-border bg-popover text-popover-foreground shadow-md", toastOptions?.className),
77
+ }, className: cn(className), ...passthrough, ...rest }, resolved));
78
+ }
79
+ function variantIcon(variant) {
80
+ switch (variant) {
81
+ case "success":
82
+ return _jsx(RiCheckLine, { className: "text-success size-4" });
83
+ case "warning":
84
+ return _jsx(RiErrorWarningLine, { className: "text-warning size-4" });
85
+ case "info":
86
+ return _jsx(RiInformationLine, { className: "text-info size-4" });
87
+ case "error":
88
+ return _jsx(RiCloseCircleLine, { className: "text-destructive size-4" });
89
+ case "loading":
90
+ return _jsx(RiLoader2Line, { className: "size-4 animate-spin" });
91
+ default:
92
+ return undefined;
93
+ }
94
+ }
95
+ function toSonnerOptions(options, variant) {
96
+ if (!options && !variant)
97
+ return undefined;
98
+ const out = {};
99
+ if (options?.id !== undefined)
100
+ out.id = options.id;
101
+ if (options?.description !== undefined)
102
+ out.description = options.description;
103
+ if (options?.duration !== undefined)
104
+ out.duration = options.duration;
105
+ if (options?.action)
106
+ out.action = options.action;
107
+ if (options?.cancel)
108
+ out.cancel = options.cancel;
109
+ if (options?.dismissible !== undefined)
110
+ out.dismissible = options.dismissible;
111
+ if (options?.icon !== undefined) {
112
+ out.icon = options.icon;
113
+ }
114
+ else if (variant && variant !== "default") {
115
+ out.icon = variantIcon(variant);
116
+ }
117
+ return out;
118
+ }
119
+ /**
120
+ * `toast(message, options)` and its variant-shortcut siblings. Wraps sonner's
121
+ * imperative API so consumers don't import sonner directly.
122
+ */
123
+ function toastBase(message, options) {
124
+ return sonnerToast(message, toSonnerOptions(options, "default"));
125
+ }
126
+ const toast = Object.assign(toastBase, {
127
+ success: (message, options) => sonnerToast.success(message, toSonnerOptions(options, "success")),
128
+ warning: (message, options) => sonnerToast.warning(message, toSonnerOptions(options, "warning")),
129
+ info: (message, options) => sonnerToast.info(message, toSonnerOptions(options, "info")),
130
+ error: (message, options) => sonnerToast.error(message, toSonnerOptions(options, "error")),
131
+ loading: (message, options) => sonnerToast.loading(message, toSonnerOptions(options, "loading")),
132
+ promise: (promise, msgs) => sonnerToast.promise(promise, {
133
+ loading: msgs.loading,
134
+ success: msgs.success,
135
+ error: msgs.error,
136
+ }),
137
+ dismiss: (id) => sonnerToast.dismiss(id),
138
+ custom: sonnerToast.custom,
139
+ });
140
+ export { Toaster, toast };
141
+ //# sourceMappingURL=toast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toast.js","sourceRoot":"","sources":["../../../components/ui/toast.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
2
+ import { type VariantProps } from "class-variance-authority";
3
+ declare const TooltipProvider: import("react").FC<TooltipPrimitive.TooltipProviderProps>;
4
+ declare const Tooltip: import("react").FC<TooltipPrimitive.TooltipProps>;
5
+ declare const TooltipTrigger: import("react").ForwardRefExoticComponent<TooltipPrimitive.TooltipTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
6
+ declare const tooltipContentVariants: (props?: ({
7
+ variant?: "default" | "kbd" | "inverse" | null | undefined;
8
+ multiline?: boolean | null | undefined;
9
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
10
+ type TooltipContentProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> & VariantProps<typeof tooltipContentVariants> & {
11
+ /** Cap width when `multiline` is true (or just for sizing in general). */
12
+ maxWidth?: number | string;
13
+ /** When set, renders the children as keyboard-shortcut key caps. Wraps each token in a `<kbd>` element with a styled appearance. */
14
+ kbd?: string[];
15
+ /** Default `true`. Set to `false` to hide the arrow. */
16
+ arrow?: boolean;
17
+ };
18
+ declare const TooltipContent: import("react").ForwardRefExoticComponent<Omit<TooltipPrimitive.TooltipContentProps & import("react").RefAttributes<HTMLDivElement>, "ref"> & VariantProps<(props?: ({
19
+ variant?: "default" | "kbd" | "inverse" | null | undefined;
20
+ multiline?: boolean | null | undefined;
21
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string> & {
22
+ /** Cap width when `multiline` is true (or just for sizing in general). */
23
+ maxWidth?: number | string;
24
+ /** When set, renders the children as keyboard-shortcut key caps. Wraps each token in a `<kbd>` element with a styled appearance. */
25
+ kbd?: string[];
26
+ /** Default `true`. Set to `false` to hide the arrow. */
27
+ arrow?: boolean;
28
+ } & import("react").RefAttributes<HTMLDivElement>>;
29
+ export { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, tooltipContentVariants };
30
+ export type { TooltipContentProps };
31
+ //# sourceMappingURL=tooltip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../../components/ui/tooltip.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAYlE,QAAA,MAAM,eAAe,2DAA4B,CAAC;AAMlD,QAAA,MAAM,OAAO,mDAAwB,CAAC;AACtC,QAAA,MAAM,cAAc,oIAA2B,CAAC;AAMhD,QAAA,MAAM,sBAAsB;;;8EA6B3B,CAAC;AAQF,KAAK,mBAAmB,GAAG,KAAK,CAAC,wBAAwB,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,GACxF,YAAY,CAAC,OAAO,sBAAsB,CAAC,GAAG;IAC5C,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,oIAAoI;IACpI,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,wDAAwD;IACxD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAcJ,QAAA,MAAM,cAAc;;;;IApBhB,0EAA0E;eAC/D,MAAM,GAAG,MAAM;IAC1B,oIAAoI;UAC9H,MAAM,EAAE;IACd,wDAAwD;YAChD,OAAO;kDA8EjB,CAAC;AAGH,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,sBAAsB,EAAE,CAAC;AAC5F,YAAY,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,71 @@
1
+ "use client";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef } from "react";
4
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
5
+ import { cva } from "class-variance-authority";
6
+ import { cn } from "@/lib/utils";
7
+ // Per docs/emara-ui-phase-3-components.md §4. Brought forward into v0.1 per
8
+ // docs/emara-ui-implementation-plan.md §5.
9
+ // ----------------------------------------------------------------------------
10
+ // TooltipProvider — typically wraps the app once. Re-export so consumers
11
+ // don't have to import from Radix directly.
12
+ // ----------------------------------------------------------------------------
13
+ const TooltipProvider = TooltipPrimitive.Provider;
14
+ // ----------------------------------------------------------------------------
15
+ // Tooltip root — Radix props passthrough.
16
+ // ----------------------------------------------------------------------------
17
+ const Tooltip = TooltipPrimitive.Root;
18
+ const TooltipTrigger = TooltipPrimitive.Trigger;
19
+ // ----------------------------------------------------------------------------
20
+ // TooltipContent
21
+ // ----------------------------------------------------------------------------
22
+ const tooltipContentVariants = cva([
23
+ "z-tooltip select-none px-2 py-1 text-xs leading-snug rounded-md shadow-md",
24
+ // Animations driven by Radix data-state. Side-specific slide-in.
25
+ "data-[state=delayed-open]:animate-[scale-in_var(--duration-fast)_var(--ease-out)]",
26
+ "data-[state=closed]:animate-[scale-out_var(--duration-fast)_var(--ease-in)]",
27
+ "data-[side=top]:data-[state=delayed-open]:animate-[slide-in-from-bottom_var(--duration-fast)_var(--ease-out)]",
28
+ "data-[side=bottom]:data-[state=delayed-open]:animate-[slide-in-from-top_var(--duration-fast)_var(--ease-out)]",
29
+ "data-[side=left]:data-[state=delayed-open]:animate-[slide-in-from-end_var(--duration-fast)_var(--ease-out)]",
30
+ "data-[side=right]:data-[state=delayed-open]:animate-[slide-in-from-start_var(--duration-fast)_var(--ease-out)]",
31
+ ].join(" "), {
32
+ variants: {
33
+ variant: {
34
+ // Dark bubble against any surface — classic tooltip.
35
+ default: "bg-foreground text-background",
36
+ // Inverse — light bubble for dark contexts (e.g. dark sidebar).
37
+ inverse: "bg-background text-foreground border border-border",
38
+ // Keyboard-shortcut style — uses kbd key caps inside.
39
+ kbd: "bg-foreground text-background font-mono",
40
+ },
41
+ multiline: {
42
+ // Single-line tooltip truncates; multi-line wraps within maxWidth.
43
+ true: "whitespace-normal",
44
+ false: "whitespace-nowrap",
45
+ },
46
+ },
47
+ defaultVariants: { variant: "default", multiline: false },
48
+ });
49
+ const arrowFillClass = {
50
+ default: "fill-foreground",
51
+ inverse: "fill-background",
52
+ kbd: "fill-foreground",
53
+ };
54
+ function Kbd({ k }) {
55
+ // `min-w-[1.25em]` is intentionally em-relative (not a Tailwind spacing
56
+ // token): kbd keys scale with the surrounding text size, and the visual
57
+ // contract is "always at least one character wide" — that's an em-bound
58
+ // measurement, not a px one. Per design-tokens §4.2 sub-canonical note.
59
+ return (_jsx("kbd", { className: "border-background/30 bg-background/10 inline-block min-w-[1.25em] rounded border px-1 text-center font-mono text-[10px] leading-tight", children: k }));
60
+ }
61
+ const TooltipContent = forwardRef(function TooltipContent({ className, variant, multiline, maxWidth, kbd, arrow = true, sideOffset = 6, style, children, ...props }, ref) {
62
+ const resolvedVariant = variant ?? (kbd ? "kbd" : "default");
63
+ const widthStyle = maxWidth !== undefined
64
+ ? { maxWidth: typeof maxWidth === "number" ? `${maxWidth}px` : maxWidth }
65
+ : undefined;
66
+ const body = kbd ? (_jsxs("span", { className: "inline-flex items-center gap-1", children: [children ? (_jsxs(_Fragment, { children: [_jsx("span", { children: children }), _jsx("span", { className: "opacity-70", children: "\u00B7" })] })) : null, kbd.map((k, i) => (_jsxs("span", { className: "inline-flex items-center gap-0.5", children: [i > 0 ? _jsx("span", { className: "opacity-70", children: "+" }) : null, _jsx(Kbd, { k: k })] }, `${k}-${i}`)))] })) : (children);
67
+ return (_jsx(TooltipPrimitive.Portal, { children: _jsxs(TooltipPrimitive.Content, { ref: ref, sideOffset: sideOffset, style: { ...widthStyle, ...style }, className: cn(tooltipContentVariants({ variant: resolvedVariant, multiline }), className), ...props, children: [body, arrow ? (_jsx(TooltipPrimitive.Arrow, { width: 10, height: 5, className: cn(arrowFillClass[resolvedVariant]) })) : null] }) }));
68
+ });
69
+ TooltipContent.displayName = "TooltipContent";
70
+ export { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, tooltipContentVariants };
71
+ //# sourceMappingURL=tooltip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tooltip.js","sourceRoot":"","sources":["../../../components/ui/tooltip.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { type VariantProps } from "class-variance-authority";
2
+ declare const topBarVariants: (props?: ({
3
+ variant?: "default" | "transparent" | "elevated" | null | undefined;
4
+ size?: "sm" | "md" | "lg" | null | undefined;
5
+ sticky?: boolean | null | undefined;
6
+ bordered?: boolean | null | undefined;
7
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
+ type TopBarVariants = VariantProps<typeof topBarVariants>;
9
+ type TopBarProps = Omit<React.HTMLAttributes<HTMLElement>, "size"> & TopBarVariants & {
10
+ asChild?: boolean;
11
+ /** Override the rendered element. Default `<header>`. */
12
+ as?: "header" | "div";
13
+ };
14
+ declare const TopBar: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLElement>, "size"> & TopBarVariants & {
15
+ asChild?: boolean;
16
+ /** Override the rendered element. Default `<header>`. */
17
+ as?: "header" | "div";
18
+ } & import("react").RefAttributes<HTMLElement>>;
19
+ declare const TopBarStart: import("react").ForwardRefExoticComponent<import("react").HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
20
+ declare const TopBarCenter: import("react").ForwardRefExoticComponent<import("react").HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
21
+ declare const TopBarEnd: import("react").ForwardRefExoticComponent<import("react").HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
22
+ type TopBarBrandProps = React.HTMLAttributes<HTMLDivElement> & {
23
+ asChild?: boolean;
24
+ };
25
+ declare const TopBarBrand: import("react").ForwardRefExoticComponent<import("react").HTMLAttributes<HTMLDivElement> & {
26
+ asChild?: boolean;
27
+ } & import("react").RefAttributes<HTMLDivElement>>;
28
+ export { TopBar, TopBarStart, TopBarCenter, TopBarEnd, TopBarBrand, topBarVariants };
29
+ export type { TopBarProps, TopBarBrandProps };
30
+ //# sourceMappingURL=top-bar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"top-bar.d.ts","sourceRoot":"","sources":["../../../components/ui/top-bar.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAQlE,QAAA,MAAM,cAAc;;;;;8EA4BlB,CAAC;AAEH,KAAK,cAAc,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC;AAE1D,KAAK,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,GAChE,cAAc,GAAG;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;CACvB,CAAC;AAEJ,QAAA,MAAM,MAAM;cALE,OAAO;IACjB,yDAAyD;SACpD,QAAQ,GAAG,KAAK;+CA0BvB,CAAC;AAKH,QAAA,MAAM,WAAW,2IAWhB,CAAC;AAGF,QAAA,MAAM,YAAY,2IAiBjB,CAAC;AAGF,QAAA,MAAM,SAAS,2IAWd,CAAC;AAKF,KAAK,gBAAgB,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG;IAC7D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,QAAA,MAAM,WAAW;cAHL,OAAO;kDAoBjB,CAAC;AAGH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;AACrF,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,64 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { forwardRef } from "react";
4
+ import { Slot } from "@radix-ui/react-slot";
5
+ import { cva } from "class-variance-authority";
6
+ import { cn } from "@/lib/utils";
7
+ // Per docs/emara-ui-phase-5-components.md §3.
8
+ // --- Root -------------------------------------------------------------------
9
+ const topBarVariants = cva("flex w-full items-center bg-background text-foreground", {
10
+ variants: {
11
+ variant: {
12
+ default: "border-b border-border",
13
+ elevated: "shadow-sm",
14
+ transparent: "bg-transparent",
15
+ },
16
+ size: {
17
+ // Heights match the AppShell `header-sm|md|lg` tokens.
18
+ sm: "h-12 px-3",
19
+ md: "h-14 px-4",
20
+ lg: "h-16 px-5",
21
+ },
22
+ sticky: {
23
+ true: "sticky top-0 z-sticky",
24
+ false: "",
25
+ },
26
+ bordered: {
27
+ true: "border-b border-border",
28
+ false: "",
29
+ },
30
+ },
31
+ defaultVariants: {
32
+ variant: "default",
33
+ size: "md",
34
+ sticky: false,
35
+ bordered: false,
36
+ },
37
+ });
38
+ const TopBar = forwardRef(function TopBar({ className, variant = "default", size = "md", sticky = false, bordered = false, asChild = false, as = "header", ...props }, ref) {
39
+ const Comp = (asChild ? Slot : as);
40
+ return (_jsx(Comp, { ref: ref, "data-slot": "top-bar", role: as === "header" && !asChild ? "banner" : undefined, className: cn(topBarVariants({ variant, size, sticky, bordered }), className), ...props }));
41
+ });
42
+ TopBar.displayName = "TopBar";
43
+ // --- Slots ------------------------------------------------------------------
44
+ const TopBarStart = forwardRef(function TopBarStart({ className, ...props }, ref) {
45
+ return (_jsx("div", { ref: ref, "data-slot": "top-bar-start", className: cn("me-auto flex min-w-0 items-center gap-2", className), ...props }));
46
+ });
47
+ TopBarStart.displayName = "TopBarStart";
48
+ const TopBarCenter = forwardRef(function TopBarCenter({ className, role, ...props }, ref) {
49
+ return (_jsx("div", { ref: ref, "data-slot": "top-bar-center",
50
+ // Hides on narrow viewports — consumers can override.
51
+ className: cn("hidden min-w-0 flex-1 items-center justify-center gap-2 px-3 md:flex", className), ...(role ? { role } : {}), ...props }));
52
+ });
53
+ TopBarCenter.displayName = "TopBarCenter";
54
+ const TopBarEnd = forwardRef(function TopBarEnd({ className, ...props }, ref) {
55
+ return (_jsx("div", { ref: ref, "data-slot": "top-bar-end", className: cn("ms-auto flex items-center gap-2", className), ...props }));
56
+ });
57
+ TopBarEnd.displayName = "TopBarEnd";
58
+ const TopBarBrand = forwardRef(function TopBarBrand({ className, asChild = false, ...props }, ref) {
59
+ const Comp = asChild ? Slot : "div";
60
+ return (_jsx(Comp, { ref: ref, "data-slot": "top-bar-brand", className: cn("text-foreground inline-flex items-center gap-2 font-semibold", "[&_svg]:size-5 [&_svg]:shrink-0", className), ...props }));
61
+ });
62
+ TopBarBrand.displayName = "TopBarBrand";
63
+ export { TopBar, TopBarStart, TopBarCenter, TopBarEnd, TopBarBrand, topBarVariants };
64
+ //# sourceMappingURL=top-bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"top-bar.js","sourceRoot":"","sources":["../../../components/ui/top-bar.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type ClassValue } from "clsx";
2
+ export declare function cn(...inputs: ClassValue[]): string;
3
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAG7C,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAElD"}
@@ -0,0 +1,6 @@
1
+ import { clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+ export function cn(...inputs) {
4
+ return twMerge(clsx(inputs));
5
+ }
6
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEzC,MAAM,UAAU,EAAE,CAAC,GAAG,MAAoB;IACxC,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/B,CAAC"}
package/lib/utils.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export function cn(...inputs: ClassValue[]): string {
5
+ return twMerge(clsx(inputs));
6
+ }
package/package.json ADDED
@@ -0,0 +1,112 @@
1
+ {
2
+ "name": "@emara/ui",
3
+ "version": "1.1.0",
4
+ "description": "Emara UI — React component library. Canonical install path is `npx @emara/cli add <name>` (shadcn-style copy-paste); direct package install is supported as an alternate path.",
5
+ "keywords": [
6
+ "emara",
7
+ "emara-ui",
8
+ "shadcn",
9
+ "react",
10
+ "react-19",
11
+ "tailwind",
12
+ "tailwind-v4",
13
+ "components",
14
+ "rtl",
15
+ "radix",
16
+ "ui"
17
+ ],
18
+ "homepage": "https://github.com/abdelkader-zaglou/emara-ui#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/abdelkader-zaglou/emara-ui/issues"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/abdelkader-zaglou/emara-ui.git",
25
+ "directory": "packages/ui"
26
+ },
27
+ "license": "MIT",
28
+ "author": "Abdelkader Zaglou",
29
+ "type": "module",
30
+ "sideEffects": [
31
+ "**/*.css"
32
+ ],
33
+ "files": [
34
+ "dist",
35
+ "components",
36
+ "lib",
37
+ "styles",
38
+ "README.md"
39
+ ],
40
+ "publishConfig": {
41
+ "access": "public",
42
+ "registry": "https://registry.npmjs.org/"
43
+ },
44
+ "exports": {
45
+ "./styles/globals.css": "./styles/globals.css",
46
+ "./lib/utils": {
47
+ "types": "./lib/utils.ts",
48
+ "import": "./lib/utils.ts"
49
+ }
50
+ },
51
+ "scripts": {
52
+ "build": "tsc -p tsconfig.build.json",
53
+ "typecheck": "tsc --noEmit",
54
+ "lint": "eslint . --max-warnings 0",
55
+ "lint:fix": "eslint . --fix",
56
+ "test": "vitest run",
57
+ "test:watch": "vitest"
58
+ },
59
+ "peerDependencies": {
60
+ "react": ">=19.0.0",
61
+ "react-dom": ">=19.0.0",
62
+ "react-hook-form": ">=7.50.0"
63
+ },
64
+ "peerDependenciesMeta": {
65
+ "react-hook-form": {
66
+ "optional": true
67
+ }
68
+ },
69
+ "dependencies": {
70
+ "@radix-ui/react-avatar": "^1.1.0",
71
+ "@radix-ui/react-checkbox": "^1.1.0",
72
+ "@radix-ui/react-context-menu": "^2.2.0",
73
+ "@radix-ui/react-dialog": "^1.1.0",
74
+ "@radix-ui/react-dropdown-menu": "^2.1.0",
75
+ "@radix-ui/react-label": "^2.1.0",
76
+ "@radix-ui/react-popover": "^1.1.0",
77
+ "@radix-ui/react-radio-group": "^1.2.0",
78
+ "@radix-ui/react-select": "^2.1.0",
79
+ "@radix-ui/react-separator": "^1.1.0",
80
+ "@radix-ui/react-accordion": "^1.2.0",
81
+ "@radix-ui/react-collapsible": "^1.1.0",
82
+ "@radix-ui/react-slot": "^1.2.0",
83
+ "@radix-ui/react-tabs": "^1.1.0",
84
+ "@tanstack/react-table": "^8.20.0",
85
+ "@radix-ui/react-switch": "^1.1.0",
86
+ "@radix-ui/react-tooltip": "^1.2.0",
87
+ "@remixicon/react": "^4.9.0",
88
+ "class-variance-authority": "^0.7.1",
89
+ "clsx": "^2.1.1",
90
+ "cmdk": "^1.1.0",
91
+ "date-fns": "^4.1.0",
92
+ "react-day-picker": "^9.4.0",
93
+ "sonner": "^2.0.0",
94
+ "tailwind-merge": "^3.6.0"
95
+ },
96
+ "devDependencies": {
97
+ "@emara/eslint-plugin": "workspace:*",
98
+ "@storybook/react-vite": "^10.4.0",
99
+ "@testing-library/jest-dom": "^6.9.0",
100
+ "@testing-library/react": "^16.3.0",
101
+ "@testing-library/user-event": "^14.6.0",
102
+ "@types/react": "^19.2.0",
103
+ "@types/react-dom": "^19.2.0",
104
+ "jsdom": "^29.1.0",
105
+ "react": "^19.2.0",
106
+ "react-dom": "^19.2.0",
107
+ "react-hook-form": "^7.55.0",
108
+ "storybook": "^10.4.0",
109
+ "tailwindcss": "^4.3.0",
110
+ "vitest": "^4.1.0"
111
+ }
112
+ }