opin-ui 0.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 (243) hide show
  1. package/README.md +5 -0
  2. package/css/aspen.css +39 -0
  3. package/css/black.css +39 -0
  4. package/css/catppuccin.css +49 -0
  5. package/css/dusk.css +47 -0
  6. package/css/emerald.css +39 -0
  7. package/css/generated/docs.css +1 -0
  8. package/css/generated/flux.css +1 -0
  9. package/css/generated/home.css +1 -0
  10. package/css/generated/notebook.css +1 -0
  11. package/css/generated/shared.css +1 -0
  12. package/css/lib/base.css +314 -0
  13. package/css/lib/default-colors.css +51 -0
  14. package/css/lib/shiki.css +108 -0
  15. package/css/neutral.css +7 -0
  16. package/css/ocean.css +44 -0
  17. package/css/preset-legacy.css +43 -0
  18. package/css/preset.css +11 -0
  19. package/css/purple.css +39 -0
  20. package/css/ruby.css +39 -0
  21. package/css/shadcn.css +36 -0
  22. package/css/solar.css +75 -0
  23. package/css/style.css +9 -0
  24. package/css/vitepress.css +65 -0
  25. package/dist/.translations/index.d.ts +49 -0
  26. package/dist/.translations/keys.js +49 -0
  27. package/dist/_virtual/_rolldown/runtime.js +13 -0
  28. package/dist/components/accordion.d.ts +23 -0
  29. package/dist/components/accordion.js +68 -0
  30. package/dist/components/banner.d.ts +33 -0
  31. package/dist/components/banner.js +85 -0
  32. package/dist/components/callout.d.ts +41 -0
  33. package/dist/components/callout.js +53 -0
  34. package/dist/components/card.d.ts +19 -0
  35. package/dist/components/card.js +38 -0
  36. package/dist/components/codeblock.d.ts +61 -0
  37. package/dist/components/codeblock.js +173 -0
  38. package/dist/components/codeblock.rsc.d.ts +20 -0
  39. package/dist/components/codeblock.rsc.js +22 -0
  40. package/dist/components/dialog/search-algolia.d.ts +36 -0
  41. package/dist/components/dialog/search-algolia.js +64 -0
  42. package/dist/components/dialog/search-default.d.ts +36 -0
  43. package/dist/components/dialog/search-default.js +58 -0
  44. package/dist/components/dialog/search-orama.d.ts +43 -0
  45. package/dist/components/dialog/search-orama.js +69 -0
  46. package/dist/components/dialog/search.d.ts +112 -0
  47. package/dist/components/dialog/search.js +350 -0
  48. package/dist/components/dynamic-codeblock.core.d.ts +34 -0
  49. package/dist/components/dynamic-codeblock.core.js +51 -0
  50. package/dist/components/dynamic-codeblock.d.ts +9 -0
  51. package/dist/components/dynamic-codeblock.js +17 -0
  52. package/dist/components/files.d.ts +34 -0
  53. package/dist/components/files.js +40 -0
  54. package/dist/components/github-info.d.ts +35 -0
  55. package/dist/components/github-info.js +75 -0
  56. package/dist/components/heading.d.ts +13 -0
  57. package/dist/components/heading.js +38 -0
  58. package/dist/components/image-zoom.d.ts +23 -0
  59. package/dist/components/image-zoom.js +32 -0
  60. package/dist/components/image-zoom2.css +71 -0
  61. package/dist/components/inline-toc.d.ts +14 -0
  62. package/dist/components/inline-toc.js +28 -0
  63. package/dist/components/sidebar/base.d.ts +131 -0
  64. package/dist/components/sidebar/base.js +274 -0
  65. package/dist/components/sidebar/link-item.d.ts +22 -0
  66. package/dist/components/sidebar/link-item.js +38 -0
  67. package/dist/components/sidebar/page-tree.d.ts +28 -0
  68. package/dist/components/sidebar/page-tree.js +71 -0
  69. package/dist/components/sidebar/tabs/dropdown.d.ts +16 -0
  70. package/dist/components/sidebar/tabs/dropdown.js +71 -0
  71. package/dist/components/sidebar/tabs/index.d.ts +11 -0
  72. package/dist/components/sidebar/tabs/index.js +46 -0
  73. package/dist/components/steps.d.ts +15 -0
  74. package/dist/components/steps.js +16 -0
  75. package/dist/components/tabs.d.ts +49 -0
  76. package/dist/components/tabs.js +88 -0
  77. package/dist/components/toc/clerk.d.ts +20 -0
  78. package/dist/components/toc/clerk.js +226 -0
  79. package/dist/components/toc/default.d.ts +23 -0
  80. package/dist/components/toc/default.js +259 -0
  81. package/dist/components/toc/index.d.ts +19 -0
  82. package/dist/components/toc/index.js +45 -0
  83. package/dist/components/type-table.d.ts +43 -0
  84. package/dist/components/type-table.js +117 -0
  85. package/dist/components/ui/accordion.d.ts +30 -0
  86. package/dist/components/ui/accordion.js +42 -0
  87. package/dist/components/ui/button.d.ts +11 -0
  88. package/dist/components/ui/button.js +20 -0
  89. package/dist/components/ui/collapsible.d.ts +15 -0
  90. package/dist/components/ui/collapsible.js +21 -0
  91. package/dist/components/ui/navigation-menu.d.ts +30 -0
  92. package/dist/components/ui/navigation-menu.js +41 -0
  93. package/dist/components/ui/popover.d.ts +15 -0
  94. package/dist/components/ui/popover.js +20 -0
  95. package/dist/components/ui/scroll-area.d.ts +22 -0
  96. package/dist/components/ui/scroll-area.js +34 -0
  97. package/dist/components/ui/tabs.d.ts +36 -0
  98. package/dist/components/ui/tabs.js +77 -0
  99. package/dist/contexts/i18n.d.ts +41 -0
  100. package/dist/contexts/i18n.js +37 -0
  101. package/dist/contexts/search.d.ts +73 -0
  102. package/dist/contexts/search.js +68 -0
  103. package/dist/contexts/tree.d.ts +20 -0
  104. package/dist/contexts/tree.js +38 -0
  105. package/dist/i18n.d.ts +16 -0
  106. package/dist/i18n.js +38 -0
  107. package/dist/layouts/docs/client.d.ts +34 -0
  108. package/dist/layouts/docs/client.js +92 -0
  109. package/dist/layouts/docs/index.d.ts +44 -0
  110. package/dist/layouts/docs/index.js +22 -0
  111. package/dist/layouts/docs/page/index.d.ts +115 -0
  112. package/dist/layouts/docs/page/index.js +124 -0
  113. package/dist/layouts/docs/page/slots/breadcrumb.d.ts +13 -0
  114. package/dist/layouts/docs/page/slots/breadcrumb.js +44 -0
  115. package/dist/layouts/docs/page/slots/container.d.ts +6 -0
  116. package/dist/layouts/docs/page/slots/container.js +17 -0
  117. package/dist/layouts/docs/page/slots/footer.d.ts +22 -0
  118. package/dist/layouts/docs/page/slots/footer.js +56 -0
  119. package/dist/layouts/docs/page/slots/toc.d.ts +62 -0
  120. package/dist/layouts/docs/page/slots/toc.js +182 -0
  121. package/dist/layouts/docs/slots/container.d.ts +6 -0
  122. package/dist/layouts/docs/slots/container.js +36 -0
  123. package/dist/layouts/docs/slots/header.d.ts +6 -0
  124. package/dist/layouts/docs/slots/header.js +38 -0
  125. package/dist/layouts/docs/slots/sidebar.d.ts +29 -0
  126. package/dist/layouts/docs/slots/sidebar.js +326 -0
  127. package/dist/layouts/flux/index.d.ts +73 -0
  128. package/dist/layouts/flux/index.js +146 -0
  129. package/dist/layouts/flux/page/index.d.ts +102 -0
  130. package/dist/layouts/flux/page/index.js +104 -0
  131. package/dist/layouts/flux/page/slots/breadcrumb.d.ts +13 -0
  132. package/dist/layouts/flux/page/slots/breadcrumb.js +44 -0
  133. package/dist/layouts/flux/page/slots/container.d.ts +6 -0
  134. package/dist/layouts/flux/page/slots/container.js +17 -0
  135. package/dist/layouts/flux/page/slots/footer.d.ts +22 -0
  136. package/dist/layouts/flux/page/slots/footer.js +56 -0
  137. package/dist/layouts/flux/page/slots/toc.d.ts +38 -0
  138. package/dist/layouts/flux/page/slots/toc.js +181 -0
  139. package/dist/layouts/flux/slots/container.d.ts +6 -0
  140. package/dist/layouts/flux/slots/container.js +13 -0
  141. package/dist/layouts/flux/slots/sidebar.d.ts +22 -0
  142. package/dist/layouts/flux/slots/sidebar.js +237 -0
  143. package/dist/layouts/flux/slots/tab-dropdown.d.ts +16 -0
  144. package/dist/layouts/flux/slots/tab-dropdown.js +85 -0
  145. package/dist/layouts/home/index.d.ts +28 -0
  146. package/dist/layouts/home/index.js +40 -0
  147. package/dist/layouts/home/navbar.d.ts +10 -0
  148. package/dist/layouts/home/navbar.js +34 -0
  149. package/dist/layouts/home/not-found.d.ts +7 -0
  150. package/dist/layouts/home/not-found.js +41 -0
  151. package/dist/layouts/home/slots/container.d.ts +6 -0
  152. package/dist/layouts/home/slots/container.js +13 -0
  153. package/dist/layouts/home/slots/header.d.ts +9 -0
  154. package/dist/layouts/home/slots/header.js +239 -0
  155. package/dist/layouts/notebook/client.d.ts +36 -0
  156. package/dist/layouts/notebook/client.js +69 -0
  157. package/dist/layouts/notebook/index.d.ts +37 -0
  158. package/dist/layouts/notebook/index.js +22 -0
  159. package/dist/layouts/notebook/page/index.d.ts +115 -0
  160. package/dist/layouts/notebook/page/index.js +124 -0
  161. package/dist/layouts/notebook/page/slots/breadcrumb.d.ts +13 -0
  162. package/dist/layouts/notebook/page/slots/breadcrumb.js +44 -0
  163. package/dist/layouts/notebook/page/slots/container.d.ts +6 -0
  164. package/dist/layouts/notebook/page/slots/container.js +17 -0
  165. package/dist/layouts/notebook/page/slots/footer.d.ts +22 -0
  166. package/dist/layouts/notebook/page/slots/footer.js +56 -0
  167. package/dist/layouts/notebook/page/slots/toc.d.ts +62 -0
  168. package/dist/layouts/notebook/page/slots/toc.js +181 -0
  169. package/dist/layouts/notebook/slots/container.d.ts +6 -0
  170. package/dist/layouts/notebook/slots/container.js +38 -0
  171. package/dist/layouts/notebook/slots/header.d.ts +6 -0
  172. package/dist/layouts/notebook/slots/header.js +194 -0
  173. package/dist/layouts/notebook/slots/sidebar.d.ts +30 -0
  174. package/dist/layouts/notebook/slots/sidebar.js +298 -0
  175. package/dist/layouts/shared/client.d.ts +44 -0
  176. package/dist/layouts/shared/client.js +84 -0
  177. package/dist/layouts/shared/index.d.ts +178 -0
  178. package/dist/layouts/shared/index.js +98 -0
  179. package/dist/layouts/shared/page-actions.d.ts +35 -0
  180. package/dist/layouts/shared/page-actions.js +195 -0
  181. package/dist/layouts/shared/slots/language-select.d.ts +18 -0
  182. package/dist/layouts/shared/slots/language-select.js +43 -0
  183. package/dist/layouts/shared/slots/search-trigger.d.ts +22 -0
  184. package/dist/layouts/shared/slots/search-trigger.js +53 -0
  185. package/dist/layouts/shared/slots/theme-switch.d.ts +13 -0
  186. package/dist/layouts/shared/slots/theme-switch.js +65 -0
  187. package/dist/legacy/layout.d.ts +36 -0
  188. package/dist/legacy/layout.js +44 -0
  189. package/dist/legacy/sidebar.d.ts +17 -0
  190. package/dist/legacy/sidebar.js +33 -0
  191. package/dist/mdx.d.ts +45 -0
  192. package/dist/mdx.js +70 -0
  193. package/dist/mdx.server.d.ts +15 -0
  194. package/dist/mdx.server.js +20 -0
  195. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/controlled.d.ts +31 -0
  196. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/controlled.js +461 -0
  197. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/index.d.ts +2 -0
  198. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/uncontrolled.d.ts +7 -0
  199. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/uncontrolled.js +17 -0
  200. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/adjust-svg-ids.js +53 -0
  201. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/compute-positioned-style.js +25 -0
  202. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/element-tests.js +12 -0
  203. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/get-div-img-style.js +45 -0
  204. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/get-img-alt.js +8 -0
  205. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/get-img-object-fit-style.js +55 -0
  206. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/get-img-regular-style.js +21 -0
  207. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/get-img-src.js +14 -0
  208. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/get-modal-img-transform.js +22 -0
  209. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/get-scale.js +27 -0
  210. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/get-style-ghost.js +31 -0
  211. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/get-style-modal-img.js +75 -0
  212. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/get-target-dimension.js +4 -0
  213. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/parse-position.js +7 -0
  214. package/dist/node_modules/.bun/react-medium-image-zoom@5.4.8_7492c01c6988791b/node_modules/react-medium-image-zoom/dist/utils/test-has-scalable-src.js +5 -0
  215. package/dist/og/takumi.d.ts +21 -0
  216. package/dist/og/takumi.js +91 -0
  217. package/dist/og.d.ts +22 -0
  218. package/dist/og.js +91 -0
  219. package/dist/page.d.ts +35 -0
  220. package/dist/page.js +33 -0
  221. package/dist/provider/base.d.ts +49 -0
  222. package/dist/provider/base.js +32 -0
  223. package/dist/provider/next.d.ts +20 -0
  224. package/dist/provider/next.js +17 -0
  225. package/dist/provider/react-router.d.ts +20 -0
  226. package/dist/provider/react-router.js +17 -0
  227. package/dist/provider/tanstack.d.ts +20 -0
  228. package/dist/provider/tanstack.js +17 -0
  229. package/dist/provider/waku.d.ts +20 -0
  230. package/dist/provider/waku.js +17 -0
  231. package/dist/style.css +3534 -0
  232. package/dist/tailwind/typography.d.ts +2 -0
  233. package/dist/tailwind/typography.js +2 -0
  234. package/dist/utils/cn.js +2 -0
  235. package/dist/utils/merge-refs.js +11 -0
  236. package/dist/utils/urls.js +15 -0
  237. package/dist/utils/use-copy-button.d.ts +6 -0
  238. package/dist/utils/use-copy-button.js +26 -0
  239. package/dist/utils/use-footer-items.d.ts +9 -0
  240. package/dist/utils/use-footer-items.js +24 -0
  241. package/dist/utils/use-is-scroll-top.d.ts +8 -0
  242. package/dist/utils/use-is-scroll-top.js +20 -0
  243. package/package.json +200 -0
@@ -0,0 +1,178 @@
1
+ import { FullSearchTriggerProps, SearchTriggerProps } from "./slots/search-trigger.js";
2
+ import { ThemeSwitchProps } from "./slots/theme-switch.js";
3
+ import { BaseSlots, BaseSlotsProps, LinkItem, baseSlots } from "./client.js";
4
+ import { ComponentProps, FC, ReactNode } from "react";
5
+ import * as PageTree from "fumadocs-core/page-tree";
6
+ import { I18nConfig } from "fumadocs-core/i18n";
7
+
8
+ //#region src/layouts/shared/index.d.ts
9
+ interface NavOptions {
10
+ enabled?: boolean;
11
+ children?: ReactNode;
12
+ title?: ReactNode | FC<ComponentProps<'a'>>;
13
+ /**
14
+ * Redirect url of title
15
+ * @defaultValue '/'
16
+ */
17
+ url?: string;
18
+ /**
19
+ * Use transparent background
20
+ *
21
+ * @defaultValue none
22
+ */
23
+ transparentMode?: 'always' | 'top' | 'none';
24
+ /**
25
+ * @deprecated use `slots.header` instead.
26
+ */
27
+ component?: ReactNode;
28
+ }
29
+ interface BaseLayoutProps {
30
+ /**
31
+ * GitHub url
32
+ */
33
+ githubUrl?: string;
34
+ links?: LinkItemType[];
35
+ /**
36
+ * navigation config
37
+ */
38
+ nav?: NavOptions;
39
+ slots?: Partial<BaseSlots>;
40
+ children?: ReactNode;
41
+ themeSwitch?: ThemeSwitchOptions;
42
+ searchToggle?: SearchToggleOptions;
43
+ /**
44
+ * @deprecated this is now optional for i18n setups, you can still customize language switch from `slots`.
45
+ */
46
+ i18n?: boolean | I18nConfig;
47
+ }
48
+ interface SearchToggleOptions {
49
+ enabled?: boolean;
50
+ sm?: SearchTriggerProps;
51
+ full?: FullSearchTriggerProps;
52
+ /** @deprecated use `slots.searchTrigger` instead */
53
+ components?: {
54
+ sm?: ReactNode;
55
+ lg?: ReactNode;
56
+ };
57
+ }
58
+ interface ThemeSwitchOptions extends ThemeSwitchProps {
59
+ enabled?: boolean;
60
+ /** @deprecated use `slots.themeSwitch` instead */
61
+ component?: ReactNode;
62
+ }
63
+ interface LayoutTab {
64
+ /**
65
+ * Redirect URL of the folder, usually the index page
66
+ */
67
+ url: string;
68
+ icon?: ReactNode;
69
+ title: ReactNode;
70
+ description?: ReactNode;
71
+ unlisted?: boolean;
72
+ props?: ComponentProps<'a'>;
73
+ /**
74
+ * bind to a page tree node.
75
+ */
76
+ $folder?: PageTree.Folder;
77
+ /**
78
+ * Detect from a list of urls (when not binded to page tree).
79
+ */
80
+ urls?: Set<string>;
81
+ }
82
+ interface GetLayoutTabsOptions {
83
+ transform?: (option: LayoutTab, node: PageTree.Folder) => LayoutTab | null;
84
+ }
85
+ declare function getLayoutTabs(tree: PageTree.Root, {
86
+ transform
87
+ }?: GetLayoutTabsOptions): LayoutTab[];
88
+ declare function isLayoutTabActive(tab: LayoutTab, pathname: string): boolean;
89
+ interface Filterable {
90
+ /**
91
+ * Restrict where the item is displayed
92
+ *
93
+ * @defaultValue 'all'
94
+ */
95
+ on?: 'menu' | 'nav' | 'all';
96
+ }
97
+ interface WithHref {
98
+ url: string;
99
+ /**
100
+ * When the item is marked as active
101
+ *
102
+ * @defaultValue 'url'
103
+ */
104
+ active?: 'url' | 'nested-url' | 'none';
105
+ external?: boolean;
106
+ }
107
+ interface MainItemType extends WithHref, Filterable {
108
+ type?: 'main';
109
+ icon?: ReactNode;
110
+ text: ReactNode;
111
+ description?: ReactNode;
112
+ }
113
+ interface IconItemType extends WithHref, Filterable {
114
+ type: 'icon';
115
+ /**
116
+ * `aria-label` of icon button
117
+ */
118
+ label?: string;
119
+ icon: ReactNode;
120
+ text: ReactNode;
121
+ /**
122
+ * @defaultValue true
123
+ */
124
+ secondary?: boolean;
125
+ }
126
+ interface ButtonItemType extends WithHref, Filterable {
127
+ type: 'button';
128
+ icon?: ReactNode;
129
+ text: ReactNode;
130
+ /**
131
+ * @defaultValue false
132
+ */
133
+ secondary?: boolean;
134
+ }
135
+ interface MenuItemType extends Partial<WithHref>, Filterable {
136
+ type: 'menu';
137
+ icon?: ReactNode;
138
+ text: ReactNode;
139
+ items: ((MainItemType & {
140
+ /**
141
+ * Options when displayed on navigation menu
142
+ */
143
+ menu?: ComponentProps<'a'> & {
144
+ banner?: ReactNode;
145
+ };
146
+ }) | CustomItemType)[];
147
+ /**
148
+ * @defaultValue false
149
+ */
150
+ secondary?: boolean;
151
+ }
152
+ interface CustomItemType extends Filterable {
153
+ type: 'custom';
154
+ /**
155
+ * @defaultValue false
156
+ */
157
+ secondary?: boolean;
158
+ children: ReactNode;
159
+ }
160
+ type LinkItemType = MainItemType | IconItemType | ButtonItemType | MenuItemType | CustomItemType;
161
+ /**
162
+ * Get link items with shortcuts
163
+ */
164
+ declare function resolveLinkItems({
165
+ links,
166
+ githubUrl
167
+ }: Pick<BaseLayoutProps, 'links' | 'githubUrl'>): LinkItemType[];
168
+ declare function useLinkItems({
169
+ githubUrl,
170
+ links
171
+ }: Pick<BaseLayoutProps, 'links' | 'githubUrl'>): {
172
+ navItems: LinkItemType[];
173
+ menuItems: LinkItemType[];
174
+ all: LinkItemType[];
175
+ };
176
+ declare function isLinkItemActive(link: LinkItemType, pathname: string): boolean;
177
+ //#endregion
178
+ export { BaseLayoutProps, type BaseSlots, type BaseSlotsProps, ButtonItemType, CustomItemType, GetLayoutTabsOptions, IconItemType, LayoutTab, LinkItem, LinkItemType, MainItemType, MenuItemType, NavOptions, baseSlots, getLayoutTabs, isLayoutTabActive, isLinkItemActive, resolveLinkItems, useLinkItems };
@@ -0,0 +1,98 @@
1
+ import { isActive, normalize } from "../../utils/urls.js";
2
+ import { LinkItem, baseSlots } from "./client.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { useMemo } from "react";
5
+ import * as PageTree from "fumadocs-core/page-tree";
6
+ //#region src/layouts/shared/index.tsx
7
+ const defaultTransform = (option, node) => {
8
+ if (!node.icon) return option;
9
+ return {
10
+ ...option,
11
+ icon: /* @__PURE__ */ jsx("div", {
12
+ className: "size-full [&_svg]:size-full max-md:p-1.5 max-md:rounded-md max-md:border max-md:bg-fd-secondary",
13
+ children: node.icon
14
+ })
15
+ };
16
+ };
17
+ function getLayoutTabs(tree, { transform = defaultTransform } = {}) {
18
+ const results = [];
19
+ function next(node, unlisted) {
20
+ if ("root" in node && node.root) {
21
+ const url = node.index?.url ?? node.children.find((node) => node.type === "page")?.url;
22
+ if (url) {
23
+ const option = {
24
+ title: node.name,
25
+ icon: node.icon,
26
+ description: node.description,
27
+ url,
28
+ unlisted,
29
+ $folder: node
30
+ };
31
+ const mapped = transform ? transform(option, node) : option;
32
+ if (mapped) results.push(mapped);
33
+ }
34
+ }
35
+ for (const child of node.children) if (child.type === "folder") next(child, unlisted);
36
+ }
37
+ next(tree);
38
+ if (tree.fallback) next(tree.fallback, true);
39
+ return results;
40
+ }
41
+ function isLayoutTabActive(tab, pathname) {
42
+ if (tab.$folder) return PageTree.findPath(tab.$folder.children, (node) => node.type === "page" && isActive(node.url, pathname)) !== null;
43
+ if (tab.urls) return tab.urls.has(normalize(pathname));
44
+ return isActive(tab.url, pathname, true);
45
+ }
46
+ /**
47
+ * Get link items with shortcuts
48
+ */
49
+ function resolveLinkItems({ links = [], githubUrl }) {
50
+ const result = [...links];
51
+ if (githubUrl) result.push({
52
+ type: "icon",
53
+ url: githubUrl,
54
+ text: "Github",
55
+ label: "GitHub",
56
+ icon: /* @__PURE__ */ jsx("svg", {
57
+ role: "img",
58
+ viewBox: "0 0 24 24",
59
+ fill: "currentColor",
60
+ children: /* @__PURE__ */ jsx("path", { d: "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" })
61
+ }),
62
+ external: true
63
+ });
64
+ return result;
65
+ }
66
+ function useLinkItems({ githubUrl, links }) {
67
+ return useMemo(() => {
68
+ const all = resolveLinkItems({
69
+ links,
70
+ githubUrl
71
+ });
72
+ const navItems = [];
73
+ const menuItems = [];
74
+ for (const item of all) switch (item.on) {
75
+ case "menu":
76
+ menuItems.push(item);
77
+ break;
78
+ case "nav":
79
+ navItems.push(item);
80
+ break;
81
+ default:
82
+ navItems.push(item);
83
+ menuItems.push(item);
84
+ }
85
+ return {
86
+ navItems,
87
+ menuItems,
88
+ all
89
+ };
90
+ }, [links, githubUrl]);
91
+ }
92
+ function isLinkItemActive(link, pathname) {
93
+ if (link.type === "custom" || !link.url) return false;
94
+ if (link.active === "none") return false;
95
+ return isActive(link.url, pathname, link.active === "nested-url");
96
+ }
97
+ //#endregion
98
+ export { LinkItem, baseSlots, getLayoutTabs, isLayoutTabActive, isLinkItemActive, resolveLinkItems, useLinkItems };
@@ -0,0 +1,35 @@
1
+ import { PopoverTrigger } from "../../components/ui/popover.js";
2
+ import { ComponentProps } from "react";
3
+
4
+ //#region src/layouts/shared/page-actions.d.ts
5
+ /**
6
+ * see https://fumadocs.dev/docs/integrations/llms#page-actions to customize.
7
+ */
8
+ declare function MarkdownCopyButton({
9
+ markdownUrl,
10
+ ...props
11
+ }: ComponentProps<'button'> & {
12
+ /**
13
+ * A URL to fetch the raw Markdown/MDX content of page
14
+ */
15
+ markdownUrl: string;
16
+ }): import("react").JSX.Element;
17
+ /**
18
+ * see https://fumadocs.dev/docs/integrations/llms#page-actions to customize.
19
+ */
20
+ declare function ViewOptionsPopover({
21
+ markdownUrl,
22
+ githubUrl,
23
+ ...props
24
+ }: ComponentProps<typeof PopoverTrigger> & {
25
+ /**
26
+ * A URL to the raw Markdown/MDX content of page
27
+ */
28
+ markdownUrl?: string;
29
+ /**
30
+ * Source file URL on GitHub
31
+ */
32
+ githubUrl?: string;
33
+ }): import("react").JSX.Element;
34
+ //#endregion
35
+ export { MarkdownCopyButton, ViewOptionsPopover };
@@ -0,0 +1,195 @@
1
+ "use client";
2
+ import { cn } from "../../utils/cn.js";
3
+ import { buttonVariants } from "../../components/ui/button.js";
4
+ import { useCopyButton } from "../../utils/use-copy-button.js";
5
+ import { Popover, PopoverContent, PopoverTrigger } from "../../components/ui/popover.js";
6
+ import { usePathname } from "fumadocs-core/framework";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { Check, ChevronDown, Copy, ExternalLinkIcon, TextIcon } from "lucide-react";
9
+ import { useMemo, useState } from "react";
10
+ import { useTranslations } from "@fuma-translate/react";
11
+ //#region src/layouts/shared/page-actions.tsx
12
+ const cache = /* @__PURE__ */ new Map();
13
+ /**
14
+ * see https://fumadocs.dev/docs/integrations/llms#page-actions to customize.
15
+ */
16
+ function MarkdownCopyButton({ markdownUrl, ...props }) {
17
+ const t = useTranslations({ note: "page actions" });
18
+ const [isLoading, setLoading] = useState(false);
19
+ const [checked, onClick] = useCopyButton(async () => {
20
+ const cached = cache.get(markdownUrl);
21
+ if (cached) return navigator.clipboard.writeText(await cached);
22
+ setLoading(true);
23
+ try {
24
+ const promise = fetch(markdownUrl).then((res) => res.text());
25
+ cache.set(markdownUrl, promise);
26
+ await navigator.clipboard.write([new ClipboardItem({ "text/plain": promise })]);
27
+ } finally {
28
+ setLoading(false);
29
+ }
30
+ });
31
+ return /* @__PURE__ */ jsxs("button", {
32
+ disabled: isLoading,
33
+ onClick,
34
+ ...props,
35
+ className: cn(buttonVariants({
36
+ color: "secondary",
37
+ size: "sm",
38
+ className: "gap-2 [&_svg]:size-3.5 [&_svg]:text-fd-muted-foreground"
39
+ }), props.className),
40
+ children: [checked ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(Copy, {}), props.children ?? t("Copy Markdown")]
41
+ });
42
+ }
43
+ /**
44
+ * see https://fumadocs.dev/docs/integrations/llms#page-actions to customize.
45
+ */
46
+ function ViewOptionsPopover({ markdownUrl, githubUrl, ...props }) {
47
+ const pathname = usePathname();
48
+ const t = useTranslations({ note: "page actions" });
49
+ const items = useMemo(() => {
50
+ const pageUrl = typeof window === "undefined" ? pathname : new URL(pathname, window.location.origin);
51
+ const q = t("Read {url}, I want to ask questions about it.", { variables: { url: String(pageUrl) } });
52
+ return [
53
+ githubUrl && {
54
+ title: t("Open in GitHub"),
55
+ href: githubUrl,
56
+ icon: /* @__PURE__ */ jsxs("svg", {
57
+ fill: "currentColor",
58
+ role: "img",
59
+ viewBox: "0 0 24 24",
60
+ children: [/* @__PURE__ */ jsx("title", { children: "GitHub" }), /* @__PURE__ */ jsx("path", { d: "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" })]
61
+ })
62
+ },
63
+ markdownUrl && {
64
+ title: t("View as Markdown"),
65
+ href: markdownUrl,
66
+ icon: /* @__PURE__ */ jsx(TextIcon, {})
67
+ },
68
+ {
69
+ title: t("Open in Scira AI"),
70
+ href: `https://scira.ai/?${new URLSearchParams({ q })}`,
71
+ icon: /* @__PURE__ */ jsxs("svg", {
72
+ width: "910",
73
+ height: "934",
74
+ viewBox: "0 0 910 934",
75
+ fill: "none",
76
+ xmlns: "http://www.w3.org/2000/svg",
77
+ children: [
78
+ /* @__PURE__ */ jsx("title", { children: "Scira AI" }),
79
+ /* @__PURE__ */ jsx("path", {
80
+ d: "M647.664 197.775C569.13 189.049 525.5 145.419 516.774 66.8849C508.048 145.419 464.418 189.049 385.884 197.775C464.418 206.501 508.048 250.131 516.774 328.665C525.5 250.131 569.13 206.501 647.664 197.775Z",
81
+ fill: "currentColor",
82
+ stroke: "currentColor",
83
+ strokeWidth: "8",
84
+ strokeLinejoin: "round"
85
+ }),
86
+ /* @__PURE__ */ jsx("path", {
87
+ d: "M516.774 304.217C510.299 275.491 498.208 252.087 480.335 234.214C462.462 216.341 439.058 204.251 410.333 197.775C439.059 191.3 462.462 179.209 480.335 161.336C498.208 143.463 510.299 120.06 516.774 91.334C523.25 120.059 535.34 143.463 553.213 161.336C571.086 179.209 594.49 191.3 623.216 197.775C594.49 204.251 571.086 216.341 553.213 234.214C535.34 252.087 523.25 275.491 516.774 304.217Z",
88
+ fill: "currentColor",
89
+ stroke: "currentColor",
90
+ strokeWidth: "8",
91
+ strokeLinejoin: "round"
92
+ }),
93
+ /* @__PURE__ */ jsx("path", {
94
+ d: "M857.5 508.116C763.259 497.644 710.903 445.288 700.432 351.047C689.961 445.288 637.605 497.644 543.364 508.116C637.605 518.587 689.961 570.943 700.432 665.184C710.903 570.943 763.259 518.587 857.5 508.116Z",
95
+ stroke: "currentColor",
96
+ strokeWidth: "20",
97
+ strokeLinejoin: "round"
98
+ }),
99
+ /* @__PURE__ */ jsx("path", {
100
+ d: "M700.432 615.957C691.848 589.05 678.575 566.357 660.383 548.165C642.191 529.973 619.499 516.7 592.593 508.116C619.499 499.533 642.191 486.258 660.383 468.066C678.575 449.874 691.848 427.181 700.432 400.274C709.015 427.181 722.289 449.874 740.481 468.066C758.673 486.258 781.365 499.533 808.271 508.116C781.365 516.7 758.673 529.973 740.481 548.165C722.289 566.357 709.015 589.05 700.432 615.957Z",
101
+ stroke: "currentColor",
102
+ strokeWidth: "20",
103
+ strokeLinejoin: "round"
104
+ }),
105
+ /* @__PURE__ */ jsx("path", {
106
+ d: "M889.949 121.237C831.049 114.692 798.326 81.9698 791.782 23.0692C785.237 81.9698 752.515 114.692 693.614 121.237C752.515 127.781 785.237 160.504 791.782 219.404C798.326 160.504 831.049 127.781 889.949 121.237Z",
107
+ fill: "currentColor",
108
+ stroke: "currentColor",
109
+ strokeWidth: "8",
110
+ strokeLinejoin: "round"
111
+ }),
112
+ /* @__PURE__ */ jsx("path", {
113
+ d: "M791.782 196.795C786.697 176.937 777.869 160.567 765.16 147.858C752.452 135.15 736.082 126.322 716.226 121.237C736.082 116.152 752.452 107.324 765.16 94.6152C777.869 81.9065 786.697 65.5368 791.782 45.6797C796.867 65.5367 805.695 81.9066 818.403 94.6152C831.112 107.324 847.481 116.152 867.338 121.237C847.481 126.322 831.112 135.15 818.403 147.858C805.694 160.567 796.867 176.937 791.782 196.795Z",
114
+ fill: "currentColor",
115
+ stroke: "currentColor",
116
+ strokeWidth: "8",
117
+ strokeLinejoin: "round"
118
+ }),
119
+ /* @__PURE__ */ jsx("path", {
120
+ d: "M760.632 764.337C720.719 814.616 669.835 855.1 611.872 882.692C553.91 910.285 490.404 924.255 426.213 923.533C362.022 922.812 298.846 907.419 241.518 878.531C184.19 849.643 134.228 808.026 95.4548 756.863C56.6815 705.7 30.1238 646.346 17.8129 583.343C5.50207 520.339 7.76433 455.354 24.4266 393.359C41.089 331.364 71.7099 274.001 113.947 225.658C156.184 177.315 208.919 139.273 268.117 114.442",
121
+ stroke: "currentColor",
122
+ strokeWidth: "30",
123
+ strokeLinecap: "round",
124
+ strokeLinejoin: "round"
125
+ })
126
+ ]
127
+ })
128
+ },
129
+ {
130
+ title: t("Open in ChatGPT"),
131
+ href: `https://chatgpt.com/?${new URLSearchParams({
132
+ hints: "search",
133
+ q
134
+ })}`,
135
+ icon: /* @__PURE__ */ jsxs("svg", {
136
+ role: "img",
137
+ viewBox: "0 0 24 24",
138
+ fill: "currentColor",
139
+ xmlns: "http://www.w3.org/2000/svg",
140
+ children: [/* @__PURE__ */ jsx("title", { children: "OpenAI" }), /* @__PURE__ */ jsx("path", { d: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z" })]
141
+ })
142
+ },
143
+ {
144
+ title: t("Open in Claude"),
145
+ href: `https://claude.ai/new?${new URLSearchParams({ q })}`,
146
+ icon: /* @__PURE__ */ jsxs("svg", {
147
+ fill: "currentColor",
148
+ role: "img",
149
+ viewBox: "0 0 24 24",
150
+ xmlns: "http://www.w3.org/2000/svg",
151
+ children: [/* @__PURE__ */ jsx("title", { children: "Anthropic" }), /* @__PURE__ */ jsx("path", { d: "M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z" })]
152
+ })
153
+ },
154
+ {
155
+ title: t("Open in Cursor"),
156
+ icon: /* @__PURE__ */ jsxs("svg", {
157
+ fill: "currentColor",
158
+ role: "img",
159
+ viewBox: "0 0 24 24",
160
+ xmlns: "http://www.w3.org/2000/svg",
161
+ children: [/* @__PURE__ */ jsx("title", { children: "Cursor" }), /* @__PURE__ */ jsx("path", { d: "M11.503.131 1.891 5.678a.84.84 0 0 0-.42.726v11.188c0 .3.162.575.42.724l9.609 5.55a1 1 0 0 0 .998 0l9.61-5.55a.84.84 0 0 0 .42-.724V6.404a.84.84 0 0 0-.42-.726L12.497.131a1.01 1.01 0 0 0-.996 0M2.657 6.338h18.55c.263 0 .43.287.297.515L12.23 22.918c-.062.107-.229.064-.229-.06V12.335a.59.59 0 0 0-.295-.51l-9.11-5.257c-.109-.063-.064-.23.061-.23" })]
162
+ }),
163
+ href: `https://cursor.com/link/prompt?${new URLSearchParams({ text: q })}`
164
+ }
165
+ ].filter((v) => !!v);
166
+ }, [
167
+ githubUrl,
168
+ markdownUrl,
169
+ pathname,
170
+ t
171
+ ]);
172
+ return /* @__PURE__ */ jsxs(Popover, { children: [/* @__PURE__ */ jsxs(PopoverTrigger, {
173
+ ...props,
174
+ className: cn(buttonVariants({
175
+ color: "secondary",
176
+ size: "sm"
177
+ }), "gap-2 data-[state=open]:bg-fd-accent data-[state=open]:text-fd-accent-foreground", props.className),
178
+ children: [props.children ?? t("Open"), /* @__PURE__ */ jsx(ChevronDown, { className: "size-3.5 text-fd-muted-foreground" })]
179
+ }), /* @__PURE__ */ jsx(PopoverContent, {
180
+ className: "flex flex-col",
181
+ children: items.map((item) => /* @__PURE__ */ jsxs("a", {
182
+ href: item.href,
183
+ rel: "noreferrer noopener",
184
+ target: "_blank",
185
+ className: "text-sm p-2 rounded-lg inline-flex items-center gap-2 hover:text-fd-accent-foreground hover:bg-fd-accent [&_svg]:size-4",
186
+ children: [
187
+ item.icon,
188
+ item.title,
189
+ /* @__PURE__ */ jsx(ExternalLinkIcon, { className: "text-fd-muted-foreground size-3.5 ms-auto" })
190
+ ]
191
+ }, item.href))
192
+ })] });
193
+ }
194
+ //#endregion
195
+ export { MarkdownCopyButton, ViewOptionsPopover };
@@ -0,0 +1,18 @@
1
+ import { buttonVariants } from "../../../components/ui/button.js";
2
+ import { VariantProps } from "class-variance-authority";
3
+ import { ComponentProps } from "react";
4
+
5
+ //#region src/layouts/shared/slots/language-select.d.ts
6
+ interface LanguageSelectProps extends ComponentProps<'button'> {
7
+ variant?: VariantProps<typeof buttonVariants>['variant'];
8
+ }
9
+ declare function LanguageSelect({
10
+ className,
11
+ variant,
12
+ children,
13
+ ...rest
14
+ }: LanguageSelectProps): React.ReactElement;
15
+ type LanguageSelectTextProps = ComponentProps<'span'>;
16
+ declare function LanguageSelectText(props: LanguageSelectTextProps): import("react").JSX.Element;
17
+ //#endregion
18
+ export { LanguageSelect, LanguageSelectProps, LanguageSelectText, LanguageSelectTextProps };
@@ -0,0 +1,43 @@
1
+ "use client";
2
+ import { cn } from "../../../utils/cn.js";
3
+ import { buttonVariants } from "../../../components/ui/button.js";
4
+ import { useI18n } from "../../../contexts/i18n.js";
5
+ import { Popover, PopoverContent, PopoverTrigger } from "../../../components/ui/popover.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { useTranslations } from "@fuma-translate/react";
8
+ //#region src/layouts/shared/slots/language-select.tsx
9
+ function LanguageSelect({ className, variant = "ghost", children, ...rest }) {
10
+ const context = useI18n();
11
+ const t = useTranslations({ note: "language switcher" });
12
+ if (!context.locales) throw new Error("Missing `<I18nProvider />`");
13
+ const chooseLanguage = t("Choose a language");
14
+ return /* @__PURE__ */ jsxs(Popover, { children: [/* @__PURE__ */ jsx(PopoverTrigger, {
15
+ "aria-label": t("Choose a language", { note: "aria-label" }),
16
+ className: cn(buttonVariants({ variant }), "gap-1.5 p-1.5 data-[state=open]:bg-fd-accent", className),
17
+ ...rest,
18
+ children
19
+ }), /* @__PURE__ */ jsxs(PopoverContent, {
20
+ className: "flex flex-col gap-0.5 p-1",
21
+ children: [/* @__PURE__ */ jsx("p", {
22
+ className: "p-2 text-xs font-medium text-fd-muted-foreground",
23
+ children: chooseLanguage
24
+ }), context.locales.map((item) => /* @__PURE__ */ jsx("button", {
25
+ type: "button",
26
+ className: cn("px-2 py-1.5 text-start text-sm rounded-lg transition-colors", item.locale === context.locale ? "bg-fd-primary/10 text-fd-primary" : "text-fd-muted-foreground hover:bg-fd-accent hover:text-fd-accent-foreground"),
27
+ onClick: () => {
28
+ context.onChange?.(item.locale);
29
+ },
30
+ children: item.name
31
+ }, item.locale))]
32
+ })] });
33
+ }
34
+ function LanguageSelectText(props) {
35
+ const { locales, locale } = useI18n();
36
+ const text = locales?.find((item) => item.locale === locale)?.name;
37
+ return /* @__PURE__ */ jsx("span", {
38
+ ...props,
39
+ children: text
40
+ });
41
+ }
42
+ //#endregion
43
+ export { LanguageSelect, LanguageSelectText };
@@ -0,0 +1,22 @@
1
+ import { ButtonProps } from "../../../components/ui/button.js";
2
+ import { ComponentProps } from "react";
3
+
4
+ //#region src/layouts/shared/slots/search-trigger.d.ts
5
+ interface SearchTriggerProps extends Omit<ComponentProps<'button'>, 'color'>, ButtonProps {
6
+ hideIfDisabled?: boolean;
7
+ }
8
+ declare function SearchTrigger({
9
+ hideIfDisabled,
10
+ size,
11
+ color,
12
+ ...props
13
+ }: SearchTriggerProps): import("react").JSX.Element | null;
14
+ interface FullSearchTriggerProps extends ComponentProps<'button'> {
15
+ hideIfDisabled?: boolean;
16
+ }
17
+ declare function FullSearchTrigger({
18
+ hideIfDisabled,
19
+ ...props
20
+ }: FullSearchTriggerProps): import("react").JSX.Element | null;
21
+ //#endregion
22
+ export { FullSearchTrigger, FullSearchTriggerProps, SearchTrigger, SearchTriggerProps };
@@ -0,0 +1,53 @@
1
+ "use client";
2
+ import { cn } from "../../../utils/cn.js";
3
+ import { buttonVariants } from "../../../components/ui/button.js";
4
+ import { useSearchContext } from "../../../contexts/search.js";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { Search } from "lucide-react";
7
+ import { useTranslations } from "@fuma-translate/react";
8
+ //#region src/layouts/shared/slots/search-trigger.tsx
9
+ function SearchTrigger({ hideIfDisabled, size = "icon-sm", color = "ghost", ...props }) {
10
+ const { setOpenSearch, enabled } = useSearchContext();
11
+ const t = useTranslations({ note: "search trigger" });
12
+ if (hideIfDisabled && !enabled) return null;
13
+ return /* @__PURE__ */ jsx("button", {
14
+ type: "button",
15
+ className: cn(buttonVariants({
16
+ size,
17
+ color
18
+ }), props.className),
19
+ "data-search": "",
20
+ "aria-label": t("Open Search", { note: "aria-label" }),
21
+ onClick: () => {
22
+ setOpenSearch(true);
23
+ },
24
+ children: /* @__PURE__ */ jsx(Search, {})
25
+ });
26
+ }
27
+ function FullSearchTrigger({ hideIfDisabled, ...props }) {
28
+ const { enabled, hotKey, setOpenSearch } = useSearchContext();
29
+ const t = useTranslations({ note: "search trigger" });
30
+ if (hideIfDisabled && !enabled) return null;
31
+ return /* @__PURE__ */ jsxs("button", {
32
+ type: "button",
33
+ "data-search-full": "",
34
+ ...props,
35
+ className: cn("inline-flex items-center gap-2 rounded-lg border bg-fd-secondary/50 p-1.5 ps-2 text-sm text-fd-muted-foreground transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground", props.className),
36
+ onClick: () => {
37
+ setOpenSearch(true);
38
+ },
39
+ children: [
40
+ /* @__PURE__ */ jsx(Search, { className: "size-4" }),
41
+ t("Search"),
42
+ /* @__PURE__ */ jsx("div", {
43
+ className: "ms-auto inline-flex gap-0.5",
44
+ children: hotKey.map((k, i) => /* @__PURE__ */ jsx("kbd", {
45
+ className: "rounded-md border bg-fd-background px-1.5",
46
+ children: k.display
47
+ }, i))
48
+ })
49
+ ]
50
+ });
51
+ }
52
+ //#endregion
53
+ export { FullSearchTrigger, SearchTrigger };
@@ -0,0 +1,13 @@
1
+ import { ComponentProps } from "react";
2
+
3
+ //#region src/layouts/shared/slots/theme-switch.d.ts
4
+ interface ThemeSwitchProps extends ComponentProps<'div'> {
5
+ mode?: 'light-dark' | 'light-dark-system';
6
+ }
7
+ declare function ThemeSwitch({
8
+ className,
9
+ mode,
10
+ ...props
11
+ }: ThemeSwitchProps): import("react").JSX.Element;
12
+ //#endregion
13
+ export { ThemeSwitch, ThemeSwitchProps };