@ratio-ui/core 0.1.1 → 0.3.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 (214) hide show
  1. package/README.md +2 -0
  2. package/dist/catalogue.json +2829 -72
  3. package/dist/components/alert/Alert.d.ts +18 -0
  4. package/dist/components/alert/Alert.js +67 -0
  5. package/dist/components/alert/index.d.ts +2 -0
  6. package/dist/components/alert/index.js +1 -0
  7. package/dist/components/alert-dialog/AlertDialog.d.ts +48 -0
  8. package/dist/components/alert-dialog/AlertDialog.js +76 -0
  9. package/dist/components/alert-dialog/index.d.ts +2 -0
  10. package/dist/components/alert-dialog/index.js +1 -0
  11. package/dist/components/app-shell/AppShell.d.ts +22 -0
  12. package/dist/components/app-shell/AppShell.js +39 -0
  13. package/dist/components/app-shell/context.js +5 -0
  14. package/dist/components/app-shell/index.d.ts +2 -0
  15. package/dist/components/app-shell/index.js +1 -0
  16. package/dist/components/avatar/Avatar.d.ts +22 -0
  17. package/dist/components/avatar/Avatar.js +38 -0
  18. package/dist/components/avatar/index.d.ts +2 -0
  19. package/dist/components/avatar/index.js +1 -0
  20. package/dist/components/button/Button.d.ts +37 -0
  21. package/dist/components/button/Button.js +41 -0
  22. package/dist/components/button/index.d.ts +2 -0
  23. package/dist/components/button/index.js +1 -0
  24. package/dist/components/calendar/Calendar.d.ts +20 -0
  25. package/dist/components/calendar/Calendar.js +119 -0
  26. package/dist/components/calendar/index.d.ts +2 -0
  27. package/dist/components/calendar/index.js +1 -0
  28. package/dist/components/card/Card.d.ts +33 -0
  29. package/dist/components/card/Card.js +53 -0
  30. package/dist/components/card/index.d.ts +2 -0
  31. package/dist/components/card/index.js +1 -0
  32. package/dist/components/checkbox/Checkbox.d.ts +10 -0
  33. package/dist/components/checkbox/Checkbox.js +28 -0
  34. package/dist/components/checkbox/index.d.ts +2 -0
  35. package/dist/components/checkbox/index.js +1 -0
  36. package/dist/components/checkbox-list/CheckboxList.d.ts +36 -0
  37. package/dist/components/checkbox-list/CheckboxList.js +93 -0
  38. package/dist/components/checkbox-list/index.d.ts +2 -0
  39. package/dist/components/checkbox-list/index.js +1 -0
  40. package/dist/components/collapsible/Collapsible.d.ts +24 -0
  41. package/dist/components/collapsible/Collapsible.js +58 -0
  42. package/dist/components/collapsible/index.d.ts +2 -0
  43. package/dist/components/collapsible/index.js +1 -0
  44. package/dist/components/data-table/DataTable.d.ts +65 -0
  45. package/dist/components/data-table/DataTable.js +141 -0
  46. package/dist/components/data-table/index.d.ts +2 -0
  47. package/dist/components/data-table/index.js +1 -0
  48. package/dist/components/date-picker/DatePicker.d.ts +33 -0
  49. package/dist/components/date-picker/DatePicker.js +104 -0
  50. package/dist/components/date-picker/index.d.ts +2 -0
  51. package/dist/components/date-picker/index.js +1 -0
  52. package/dist/components/date-range-picker/DateRangePicker.d.ts +39 -0
  53. package/dist/components/date-range-picker/DateRangePicker.js +142 -0
  54. package/dist/components/date-range-picker/index.d.ts +2 -0
  55. package/dist/components/date-range-picker/index.js +1 -0
  56. package/dist/components/definition/Definition.d.ts +14 -0
  57. package/dist/components/definition/Definition.js +29 -0
  58. package/dist/components/definition/index.d.ts +2 -0
  59. package/dist/components/definition/index.js +1 -0
  60. package/dist/components/dialog/Dialog.d.ts +44 -0
  61. package/dist/components/dialog/Dialog.js +79 -0
  62. package/dist/components/dialog/index.d.ts +2 -0
  63. package/dist/components/dialog/index.js +1 -0
  64. package/dist/components/dropdown-menu/DropdownMenu.d.ts +73 -0
  65. package/dist/components/dropdown-menu/DropdownMenu.js +116 -0
  66. package/dist/components/dropdown-menu/index.d.ts +2 -0
  67. package/dist/components/dropdown-menu/index.js +1 -0
  68. package/dist/components/empty-state/EmptyState.d.ts +15 -0
  69. package/dist/components/empty-state/EmptyState.js +30 -0
  70. package/dist/components/empty-state/index.d.ts +2 -0
  71. package/dist/components/empty-state/index.js +1 -0
  72. package/dist/components/field/Field.d.ts +35 -0
  73. package/dist/components/field/Field.js +67 -0
  74. package/dist/components/field/Label.d.ts +8 -0
  75. package/dist/components/field/Label.js +13 -0
  76. package/dist/components/field/index.d.ts +3 -0
  77. package/dist/components/field/index.js +3 -0
  78. package/dist/components/filter-tabs/FilterTabs.d.ts +28 -0
  79. package/dist/components/filter-tabs/FilterTabs.js +37 -0
  80. package/dist/components/filter-tabs/index.d.ts +2 -0
  81. package/dist/components/filter-tabs/index.js +1 -0
  82. package/dist/components/global-search/GlobalSearch.d.ts +51 -0
  83. package/dist/components/global-search/GlobalSearch.js +144 -0
  84. package/dist/components/global-search/index.d.ts +2 -0
  85. package/dist/components/global-search/index.js +1 -0
  86. package/dist/components/icon/registry.d.ts +3 -2
  87. package/dist/components/icon/registry.js +57 -1
  88. package/dist/components/input/Input.d.ts +19 -0
  89. package/dist/components/input/Input.js +26 -0
  90. package/dist/components/input/index.d.ts +2 -0
  91. package/dist/components/input/index.js +1 -0
  92. package/dist/components/input-group/InputGroup.d.ts +42 -0
  93. package/dist/components/input-group/InputGroup.js +83 -0
  94. package/dist/components/input-group/index.d.ts +2 -0
  95. package/dist/components/input-group/index.js +1 -0
  96. package/dist/components/kbd/Kbd.d.ts +17 -0
  97. package/dist/components/kbd/Kbd.js +21 -0
  98. package/dist/components/kbd/index.d.ts +2 -0
  99. package/dist/components/kbd/index.js +1 -0
  100. package/dist/components/link/Link.d.ts +22 -0
  101. package/dist/components/link/Link.js +31 -0
  102. package/dist/components/link/index.d.ts +2 -0
  103. package/dist/components/link/index.js +1 -0
  104. package/dist/components/link-provider/LinkProvider.d.ts +29 -0
  105. package/dist/components/link-provider/LinkProvider.js +15 -0
  106. package/dist/components/link-provider/RatioLink.js +18 -0
  107. package/dist/components/link-provider/context.js +4 -0
  108. package/dist/components/link-provider/index.d.ts +2 -0
  109. package/dist/components/link-provider/index.js +1 -0
  110. package/dist/components/media-grid/MediaGrid.d.ts +49 -0
  111. package/dist/components/media-grid/MediaGrid.js +303 -0
  112. package/dist/components/media-grid/index.d.ts +2 -0
  113. package/dist/components/media-grid/index.js +1 -0
  114. package/dist/components/metric-strip/MetricStrip.d.ts +23 -0
  115. package/dist/components/metric-strip/MetricStrip.js +39 -0
  116. package/dist/components/metric-strip/index.d.ts +2 -0
  117. package/dist/components/metric-strip/index.js +1 -0
  118. package/dist/components/money-input/MoneyInput.d.ts +30 -0
  119. package/dist/components/money-input/MoneyInput.js +72 -0
  120. package/dist/components/money-input/index.d.ts +2 -0
  121. package/dist/components/money-input/index.js +1 -0
  122. package/dist/components/page-header/PageHeader.d.ts +37 -0
  123. package/dist/components/page-header/PageHeader.js +62 -0
  124. package/dist/components/page-header/index.d.ts +2 -0
  125. package/dist/components/page-header/index.js +1 -0
  126. package/dist/components/pagination/Pagination.d.ts +18 -0
  127. package/dist/components/pagination/Pagination.js +59 -0
  128. package/dist/components/pagination/index.d.ts +2 -0
  129. package/dist/components/pagination/index.js +1 -0
  130. package/dist/components/popover/Popover.d.ts +27 -0
  131. package/dist/components/popover/Popover.js +47 -0
  132. package/dist/components/popover/index.d.ts +2 -0
  133. package/dist/components/popover/index.js +1 -0
  134. package/dist/components/save-bar/SaveBar.d.ts +27 -0
  135. package/dist/components/save-bar/SaveBar.js +37 -0
  136. package/dist/components/save-bar/index.d.ts +2 -0
  137. package/dist/components/save-bar/index.js +1 -0
  138. package/dist/components/search-field/SearchField.d.ts +23 -0
  139. package/dist/components/search-field/SearchField.js +66 -0
  140. package/dist/components/search-field/index.d.ts +2 -0
  141. package/dist/components/search-field/index.js +1 -0
  142. package/dist/components/select/Select.d.ts +40 -0
  143. package/dist/components/select/Select.js +84 -0
  144. package/dist/components/select/index.d.ts +2 -0
  145. package/dist/components/select/index.js +1 -0
  146. package/dist/components/side-nav/SideNav.d.ts +64 -0
  147. package/dist/components/side-nav/SideNav.js +194 -0
  148. package/dist/components/side-nav/index.d.ts +2 -0
  149. package/dist/components/side-nav/index.js +1 -0
  150. package/dist/components/skeleton/Skeleton.d.ts +13 -0
  151. package/dist/components/skeleton/Skeleton.js +21 -0
  152. package/dist/components/skeleton/index.d.ts +2 -0
  153. package/dist/components/skeleton/index.js +1 -0
  154. package/dist/components/spinner/Spinner.d.ts +11 -0
  155. package/dist/components/spinner/Spinner.js +16 -0
  156. package/dist/components/spinner/index.d.ts +2 -0
  157. package/dist/components/spinner/index.js +1 -0
  158. package/dist/components/status-pill/StatusPill.d.ts +14 -0
  159. package/dist/components/status-pill/StatusPill.js +19 -0
  160. package/dist/components/status-pill/index.d.ts +2 -0
  161. package/dist/components/status-pill/index.js +1 -0
  162. package/dist/components/summary-chips/SummaryChips.d.ts +17 -0
  163. package/dist/components/summary-chips/SummaryChips.js +19 -0
  164. package/dist/components/summary-chips/index.d.ts +2 -0
  165. package/dist/components/summary-chips/index.js +1 -0
  166. package/dist/components/switch/Switch.d.ts +10 -0
  167. package/dist/components/switch/Switch.js +20 -0
  168. package/dist/components/switch/index.d.ts +2 -0
  169. package/dist/components/switch/index.js +1 -0
  170. package/dist/components/table/Table.d.ts +46 -0
  171. package/dist/components/table/Table.js +87 -0
  172. package/dist/components/table/index.d.ts +2 -0
  173. package/dist/components/table/index.js +1 -0
  174. package/dist/components/table-loader/TableLoader.d.ts +31 -0
  175. package/dist/components/table-loader/TableLoader.js +35 -0
  176. package/dist/components/table-loader/index.d.ts +2 -0
  177. package/dist/components/table-loader/index.js +1 -0
  178. package/dist/components/tabs/Tabs.d.ts +23 -0
  179. package/dist/components/tabs/Tabs.js +41 -0
  180. package/dist/components/tabs/index.d.ts +2 -0
  181. package/dist/components/tabs/index.js +1 -0
  182. package/dist/components/tag-input/TagInput.d.ts +44 -0
  183. package/dist/components/tag-input/TagInput.js +102 -0
  184. package/dist/components/tag-input/index.d.ts +2 -0
  185. package/dist/components/tag-input/index.js +1 -0
  186. package/dist/components/textarea/Textarea.d.ts +15 -0
  187. package/dist/components/textarea/Textarea.js +21 -0
  188. package/dist/components/textarea/index.d.ts +2 -0
  189. package/dist/components/textarea/index.js +1 -0
  190. package/dist/components/toaster/Toaster.d.ts +32 -0
  191. package/dist/components/toaster/Toaster.js +89 -0
  192. package/dist/components/toaster/index.d.ts +2 -0
  193. package/dist/components/toaster/index.js +1 -0
  194. package/dist/components/tooltip/Tooltip.d.ts +18 -0
  195. package/dist/components/tooltip/Tooltip.js +35 -0
  196. package/dist/components/tooltip/index.d.ts +2 -0
  197. package/dist/components/tooltip/index.js +1 -0
  198. package/dist/components/top-bar/StoreSwitcher.d.ts +26 -0
  199. package/dist/components/top-bar/StoreSwitcher.js +48 -0
  200. package/dist/components/top-bar/TopBar.d.ts +24 -0
  201. package/dist/components/top-bar/TopBar.js +53 -0
  202. package/dist/components/top-bar/index.d.ts +3 -0
  203. package/dist/components/top-bar/index.js +3 -0
  204. package/dist/components/unit-input/UnitInput.d.ts +33 -0
  205. package/dist/components/unit-input/UnitInput.js +47 -0
  206. package/dist/components/unit-input/index.d.ts +2 -0
  207. package/dist/components/unit-input/index.js +1 -0
  208. package/dist/index.d.ts +102 -1
  209. package/dist/index.js +54 -2
  210. package/dist/lib/cn.js +38 -27
  211. package/dist/lib/format.d.ts +92 -0
  212. package/dist/lib/format.js +222 -0
  213. package/dist/styles.css +1 -1
  214. package/package.json +205 -3
@@ -1,5 +1,5 @@
1
1
  import { CHEVRON_LEFT, CHEVRON_RIGHT, EXPORT, NAV_CHEVRON, NAV_HOME, NAV_PRODUCT, NAV_PRODUCT_2, NAV_SHORTCUT, PLUS, SEARCH } from "./glyphs.js";
2
- import { IconAlertTriangle, IconCheck, IconInfoCircle, IconX } from "@tabler/icons-react";
2
+ import { IconAlertTriangle, IconApps, IconBuildingStore, IconCalendar, IconChartBar, IconCheck, IconDiscount2, IconDots, IconFileImport, IconFileText, IconInfoCircle, IconMenu2, IconReceipt, IconSettings, IconTrendingUp, IconUsers, IconWorld, IconX } from "@tabler/icons-react";
3
3
  // src/components/icon/registry.ts
4
4
  /**
5
5
  * Every icon by name. nav-chevron and nav-caret-down are one glyph under two names, as in the design system, whose
@@ -65,6 +65,62 @@ const ICONS = {
65
65
  "info-circle": {
66
66
  kind: "tabler",
67
67
  component: IconInfoCircle
68
+ },
69
+ "nav-orders": {
70
+ kind: "tabler",
71
+ component: IconReceipt
72
+ },
73
+ "nav-customers": {
74
+ kind: "tabler",
75
+ component: IconUsers
76
+ },
77
+ "nav-growth": {
78
+ kind: "tabler",
79
+ component: IconTrendingUp
80
+ },
81
+ "nav-discounts": {
82
+ kind: "tabler",
83
+ component: IconDiscount2
84
+ },
85
+ "nav-content": {
86
+ kind: "tabler",
87
+ component: IconFileText
88
+ },
89
+ "nav-markets": {
90
+ kind: "tabler",
91
+ component: IconWorld
92
+ },
93
+ "nav-analytics": {
94
+ kind: "tabler",
95
+ component: IconChartBar
96
+ },
97
+ "nav-sales-channels": {
98
+ kind: "tabler",
99
+ component: IconBuildingStore
100
+ },
101
+ "nav-apps": {
102
+ kind: "tabler",
103
+ component: IconApps
104
+ },
105
+ "nav-settings": {
106
+ kind: "tabler",
107
+ component: IconSettings
108
+ },
109
+ import: {
110
+ kind: "tabler",
111
+ component: IconFileImport
112
+ },
113
+ more: {
114
+ kind: "tabler",
115
+ component: IconDots
116
+ },
117
+ menu: {
118
+ kind: "tabler",
119
+ component: IconMenu2
120
+ },
121
+ calendar: {
122
+ kind: "tabler",
123
+ component: IconCalendar
68
124
  }
69
125
  };
70
126
  export { ICONS };
@@ -0,0 +1,19 @@
1
+ import { InputHTMLAttributes, JSX, Ref } from "react";
2
+ /** The height of the field in px: 36 is the design system's input, 32 the compact one inside tables. */
3
+ export type InputSize = 36 | 32;
4
+ /**
5
+ * The props of Input: the HTML attributes of an input, except className, style and size, with the height of the field.
6
+ * Mark an invalid field with aria-invalid, which draws the error ring in the danger colour, also while focused.
7
+ */
8
+ export type InputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'className' | 'style' | 'size'> & {
9
+ /** The height in px: 36 for forms and search, 32 for fields inside a table. Defaults to 36. */
10
+ size?: InputSize;
11
+ /** Receives the input element. */
12
+ ref?: Ref<HTMLInputElement>;
13
+ };
14
+ /**
15
+ * A single-line text field in the design system's look: 8px radius, a 1px ring that turns blue on focus, 14px body type.
16
+ * It takes every attribute of an input (type, inputMode, value, onChange). For a prefix, suffix, icon or shortcut hint,
17
+ * put an InputGroupInput in an InputGroup.
18
+ */
19
+ export declare function Input({ size, ref, ...rest }: InputProps): JSX.Element;
@@ -0,0 +1,26 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { cva } from "class-variance-authority";
4
+ import { Input } from "@base-ui/react/input";
5
+ // src/components/input/Input.tsx
6
+ const inputVariants = cva("rt:w-full rt:min-w-0 rt:rounded-lg rt:bg-background rt:text-b3 rt:text-foreground rt:placeholder:text-muted-foreground rt:shadow-ring-subtle rt:outline-none rt:transition-colors rt:forced-outline rt:focus-visible:shadow-ring-focus rt:aria-invalid:shadow-ring-invalid rt:aria-invalid:focus-visible:shadow-ring-invalid rt:disabled:pointer-events-none rt:disabled:cursor-not-allowed rt:disabled:opacity-50", {
7
+ variants: { size: {
8
+ 36: "rt:h-9 rt:px-3",
9
+ 32: "rt:h-8 rt:px-2.75"
10
+ } },
11
+ defaultVariants: { size: 36 }
12
+ });
13
+ /**
14
+ * A single-line text field in the design system's look: 8px radius, a 1px ring that turns blue on focus, 14px body type.
15
+ * It takes every attribute of an input (type, inputMode, value, onChange). For a prefix, suffix, icon or shortcut hint,
16
+ * put an InputGroupInput in an InputGroup.
17
+ */
18
+ function Input$1({ size = 36, ref, ...rest }) {
19
+ return /* @__PURE__ */ jsx(Input, {
20
+ "data-slot": "input",
21
+ ref,
22
+ className: cn(inputVariants({ size })),
23
+ ...rest
24
+ });
25
+ }
26
+ export { Input$1 as Input };
@@ -0,0 +1,2 @@
1
+ import { Input, InputProps, InputSize } from "./Input.js";
2
+ export { Input, type InputProps, type InputSize };
@@ -0,0 +1 @@
1
+ export { Input } from "./Input.js";
@@ -0,0 +1,42 @@
1
+ import { HTMLAttributes, InputHTMLAttributes, JSX, Ref } from "react";
2
+ /** The height of the group in px: 36 is the design system's input, 32 the compact one inside tables. */
3
+ export type InputGroupSize = 36 | 32;
4
+ /** The props of InputGroup: the HTML attributes of a div, except className and style, with the height of the group. */
5
+ export type InputGroupProps = Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'style'> & {
6
+ /** The height in px: 36 for forms and search, 32 for fields inside a table. Defaults to 36. */
7
+ size?: InputGroupSize;
8
+ /** Receives the group element. */
9
+ ref?: Ref<HTMLDivElement>;
10
+ };
11
+ /**
12
+ * A field with a prefix, suffix, icon or shortcut hint beside the input, inside one ring. Put an InputGroupInput in it
13
+ * and an InputGroupAddon on either side, for example a rupee sign before a price or kg after a weight.
14
+ */
15
+ export declare function InputGroup({ size, ref, ...rest }: InputGroupProps): JSX.Element;
16
+ /** The side of the input an addon sits on: start is before it, end is after it. */
17
+ export type InputGroupAddonAlign = 'start' | 'end';
18
+ /** The props of InputGroupAddon: the HTML attributes of a div, except className and style, with its side. */
19
+ export type InputGroupAddonProps = Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'style'> & {
20
+ /** The side of the input: start before it, end after it. Defaults to start. */
21
+ align?: InputGroupAddonAlign;
22
+ };
23
+ /**
24
+ * Holds an icon, a prefix, a suffix or a shortcut hint on one side of the input. Clicking it, off a button, moves focus
25
+ * to the input.
26
+ */
27
+ export declare function InputGroupAddon({ align, ...rest }: InputGroupAddonProps): JSX.Element;
28
+ /** The props of InputGroupText: the HTML attributes of a span, except className and style. */
29
+ export type InputGroupTextProps = Omit<HTMLAttributes<HTMLSpanElement>, 'className' | 'style'>;
30
+ /** A text prefix or suffix inside an addon, such as a currency sign or a unit, in the muted colour. */
31
+ export declare function InputGroupText(props: InputGroupTextProps): JSX.Element;
32
+ /** The props of InputGroupShortcut: the HTML attributes of a kbd, except className and style. */
33
+ export type InputGroupShortcutProps = Omit<HTMLAttributes<HTMLElement>, 'className' | 'style'>;
34
+ /** A shortcut hint such as ⌘K inside an end addon, drawn as a small keycap. */
35
+ export declare function InputGroupShortcut(props: InputGroupShortcutProps): JSX.Element;
36
+ /** The props of InputGroupInput: the HTML attributes of an input, except className, style and size. */
37
+ export type InputGroupInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'className' | 'style' | 'size'> & {
38
+ /** Receives the input element. */
39
+ ref?: Ref<HTMLInputElement>;
40
+ };
41
+ /** The input of an InputGroup. It draws no ring: the group does. Mark it invalid with aria-invalid. */
42
+ export declare function InputGroupInput({ ref, ...rest }: InputGroupInputProps): JSX.Element;
@@ -0,0 +1,83 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from "react";
4
+ import { cva } from "class-variance-authority";
5
+ import { Input } from "@base-ui/react/input";
6
+ // src/components/input-group/InputGroup.tsx
7
+ const groupVariants = cva("rt:flex rt:w-full rt:min-w-0 rt:items-center rt:gap-2 rt:rounded-lg rt:bg-background rt:shadow-ring-subtle rt:transition-colors rt:forced-outline rt:focus-within:shadow-ring-focus rt:has-aria-invalid:shadow-ring-invalid rt:has-aria-invalid:focus-within:shadow-ring-invalid rt:has-disabled:opacity-50", {
8
+ variants: { size: {
9
+ 36: "rt:h-9 rt:px-3",
10
+ 32: "rt:h-8 rt:px-2.75"
11
+ } },
12
+ defaultVariants: { size: 36 }
13
+ });
14
+ /**
15
+ * A field with a prefix, suffix, icon or shortcut hint beside the input, inside one ring. Put an InputGroupInput in it
16
+ * and an InputGroupAddon on either side, for example a rupee sign before a price or kg after a weight.
17
+ */
18
+ function InputGroup({ size = 36, ref, ...rest }) {
19
+ return /* @__PURE__ */ jsx("div", {
20
+ "data-slot": "input-group",
21
+ role: "group",
22
+ ref,
23
+ className: cn(groupVariants({ size })),
24
+ ...rest
25
+ });
26
+ }
27
+ const addonVariants = cva("rt:flex rt:shrink-0 rt:cursor-text rt:items-center rt:gap-2 rt:text-muted-foreground rt:select-none", {
28
+ variants: { align: {
29
+ start: "rt:order-first",
30
+ end: "rt:order-last"
31
+ } },
32
+ defaultVariants: { align: "start" }
33
+ });
34
+ /**
35
+ * Holds an icon, a prefix, a suffix or a shortcut hint on one side of the input. Clicking it, off a button, moves focus
36
+ * to the input.
37
+ */
38
+ function InputGroupAddon({ align = "start", ...rest }) {
39
+ const addonRef = useRef(null);
40
+ useEffect(() => {
41
+ const element = addonRef.current;
42
+ if (element === null) return;
43
+ const focusInput = (event) => {
44
+ if (event.defaultPrevented || event.target.closest("button") !== null) return;
45
+ element.parentElement?.querySelector("input")?.focus();
46
+ };
47
+ element.addEventListener("click", focusInput);
48
+ return () => element.removeEventListener("click", focusInput);
49
+ }, []);
50
+ return /* @__PURE__ */ jsx("div", {
51
+ "data-slot": "input-group-addon",
52
+ "data-align": align,
53
+ ref: addonRef,
54
+ className: cn(addonVariants({ align })),
55
+ ...rest
56
+ });
57
+ }
58
+ /** A text prefix or suffix inside an addon, such as a currency sign or a unit, in the muted colour. */
59
+ function InputGroupText(props) {
60
+ return /* @__PURE__ */ jsx("span", {
61
+ "data-slot": "input-group-text",
62
+ className: "rt:text-b3 rt:text-muted-foreground",
63
+ ...props
64
+ });
65
+ }
66
+ /** A shortcut hint such as ⌘K inside an end addon, drawn as a small keycap. */
67
+ function InputGroupShortcut(props) {
68
+ return /* @__PURE__ */ jsx("kbd", {
69
+ "data-slot": "input-group-shortcut",
70
+ className: "rt:inline-flex rt:h-5 rt:items-center rt:rounded-sm rt:px-1 rt:text-c1 rt:text-muted-foreground rt:shadow-ring-hairline",
71
+ ...props
72
+ });
73
+ }
74
+ /** The input of an InputGroup. It draws no ring: the group does. Mark it invalid with aria-invalid. */
75
+ function InputGroupInput({ ref, ...rest }) {
76
+ return /* @__PURE__ */ jsx(Input, {
77
+ "data-slot": "input-group-control",
78
+ ref,
79
+ className: "rt:h-full rt:min-w-0 rt:flex-1 rt:bg-transparent rt:text-b3 rt:text-foreground rt:placeholder:text-muted-foreground rt:outline-none rt:disabled:cursor-not-allowed",
80
+ ...rest
81
+ });
82
+ }
83
+ export { InputGroup, InputGroupAddon, InputGroupInput, InputGroupShortcut, InputGroupText };
@@ -0,0 +1,2 @@
1
+ import { InputGroup, InputGroupAddon, InputGroupAddonAlign, InputGroupAddonProps, InputGroupInput, InputGroupInputProps, InputGroupProps, InputGroupShortcut, InputGroupShortcutProps, InputGroupSize, InputGroupText, InputGroupTextProps } from "./InputGroup.js";
2
+ export { InputGroup, InputGroupAddon, type InputGroupAddonAlign, type InputGroupAddonProps, InputGroupInput, type InputGroupInputProps, type InputGroupProps, InputGroupShortcut, type InputGroupShortcutProps, type InputGroupSize, InputGroupText, type InputGroupTextProps };
@@ -0,0 +1 @@
1
+ export { InputGroup, InputGroupAddon, InputGroupInput, InputGroupShortcut, InputGroupText } from "./InputGroup.js";
@@ -0,0 +1,17 @@
1
+ import { HTMLAttributes, JSX, Ref } from "react";
2
+ /** The props of Kbd: the HTML attributes of a kbd element, except className and style. */
3
+ export type KbdProps = Omit<HTMLAttributes<HTMLElement>, 'className' | 'style'> & {
4
+ /** The key: a symbol such as ⌘ or ↵, a letter, or a short name such as esc. */
5
+ children: React.ReactNode;
6
+ /** Receives the rendered element. */
7
+ ref?: Ref<HTMLElement>;
8
+ };
9
+ /** A key hint, 20px high with a 4px radius, such as ⌘K or esc. */
10
+ export declare function Kbd({ children, ref, ...rest }: KbdProps): JSX.Element;
11
+ /** The props of KbdGroup: the HTML attributes of a span, except className and style. */
12
+ export type KbdGroupProps = Omit<HTMLAttributes<HTMLSpanElement>, 'className' | 'style'> & {
13
+ /** The keys of one shortcut, each a Kbd. */
14
+ children: React.ReactNode;
15
+ };
16
+ /** Puts the keys of one shortcut in a row with a 4px gap. */
17
+ export declare function KbdGroup({ children, ...rest }: KbdGroupProps): JSX.Element;
@@ -0,0 +1,21 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ // src/components/kbd/Kbd.tsx
4
+ /** A key hint, 20px high with a 4px radius, such as ⌘K or esc. */
5
+ function Kbd({ children, ref, ...rest }) {
6
+ return /* @__PURE__ */ jsx("kbd", {
7
+ ...rest,
8
+ ref,
9
+ className: cn("rt:inline-flex rt:h-5 rt:min-w-5 rt:w-fit rt:items-center rt:justify-center rt:rounded-sm rt:bg-muted rt:px-1 rt:font-sans rt:text-c2 rt:text-foreground-subdued rt:select-none"),
10
+ children
11
+ });
12
+ }
13
+ /** Puts the keys of one shortcut in a row with a 4px gap. */
14
+ function KbdGroup({ children, ...rest }) {
15
+ return /* @__PURE__ */ jsx("span", {
16
+ ...rest,
17
+ className: "rt:inline-flex rt:items-center rt:gap-1",
18
+ children
19
+ });
20
+ }
21
+ export { Kbd, KbdGroup };
@@ -0,0 +1,2 @@
1
+ import { Kbd, KbdGroup, KbdGroupProps, KbdProps } from "./Kbd.js";
2
+ export { Kbd, KbdGroup, type KbdGroupProps, type KbdProps };
@@ -0,0 +1 @@
1
+ export { Kbd, KbdGroup } from "./Kbd.js";
@@ -0,0 +1,22 @@
1
+ import { AnchorHTMLAttributes, JSX, ReactNode, Ref } from "react";
2
+ /**
3
+ * The props of Link: the attributes of an anchor, except className and style, with the address and the two arrows.
4
+ */
5
+ export type LinkProps = Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'className' | 'style' | 'href' | 'children'> & {
6
+ /** Where the link goes. */
7
+ href: string;
8
+ /** The link text. */
9
+ children: ReactNode;
10
+ /** Shows a back arrow before the text, as in "← Products". Screen readers skip it. */
11
+ back?: boolean;
12
+ /** Shows a forward arrow after the text, as in "View all variants →". Screen readers skip it. */
13
+ forward?: boolean;
14
+ /** Receives the anchor element. */
15
+ ref?: Ref<HTMLAnchorElement>;
16
+ };
17
+ /**
18
+ * A text link to another page, such as "← Products" or "View all variants →". It is drawn by the app's LinkProvider, so a
19
+ * router navigates without a reload; without one it is a plain <a href>. The arrows are decoration and are hidden from
20
+ * screen readers.
21
+ */
22
+ export declare function Link({ href, children, back, forward, ref, ...rest }: LinkProps): JSX.Element;
@@ -0,0 +1,31 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { RatioLink } from "../link-provider/RatioLink.js";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ // src/components/link/Link.tsx
5
+ const LINK = "rt:inline-flex rt:items-center rt:gap-1 rt:rounded-sm rt:text-primary rt:transition-colors rt:hover:underline rt:focus-visible:focus-ring rt:forced-outline";
6
+ /**
7
+ * A text link to another page, such as "← Products" or "View all variants →". It is drawn by the app's LinkProvider, so a
8
+ * router navigates without a reload; without one it is a plain <a href>. The arrows are decoration and are hidden from
9
+ * screen readers.
10
+ */
11
+ function Link({ href, children, back = false, forward = false, ref, ...rest }) {
12
+ return /* @__PURE__ */ jsxs(RatioLink, {
13
+ ...rest,
14
+ ref,
15
+ href,
16
+ "data-slot": "link",
17
+ className: cn(LINK),
18
+ children: [
19
+ back && /* @__PURE__ */ jsx("span", {
20
+ "aria-hidden": "true",
21
+ children: "←"
22
+ }),
23
+ children,
24
+ forward && /* @__PURE__ */ jsx("span", {
25
+ "aria-hidden": "true",
26
+ children: "→"
27
+ })
28
+ ]
29
+ });
30
+ }
31
+ export { Link };
@@ -0,0 +1,2 @@
1
+ import { Link, LinkProps } from "./Link.js";
2
+ export { Link, type LinkProps };
@@ -0,0 +1 @@
1
+ export { Link } from "./Link.js";
@@ -0,0 +1,29 @@
1
+ import { AnchorHTMLAttributes, JSX, ReactElement, ReactNode, Ref } from "react";
2
+ /**
3
+ * What the app's link element receives from Ratio: the address, Ratio's styling class, the content and the attributes
4
+ * the component sets, such as aria-current and onClick. Spread them all onto the element.
5
+ */
6
+ export type LinkRenderProps = Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> & {
7
+ /** Where the link goes. A router link takes it as its own address prop, such as React Router's `to`. */
8
+ href: string;
9
+ /** Receives the rendered element. */
10
+ ref?: Ref<HTMLAnchorElement>;
11
+ };
12
+ /** The app's link element: a function that draws it from the link props. */
13
+ export type LinkRender = (props: LinkRenderProps) => ReactElement;
14
+ /** The props of LinkProvider. */
15
+ export type LinkProviderProps = {
16
+ /**
17
+ * Draws every link Ratio renders. The function receives href, the styling class, the content and attributes such as
18
+ * aria-current and onClick, all to spread onto the element: `({ href, ...props }) => <RouterLink to={href} {...props} />`.
19
+ */
20
+ render: LinkRender;
21
+ /** The app, or the part of it that the router serves. */
22
+ children: ReactNode;
23
+ };
24
+ /**
25
+ * Draws every link of Ratio's components with the app's own router link, so a click navigates without a page reload:
26
+ * SideNav rows with an href, DataTable row links and the PageHeader back link. Wrap the app once, at its root. Without
27
+ * it those links are plain <a href> elements, which reload the page.
28
+ */
29
+ export declare function LinkProvider({ render, children }: LinkProviderProps): JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { LinkContext } from "./context.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ // src/components/link-provider/LinkProvider.tsx
4
+ /**
5
+ * Draws every link of Ratio's components with the app's own router link, so a click navigates without a page reload:
6
+ * SideNav rows with an href, DataTable row links and the PageHeader back link. Wrap the app once, at its root. Without
7
+ * it those links are plain <a href> elements, which reload the page.
8
+ */
9
+ function LinkProvider({ render, children }) {
10
+ return /* @__PURE__ */ jsx(LinkContext, {
11
+ value: render,
12
+ children
13
+ });
14
+ }
15
+ export { LinkProvider };
@@ -0,0 +1,18 @@
1
+ import { LinkContext } from "./context.js";
2
+ import { use } from "react";
3
+ import { useRender } from "@base-ui/react/use-render";
4
+ // src/components/link-provider/RatioLink.tsx
5
+ /**
6
+ * A link of one of Ratio's components, drawn by the app's LinkProvider, or a plain <a> without one. For the package's own
7
+ * components only; the package does not export it.
8
+ */
9
+ function RatioLink({ ref, ...props }) {
10
+ const render = use(LinkContext);
11
+ return useRender({
12
+ defaultTagName: "a",
13
+ render: render ? (merged) => render(merged) : void 0,
14
+ ref,
15
+ props
16
+ });
17
+ }
18
+ export { RatioLink };
@@ -0,0 +1,4 @@
1
+ import { createContext } from "react";
2
+ // src/components/link-provider/context.ts
3
+ const LinkContext = createContext(void 0);
4
+ export { LinkContext };
@@ -0,0 +1,2 @@
1
+ import { LinkProvider, LinkProviderProps, LinkRender, LinkRenderProps } from "./LinkProvider.js";
2
+ export { LinkProvider, type LinkProviderProps, type LinkRender, type LinkRenderProps };
@@ -0,0 +1 @@
1
+ export { LinkProvider } from "./LinkProvider.js";
@@ -0,0 +1,49 @@
1
+ import { JSX } from "react";
2
+ import { Accept } from "react-dropzone";
3
+ /** One image in a MediaGrid. */
4
+ export type MediaGridItem = {
5
+ /** A stable id, reported back by onReorder, onRemove and onMakeCover. */
6
+ id: string;
7
+ /** The image URL, or an object URL while the file uploads. */
8
+ src: string;
9
+ /** The text alternative. It also names the item in the action group and the announcements. */
10
+ alt: string;
11
+ /** Upload progress from 0 to 100. A thin bar shows on the thumb while it is below 100. */
12
+ progress?: number;
13
+ /** Why the upload failed, shown under the thumb beside the warning glyph; the thumb takes the error ring. */
14
+ error?: string;
15
+ };
16
+ /** The props of MediaGrid. The app uploads the files and owns the list; the grid reports what the person did. */
17
+ export type MediaGridProps = {
18
+ /** The images in order. The first one is the cover. */
19
+ items: MediaGridItem[];
20
+ /** Called with the files chosen in the add tile or dropped on the grid. */
21
+ onAdd: (files: File[]) => void;
22
+ /** Called with every id in the new order after a drag, Move left, Move right or Make cover. */
23
+ onReorder: (ids: string[]) => void;
24
+ /** Called with the id of the item to take off the grid. */
25
+ onRemove: (id: string) => void;
26
+ /** Called with the id after Make cover has moved it first through onReorder, for an app that saves the cover on its own. */
27
+ onMakeCover?: (id: string) => void;
28
+ /** The file types the add tile takes, as react-dropzone's accept map. Defaults to every image type. */
29
+ accept?: Accept;
30
+ /** Stops adding, dragging and every button. */
31
+ disabled?: boolean;
32
+ /** The accessible name of the add tile. Defaults to "Add media". */
33
+ addLabel?: string;
34
+ /** The id of the grid. */
35
+ id?: string;
36
+ /** The accessible name of the grid. Defaults to "Media" when there is no aria-labelledby. */
37
+ 'aria-label'?: string;
38
+ /** The id of the visible label that names the grid, such as a Field label. */
39
+ 'aria-labelledby'?: string;
40
+ /** The id of help text for the grid. */
41
+ 'aria-describedby'?: string;
42
+ };
43
+ /**
44
+ * The media of a product: a row of square thumbs with an add tile that opens the file picker and takes dropped files.
45
+ * Thumbs reorder by drag (pointer, touch or keyboard) and by the Move left, Move right and Make cover buttons, so no
46
+ * drag is needed. The first image is the cover and carries a badge. Uploads show a thin progress bar and failures an
47
+ * error under the thumb. Every move, cover change and removal is announced to screen readers.
48
+ */
49
+ export declare function MediaGrid({ items, onAdd, onReorder, onRemove, onMakeCover, accept, disabled, addLabel, 'aria-label': ariaLabel, 'aria-labelledby': labelledBy, ...rest }: MediaGridProps): JSX.Element;