@-reddacted-/react-ui 0.3.0 → 0.4.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 (137) hide show
  1. package/dist/components/Accordion.d.ts +27 -0
  2. package/dist/components/Accordion.d.ts.map +1 -0
  3. package/dist/components/Accordion.js +35 -0
  4. package/dist/components/Badge.d.ts +15 -0
  5. package/dist/components/Badge.d.ts.map +1 -0
  6. package/dist/components/Badge.js +7 -0
  7. package/dist/components/Button.d.ts +15 -2
  8. package/dist/components/Button.d.ts.map +1 -1
  9. package/dist/components/Button.js +76 -44
  10. package/dist/components/Card.d.ts +21 -0
  11. package/dist/components/Card.d.ts.map +1 -0
  12. package/dist/components/Card.js +17 -0
  13. package/dist/components/ColorField.d.ts.map +1 -1
  14. package/dist/components/ColorField.js +1 -1
  15. package/dist/components/ConfirmDeleteButton.d.ts +4 -1
  16. package/dist/components/ConfirmDeleteButton.d.ts.map +1 -1
  17. package/dist/components/ConfirmDeleteButton.js +6 -7
  18. package/dist/components/Drawer.d.ts +33 -0
  19. package/dist/components/Drawer.d.ts.map +1 -0
  20. package/dist/components/Drawer.js +123 -0
  21. package/dist/components/DropdownMenu.d.ts +61 -0
  22. package/dist/components/DropdownMenu.d.ts.map +1 -0
  23. package/dist/components/DropdownMenu.js +302 -0
  24. package/dist/components/Modal.d.ts.map +1 -1
  25. package/dist/components/Modal.js +102 -134
  26. package/dist/components/NavBar.d.ts +11 -14
  27. package/dist/components/NavBar.d.ts.map +1 -1
  28. package/dist/components/NavBar.js +53 -31
  29. package/dist/components/PageStatus.d.ts +12 -12
  30. package/dist/components/PageStatus.d.ts.map +1 -1
  31. package/dist/components/PageStatus.js +9 -29
  32. package/dist/components/Pagination.d.ts +44 -0
  33. package/dist/components/Pagination.d.ts.map +1 -0
  34. package/dist/components/Pagination.js +57 -0
  35. package/dist/components/Skeleton.d.ts +13 -0
  36. package/dist/components/Skeleton.d.ts.map +1 -0
  37. package/dist/components/Skeleton.js +15 -0
  38. package/dist/components/Spinner.d.ts +14 -0
  39. package/dist/components/Spinner.d.ts.map +1 -0
  40. package/dist/components/Spinner.js +14 -0
  41. package/dist/components/Stack.d.ts +13 -0
  42. package/dist/components/Stack.d.ts.map +1 -0
  43. package/dist/components/Stack.js +15 -0
  44. package/dist/components/Table.d.ts +54 -0
  45. package/dist/components/Table.d.ts.map +1 -0
  46. package/dist/components/Table.js +101 -0
  47. package/dist/components/Tabs.d.ts +34 -0
  48. package/dist/components/Tabs.d.ts.map +1 -0
  49. package/dist/components/Tabs.js +82 -0
  50. package/dist/components/Tag.d.ts +10 -0
  51. package/dist/components/Tag.d.ts.map +1 -0
  52. package/dist/components/Tag.js +7 -0
  53. package/dist/components/Tooltip.d.ts +22 -0
  54. package/dist/components/Tooltip.d.ts.map +1 -0
  55. package/dist/components/Tooltip.js +76 -0
  56. package/dist/components/drawerStore.d.ts +11 -0
  57. package/dist/components/drawerStore.d.ts.map +1 -0
  58. package/dist/components/drawerStore.js +40 -0
  59. package/dist/components/paginationItems.d.ts +18 -0
  60. package/dist/components/paginationItems.d.ts.map +1 -0
  61. package/dist/components/paginationItems.js +32 -0
  62. package/dist/index.d.ts +23 -7
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +16 -2
  65. package/dist/popup/PopupHost.d.ts +19 -3
  66. package/dist/popup/PopupHost.d.ts.map +1 -1
  67. package/dist/popup/PopupHost.js +65 -44
  68. package/dist/popup/PopupProvider.d.ts +19 -2
  69. package/dist/popup/PopupProvider.d.ts.map +1 -1
  70. package/dist/popup/PopupProvider.js +69 -17
  71. package/dist/popup/usePopup.d.ts +11 -4
  72. package/dist/popup/usePopup.d.ts.map +1 -1
  73. package/dist/style/accordionCss.d.ts +2 -0
  74. package/dist/style/accordionCss.d.ts.map +1 -0
  75. package/dist/style/accordionCss.js +101 -0
  76. package/dist/style/badgeCss.d.ts +5 -0
  77. package/dist/style/badgeCss.d.ts.map +1 -0
  78. package/dist/style/badgeCss.js +68 -0
  79. package/dist/style/breadcrumbCss.d.ts +2 -0
  80. package/dist/style/breadcrumbCss.d.ts.map +1 -0
  81. package/dist/style/breadcrumbCss.js +53 -0
  82. package/dist/style/cardCss.d.ts +2 -0
  83. package/dist/style/cardCss.d.ts.map +1 -0
  84. package/dist/style/cardCss.js +49 -0
  85. package/dist/style/inputCss.d.ts +2 -0
  86. package/dist/style/inputCss.d.ts.map +1 -0
  87. package/dist/style/inputCss.js +107 -0
  88. package/dist/style/loaderCss.d.ts +2 -0
  89. package/dist/style/loaderCss.d.ts.map +1 -0
  90. package/dist/style/loaderCss.js +39 -0
  91. package/dist/style/menuCss.d.ts +2 -0
  92. package/dist/style/menuCss.d.ts.map +1 -0
  93. package/dist/style/menuCss.js +71 -0
  94. package/dist/style/paginationCss.d.ts +2 -0
  95. package/dist/style/paginationCss.d.ts.map +1 -0
  96. package/dist/style/paginationCss.js +57 -0
  97. package/dist/style/resolveColor.d.ts +8 -0
  98. package/dist/style/resolveColor.d.ts.map +1 -0
  99. package/dist/style/resolveColor.js +13 -0
  100. package/dist/style/stackCss.d.ts +2 -0
  101. package/dist/style/stackCss.d.ts.map +1 -0
  102. package/dist/style/stackCss.js +21 -0
  103. package/dist/style/statusCss.d.ts +2 -0
  104. package/dist/style/statusCss.d.ts.map +1 -0
  105. package/dist/style/statusCss.js +38 -0
  106. package/dist/style/tableCss.d.ts +2 -0
  107. package/dist/style/tableCss.d.ts.map +1 -0
  108. package/dist/style/tableCss.js +92 -0
  109. package/dist/style/tabsCss.d.ts +2 -0
  110. package/dist/style/tabsCss.d.ts.map +1 -0
  111. package/dist/style/tabsCss.js +72 -0
  112. package/dist/style/toLength.d.ts +4 -0
  113. package/dist/style/toLength.d.ts.map +1 -0
  114. package/dist/style/toLength.js +3 -0
  115. package/dist/style/tooltipCss.d.ts +2 -0
  116. package/dist/style/tooltipCss.d.ts.map +1 -0
  117. package/dist/style/tooltipCss.js +44 -0
  118. package/dist/style/useStyle.d.ts +7 -0
  119. package/dist/style/useStyle.d.ts.map +1 -0
  120. package/dist/style/useStyle.js +16 -0
  121. package/dist/theme/ThemeProvider.d.ts.map +1 -1
  122. package/dist/theme/ThemeProvider.js +32 -0
  123. package/dist/theme/palette.d.ts.map +1 -1
  124. package/dist/theme/palette.js +0 -2
  125. package/dist/tooltip/attributeTooltips.d.ts +7 -0
  126. package/dist/tooltip/attributeTooltips.d.ts.map +1 -0
  127. package/dist/tooltip/attributeTooltips.js +76 -0
  128. package/dist/tooltip/tooltipEngine.d.ts +41 -0
  129. package/dist/tooltip/tooltipEngine.d.ts.map +1 -0
  130. package/dist/tooltip/tooltipEngine.js +128 -0
  131. package/dist/utils/childRef.d.ts +5 -0
  132. package/dist/utils/childRef.d.ts.map +1 -0
  133. package/dist/utils/childRef.js +14 -0
  134. package/dist/utils/isDev.d.ts +3 -0
  135. package/dist/utils/isDev.d.ts.map +1 -0
  136. package/dist/utils/isDev.js +4 -0
  137. package/package.json +5 -4
@@ -0,0 +1,27 @@
1
+ import type { CSSProperties, HTMLAttributes, ReactNode } from "react";
2
+ type AccordionProps = HTMLAttributes<HTMLDivElement> & {
3
+ /** Only one item open at a time (native `name` on the <details>). */
4
+ exclusive?: boolean;
5
+ /** Defaults to `"joined"`. */
6
+ variant?: "separated" | "joined";
7
+ /** Defaults to `"end"`. */
8
+ chevron?: "start" | "end" | "none";
9
+ children: ReactNode;
10
+ };
11
+ export declare function Accordion({ exclusive, variant, chevron, className, ...props }: AccordionProps): import("react").JSX.Element;
12
+ export declare namespace Accordion {
13
+ var Item: ({ title, children, defaultOpen, open, onOpenChange, className, style }: AccordionItemProps) => import("react").JSX.Element;
14
+ }
15
+ type AccordionItemProps = {
16
+ title: ReactNode;
17
+ children: ReactNode;
18
+ /** Uncontrolled: open on mount. */
19
+ defaultOpen?: boolean;
20
+ /** Controlled mode, kept in sync with the native toggle. */
21
+ open?: boolean;
22
+ onOpenChange?: (open: boolean) => void;
23
+ className?: string;
24
+ style?: CSSProperties;
25
+ };
26
+ export {};
27
+ //# sourceMappingURL=Accordion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Accordion.d.ts","sourceRoot":"","sources":["../../src/components/Accordion.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAkB,MAAM,OAAO,CAAA;AAOrF,KAAK,cAAc,GAAG,cAAc,CAAC,cAAc,CAAC,GAAG;IACrD,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAA;IAChC,2BAA2B;IAC3B,OAAO,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,CAAA;IAClC,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAA;AAED,wBAAgB,SAAS,CAAC,EACxB,SAAiB,EACjB,OAAkB,EAClB,OAAe,EACf,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,+BAahB;yBAnBe,SAAS;uFAiCqE,kBAAkB;;AAZhH,KAAK,kBAAkB,GAAG;IACxB,KAAK,EAAE,SAAS,CAAA;IAChB,QAAQ,EAAE,SAAS,CAAA;IACnB,mCAAmC;IACnC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB,CAAA"}
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createContext, useContext, useId, useRef } from "react";
3
+ import { accordionCss } from "../style/accordionCss.js";
4
+ import { useStyle } from "../style/useStyle.js";
5
+ // Shared `name` of the group's <details> when exclusive: the browser keeps one open.
6
+ const AccordionContext = createContext(undefined);
7
+ export function Accordion({ exclusive = false, variant = "joined", chevron = "end", className, ...props }) {
8
+ useStyle("accordion", accordionCss);
9
+ const name = useId();
10
+ return (_jsx(AccordionContext.Provider, { value: exclusive ? name : undefined, children: _jsx("div", { ...props, className: className ? `rui-accordion ${className}` : "rui-accordion", "data-variant": variant, "data-chevron": chevron }) }));
11
+ }
12
+ function Item({ title, children, defaultOpen = false, open, onOpenChange, className, style }) {
13
+ const name = useContext(AccordionContext);
14
+ const controlled = open !== undefined;
15
+ const openRef = useRef(open);
16
+ openRef.current = open;
17
+ // <details> toggles natively before React knows: report it. In controlled mode, once the
18
+ // parent had a chance to re-render, put the element back if the change was not accepted
19
+ // (not synchronously: an exclusive group would then reopen and close items in a loop).
20
+ const onToggle = (event) => {
21
+ const el = event.currentTarget;
22
+ if (controlled && el.open === openRef.current)
23
+ return;
24
+ onOpenChange?.(el.open);
25
+ if (!controlled)
26
+ return;
27
+ requestAnimationFrame(() => {
28
+ const wanted = openRef.current;
29
+ if (wanted !== undefined && el.open !== wanted)
30
+ el.open = wanted;
31
+ });
32
+ };
33
+ return (_jsxs("details", { ...{ name }, open: controlled ? open : defaultOpen, onToggle: onToggle, className: className, style: style, children: [_jsx("summary", { children: title }), _jsx("div", { className: "rui-accordion-content", children: children })] }));
34
+ }
35
+ Accordion.Item = Item;
@@ -0,0 +1,15 @@
1
+ import type { HTMLAttributes } from "react";
2
+ export type BadgeVariant = "solid" | "outline" | "soft";
3
+ export type BadgeProps = HTMLAttributes<HTMLSpanElement> & {
4
+ /** Defaults to `"solid"`. */
5
+ variant?: BadgeVariant;
6
+ /**
7
+ * `"--color-x"` reads the theme variable (text on solid reads `--color-on-x`, falling back
8
+ * to `--color-bg`); anything else is a raw CSS color. Defaults to `"--color-primary"`.
9
+ */
10
+ color?: string;
11
+ /** Font size; padding and radius follow. Numbers are pixels. Defaults to `"0.75em"`. */
12
+ size?: string | number;
13
+ };
14
+ export declare function Badge({ variant, color, size, className, style, ...props }: BadgeProps): import("react").JSX.Element;
15
+ //# sourceMappingURL=Badge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../src/components/Badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAI3C,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAEvD,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC,eAAe,CAAC,GAAG;IACzD,6BAA6B;IAC7B,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wFAAwF;IACxF,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CACvB,CAAA;AAED,wBAAgB,KAAK,CAAC,EAAE,OAAiB,EAAE,KAAyB,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,+BAUnH"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { badgeCss, badgeVars } from "../style/badgeCss.js";
3
+ import { useStyle } from "../style/useStyle.js";
4
+ export function Badge({ variant = "solid", color = "--color-primary", size, className, style, ...props }) {
5
+ useStyle("badge", badgeCss);
6
+ return (_jsx("span", { ...props, className: className ? `rui-badge ${className}` : "rui-badge", "data-variant": variant, style: { ...badgeVars(color, size), ...style } }));
7
+ }
@@ -1,9 +1,22 @@
1
1
  import type { ButtonHTMLAttributes, ReactNode } from "react";
2
- export type ButtonVariant = "primary" | "secondary" | "ghost";
2
+ export type ButtonVariant = "solid" | "outline" | "ghost";
3
+ /** Name of a theme variable, e.g. `"--color-primary"`. */
4
+ export type ThemeColorVar = `--color-${string}`;
3
5
  type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
6
+ /** Shape: filled, bordered or text only. Defaults to `"solid"`. */
4
7
  variant?: ButtonVariant;
8
+ /**
9
+ * Theme variable used by the button. Text on a solid background reads the matching
10
+ * `--color-on-x` variable, falling back to `--color-bg`. Defaults to `"--color-primary"`.
11
+ */
12
+ color?: ThemeColorVar;
13
+ /** Numbers are pixels; strings are any CSS length (`"100%"`, `"2.5rem"`). */
14
+ width?: string | number;
15
+ height?: string | number;
16
+ /** Shows a spinner instead of the content, keeping the width, and disables the button. */
17
+ loading?: boolean;
5
18
  children: ReactNode;
6
19
  };
7
- export declare function Button({ variant, style, disabled, children, ...props }: ButtonProps): import("react").JSX.Element;
20
+ export declare function Button({ variant, color, width, height, loading, disabled, className, style, children, ...props }: ButtonProps): import("react").JSX.Element;
8
21
  export {};
9
22
  //# sourceMappingURL=Button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/components/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AAE3E,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAA;AAE7D,KAAK,WAAW,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,GAAG;IAC3D,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAA;AAED,wBAAgB,MAAM,CAAC,EAAE,OAAmB,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,WAAW,+BAe/F"}
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/components/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AAK3E,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAA;AAEzD,0DAA0D;AAC1D,MAAM,MAAM,aAAa,GAAG,WAAW,MAAM,EAAE,CAAA;AAE/C,KAAK,WAAW,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,GAAG;IAC3D,mEAAmE;IACnE,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,0FAA0F;IAC1F,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAA;AAED,wBAAgB,MAAM,CAAC,EACrB,OAAiB,EACjB,KAAyB,EACzB,KAAK,EACL,MAAM,EACN,OAAe,EACf,QAAQ,EACR,SAAS,EACT,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,WAAW,+BAyBb"}
@@ -1,44 +1,76 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- export function Button({ variant = "primary", style, disabled, children, ...props }) {
3
- return (_jsx("button", { disabled: disabled, style: {
4
- ...baseStyle,
5
- ...variantStyles[variant],
6
- ...(disabled ? disabledStyle : undefined),
7
- ...style,
8
- }, ...props, children: children }));
9
- }
10
- const baseStyle = {
11
- display: "inline-flex",
12
- alignItems: "center",
13
- justifyContent: "center",
14
- gap: "0.5rem",
15
- padding: "0.5rem 1rem",
16
- borderRadius: "6px",
17
- fontSize: "0.875rem",
18
- fontWeight: 500,
19
- cursor: "pointer",
20
- border: "1px solid transparent",
21
- lineHeight: 1,
22
- whiteSpace: "nowrap",
23
- };
24
- const disabledStyle = {
25
- opacity: 0.4,
26
- cursor: "not-allowed",
27
- };
28
- const variantStyles = {
29
- primary: {
30
- backgroundColor: "var(--color-primary)",
31
- color: "var(--color-on-primary)",
32
- borderColor: "var(--color-primary)",
33
- },
34
- secondary: {
35
- backgroundColor: "transparent",
36
- color: "var(--color-primary)",
37
- borderColor: "var(--color-primary)",
38
- },
39
- ghost: {
40
- backgroundColor: "transparent",
41
- color: "var(--color-text-muted)",
42
- borderColor: "transparent",
43
- },
44
- };
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { toLength } from "../style/toLength.js";
3
+ import { useStyle } from "../style/useStyle.js";
4
+ import { Spinner } from "./Spinner.js";
5
+ export function Button({ variant = "solid", color = "--color-primary", width, height, loading = false, disabled, className, style, children, ...props }) {
6
+ useStyle("button", buttonCss);
7
+ const onColor = color.replace(/^--color-/, "--color-on-");
8
+ const buttonStyle = {
9
+ "--rui-btn-color": `var(${color})`,
10
+ "--rui-btn-on": `var(${onColor}, var(--color-bg))`,
11
+ width: toLength(width),
12
+ height: toLength(height),
13
+ ...style,
14
+ };
15
+ return (_jsxs("button", { ...props, className: className ? `rui-button ${className}` : "rui-button", "data-variant": variant, disabled: disabled || loading, "aria-busy": loading || undefined, style: buttonStyle, children: [_jsx("span", { className: "rui-button-label", children: children }), loading && _jsx(Spinner, { className: "rui-button-spinner", "aria-hidden": "true" })] }));
16
+ }
17
+ // Every selector is wrapped in :where() so it has zero specificity:
18
+ // any class or style set by the consuming project wins without !important.
19
+ const buttonCss = `
20
+ :where(.rui-button) {
21
+ position: relative;
22
+ display: inline-flex;
23
+ align-items: center;
24
+ justify-content: center;
25
+ gap: 0.5rem;
26
+ padding: 0.5rem 1rem;
27
+ border: 1px solid var(--rui-btn-color);
28
+ border-radius: 6px;
29
+ background-color: var(--rui-btn-color);
30
+ color: var(--rui-btn-on);
31
+ font: inherit;
32
+ font-size: 0.875rem;
33
+ font-weight: 500;
34
+ line-height: 1;
35
+ white-space: nowrap;
36
+ cursor: pointer;
37
+ transition: background-color 120ms, border-color 120ms;
38
+ }
39
+ :where(.rui-button[data-variant="solid"]:hover:not(:disabled)) {
40
+ background-color: color-mix(in srgb, var(--rui-btn-color) 85%, black);
41
+ border-color: color-mix(in srgb, var(--rui-btn-color) 85%, black);
42
+ }
43
+ :where(.rui-button[data-variant="outline"], .rui-button[data-variant="ghost"]) {
44
+ background-color: transparent;
45
+ color: var(--rui-btn-color);
46
+ }
47
+ :where(.rui-button[data-variant="ghost"]) {
48
+ border-color: transparent;
49
+ }
50
+ :where(.rui-button[data-variant="outline"]:hover:not(:disabled), .rui-button[data-variant="ghost"]:hover:not(:disabled)) {
51
+ background-color: color-mix(in srgb, var(--rui-btn-color) 12%, transparent);
52
+ }
53
+ :where(.rui-button:focus-visible) {
54
+ outline: 2px solid var(--rui-btn-color);
55
+ outline-offset: 2px;
56
+ }
57
+ :where(.rui-button:disabled) {
58
+ opacity: 0.4;
59
+ cursor: not-allowed;
60
+ }
61
+ :where(.rui-button[aria-busy="true"]) {
62
+ opacity: 1;
63
+ cursor: progress;
64
+ }
65
+ :where(.rui-button-label) {
66
+ display: contents;
67
+ }
68
+ :where(.rui-button[aria-busy="true"] > .rui-button-label) {
69
+ visibility: hidden;
70
+ }
71
+ :where(.rui-button-spinner) {
72
+ position: absolute;
73
+ inset: 0;
74
+ margin: auto;
75
+ }
76
+ `;
@@ -0,0 +1,21 @@
1
+ import type { HTMLAttributes } from "react";
2
+ type CardProps = HTMLAttributes<HTMLDivElement> & {
3
+ /** Colors: `"--color-x"` reads the theme variable; anything else is a raw CSS value. */
4
+ bg?: string;
5
+ border?: string;
6
+ /** Any `box-shadow` value, or a theme variable holding one. */
7
+ shadow?: string;
8
+ /** Numbers are pixels. */
9
+ padding?: string | number;
10
+ radius?: string | number;
11
+ /** Focus ring color when interactive. Defaults to `--color-primary`. */
12
+ accent?: string;
13
+ /**
14
+ * Hover and focus states, pointer cursor, and `tabIndex={0}` unless set. Keyboard
15
+ * activation stays with the project: prefer `<a className="rui-card">` or `<button>`.
16
+ */
17
+ interactive?: boolean;
18
+ };
19
+ export declare function Card({ bg, border, shadow, padding, radius, accent, interactive, className, style, tabIndex, ...props }: CardProps): import("react").JSX.Element;
20
+ export {};
21
+ //# sourceMappingURL=Card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../src/components/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,OAAO,CAAA;AAM1D,KAAK,SAAS,GAAG,cAAc,CAAC,cAAc,CAAC,GAAG;IAChD,wFAAwF;IACxF,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0BAA0B;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,wBAAgB,IAAI,CAAC,EACnB,EAAE,EACF,MAAM,EACN,MAAM,EACN,OAAO,EACP,MAAM,EACN,MAAM,EACN,WAAmB,EACnB,SAAS,EACT,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,SAAS,+BAqBX"}
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cardCss } from "../style/cardCss.js";
3
+ import { resolveColor } from "../style/resolveColor.js";
4
+ import { toLength } from "../style/toLength.js";
5
+ import { useStyle } from "../style/useStyle.js";
6
+ export function Card({ bg, border, shadow, padding, radius, accent, interactive = false, className, style, tabIndex, ...props }) {
7
+ useStyle("card", cardCss);
8
+ return (_jsx("div", { ...props, className: className ? `rui-card ${className}` : "rui-card", "data-interactive": interactive || undefined, tabIndex: tabIndex ?? (interactive ? 0 : undefined), style: {
9
+ "--rui-card-bg": bg && resolveColor(bg),
10
+ "--rui-card-border": border && resolveColor(border),
11
+ "--rui-card-shadow": shadow && resolveColor(shadow),
12
+ "--rui-card-padding": toLength(padding),
13
+ "--rui-card-radius": toLength(radius),
14
+ "--rui-card-accent": accent && resolveColor(accent),
15
+ ...style,
16
+ } }));
17
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"ColorField.d.ts","sourceRoot":"","sources":["../../src/components/ColorField.tsx"],"names":[],"mappings":"AAKA,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,WAA4B,EAAE,EAAE,eAAe,+BAanG"}
1
+ {"version":3,"file":"ColorField.d.ts","sourceRoot":"","sources":["../../src/components/ColorField.tsx"],"names":[],"mappings":"AAKA,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,WAA4B,EAAE,EAAE,eAAe,+BAmBnG"}
@@ -3,7 +3,7 @@ import ColorPicker from "./ColorPicker.js";
3
3
  import { Button } from "./Button.js";
4
4
  import { randomHex } from "../theme/clipboard.js";
5
5
  export function ColorField({ label, value, onChange, randomLabel = "Random color" }) {
6
- return (_jsxs("div", { style: rowStyle, children: [_jsx("label", { style: labelStyle, children: label }), _jsxs("div", { style: controlsStyle, children: [_jsx("code", { style: hexStyle, children: value }), _jsx(ColorPicker, { value: value, onChange: onChange, ariaLabel: label }), _jsx(Button, { variant: "ghost", onClick: () => onChange(randomHex()), style: randomBtnStyle, title: randomLabel, children: "\u21BB" })] })] }));
6
+ return (_jsxs("div", { style: rowStyle, children: [_jsx("label", { style: labelStyle, children: label }), _jsxs("div", { style: controlsStyle, children: [_jsx("code", { style: hexStyle, children: value }), _jsx(ColorPicker, { value: value, onChange: onChange, ariaLabel: label }), _jsx(Button, { variant: "ghost", color: "--color-text-muted", onClick: () => onChange(randomHex()), style: randomBtnStyle, title: randomLabel, children: "\u21BB" })] })] }));
7
7
  }
8
8
  const rowStyle = {
9
9
  display: "flex",
@@ -1,13 +1,16 @@
1
1
  import type { CSSProperties } from "react";
2
+ import type { ThemeColorVar } from "./Button.js";
2
3
  type Props = {
3
4
  onConfirm: () => void;
4
5
  label?: string;
5
6
  confirmLabel?: string;
7
+ /** Theme variable used by the button, as for `Button`. Defaults to `"--color-primary"`. */
8
+ color?: ThemeColorVar;
6
9
  className?: string;
7
10
  style?: CSSProperties;
8
11
  /** Delay in ms before the confirm state auto-resets (default: 10000) */
9
12
  resetDelay?: number;
10
13
  };
11
- export default function ConfirmDeleteButton({ onConfirm, label, confirmLabel, className, style, resetDelay, }: Props): import("react").JSX.Element;
14
+ export default function ConfirmDeleteButton({ onConfirm, label, confirmLabel, color, className, style, resetDelay, }: Props): import("react").JSX.Element;
12
15
  export {};
13
16
  //# sourceMappingURL=ConfirmDeleteButton.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmDeleteButton.d.ts","sourceRoot":"","sources":["../../src/components/ConfirmDeleteButton.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAG1C,KAAK,KAAK,GAAG;IACX,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAC1C,SAAS,EACT,KAAgB,EAChB,YAA8B,EAC9B,SAAS,EACT,KAAK,EACL,UAAmB,GACpB,EAAE,KAAK,+BAgCP"}
1
+ {"version":3,"file":"ConfirmDeleteButton.d.ts","sourceRoot":"","sources":["../../src/components/ConfirmDeleteButton.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,KAAK,KAAK,GAAG;IACX,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2FAA2F;IAC3F,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAC1C,SAAS,EACT,KAAgB,EAChB,YAA8B,EAC9B,KAAyB,EACzB,SAAS,EACT,KAAK,EACL,UAAmB,GACpB,EAAE,KAAK,+BA4BP"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from "react";
3
3
  import { Button } from "./Button.js";
4
- export default function ConfirmDeleteButton({ onConfirm, label = "Delete", confirmLabel = "Are you sure?", className, style, resetDelay = 10000, }) {
4
+ export default function ConfirmDeleteButton({ onConfirm, label = "Delete", confirmLabel = "Are you sure?", color = "--color-primary", className, style, resetDelay = 10000, }) {
5
5
  const [confirming, setConfirming] = useState(false);
6
6
  useEffect(() => {
7
7
  if (!confirming)
@@ -16,10 +16,9 @@ export default function ConfirmDeleteButton({ onConfirm, label = "Delete", confi
16
16
  }
17
17
  onConfirm();
18
18
  };
19
- return (_jsx(Button, { variant: "ghost", onClick: handleClick, className: className, style: {
20
- color: "var(--color-danger)",
21
- borderColor: "var(--color-danger)",
22
- backgroundColor: confirming ? "var(--color-danger-soft)" : "transparent",
23
- ...style,
24
- }, children: confirming ? confirmLabel : label }));
19
+ return (_jsx(Button, { variant: "outline", color: color, onClick: handleClick, className: className, style: confirming ? { ...confirmingStyle, ...style } : style, children: confirming ? confirmLabel : label }));
25
20
  }
21
+ // Soft tint of the button color, read from the variable Button sets.
22
+ const confirmingStyle = {
23
+ backgroundColor: "color-mix(in srgb, var(--rui-btn-color) 12%, transparent)",
24
+ };
@@ -0,0 +1,33 @@
1
+ import type { CSSProperties, ReactNode } from "react";
2
+ export type DrawerSide = "left" | "right" | "top" | "bottom";
3
+ /**
4
+ * - `fixed`: always open, in the page flow.
5
+ * - `hover`: a rail in the flow that expands over the page while hovered or focused.
6
+ * - `manual`: opened and closed by call only (`openDrawer` / `closeDrawer` / `toggleDrawer`), over the page.
7
+ * - `hover-manual`: both; opened by call it stays pinned until closed by call.
8
+ */
9
+ export type DrawerMode = "fixed" | "hover" | "manual" | "hover-manual";
10
+ type DrawerProps = {
11
+ id: string;
12
+ /** Defaults to `"left"`. */
13
+ side?: DrawerSide;
14
+ /** Defaults to `"manual"`. */
15
+ mode?: DrawerMode;
16
+ /** Width for left / right, height for top / bottom. Numbers are pixels. Defaults to 320. */
17
+ size?: string | number;
18
+ /** Rail size in `hover` / `hover-manual` modes. Numbers are pixels. Defaults to 56. */
19
+ collapsedSize?: string | number;
20
+ /** Controlled mode: the parent owns visibility and calls by id are ignored. */
21
+ open?: boolean;
22
+ /** Called when the drawer asks to change state (hover), in controlled mode. */
23
+ onOpenChange?: (open: boolean) => void;
24
+ /** Delay in ms before a hovered drawer closes once the pointer leaves. Defaults to 200. */
25
+ closeDelay?: number;
26
+ ariaLabel?: string;
27
+ className?: string;
28
+ style?: CSSProperties;
29
+ children: ReactNode;
30
+ };
31
+ export declare function Drawer({ id, side, mode, size, collapsedSize, open, onOpenChange, closeDelay, ariaLabel, className, style, children, }: DrawerProps): import("react").JSX.Element | null;
32
+ export {};
33
+ //# sourceMappingURL=Drawer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../src/components/Drawer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAc,SAAS,EAAE,MAAM,OAAO,CAAA;AAOjE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAA;AAE5D;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,cAAc,CAAA;AAEtE,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,4BAA4B;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,4FAA4F;IAC5F,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC/B,+EAA+E;IAC/E,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,+EAA+E;IAC/E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC,2FAA2F;IAC3F,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAA;AAED,wBAAgB,MAAM,CAAC,EACrB,EAAE,EACF,IAAa,EACb,IAAe,EACf,IAAU,EACV,aAAkB,EAClB,IAAI,EACJ,YAAY,EACZ,UAAgB,EAChB,SAAS,EACT,SAAS,EACT,KAAK,EACL,QAAQ,GACT,EAAE,WAAW,sCA+Eb"}
@@ -0,0 +1,123 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { createPortal } from "react-dom";
4
+ import { useOverlayStack } from "@-reddacted-/react-hooks";
5
+ import { toLength } from "../style/toLength.js";
6
+ import { useStyle } from "../style/useStyle.js";
7
+ import { useDrawer } from "./drawerStore.js";
8
+ export function Drawer({ id, side = "left", mode = "manual", size = 320, collapsedSize = 56, open, onOpenChange, closeDelay = 200, ariaLabel, className, style, children, }) {
9
+ useStyle("drawer", drawerCss);
10
+ const controlled = open !== undefined;
11
+ const hoverable = mode === "hover" || mode === "hover-manual";
12
+ const callable = mode === "manual" || mode === "hover-manual";
13
+ const { isOpen: openByCall } = useDrawer(id);
14
+ const [hovered, setHovered] = useState(false);
15
+ // Controlled hover-manual: remembers that the parent opened the drawer because of the
16
+ // hover, so leaving only closes what the hover opened.
17
+ const openedByHover = useRef(false);
18
+ const closeTimer = useRef();
19
+ const isOpen = mode === "fixed" || (controlled ? open : (callable && openByCall) || (hoverable && hovered));
20
+ const { zIndex } = useOverlayStack(isOpen && mode !== "fixed");
21
+ useEffect(() => () => clearTimeout(closeTimer.current), []);
22
+ const enter = () => {
23
+ clearTimeout(closeTimer.current);
24
+ if (!controlled) {
25
+ setHovered(true);
26
+ }
27
+ else if (!open) {
28
+ openedByHover.current = true;
29
+ onOpenChange?.(true);
30
+ }
31
+ };
32
+ const leave = () => {
33
+ clearTimeout(closeTimer.current);
34
+ closeTimer.current = setTimeout(() => {
35
+ if (!controlled) {
36
+ setHovered(false);
37
+ }
38
+ else if (mode === "hover" || openedByHover.current) {
39
+ openedByHover.current = false;
40
+ onOpenChange?.(false);
41
+ }
42
+ }, closeDelay);
43
+ };
44
+ // Focus moving between children of the drawer is not a leave.
45
+ const blur = (e) => {
46
+ if (!e.currentTarget.contains(e.relatedTarget))
47
+ leave();
48
+ };
49
+ const sizeVars = {
50
+ "--rui-drawer-size": toLength(size),
51
+ "--rui-drawer-collapsed": toLength(collapsedSize),
52
+ };
53
+ const aside = (_jsx("aside", { className: className ? `rui-drawer ${className}` : "rui-drawer", "data-side": side, "data-mode": mode, "data-open": isOpen || undefined, "aria-label": ariaLabel, style: { ...sizeVars, ...(isOpen && mode !== "fixed" ? { zIndex } : undefined), ...style }, onMouseEnter: hoverable ? enter : undefined, onMouseLeave: hoverable ? leave : undefined, onFocus: hoverable ? enter : undefined, onBlur: hoverable ? blur : undefined, children: children }));
54
+ if (mode === "manual")
55
+ return isOpen ? createPortal(aside, document.body) : null;
56
+ if (hoverable) {
57
+ return (_jsx("div", { className: "rui-drawer-rail", "data-side": side, style: sizeVars, children: aside }));
58
+ }
59
+ return aside;
60
+ }
61
+ // Every selector is wrapped in :where() so it has zero specificity:
62
+ // any class or style set by the consuming project wins without !important.
63
+ const drawerCss = `
64
+ :where(.rui-drawer) {
65
+ box-sizing: border-box;
66
+ overflow: auto;
67
+ background-color: var(--color-surface);
68
+ }
69
+ :where(.rui-drawer[data-side="left"]) { border-right: 1px solid var(--color-border); }
70
+ :where(.rui-drawer[data-side="right"]) { border-left: 1px solid var(--color-border); }
71
+ :where(.rui-drawer[data-side="top"]) { border-bottom: 1px solid var(--color-border); }
72
+ :where(.rui-drawer[data-side="bottom"]) { border-top: 1px solid var(--color-border); }
73
+ :where(.rui-drawer[data-side="left"], .rui-drawer[data-side="right"]) { width: var(--rui-drawer-size); }
74
+ :where(.rui-drawer[data-side="top"], .rui-drawer[data-side="bottom"]) { height: var(--rui-drawer-size); }
75
+ :where(.rui-drawer[data-mode="fixed"]) { flex-shrink: 0; }
76
+
77
+ :where(.rui-drawer[data-mode="manual"]) {
78
+ position: fixed;
79
+ box-shadow: 0 4px 16px color-mix(in srgb, var(--color-text) 15%, transparent);
80
+ animation: 180ms ease-out both;
81
+ }
82
+ :where(.rui-drawer[data-mode="manual"][data-side="left"]) { top: 0; bottom: 0; left: 0; animation-name: rui-drawer-in-left; }
83
+ :where(.rui-drawer[data-mode="manual"][data-side="right"]) { top: 0; bottom: 0; right: 0; animation-name: rui-drawer-in-right; }
84
+ :where(.rui-drawer[data-mode="manual"][data-side="top"]) { top: 0; left: 0; right: 0; animation-name: rui-drawer-in-top; }
85
+ :where(.rui-drawer[data-mode="manual"][data-side="bottom"]) { bottom: 0; left: 0; right: 0; animation-name: rui-drawer-in-bottom; }
86
+
87
+ :where(.rui-drawer-rail) {
88
+ position: relative;
89
+ flex-shrink: 0;
90
+ }
91
+ :where(.rui-drawer-rail[data-side="left"], .rui-drawer-rail[data-side="right"]) { width: var(--rui-drawer-collapsed); }
92
+ :where(.rui-drawer-rail[data-side="top"], .rui-drawer-rail[data-side="bottom"]) { height: var(--rui-drawer-collapsed); }
93
+ :where(.rui-drawer-rail > .rui-drawer) {
94
+ position: absolute;
95
+ overflow: hidden;
96
+ transition: width 150ms ease-out, height 150ms ease-out;
97
+ }
98
+ :where(.rui-drawer-rail > .rui-drawer[data-side="left"]) { top: 0; bottom: 0; left: 0; width: var(--rui-drawer-collapsed); }
99
+ :where(.rui-drawer-rail > .rui-drawer[data-side="right"]) { top: 0; bottom: 0; right: 0; width: var(--rui-drawer-collapsed); }
100
+ :where(.rui-drawer-rail > .rui-drawer[data-side="top"]) { top: 0; left: 0; right: 0; height: var(--rui-drawer-collapsed); }
101
+ :where(.rui-drawer-rail > .rui-drawer[data-side="bottom"]) { bottom: 0; left: 0; right: 0; height: var(--rui-drawer-collapsed); }
102
+ :where(.rui-drawer-rail > .rui-drawer[data-open]) {
103
+ overflow: auto;
104
+ box-shadow: 0 4px 16px color-mix(in srgb, var(--color-text) 15%, transparent);
105
+ }
106
+ :where(.rui-drawer-rail > .rui-drawer[data-open][data-side="left"], .rui-drawer-rail > .rui-drawer[data-open][data-side="right"]) {
107
+ width: var(--rui-drawer-size);
108
+ }
109
+ :where(.rui-drawer-rail > .rui-drawer[data-open][data-side="top"], .rui-drawer-rail > .rui-drawer[data-open][data-side="bottom"]) {
110
+ height: var(--rui-drawer-size);
111
+ }
112
+
113
+ @media (prefers-reduced-motion: reduce) {
114
+ :where(.rui-drawer, .rui-drawer-rail > .rui-drawer) {
115
+ animation: none;
116
+ transition: none;
117
+ }
118
+ }
119
+ @keyframes rui-drawer-in-left { from { transform: translateX(-100%); } }
120
+ @keyframes rui-drawer-in-right { from { transform: translateX(100%); } }
121
+ @keyframes rui-drawer-in-top { from { transform: translateY(-100%); } }
122
+ @keyframes rui-drawer-in-bottom { from { transform: translateY(100%); } }
123
+ `;
@@ -0,0 +1,61 @@
1
+ import type { HTMLAttributes, MouseEvent, ReactElement, ReactNode } from "react";
2
+ import type { TooltipPlacement } from "../tooltip/tooltipEngine.js";
3
+ type DropdownMenuProps = {
4
+ /** Defaults to `"click"`. On touch, `"hover"` behaves like `"click"`. */
5
+ trigger?: "click" | "hover";
6
+ /** Flips and shifts by itself when there is no room. Defaults to `"bottom-start"`. */
7
+ placement?: TooltipPlacement;
8
+ /** Controlled mode. */
9
+ open?: boolean;
10
+ defaultOpen?: boolean;
11
+ onOpenChange?: (open: boolean) => void;
12
+ /** Delay in ms before closing once the pointer left both trigger and menu (`hover`). Defaults to 200. */
13
+ closeDelay?: number;
14
+ /** Hovered / focused item tint and indicators. `"--color-x"` reads the theme variable. Defaults to `"--color-primary"`. */
15
+ color?: string;
16
+ children: ReactNode;
17
+ };
18
+ export declare function DropdownMenu({ trigger, placement, open: controlledOpen, defaultOpen, onOpenChange, closeDelay, color, children, }: DropdownMenuProps): import("react").JSX.Element;
19
+ export declare namespace DropdownMenu {
20
+ var Trigger: ({ children }: {
21
+ children: ReactElement;
22
+ }) => ReactElement<ChildProps, string | import("react").JSXElementConstructor<any>>;
23
+ var Content: ({ minWidth, className, style, onKeyDown, children, ...props }: ContentProps) => import("react").ReactPortal | null;
24
+ var Item: ({ disabled, closeOnSelect, textValue, onSelect, asChild, className, children, ...props }: ItemProps) => import("react").JSX.Element;
25
+ var CheckboxItem: ({ disabled, closeOnSelect, textValue, checked, onCheckedChange, className, children, ...props }: CheckboxItemProps) => import("react").JSX.Element;
26
+ var RadioGroup: ({ value, onValueChange, ...props }: RadioGroupProps) => import("react").JSX.Element;
27
+ var RadioItem: ({ value, disabled, closeOnSelect, textValue, className, children, ...props }: RadioItemProps) => import("react").JSX.Element;
28
+ var Label: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => import("react").JSX.Element;
29
+ var Separator: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => import("react").JSX.Element;
30
+ }
31
+ type ChildProps = HTMLAttributes<HTMLElement>;
32
+ type ContentProps = HTMLAttributes<HTMLDivElement> & {
33
+ /** Numbers are pixels. Defaults to the trigger's width. */
34
+ minWidth?: string | number;
35
+ };
36
+ type ItemBaseProps = {
37
+ disabled?: boolean;
38
+ /** Defaults to true. */
39
+ closeOnSelect?: boolean;
40
+ /** Text used by typeahead when the content is not plain text. */
41
+ textValue?: string;
42
+ };
43
+ type ItemProps = ItemBaseProps & Omit<HTMLAttributes<HTMLDivElement>, "onSelect"> & {
44
+ /** Call `event.preventDefault()` to keep the menu open. */
45
+ onSelect?: (event: MouseEvent<HTMLElement>) => void;
46
+ /** Renders the single child (a link, a router Link…) as the item. */
47
+ asChild?: boolean;
48
+ };
49
+ type CheckboxItemProps = ItemBaseProps & HTMLAttributes<HTMLDivElement> & {
50
+ checked: boolean;
51
+ onCheckedChange: (checked: boolean) => void;
52
+ };
53
+ type RadioGroupProps = HTMLAttributes<HTMLDivElement> & {
54
+ value: string | undefined;
55
+ onValueChange: (value: string) => void;
56
+ };
57
+ type RadioItemProps = ItemBaseProps & HTMLAttributes<HTMLDivElement> & {
58
+ value: string;
59
+ };
60
+ export {};
61
+ //# sourceMappingURL=DropdownMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/components/DropdownMenu.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAEV,cAAc,EAEd,UAAU,EAEV,YAAY,EACZ,SAAS,EAEV,MAAM,OAAO,CAAA;AAQd,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAyCnE,KAAK,iBAAiB,GAAG;IACvB,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;IAC3B,sFAAsF;IACtF,SAAS,CAAC,EAAE,gBAAgB,CAAA;IAC5B,uBAAuB;IACvB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC,yGAAyG;IACzG,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2HAA2H;IAC3H,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAA;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAiB,EACjB,SAA0B,EAC1B,IAAI,EAAE,cAAc,EACpB,WAAmB,EACnB,YAAY,EACZ,UAAgB,EAChB,KAAyB,EACzB,QAAQ,GACT,EAAE,iBAAiB,+BAyDnB;yBAlEe,YAAY;gCAuEG;QAAE,QAAQ,EAAE,YAAY,CAAA;KAAE;iFA+DuB,YAAY;yGAmKY,SAAS;wHAqC9G,iBAAiB;yDAyBoC,eAAe;kGAU0B,cAAc;yCAqBvE,cAAc,CAAC,cAAc,CAAC;6CAI1B,cAAc,CAAC,cAAc,CAAC;;AAtU1E,KAAK,UAAU,GAAG,cAAc,CAAC,WAAW,CAAC,CAAA;AA6D7C,KAAK,YAAY,GAAG,cAAc,CAAC,cAAc,CAAC,GAAG;IACnD,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAC3B,CAAA;AAyHD,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,wBAAwB;IACxB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AA8BD,KAAK,SAAS,GAAG,aAAa,GAC5B,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,GAAG;IACjD,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;IACnD,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAwBH,KAAK,iBAAiB,GAAG,aAAa,GACpC,cAAc,CAAC,cAAc,CAAC,GAAG;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CAC5C,CAAA;AA+BH,KAAK,eAAe,GAAG,cAAc,CAAC,cAAc,CAAC,GAAG;IACtD,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACvC,CAAA;AAUD,KAAK,cAAc,GAAG,aAAa,GAAG,cAAc,CAAC,cAAc,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA"}