@shadow-js/ui 0.0.0-stage → 1.0.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 (190) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/LICENSE +21 -0
  3. package/README.md +598 -2
  4. package/dist/cli.mjs +2293 -0
  5. package/dist/dev/cli/schema.d.ts +73 -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 +141 -0
  9. package/dist/dev/locales/ar.js +128 -0
  10. package/dist/dev/locales/ar.js.map +1 -0
  11. package/dist/dev/locales/en.d.ts +141 -0
  12. package/dist/dev/locales/en.js +128 -0
  13. package/dist/dev/locales/en.js.map +1 -0
  14. package/dist/dev/registry/utils/utils.d.ts +29 -0
  15. package/dist/dev/registry/utils/utils.js +27 -0
  16. package/dist/dev/registry/utils/utils.js.map +1 -0
  17. package/dist/dev/theme/theme-logic.d.ts +187 -0
  18. package/dist/dev/theme/theme-logic.js +184 -0
  19. package/dist/dev/theme/theme-logic.js.map +1 -0
  20. package/dist/dev/theme/theme-provider.d.ts +90 -0
  21. package/dist/dev/theme/theme-provider.js +150 -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,4 @@
1
+ {
2
+ "title": "Dropdown Menu",
3
+ "description": "Displays a menu to the user, such as a set of actions or functions, triggered by a button."
4
+ }
@@ -0,0 +1,240 @@
1
+ import { splitProps } from "@shadow-js/core";
2
+ import type { ComponentProps, JSX } from "@shadow-js/web";
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+ import { cn } from "@/lib/utils";
5
+
6
+ /**
7
+ * A block for "nothing here yet" or "no results": an icon or illustration, a title, a description and
8
+ * the next action. It is a dashed, centered box, and its parts are plain elements.
9
+ *
10
+ * Keyboard and ARIA: the block and its parts have no role and no keys. The title is a `div`, so it is
11
+ * not a heading for assistive technology. To make it one, pass `role="heading"` and `aria-level`. The
12
+ * description is a `p`, and its links are underlined.
13
+ *
14
+ * shadcn/ui differences: the prop is `class`, not `className`, and every part has a `data-slot`. The media part
15
+ * is `empty-icon` (`data-slot="empty-icon"`), not `empty-media`.
16
+ *
17
+ * @param props The block props: the attributes of the rendered `div` and `class`.
18
+ * @returns The empty state block.
19
+ * @example
20
+ * import { Button } from "@/components/ui/button";
21
+ * import {
22
+ * Empty,
23
+ * EmptyContent,
24
+ * EmptyDescription,
25
+ * EmptyHeader,
26
+ * EmptyMedia,
27
+ * EmptyTitle,
28
+ * } from "@/components/ui/empty";
29
+ * import { SearchIcon } from "@/components/ui/icons";
30
+ *
31
+ * export function NoResults() {
32
+ * return (
33
+ * <Empty>
34
+ * <EmptyHeader>
35
+ * <EmptyMedia variant="icon">
36
+ * <SearchIcon />
37
+ * </EmptyMedia>
38
+ * <EmptyTitle>No results</EmptyTitle>
39
+ * <EmptyDescription>Try a different search.</EmptyDescription>
40
+ * </EmptyHeader>
41
+ * <EmptyContent>
42
+ * <Button>Clear filters</Button>
43
+ * </EmptyContent>
44
+ * </Empty>
45
+ * );
46
+ * }
47
+ * @see {@link EmptyHeader}
48
+ * @see {@link EmptyContent}
49
+ * @since 1.0.0
50
+ */
51
+ function Empty(props: ComponentProps<"div">): JSX.Element {
52
+ const [local, rest] = splitProps(props, ["class"]);
53
+ return (
54
+ <div
55
+ data-slot="empty"
56
+ class={cn(
57
+ "flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border border-dashed p-6 text-center text-balance md:p-12",
58
+ local.class,
59
+ )}
60
+ {...rest}
61
+ />
62
+ );
63
+ }
64
+
65
+ /**
66
+ * The top of an empty state, which holds the {@link EmptyMedia}, the {@link EmptyTitle} and the
67
+ * {@link EmptyDescription}. It stacks them centered, with a maximum width. It is a plain `div`.
68
+ *
69
+ * @param props The header props: the attributes of the rendered `div` and `class`.
70
+ * @returns The header.
71
+ * @example
72
+ * import { EmptyDescription, EmptyHeader, EmptyTitle } from "@/components/ui/empty";
73
+ *
74
+ * export function Heading() {
75
+ * return (
76
+ * <EmptyHeader>
77
+ * <EmptyTitle>Nothing here</EmptyTitle>
78
+ * <EmptyDescription>New items show up here.</EmptyDescription>
79
+ * </EmptyHeader>
80
+ * );
81
+ * }
82
+ * @see {@link Empty}
83
+ * @since 1.0.0
84
+ */
85
+ function EmptyHeader(props: ComponentProps<"div">): JSX.Element {
86
+ const [local, rest] = splitProps(props, ["class"]);
87
+ return (
88
+ <div
89
+ data-slot="empty-header"
90
+ class={cn("flex max-w-sm flex-col items-center gap-2 text-center", local.class)}
91
+ {...rest}
92
+ />
93
+ );
94
+ }
95
+
96
+ const mediaVariants = cva(
97
+ "mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
98
+ {
99
+ variants: {
100
+ variant: {
101
+ default: "bg-transparent",
102
+ icon: "size-10 rounded-lg bg-muted text-foreground [&_svg:not([class*='size-'])]:size-6",
103
+ },
104
+ },
105
+ defaultVariants: { variant: "default" },
106
+ },
107
+ );
108
+
109
+ /**
110
+ * Props of {@link EmptyMedia}: the attributes of the rendered `div` and `variant`, which is `default`
111
+ * (the media is shown as it is) or `icon` (the media sits on a muted tile).
112
+ * @see {@link EmptyMedia}
113
+ * @since 1.0.0
114
+ */
115
+ export type EmptyMediaProps = ComponentProps<"div"> & VariantProps<typeof mediaVariants>;
116
+
117
+ /**
118
+ * The icon or picture of an empty state. With `variant="icon"` the child (an icon, sized to 1.5rem by
119
+ * default) sits on a muted, rounded tile. The part is `data-slot="empty-icon"`.
120
+ *
121
+ * @param props The media props: see {@link EmptyMediaProps}.
122
+ * @returns The media.
123
+ * @example
124
+ * import { Empty, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty";
125
+ * import { SearchIcon } from "@/components/ui/icons";
126
+ *
127
+ * export function Searching() {
128
+ * return (
129
+ * <Empty>
130
+ * <EmptyHeader>
131
+ * <EmptyMedia variant="icon">
132
+ * <SearchIcon />
133
+ * </EmptyMedia>
134
+ * <EmptyTitle>No results</EmptyTitle>
135
+ * </EmptyHeader>
136
+ * </Empty>
137
+ * );
138
+ * }
139
+ * @see {@link EmptyHeader}
140
+ * @since 1.0.0
141
+ */
142
+ function EmptyMedia(props: EmptyMediaProps): JSX.Element {
143
+ const [local, rest] = splitProps(props, ["class", "variant"]);
144
+ return (
145
+ <div
146
+ data-slot="empty-icon"
147
+ data-variant={local.variant ?? "default"}
148
+ class={cn(mediaVariants({ variant: local.variant }), local.class)}
149
+ {...rest}
150
+ />
151
+ );
152
+ }
153
+
154
+ /**
155
+ * The title of an empty state. It is a `div` with no heading role; pass `role="heading"` and
156
+ * `aria-level` to make it a heading for assistive technology.
157
+ *
158
+ * @param props The title props: the attributes of the rendered `div` and `class`.
159
+ * @returns The title.
160
+ * @example
161
+ * import { EmptyTitle } from "@/components/ui/empty";
162
+ *
163
+ * export const Title = <EmptyTitle role="heading" aria-level={2}>No results</EmptyTitle>;
164
+ * @see {@link EmptyHeader}
165
+ * @since 1.0.0
166
+ */
167
+ function EmptyTitle(props: ComponentProps<"div">): JSX.Element {
168
+ const [local, rest] = splitProps(props, ["class"]);
169
+ return (
170
+ <div
171
+ data-slot="empty-title"
172
+ class={cn("text-lg font-medium tracking-tight", local.class)}
173
+ {...rest}
174
+ />
175
+ );
176
+ }
177
+
178
+ /**
179
+ * The explanation under an empty state's title. It is a `p`, and the links in it are underlined.
180
+ *
181
+ * @param props The description props: the attributes of the rendered `p` and `class`.
182
+ * @returns The paragraph.
183
+ * @example
184
+ * import { EmptyDescription } from "@/components/ui/empty";
185
+ *
186
+ * export const Explanation = (
187
+ * <EmptyDescription>
188
+ * Try <a href="/reset">another search</a>.
189
+ * </EmptyDescription>
190
+ * );
191
+ * @see {@link EmptyHeader}
192
+ * @since 1.0.0
193
+ */
194
+ function EmptyDescription(props: ComponentProps<"p">): JSX.Element {
195
+ const [local, rest] = splitProps(props, ["class"]);
196
+ return (
197
+ <p
198
+ data-slot="empty-description"
199
+ class={cn(
200
+ "text-sm/relaxed text-muted-foreground [&_a]:underline [&_a]:underline-offset-4 [&_a:hover]:text-primary",
201
+ local.class,
202
+ )}
203
+ {...rest}
204
+ />
205
+ );
206
+ }
207
+
208
+ /**
209
+ * The actions of an empty state, such as the button that creates the first item. It is a centered
210
+ * column below the header.
211
+ *
212
+ * @param props The content props: the attributes of the rendered `div` and `class`.
213
+ * @returns The actions block.
214
+ * @example
215
+ * import { Button } from "@/components/ui/button";
216
+ * import { EmptyContent } from "@/components/ui/empty";
217
+ *
218
+ * export const Actions = (
219
+ * <EmptyContent>
220
+ * <Button>Create</Button>
221
+ * </EmptyContent>
222
+ * );
223
+ * @see {@link Empty}
224
+ * @since 1.0.0
225
+ */
226
+ function EmptyContent(props: ComponentProps<"div">): JSX.Element {
227
+ const [local, rest] = splitProps(props, ["class"]);
228
+ return (
229
+ <div
230
+ data-slot="empty-content"
231
+ class={cn(
232
+ "flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance",
233
+ local.class,
234
+ )}
235
+ {...rest}
236
+ />
237
+ );
238
+ }
239
+
240
+ export { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle };
@@ -0,0 +1,4 @@
1
+ {
2
+ "title": "Empty",
3
+ "description": "An empty-state block: media, title, description and the next action."
4
+ }