@shadow-js/ui 0.0.0-stage → 1.0.1

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 (190) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/LICENSE +21 -0
  3. package/README.md +598 -2
  4. package/dist/cli.mjs +2281 -0
  5. package/dist/dev/cli/schema.d.ts +71 -0
  6. package/dist/dev/index.d.ts +6 -0
  7. package/dist/dev/index.js +5 -0
  8. package/dist/dev/locales/ar.d.ts +139 -0
  9. package/dist/dev/locales/ar.js +127 -0
  10. package/dist/dev/locales/ar.js.map +1 -0
  11. package/dist/dev/locales/en.d.ts +139 -0
  12. package/dist/dev/locales/en.js +127 -0
  13. package/dist/dev/locales/en.js.map +1 -0
  14. package/dist/dev/registry/utils/utils.d.ts +27 -0
  15. package/dist/dev/registry/utils/utils.js +26 -0
  16. package/dist/dev/registry/utils/utils.js.map +1 -0
  17. package/dist/dev/theme/theme-logic.d.ts +185 -0
  18. package/dist/dev/theme/theme-logic.js +183 -0
  19. package/dist/dev/theme/theme-logic.js.map +1 -0
  20. package/dist/dev/theme/theme-provider.d.ts +88 -0
  21. package/dist/dev/theme/theme-provider.js +149 -0
  22. package/dist/dev/theme/theme-provider.js.map +1 -0
  23. package/dist/prod/index.js +1 -0
  24. package/dist/prod/locales/ar.js +2 -0
  25. package/dist/prod/locales/ar.js.map +1 -0
  26. package/dist/prod/locales/en.js +2 -0
  27. package/dist/prod/locales/en.js.map +1 -0
  28. package/dist/prod/registry/utils/utils.js +2 -0
  29. package/dist/prod/registry/utils/utils.js.map +1 -0
  30. package/dist/prod/theme/theme-logic.js +2 -0
  31. package/dist/prod/theme/theme-logic.js.map +1 -0
  32. package/dist/prod/theme/theme-provider.js +2 -0
  33. package/dist/prod/theme/theme-provider.js.map +1 -0
  34. package/package.json +102 -4
  35. package/registry/accordion/accordion.tsx +210 -0
  36. package/registry/accordion/item.json +4 -0
  37. package/registry/alert/alert.tsx +200 -0
  38. package/registry/alert/item.json +4 -0
  39. package/registry/alert-dialog/alert-dialog.tsx +530 -0
  40. package/registry/alert-dialog/item.json +4 -0
  41. package/registry/aspect-ratio/aspect-ratio.tsx +71 -0
  42. package/registry/aspect-ratio/item.json +4 -0
  43. package/registry/attachment/attachment.tsx +459 -0
  44. package/registry/attachment/item.json +4 -0
  45. package/registry/avatar/avatar.tsx +385 -0
  46. package/registry/avatar/item.json +4 -0
  47. package/registry/badge/badge.tsx +108 -0
  48. package/registry/badge/item.json +4 -0
  49. package/registry/breadcrumb/breadcrumb.tsx +354 -0
  50. package/registry/breadcrumb/item.json +4 -0
  51. package/registry/bubble/bubble.tsx +260 -0
  52. package/registry/bubble/item.json +4 -0
  53. package/registry/button/button.tsx +125 -0
  54. package/registry/button/item.json +4 -0
  55. package/registry/button-group/button-group.tsx +189 -0
  56. package/registry/button-group/item.json +4 -0
  57. package/registry/calendar/calendar.tsx +348 -0
  58. package/registry/calendar/item.json +4 -0
  59. package/registry/card/card.tsx +311 -0
  60. package/registry/card/item.json +4 -0
  61. package/registry/carousel/carousel.tsx +851 -0
  62. package/registry/carousel/item.json +4 -0
  63. package/registry/chart/chart.tsx +1956 -0
  64. package/registry/chart/item.json +4 -0
  65. package/registry/chart-scale/chart-scale.ts +670 -0
  66. package/registry/chart-scale/item.json +5 -0
  67. package/registry/checkbox/checkbox.tsx +79 -0
  68. package/registry/checkbox/item.json +4 -0
  69. package/registry/code-block/code-block.tsx +470 -0
  70. package/registry/code-block/item.json +4 -0
  71. package/registry/collapsible/collapsible.tsx +117 -0
  72. package/registry/collapsible/item.json +4 -0
  73. package/registry/combobox/combobox.tsx +977 -0
  74. package/registry/combobox/item.json +4 -0
  75. package/registry/command/command.tsx +757 -0
  76. package/registry/command/item.json +4 -0
  77. package/registry/context-menu/context-menu.tsx +697 -0
  78. package/registry/context-menu/item.json +4 -0
  79. package/registry/data-table/data-table.tsx +437 -0
  80. package/registry/data-table/item.json +4 -0
  81. package/registry/date-picker/date-picker.tsx +349 -0
  82. package/registry/date-picker/item.json +4 -0
  83. package/registry/dialog/dialog.tsx +412 -0
  84. package/registry/dialog/item.json +4 -0
  85. package/registry/direction/direction.tsx +88 -0
  86. package/registry/direction/item.json +4 -0
  87. package/registry/drawer/drawer.tsx +787 -0
  88. package/registry/drawer/item.json +4 -0
  89. package/registry/dropdown-menu/dropdown-menu.tsx +692 -0
  90. package/registry/dropdown-menu/item.json +4 -0
  91. package/registry/empty/empty.tsx +240 -0
  92. package/registry/empty/item.json +4 -0
  93. package/registry/field/field.tsx +624 -0
  94. package/registry/field/item.json +4 -0
  95. package/registry/form/form.tsx +1112 -0
  96. package/registry/form/item.json +4 -0
  97. package/registry/hover-card/hover-card.tsx +144 -0
  98. package/registry/hover-card/item.json +4 -0
  99. package/registry/icons/icons.tsx +1691 -0
  100. package/registry/icons/item.json +4 -0
  101. package/registry/input/input.tsx +43 -0
  102. package/registry/input/item.json +4 -0
  103. package/registry/input-group/input-group.tsx +315 -0
  104. package/registry/input-group/item.json +4 -0
  105. package/registry/input-otp/input-otp.tsx +329 -0
  106. package/registry/input-otp/item.json +4 -0
  107. package/registry/item/item.json +4 -0
  108. package/registry/item/item.tsx +439 -0
  109. package/registry/kbd/item.json +4 -0
  110. package/registry/kbd/kbd.tsx +65 -0
  111. package/registry/label/item.json +4 -0
  112. package/registry/label/label.tsx +60 -0
  113. package/registry/marker/item.json +4 -0
  114. package/registry/marker/marker.tsx +175 -0
  115. package/registry/menubar/item.json +4 -0
  116. package/registry/menubar/menubar.tsx +694 -0
  117. package/registry/message/item.json +4 -0
  118. package/registry/message/message.tsx +280 -0
  119. package/registry/message-scroller/item.json +4 -0
  120. package/registry/message-scroller/message-scroller.tsx +262 -0
  121. package/registry/native-select/item.json +4 -0
  122. package/registry/native-select/native-select.tsx +113 -0
  123. package/registry/navigation-menu/item.json +4 -0
  124. package/registry/navigation-menu/navigation-menu.tsx +362 -0
  125. package/registry/pagination/item.json +4 -0
  126. package/registry/pagination/pagination.tsx +460 -0
  127. package/registry/password-input/item.json +5 -0
  128. package/registry/password-input/password-input.tsx +494 -0
  129. package/registry/popover/item.json +4 -0
  130. package/registry/popover/popover.tsx +284 -0
  131. package/registry/progress/item.json +4 -0
  132. package/registry/progress/progress.tsx +190 -0
  133. package/registry/questionnaire/item.json +4 -0
  134. package/registry/questionnaire/questionnaire.tsx +569 -0
  135. package/registry/radio-group/item.json +4 -0
  136. package/registry/radio-group/radio-group.tsx +101 -0
  137. package/registry/resizable/item.json +4 -0
  138. package/registry/resizable/resizable.tsx +455 -0
  139. package/registry/scroll-area/item.json +4 -0
  140. package/registry/scroll-area/scroll-area.tsx +149 -0
  141. package/registry/select/item.json +4 -0
  142. package/registry/select/select.tsx +571 -0
  143. package/registry/separator/item.json +4 -0
  144. package/registry/separator/separator.tsx +52 -0
  145. package/registry/sheet/item.json +4 -0
  146. package/registry/sheet/sheet.tsx +476 -0
  147. package/registry/sidebar/item.json +4 -0
  148. package/registry/sidebar/sidebar.tsx +1870 -0
  149. package/registry/skeleton/item.json +4 -0
  150. package/registry/skeleton/skeleton.tsx +47 -0
  151. package/registry/slider/item.json +4 -0
  152. package/registry/slider/slider.tsx +149 -0
  153. package/registry/spinner/item.json +4 -0
  154. package/registry/spinner/spinner.tsx +51 -0
  155. package/registry/switch/item.json +4 -0
  156. package/registry/switch/switch.tsx +93 -0
  157. package/registry/table/item.json +4 -0
  158. package/registry/table/table.tsx +373 -0
  159. package/registry/tabs/item.json +4 -0
  160. package/registry/tabs/tabs.tsx +209 -0
  161. package/registry/textarea/item.json +4 -0
  162. package/registry/textarea/textarea.tsx +51 -0
  163. package/registry/toast/item.json +4 -0
  164. package/registry/toast/toast.tsx +949 -0
  165. package/registry/toggle/item.json +4 -0
  166. package/registry/toggle/toggle.tsx +110 -0
  167. package/registry/toggle-group/item.json +4 -0
  168. package/registry/toggle-group/toggle-group.tsx +189 -0
  169. package/registry/tooltip/item.json +4 -0
  170. package/registry/tooltip/tooltip.tsx +169 -0
  171. package/registry/trace/item.json +4 -0
  172. package/registry/trace/trace.tsx +356 -0
  173. package/registry/ui-strings/item.json +5 -0
  174. package/registry/ui-strings/ui-strings.tsx +454 -0
  175. package/registry/use-highlighted-code/item.json +5 -0
  176. package/registry/use-highlighted-code/use-highlighted-code.tsx +145 -0
  177. package/registry/use-mobile/item.json +5 -0
  178. package/registry/use-mobile/use-mobile.ts +46 -0
  179. package/registry/utils/item.json +5 -0
  180. package/registry/utils/utils.ts +38 -0
  181. package/registry.json +3274 -0
  182. package/styles/animations.css +321 -0
  183. package/styles/theme-core.css +55 -0
  184. package/styles/theme.css +12 -0
  185. package/styles/themes/gray.css +69 -0
  186. package/styles/themes/neutral.css +69 -0
  187. package/styles/themes/slate.css +69 -0
  188. package/styles/themes/stone.css +69 -0
  189. package/styles/themes/zinc.css +69 -0
  190. package/styles/typeset.css +251 -0
@@ -0,0 +1,362 @@
1
+ import { splitProps } from "@shadow-js/core";
2
+ import {
3
+ NavigationMenu as NavigationMenuPrimitive,
4
+ type NavigationMenuProps as NavigationMenuPrimitiveProps,
5
+ } from "@shadow-js/primitives";
6
+ import type { ComponentProps, JSX } from "@shadow-js/web";
7
+ import { cva } from "class-variance-authority";
8
+ import { ChevronDownIcon } from "@/components/ui/icons";
9
+ import { cn } from "@/lib/utils";
10
+
11
+ /**
12
+ * The classes of a trigger, for a plain link or a button that should look like a top-level item of
13
+ * a {@link NavigationMenu}.
14
+ *
15
+ * @param props Optional `class` (or `className`) to add to the classes.
16
+ * @returns The class string.
17
+ * @example
18
+ * import { navigationMenuTriggerStyle } from "@/components/ui/navigation-menu";
19
+ *
20
+ * <a href="/about" class={navigationMenuTriggerStyle()}>About</a>
21
+ * @since 1.0.0
22
+ * @see {@link NavigationMenu}
23
+ */
24
+ const navigationMenuTriggerStyle = cva(
25
+ "group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-[state=open]:bg-accent/50 data-[state=open]:text-accent-foreground motion-reduce:transition-none focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-transparent",
26
+ );
27
+
28
+ /**
29
+ * Props of {@link NavigationMenu}: the `nav` attributes plus `value`, `defaultValue`,
30
+ * `onValueChange`, `delayDuration`, `orientation` and `dir`, which are the primitive's.
31
+ * @since 1.0.0
32
+ * @see {@link NavigationMenu}
33
+ */
34
+ export type NavigationMenuProps = NavigationMenuPrimitiveProps;
35
+
36
+ /**
37
+ * The site navigation with flyouts. Each trigger opens its content on click, on a pointer rest
38
+ * (after `delayDuration`), or with ArrowDown, which moves focus into the content. Escape closes the
39
+ * open item and returns focus to its trigger, and a press outside closes it.
40
+ *
41
+ * Keyboard and ARIA: a `nav` element. Name it with `aria-label` (for example `aria-label="Main"`)
42
+ * when the page has more than one navigation. Each trigger has `aria-expanded`, and `aria-controls`
43
+ * while its content is open; the content is labeled by its trigger. Left and Right move between the
44
+ * triggers (Up and Down when vertical); Home and End go to the first and last.
45
+ *
46
+ * @param props See {@link NavigationMenuProps}. `class` adds to the menu's classes.
47
+ * @returns The `nav` element with the items inside.
48
+ * @example
49
+ * import {
50
+ * NavigationMenu,
51
+ * NavigationMenuContent,
52
+ * NavigationMenuItem,
53
+ * NavigationMenuLink,
54
+ * NavigationMenuList,
55
+ * NavigationMenuTrigger,
56
+ * } from "@/components/ui/navigation-menu";
57
+ *
58
+ * <NavigationMenu aria-label="Main">
59
+ * <NavigationMenuList>
60
+ * <NavigationMenuItem value="docs">
61
+ * <NavigationMenuTrigger>Docs</NavigationMenuTrigger>
62
+ * <NavigationMenuContent>
63
+ * <NavigationMenuLink href="/docs/start">Get started</NavigationMenuLink>
64
+ * </NavigationMenuContent>
65
+ * </NavigationMenuItem>
66
+ * </NavigationMenuList>
67
+ * </NavigationMenu>
68
+ * @since 1.0.0
69
+ * @see {@link NavigationMenuItem}
70
+ */
71
+ function NavigationMenu(props: NavigationMenuProps): JSX.Element {
72
+ const [local, rest] = splitProps(
73
+ props as NavigationMenuProps & { readonly class?: unknown; readonly children?: unknown },
74
+ ["class", "children"],
75
+ );
76
+ return (
77
+ <NavigationMenuPrimitive
78
+ data-slot="navigation-menu"
79
+ class={cn(
80
+ "group/navigation-menu relative flex max-w-max flex-1 items-center justify-center",
81
+ local.class as string | undefined,
82
+ )}
83
+ {...rest}
84
+ >
85
+ {local.children as JSX.Element}
86
+ <div data-slot="navigation-menu-viewport-position" class="absolute start-0 top-full" />
87
+ </NavigationMenuPrimitive>
88
+ );
89
+ }
90
+
91
+ /**
92
+ * The row of top-level items of a {@link NavigationMenu}: a `ul`.
93
+ *
94
+ * Keyboard and ARIA: a plain list with no role of its own. The triggers inside it are the tab
95
+ * stops, one at a time, and carry the keys.
96
+ *
97
+ * @param props The `ul` attributes. `class` adds to the classes.
98
+ * @returns The `ul` element.
99
+ * @throws Error when rendered outside a {@link NavigationMenu}.
100
+ * @example
101
+ * import { NavigationMenuItem, NavigationMenuList } from "@/components/ui/navigation-menu";
102
+ *
103
+ * <NavigationMenuList>
104
+ * <NavigationMenuItem value="about">...</NavigationMenuItem>
105
+ * </NavigationMenuList>
106
+ * @since 1.0.0
107
+ * @see {@link NavigationMenu}
108
+ */
109
+ function NavigationMenuList(props: ComponentProps<"ul">): JSX.Element {
110
+ const [local, rest] = splitProps(props, ["class"]);
111
+ return (
112
+ <NavigationMenuPrimitive.List
113
+ data-slot="navigation-menu-list"
114
+ class={cn("group flex flex-1 list-none items-center justify-center gap-1", local.class)}
115
+ {...rest}
116
+ />
117
+ );
118
+ }
119
+
120
+ /**
121
+ * One item of the list: a trigger and its content, linked through `value`. Use it as the container
122
+ * of a {@link NavigationMenuTrigger} and a {@link NavigationMenuContent}.
123
+ *
124
+ * Keyboard and ARIA: an `li` with no role of its own. The trigger and the content are linked
125
+ * through `value`, which builds their ids.
126
+ *
127
+ * shadcn/ui differences: `value` is required here, because it links the trigger to the content. The
128
+ * shadcn examples render `NavigationMenuItem` without one.
129
+ *
130
+ * @param props The `li` attributes, plus `value` (the name of the item). `class` adds to the classes.
131
+ * @returns The `li` element.
132
+ * @throws Error when rendered outside a {@link NavigationMenu}.
133
+ * @example
134
+ * import {
135
+ * NavigationMenuContent,
136
+ * NavigationMenuItem,
137
+ * NavigationMenuLink,
138
+ * NavigationMenuList,
139
+ * NavigationMenuTrigger,
140
+ * } from "@/components/ui/navigation-menu";
141
+ *
142
+ * <NavigationMenuList>
143
+ * <NavigationMenuItem value="products">
144
+ * <NavigationMenuTrigger>Products</NavigationMenuTrigger>
145
+ * <NavigationMenuContent>
146
+ * <NavigationMenuLink href="/products/tools">Tools</NavigationMenuLink>
147
+ * </NavigationMenuContent>
148
+ * </NavigationMenuItem>
149
+ * </NavigationMenuList>
150
+ * @since 1.0.0
151
+ * @see {@link NavigationMenuTrigger}
152
+ */
153
+ function NavigationMenuItem(props: ComponentProps<"li"> & { readonly value: string }): JSX.Element {
154
+ const [local, rest] = splitProps(
155
+ props as ComponentProps<"li"> & { readonly value: string; readonly class?: unknown },
156
+ ["class", "value"],
157
+ );
158
+ return (
159
+ <NavigationMenuPrimitive.Item
160
+ data-slot="navigation-menu-item"
161
+ value={local.value}
162
+ // Not positioned: a flyout is placed against the menu (the nearest positioned ancestor), so it
163
+ // hangs below the bar instead of over its own trigger.
164
+ class={cn(local.class as string | undefined)}
165
+ {...rest}
166
+ />
167
+ );
168
+ }
169
+
170
+ /**
171
+ * The button that opens an item's content, with a chevron that turns while the content is open.
172
+ *
173
+ * Keyboard and ARIA: a button with `aria-expanded`, and `aria-controls` while its content is open.
174
+ * Enter and Space toggle the content; ArrowDown opens it and moves focus into it; Left and Right move
175
+ * to the neighboring trigger; Home and End go to the first and last. The chevron is decorative and
176
+ * hidden from assistive technology. Its name is its text.
177
+ *
178
+ * @param props The `button` attributes. `class` adds to the classes; `children` is the label.
179
+ * @returns The trigger button.
180
+ * @throws Error when rendered outside a {@link NavigationMenu} or its {@link NavigationMenuItem}.
181
+ * @example
182
+ * import { NavigationMenuItem, NavigationMenuTrigger } from "@/components/ui/navigation-menu";
183
+ *
184
+ * <NavigationMenuItem value="products">
185
+ * <NavigationMenuTrigger>Products</NavigationMenuTrigger>
186
+ * </NavigationMenuItem>
187
+ * @since 1.0.0
188
+ * @see {@link NavigationMenuContent}
189
+ */
190
+ function NavigationMenuTrigger(props: ComponentProps<"button">): JSX.Element {
191
+ const [local, rest] = splitProps(props, ["class", "children"]);
192
+ return (
193
+ <NavigationMenuPrimitive.Trigger
194
+ data-slot="navigation-menu-trigger"
195
+ class={cn(navigationMenuTriggerStyle(), "group", local.class)}
196
+ {...rest}
197
+ >
198
+ {local.children}
199
+ <ChevronDownIcon
200
+ aria-hidden="true"
201
+ class="relative top-px ms-1 size-3 transition duration-300 group-data-[state=open]:rotate-180 motion-reduce:transition-none"
202
+ />
203
+ </NavigationMenuPrimitive.Trigger>
204
+ );
205
+ }
206
+
207
+ /**
208
+ * The flyout of an item. It is mounted only while its item is open; once it closes, it is removed
209
+ * after any exit animation has ended.
210
+ *
211
+ * Keyboard and ARIA: it is labeled by its trigger (`aria-labelledby`). Escape, which closes the
212
+ * item, is handled by the menu, so it works from inside the content too.
213
+ *
214
+ * @param props The `div` attributes. `class` adds to the classes; `children` are the links.
215
+ * @returns The flyout `div`, or nothing while the item is closed.
216
+ * @throws Error when rendered outside a {@link NavigationMenu} or its {@link NavigationMenuItem}.
217
+ * @example
218
+ * import { NavigationMenuContent, NavigationMenuLink } from "@/components/ui/navigation-menu";
219
+ *
220
+ * <NavigationMenuContent>
221
+ * <NavigationMenuLink href="/products/tools">Tools</NavigationMenuLink>
222
+ * </NavigationMenuContent>
223
+ * @since 1.0.0
224
+ * @see {@link NavigationMenuTrigger}
225
+ */
226
+ function NavigationMenuContent(props: ComponentProps<"div">): JSX.Element {
227
+ const [local, rest] = splitProps(props, ["class", "children"]);
228
+ return (
229
+ <NavigationMenuPrimitive.Content
230
+ data-slot="navigation-menu-content"
231
+ class={cn(
232
+ "start-0 w-full rounded-md border bg-popover p-2 pe-2.5 text-popover-foreground shadow md:absolute md:top-full md:mt-2 md:w-auto data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 motion-reduce:animate-none",
233
+ local.class,
234
+ )}
235
+ {...rest}
236
+ >
237
+ {local.children}
238
+ </NavigationMenuPrimitive.Content>
239
+ );
240
+ }
241
+
242
+ /**
243
+ * A link in the navigation: a link inside a content, or a plain link as a top-level item. Following
244
+ * the link closes the menu. `active` marks the page the user is on.
245
+ *
246
+ * Keyboard and ARIA: a native link, so Enter follows it. `active` sets `aria-current="page"`. The
247
+ * link adds no other ARIA attribute; its name is its text.
248
+ *
249
+ * @param props The `a` attributes, plus `active`. `class` adds to the classes.
250
+ * @returns The `a` element.
251
+ * @throws Error when rendered outside a {@link NavigationMenu}.
252
+ * @example
253
+ * import { NavigationMenuLink } from "@/components/ui/navigation-menu";
254
+ *
255
+ * <NavigationMenuLink href="/docs" active>Docs</NavigationMenuLink>
256
+ * @since 1.0.0
257
+ * @see {@link NavigationMenuContent}
258
+ */
259
+ function NavigationMenuLink(
260
+ props: ComponentProps<"a"> & { readonly active?: boolean | undefined },
261
+ ): JSX.Element {
262
+ const [local, rest] = splitProps(
263
+ props as ComponentProps<"a"> & {
264
+ readonly active?: boolean | undefined;
265
+ readonly class?: unknown;
266
+ },
267
+ ["class", "active"],
268
+ );
269
+ return (
270
+ <NavigationMenuPrimitive.Link
271
+ data-slot="navigation-menu-link"
272
+ active={local.active === true}
273
+ class={cn(
274
+ "flex flex-col gap-1 rounded-sm p-2 text-sm outline-none hover:bg-accent hover:text-accent-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-[current=page]:font-medium [&_svg:not([class*='size-'])]:size-4 focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-transparent",
275
+ local.class as string | undefined,
276
+ )}
277
+ {...rest}
278
+ />
279
+ );
280
+ }
281
+
282
+ /**
283
+ * The shared panel that hosts the open item's content, so the flyout resizes between items. Render it
284
+ * once after the list. While it is rendered, every {@link NavigationMenuContent} renders inside it;
285
+ * give the content `md:static md:mt-0 md:border-0 md:shadow-none` classes (or your own) to drop the
286
+ * floating look it has on its own. Its size follows the open content through the CSS variables
287
+ * `--primitives-navigation-menu-viewport-width` and `--primitives-navigation-menu-viewport-height`.
288
+ *
289
+ * Keyboard and ARIA: none of its own; the content keeps its labeling. In RTL the panel starts at the
290
+ * right edge of the menu.
291
+ *
292
+ * @param props The `div` attributes. `class` adds to the classes of the panel.
293
+ * @returns The wrapper `div` that holds the panel.
294
+ * @throws Error when rendered outside a {@link NavigationMenu}.
295
+ * @example
296
+ * import { NavigationMenuViewport } from "@/components/ui/navigation-menu";
297
+ *
298
+ * <NavigationMenuViewport />
299
+ * @since 1.0.0
300
+ * @see {@link NavigationMenuContent}
301
+ */
302
+ function NavigationMenuViewport(props: ComponentProps<"div">): JSX.Element {
303
+ const [local, rest] = splitProps(props, ["class"]);
304
+ return (
305
+ <div class="absolute start-0 top-full isolate z-50 flex justify-center">
306
+ <NavigationMenuPrimitive.Viewport
307
+ data-slot="navigation-menu-viewport"
308
+ class={cn(
309
+ "relative mt-1.5 h-[var(--primitives-navigation-menu-viewport-height)] w-full origin-top overflow-hidden rounded-md border bg-popover text-popover-foreground shadow md:w-[var(--primitives-navigation-menu-viewport-width)] data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:zoom-in-90 motion-reduce:animate-none",
310
+ local.class,
311
+ )}
312
+ {...rest}
313
+ />
314
+ </div>
315
+ );
316
+ }
317
+
318
+ /**
319
+ * A marker that follows the open item's trigger: an arrow under the active item. Render it inside
320
+ * the {@link NavigationMenuList}, which is positioned. It places itself with the CSS variables
321
+ * `--primitives-navigation-menu-indicator-position` and `--primitives-navigation-menu-indicator-size`,
322
+ * counted from the start edge, so it follows the trigger in RTL as well.
323
+ *
324
+ * Keyboard and ARIA: decorative, hidden from assistive technology.
325
+ *
326
+ * @param props The `div` attributes. `class` adds to the classes.
327
+ * @returns The `div` element with the arrow inside.
328
+ * @throws Error when rendered outside a {@link NavigationMenu}.
329
+ * @example
330
+ * import { NavigationMenuIndicator } from "@/components/ui/navigation-menu";
331
+ *
332
+ * <NavigationMenuIndicator />
333
+ * @since 1.0.0
334
+ * @see {@link NavigationMenuTrigger}
335
+ */
336
+ function NavigationMenuIndicator(props: ComponentProps<"div">): JSX.Element {
337
+ const [local, rest] = splitProps(props, ["class"]);
338
+ return (
339
+ <NavigationMenuPrimitive.Indicator
340
+ data-slot="navigation-menu-indicator"
341
+ class={cn(
342
+ "absolute start-[var(--primitives-navigation-menu-indicator-position)] top-full z-[1] flex h-1.5 w-[var(--primitives-navigation-menu-indicator-size)] items-end justify-center overflow-hidden data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:animate-in data-[state=visible]:fade-in motion-reduce:animate-none",
343
+ local.class,
344
+ )}
345
+ {...rest}
346
+ >
347
+ <div class="relative top-[60%] size-2 rotate-45 rounded-ss-sm bg-border shadow-md" />
348
+ </NavigationMenuPrimitive.Indicator>
349
+ );
350
+ }
351
+
352
+ export {
353
+ NavigationMenu,
354
+ NavigationMenuContent,
355
+ NavigationMenuIndicator,
356
+ NavigationMenuItem,
357
+ NavigationMenuLink,
358
+ NavigationMenuList,
359
+ NavigationMenuTrigger,
360
+ NavigationMenuViewport,
361
+ navigationMenuTriggerStyle,
362
+ };
@@ -0,0 +1,4 @@
1
+ {
2
+ "title": "Pagination",
3
+ "description": "Pagination with page navigation, next and previous links."
4
+ }