canny-ui-react 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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +68 -0
  3. package/dist/components/Alert/Alert.d.ts +2 -0
  4. package/dist/components/Alert/Alert.types.d.ts +8 -0
  5. package/dist/components/Alert/index.d.ts +2 -0
  6. package/dist/components/Avatar/Avatar.d.ts +3 -0
  7. package/dist/components/Avatar/Avatar.types.d.ts +13 -0
  8. package/dist/components/Avatar/index.d.ts +2 -0
  9. package/dist/components/Button/Button.d.ts +2 -0
  10. package/dist/components/Button/Button.types.d.ts +27 -0
  11. package/dist/components/Button/ButtonGroup.d.ts +13 -0
  12. package/dist/components/Button/FAB.d.ts +37 -0
  13. package/dist/components/Button/IconButton.d.ts +13 -0
  14. package/dist/components/Button/Ripple.d.ts +17 -0
  15. package/dist/components/Button/ToggleButton.d.ts +18 -0
  16. package/dist/components/Button/ToggleButtonGroup.d.ts +29 -0
  17. package/dist/components/Button/index.d.ts +11 -0
  18. package/dist/components/Card/Card.d.ts +2 -0
  19. package/dist/components/Card/Card.types.d.ts +6 -0
  20. package/dist/components/Card/index.d.ts +2 -0
  21. package/dist/components/Checkbox/Checkbox.d.ts +10 -0
  22. package/dist/components/Checkbox/index.d.ts +2 -0
  23. package/dist/components/Field/Field.d.ts +31 -0
  24. package/dist/components/Field/index.d.ts +2 -0
  25. package/dist/components/Input/Input.d.ts +2 -0
  26. package/dist/components/Input/Input.types.d.ts +18 -0
  27. package/dist/components/Input/index.d.ts +2 -0
  28. package/dist/components/Layout/Box.d.ts +19 -0
  29. package/dist/components/Layout/Container.d.ts +11 -0
  30. package/dist/components/Layout/Divider.d.ts +11 -0
  31. package/dist/components/Layout/Grid.d.ts +11 -0
  32. package/dist/components/Layout/Spacer.d.ts +4 -0
  33. package/dist/components/Layout/Stack.d.ts +12 -0
  34. package/dist/components/Layout/index.d.ts +13 -0
  35. package/dist/components/Layout/layout.types.d.ts +38 -0
  36. package/dist/components/MultiSelect/MultiSelect.d.ts +54 -0
  37. package/dist/components/MultiSelect/index.d.ts +2 -0
  38. package/dist/components/Navbar/Navbar.d.ts +6 -0
  39. package/dist/components/Navbar/Navbar.types.d.ts +19 -0
  40. package/dist/components/Navbar/index.d.ts +2 -0
  41. package/dist/components/Progress/Progress.d.ts +3 -0
  42. package/dist/components/Progress/Progress.types.d.ts +12 -0
  43. package/dist/components/Progress/index.d.ts +2 -0
  44. package/dist/components/Radio/Radio.d.ts +14 -0
  45. package/dist/components/Radio/index.d.ts +2 -0
  46. package/dist/components/Scroll/Scroll.d.ts +3 -0
  47. package/dist/components/Scroll/Scroll.types.d.ts +13 -0
  48. package/dist/components/Scroll/index.d.ts +2 -0
  49. package/dist/components/Select/Select.d.ts +51 -0
  50. package/dist/components/Select/index.d.ts +2 -0
  51. package/dist/components/Sidebar/Sidebar.d.ts +4 -0
  52. package/dist/components/Sidebar/Sidebar.types.d.ts +20 -0
  53. package/dist/components/Sidebar/index.d.ts +2 -0
  54. package/dist/components/Skeleton/Skeleton.d.ts +2 -0
  55. package/dist/components/Skeleton/Skeleton.types.d.ts +7 -0
  56. package/dist/components/Skeleton/index.d.ts +2 -0
  57. package/dist/components/Switch/Switch.d.ts +8 -0
  58. package/dist/components/Switch/index.d.ts +2 -0
  59. package/dist/components/Text/Text.d.ts +26 -0
  60. package/dist/components/Text/index.d.ts +2 -0
  61. package/dist/components/Textarea/Textarea.d.ts +13 -0
  62. package/dist/components/Textarea/index.d.ts +2 -0
  63. package/dist/index.cjs +119 -0
  64. package/dist/index.cjs.map +1 -0
  65. package/dist/index.d.ts +19 -0
  66. package/dist/index.js +11531 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/test/setup.d.ts +1 -0
  69. package/dist/utils/cx.d.ts +2 -0
  70. package/package.json +83 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CannyMinds
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # canny-ui-react
2
+
3
+ Typed React component wrappers for the [Canny-UI](https://www.npmjs.com/package/canny-ui) design system.
4
+
5
+ Built on [Radix UI](https://www.radix-ui.com), [motion](https://motion.dev), [cmdk](https://cmdk.paco.me), and [lucide-react](https://lucide.dev). Zero inline styles — every prop maps to a utility class in `canny-ui`.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add canny-ui canny-ui-react
11
+ # or
12
+ npm install canny-ui canny-ui-react
13
+ ```
14
+
15
+ Peer deps: `react` / `react-dom` >= 18.
16
+
17
+ ## Use
18
+
19
+ ```tsx
20
+ import 'canny-ui/dist/canny-ui.min.css';
21
+ import {
22
+ Button, ButtonGroup, FAB, IconButton,
23
+ ToggleButton, ToggleButtonGroup, ToggleButtonGroupItem,
24
+ Input, Textarea, Field,
25
+ Select, SelectItem,
26
+ MultiSelect,
27
+ Checkbox, Radio, RadioGroup, Switch,
28
+ Box, Stack, Row, Grid, Container, Divider, Spacer, Text,
29
+ Card, Alert, Avatar, Progress, Skeleton,
30
+ Navbar, Sidebar, Scroll,
31
+ } from 'canny-ui-react';
32
+
33
+ export function SignInCard() {
34
+ return (
35
+ <Container size="sm">
36
+ <Card>
37
+ <Stack gap={4}>
38
+ <Text variant="h2">Welcome back</Text>
39
+ <Field label="Email" required>
40
+ <Input type="email" placeholder="name@company.com" />
41
+ </Field>
42
+ <Field label="Password" required>
43
+ <Input type="password" showPasswordToggle />
44
+ </Field>
45
+ <Row gap={2} justify="end">
46
+ <Button variant="ghost">Forgot?</Button>
47
+ <Button>Sign in</Button>
48
+ </Row>
49
+ </Stack>
50
+ </Card>
51
+ </Container>
52
+ );
53
+ }
54
+ ```
55
+
56
+ ## Highlights
57
+
58
+ - **Buttons** — 7 variants × 5 colors × 3 sizes × 3 shapes, click-position ripple powered by `motion`, attached/spaced groups, FAB with spring entrance, Radix-powered toggles and segmented controls
59
+ - **Inputs** — prefix/suffix slots, clear button, password toggle, validation states wired through `<Field>`
60
+ - **Select / MultiSelect** — Radix Select + cmdk combobox with chip tokens, groups, descriptions, `maxItems` cap
61
+ - **Layout primitives** — `<Box>`, `<Stack>`, `<Row>`, `<Grid>`, `<Container>` map props to utility classes, polymorphic `as`
62
+ - **Typography** — `<Text variant="h1|h2|...|caption|code|kbd">` picks element + scale together
63
+
64
+ ## Links
65
+
66
+ - **Docs**: https://github.com/CannyMinds/Canny-UI#readme
67
+ - **Issues**: https://github.com/CannyMinds/Canny-UI/issues
68
+ - **License**: MIT
@@ -0,0 +1,2 @@
1
+ import type { AlertProps } from './Alert.types';
2
+ export declare const Alert: import("react").ForwardRefExoticComponent<AlertProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,8 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ export type AlertColor = 'info' | 'success' | 'warning' | 'danger';
3
+ export interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
4
+ color?: AlertColor;
5
+ solid?: boolean;
6
+ title?: ReactNode;
7
+ children?: ReactNode;
8
+ }
@@ -0,0 +1,2 @@
1
+ export { Alert } from './Alert';
2
+ export type { AlertProps, AlertColor } from './Alert.types';
@@ -0,0 +1,3 @@
1
+ import type { AvatarProps, AvatarStackProps } from './Avatar.types';
2
+ export declare const Avatar: import("react").ForwardRefExoticComponent<AvatarProps & import("react").RefAttributes<HTMLSpanElement>>;
3
+ export declare const AvatarStack: import("react").ForwardRefExoticComponent<AvatarStackProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,13 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ export type AvatarSize = 'xs' | 'sm' | 'md' | 'lg';
3
+ export type AvatarStatus = 'online' | 'busy' | 'offline';
4
+ export interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {
5
+ size?: AvatarSize;
6
+ status?: AvatarStatus;
7
+ src?: string;
8
+ alt?: string;
9
+ children?: ReactNode;
10
+ }
11
+ export interface AvatarStackProps extends HTMLAttributes<HTMLDivElement> {
12
+ children: ReactNode;
13
+ }
@@ -0,0 +1,2 @@
1
+ export { Avatar, AvatarStack } from './Avatar';
2
+ export type { AvatarProps, AvatarStackProps, AvatarSize, AvatarStatus } from './Avatar.types';
@@ -0,0 +1,2 @@
1
+ import type { ButtonProps } from './Button.types';
2
+ export declare const Button: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,27 @@
1
+ import type { ButtonHTMLAttributes, ReactNode } from 'react';
2
+ export type ButtonVariant = 'solid' | 'secondary' | 'outline' | 'dashed' | 'ghost' | 'soft' | 'link';
3
+ export type ButtonColor = 'primary' | 'danger' | 'warning' | 'success' | 'info';
4
+ export type ButtonSize = 'sm' | 'md' | 'lg';
5
+ export type ButtonShape = 'default' | 'round' | 'circle';
6
+ export type ButtonIconPosition = 'start' | 'end';
7
+ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
8
+ /** Visual tier. Default: `'solid'`. */
9
+ variant?: ButtonVariant;
10
+ /** Semantic color role. Default: `'primary'`. */
11
+ color?: ButtonColor;
12
+ /** Size modifier. `'md'` is the default (no class). */
13
+ size?: ButtonSize;
14
+ /** Corner style. `'round'` → pill, `'circle'` → icon-only circular. */
15
+ shape?: ButtonShape;
16
+ /** Stretch to full width of parent. */
17
+ block?: boolean;
18
+ /** Replace leading slot with a spinner and disable interaction. */
19
+ loading?: boolean;
20
+ /** Icon node placed in the leading or trailing slot. */
21
+ icon?: ReactNode;
22
+ /** Side to place the `icon` on. Default: `'start'`. */
23
+ iconPosition?: ButtonIconPosition;
24
+ /** Disable the MUI-style click ripple. Default: `false`. */
25
+ disableRipple?: boolean;
26
+ children?: ReactNode;
27
+ }
@@ -0,0 +1,13 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ export type ButtonGroupOrientation = 'horizontal' | 'vertical';
3
+ export type ButtonGroupLayout = 'attached' | 'spaced';
4
+ export interface ButtonGroupProps extends HTMLAttributes<HTMLDivElement> {
5
+ /** Stack direction. Default: `'horizontal'`. */
6
+ orientation?: ButtonGroupOrientation;
7
+ /** `'attached'` collapses borders; `'spaced'` leaves a small gap. Default: `'attached'`. */
8
+ layout?: ButtonGroupLayout;
9
+ /** Use pill radii on the first/last buttons. */
10
+ round?: boolean;
11
+ children: ReactNode;
12
+ }
13
+ export declare const ButtonGroup: import("react").ForwardRefExoticComponent<ButtonGroupProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,37 @@
1
+ import type { ButtonHTMLAttributes, ReactNode } from 'react';
2
+ import type { ButtonColor, ButtonSize, ButtonVariant } from './Button.types';
3
+ export type FABPosition = 'static' | 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
4
+ type FABVariant = Extract<ButtonVariant, 'solid' | 'secondary' | 'soft'>;
5
+ type MotionIncompatible = 'onAnimationStart' | 'onAnimationEnd' | 'onAnimationIteration' | 'onTransitionEnd' | 'onDrag' | 'onDragStart' | 'onDragEnd' | 'onDragEnter' | 'onDragLeave' | 'onDragOver' | 'onDragExit' | 'onDrop';
6
+ type BaseFABProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | MotionIncompatible> & {
7
+ variant?: FABVariant;
8
+ color?: ButtonColor;
9
+ size?: Exclude<ButtonSize, 'md'> | 'md';
10
+ position?: FABPosition;
11
+ disableRipple?: boolean;
12
+ /** Icon element. Required. */
13
+ icon: ReactNode;
14
+ /** Text label. When provided, FAB becomes the extended pill variant. */
15
+ label?: ReactNode;
16
+ /** Control mount. When false, FAB exits with a spring shrink via motion. */
17
+ open?: boolean;
18
+ };
19
+ type FABWithLabel = BaseFABProps & {
20
+ label: ReactNode;
21
+ 'aria-label'?: string;
22
+ };
23
+ type FABIconOnly = BaseFABProps & {
24
+ label?: undefined;
25
+ 'aria-label': string;
26
+ };
27
+ export type FABProps = FABWithLabel | FABIconOnly;
28
+ /**
29
+ * Floating Action Button — elevated circular primary action (Material-style).
30
+ * Provide `label` for the extended pill variant.
31
+ *
32
+ * Entrance and exit are animated with `motion`'s spring presets. Pair with
33
+ * `open` + `AnimatePresence` at the call site for conditional FABs that exit
34
+ * gracefully.
35
+ */
36
+ export declare const FAB: import("react").ForwardRefExoticComponent<FABProps & import("react").RefAttributes<HTMLButtonElement>>;
37
+ export {};
@@ -0,0 +1,13 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { ButtonProps } from './Button.types';
3
+ export interface IconButtonProps extends Omit<ButtonProps, 'children' | 'icon' | 'iconPosition'> {
4
+ /** Icon element. Required. */
5
+ icon: ReactNode;
6
+ /** Accessible label. Required — icon-only buttons must have one. */
7
+ 'aria-label': string;
8
+ }
9
+ /**
10
+ * Convenience over `<Button shape="circle" icon={...} aria-label="…" />`.
11
+ * Enforces `aria-label` at the type level for icon-only accessibility.
12
+ */
13
+ export declare const IconButton: import("react").ForwardRefExoticComponent<IconButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,17 @@
1
+ import type { MouseEvent as ReactMouseEvent } from 'react';
2
+ type RippleItem = {
3
+ id: number;
4
+ x: number;
5
+ y: number;
6
+ size: number;
7
+ };
8
+ export declare function useRipple(): {
9
+ ripples: RippleItem[];
10
+ add: (event: ReactMouseEvent<HTMLElement>) => void;
11
+ remove: (id: number) => void;
12
+ };
13
+ export declare function Ripples({ ripples, onDone, }: {
14
+ ripples: RippleItem[];
15
+ onDone: (id: number) => void;
16
+ }): import("react/jsx-runtime").JSX.Element;
17
+ export {};
@@ -0,0 +1,18 @@
1
+ import type { ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ import { Root as RadixToggle } from '@radix-ui/react-toggle';
3
+ import type { ButtonColor, ButtonShape, ButtonSize, ButtonVariant } from './Button.types';
4
+ type RadixToggleProps = ComponentPropsWithoutRef<typeof RadixToggle>;
5
+ export interface ToggleButtonProps extends Omit<RadixToggleProps, 'asChild'> {
6
+ variant?: Extract<ButtonVariant, 'ghost' | 'outline' | 'soft' | 'dashed'>;
7
+ color?: ButtonColor;
8
+ size?: ButtonSize;
9
+ shape?: ButtonShape;
10
+ icon?: ReactNode;
11
+ children?: ReactNode;
12
+ }
13
+ /**
14
+ * Accessible toggle built on Radix's `Toggle` primitive.
15
+ * Handles `aria-pressed` / `data-state` natively; CSS hooks into both.
16
+ */
17
+ export declare const ToggleButton: import("react").ForwardRefExoticComponent<ToggleButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
18
+ export {};
@@ -0,0 +1,29 @@
1
+ import type { ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ import { Root as RadixToggleGroup, Item as RadixToggleGroupItem } from '@radix-ui/react-toggle-group';
3
+ import type { ButtonColor, ButtonShape, ButtonSize, ButtonVariant } from './Button.types';
4
+ type GroupRootProps = ComponentPropsWithoutRef<typeof RadixToggleGroup>;
5
+ type GroupItemProps = ComponentPropsWithoutRef<typeof RadixToggleGroupItem>;
6
+ type GroupVariant = Extract<ButtonVariant, 'ghost' | 'outline' | 'soft' | 'dashed'>;
7
+ export type ToggleButtonGroupProps = GroupRootProps & {
8
+ variant?: GroupVariant;
9
+ color?: ButtonColor;
10
+ size?: ButtonSize;
11
+ /** `attached` collapses borders, `spaced` leaves a small gap. Default: `attached`. */
12
+ layout?: 'attached' | 'spaced';
13
+ /** Pill-shaped ends. */
14
+ round?: boolean;
15
+ };
16
+ export interface ToggleButtonGroupItemProps extends Omit<GroupItemProps, 'asChild'> {
17
+ icon?: ReactNode;
18
+ shape?: ButtonShape;
19
+ children?: ReactNode;
20
+ }
21
+ /**
22
+ * Accessible segmented control / toolbar built on Radix's `ToggleGroup` primitive.
23
+ * Supports single-select (`type="single"`) or multi-select (`type="multiple"`).
24
+ * Items inherit styling via React context; override per-item if needed.
25
+ */
26
+ export declare const ToggleButtonGroup: import("react").ForwardRefExoticComponent<ToggleButtonGroupProps & import("react").RefAttributes<HTMLDivElement>>;
27
+ /** Individual toggle item. Styling inherits from `ToggleButtonGroup` via context. */
28
+ export declare const ToggleButtonGroupItem: import("react").ForwardRefExoticComponent<ToggleButtonGroupItemProps & import("react").RefAttributes<HTMLButtonElement>>;
29
+ export {};
@@ -0,0 +1,11 @@
1
+ export { Button } from './Button';
2
+ export { ButtonGroup } from './ButtonGroup';
3
+ export { FAB } from './FAB';
4
+ export { IconButton } from './IconButton';
5
+ export { ToggleButton } from './ToggleButton';
6
+ export { ToggleButtonGroup, ToggleButtonGroupItem } from './ToggleButtonGroup';
7
+ export type { ButtonProps, ButtonVariant, ButtonColor, ButtonSize, ButtonShape, ButtonIconPosition, } from './Button.types';
8
+ export type { ButtonGroupProps, ButtonGroupOrientation, ButtonGroupLayout } from './ButtonGroup';
9
+ export type { IconButtonProps } from './IconButton';
10
+ export type { ToggleButtonProps } from './ToggleButton';
11
+ export type { ToggleButtonGroupProps, ToggleButtonGroupItemProps } from './ToggleButtonGroup';
@@ -0,0 +1,2 @@
1
+ import type { CardProps } from './Card.types';
2
+ export declare const Card: import("react").ForwardRefExoticComponent<CardProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,6 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ export type CardColor = 'default' | 'danger' | 'warning' | 'success' | 'info';
3
+ export interface CardProps extends HTMLAttributes<HTMLDivElement> {
4
+ color?: CardColor;
5
+ children: ReactNode;
6
+ }
@@ -0,0 +1,2 @@
1
+ export { Card } from './Card';
2
+ export type { CardProps, CardColor } from './Card.types';
@@ -0,0 +1,10 @@
1
+ import type { ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ import * as RadixCheckbox from '@radix-ui/react-checkbox';
3
+ type CheckboxRootProps = ComponentPropsWithoutRef<typeof RadixCheckbox.Root>;
4
+ export interface CheckboxProps extends Omit<CheckboxRootProps, 'children'> {
5
+ /** Label text or node rendered next to the box. */
6
+ children?: ReactNode;
7
+ }
8
+ /** Accessible checkbox — tri-state (`checked | 'indeterminate' | false`). */
9
+ export declare const Checkbox: import("react").ForwardRefExoticComponent<CheckboxProps & import("react").RefAttributes<HTMLButtonElement>>;
10
+ export {};
@@ -0,0 +1,2 @@
1
+ export { Checkbox } from './Checkbox';
2
+ export type { CheckboxProps } from './Checkbox';
@@ -0,0 +1,31 @@
1
+ import type { HTMLAttributes, ReactElement, ReactNode } from 'react';
2
+ export type FieldValidationState = 'default' | 'danger' | 'warning' | 'success';
3
+ export interface FieldProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
4
+ /** Label text. */
5
+ label?: ReactNode;
6
+ /** Helper copy shown under the control. */
7
+ hint?: ReactNode;
8
+ /** Error message — overrides `hint` and applies danger styling to the control. */
9
+ error?: ReactNode;
10
+ /** Show a red asterisk next to the label. */
11
+ required?: boolean;
12
+ /** Show a muted "(optional)" tag next to the label. */
13
+ optional?: boolean;
14
+ /** Character counter — pass the current length. Pair with `maxLength`. */
15
+ counter?: number;
16
+ /** Max characters; when `counter` >= this, the counter flips to danger. */
17
+ maxLength?: number;
18
+ /** Override validation styling explicitly. */
19
+ state?: FieldValidationState;
20
+ /** Single form control element. The `id` is threaded to the label and aria-describedby. */
21
+ children: ReactElement;
22
+ }
23
+ /**
24
+ * Field — the canonical wrapper for form controls. Handles:
25
+ * • Label + required asterisk / optional tag
26
+ * • Helper / error text (error overrides hint)
27
+ * • Character counter with auto-danger when > maxLength
28
+ * • ARIA wiring: `htmlFor`, `aria-describedby`, `aria-invalid`
29
+ * • Validation state propagation to the child control via className
30
+ */
31
+ export declare function Field({ label, hint, error, required, optional, counter, maxLength, state, className, children, ...rest }: FieldProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Field } from './Field';
2
+ export type { FieldProps, FieldValidationState } from './Field';
@@ -0,0 +1,2 @@
1
+ import type { InputProps } from './Input.types';
2
+ export declare const Input: import("react").ForwardRefExoticComponent<InputProps & import("react").RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,18 @@
1
+ import type { InputHTMLAttributes, ReactNode } from 'react';
2
+ export type InputColor = 'primary' | 'danger' | 'warning' | 'success';
3
+ export type InputSize = 'sm' | 'md' | 'lg';
4
+ export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'prefix'> {
5
+ color?: InputColor;
6
+ /** Size modifier. `'md'` is the default (no class). */
7
+ size?: InputSize;
8
+ /** Icon / content placed inside the input, left of the text. */
9
+ prefix?: ReactNode;
10
+ /** Icon / content placed inside the input, right of the text. */
11
+ suffix?: ReactNode;
12
+ /** Show a clear button when the input has a value and is not disabled. */
13
+ clearable?: boolean;
14
+ /** Called when the clear button is clicked. */
15
+ onClear?: () => void;
16
+ /** Show a password-visibility toggle. Forces `type="password"` when hidden. */
17
+ showPasswordToggle?: boolean;
18
+ }
@@ -0,0 +1,2 @@
1
+ export { Input } from './Input';
2
+ export type { InputProps, InputColor } from './Input.types';
@@ -0,0 +1,19 @@
1
+ import type { ComponentPropsWithoutRef, ElementType, ForwardedRef, ReactElement } from 'react';
2
+ import type { LayoutProps } from './layout.types';
3
+ export type BoxProps<E extends ElementType = 'div'> = LayoutProps & Omit<ComponentPropsWithoutRef<E>, keyof LayoutProps> & {
4
+ as?: E;
5
+ };
6
+ /**
7
+ * Box — the universal layout primitive.
8
+ *
9
+ * Defaults to `<div>` but polymorphic via `as`. All layout props map to
10
+ * the utility classes in core, so styles stay predictable and debuggable
11
+ * in DevTools (no inline styles).
12
+ *
13
+ * @example
14
+ * <Box p={4} gap={2} direction="column">...</Box>
15
+ * <Box as="section" py={6} px={4}>...</Box>
16
+ */
17
+ export declare const Box: <E extends ElementType = "div">(props: BoxProps<E> & {
18
+ ref?: ForwardedRef<Element>;
19
+ }) => ReactElement;
@@ -0,0 +1,11 @@
1
+ import type { ElementType, ForwardedRef, ReactElement } from 'react';
2
+ import type { BoxProps } from './Box';
3
+ export type ContainerSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';
4
+ export type ContainerProps<E extends ElementType = 'div'> = Omit<BoxProps<E>, 'w'> & {
5
+ /** Max-width token. Default: `'lg'` (1024px). */
6
+ size?: ContainerSize;
7
+ };
8
+ /** Responsive max-width wrapper with centered horizontal inline padding. */
9
+ export declare const Container: <E extends ElementType = "div">(props: ContainerProps<E> & {
10
+ ref?: ForwardedRef<Element>;
11
+ }) => ReactElement;
@@ -0,0 +1,11 @@
1
+ import type { HTMLAttributes } from 'react';
2
+ export interface DividerProps extends Omit<HTMLAttributes<HTMLHRElement | HTMLSpanElement>, 'role'> {
3
+ /** Axis. Default: `'horizontal'`. */
4
+ orientation?: 'horizontal' | 'vertical';
5
+ }
6
+ /**
7
+ * Hairline divider. Renders `<hr>` when horizontal (no accessible name needed)
8
+ * and a semantic `<span role="separator" aria-orientation="vertical">` when
9
+ * vertical — `<hr>` is block-level and doesn't lay out inline.
10
+ */
11
+ export declare const Divider: import("react").ForwardRefExoticComponent<DividerProps & import("react").RefAttributes<HTMLElement>>;
@@ -0,0 +1,11 @@
1
+ import type { ElementType, ForwardedRef, ReactElement } from 'react';
2
+ import type { BoxProps } from './Box';
3
+ type GridCols = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
4
+ export type GridProps<E extends ElementType = 'div'> = Omit<BoxProps<E>, 'display' | 'direction'> & {
5
+ cols?: GridCols;
6
+ };
7
+ /** CSS Grid container. `cols` maps to `.grid-cols-{n}` utility. */
8
+ export declare const Grid: <E extends ElementType = "div">(props: GridProps<E> & {
9
+ ref?: ForwardedRef<Element>;
10
+ }) => ReactElement;
11
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { HTMLAttributes } from 'react';
2
+ export type SpacerProps = HTMLAttributes<HTMLSpanElement>;
3
+ /** Flexible filler — `flex: 1 1 auto`. Use inside a `<Row>` or `<Stack>`. */
4
+ export declare const Spacer: import("react").ForwardRefExoticComponent<SpacerProps & import("react").RefAttributes<HTMLSpanElement>>;
@@ -0,0 +1,12 @@
1
+ import type { ElementType, ForwardedRef, ReactElement } from 'react';
2
+ import type { BoxProps } from './Box';
3
+ export type StackProps<E extends ElementType = 'div'> = Omit<BoxProps<E>, 'direction' | 'display'>;
4
+ /** Vertical flex column with a gap. Default element: `<div>`. */
5
+ export declare const Stack: <E extends ElementType = "div">(props: StackProps<E> & {
6
+ ref?: ForwardedRef<Element>;
7
+ }) => ReactElement;
8
+ export type RowProps<E extends ElementType = 'div'> = Omit<BoxProps<E>, 'direction' | 'display'>;
9
+ /** Horizontal flex row with a gap. Default `align: 'center'`. */
10
+ export declare const Row: <E extends ElementType = "div">(props: RowProps<E> & {
11
+ ref?: ForwardedRef<Element>;
12
+ }) => ReactElement;
@@ -0,0 +1,13 @@
1
+ export { Box } from './Box';
2
+ export { Stack, Row } from './Stack';
3
+ export { Grid } from './Grid';
4
+ export { Container } from './Container';
5
+ export { Divider } from './Divider';
6
+ export { Spacer } from './Spacer';
7
+ export type { BoxProps } from './Box';
8
+ export type { StackProps, RowProps } from './Stack';
9
+ export type { GridProps } from './Grid';
10
+ export type { ContainerProps, ContainerSize } from './Container';
11
+ export type { DividerProps } from './Divider';
12
+ export type { SpacerProps } from './Spacer';
13
+ export type { Space, Align, Justify, Direction, Display, LayoutProps } from './layout.types';
@@ -0,0 +1,38 @@
1
+ import type { ElementType, ReactNode } from 'react';
2
+ /** Spacing scale token — maps 1:1 to `.p-{n}`, `.m-{n}`, `.gap-{n}` utilities. */
3
+ export type Space = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16;
4
+ export type Align = 'start' | 'center' | 'end' | 'stretch' | 'baseline';
5
+ export type Justify = 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';
6
+ export type Direction = 'row' | 'column' | 'row-reverse' | 'column-reverse';
7
+ export type Display = 'block' | 'inline-block' | 'flex' | 'inline-flex' | 'grid' | 'inline-grid' | 'none';
8
+ export interface LayoutProps {
9
+ /** Polymorphic render target. Defaults vary per component. */
10
+ as?: ElementType;
11
+ p?: Space;
12
+ px?: Space;
13
+ py?: Space;
14
+ pt?: Space;
15
+ pr?: Space;
16
+ pb?: Space;
17
+ pl?: Space;
18
+ m?: Space;
19
+ mx?: Space;
20
+ my?: Space;
21
+ mt?: Space;
22
+ mr?: Space;
23
+ mb?: Space;
24
+ ml?: Space;
25
+ gap?: Space;
26
+ gapX?: Space;
27
+ gapY?: Space;
28
+ display?: Display;
29
+ direction?: Direction;
30
+ align?: Align;
31
+ justify?: Justify;
32
+ wrap?: boolean;
33
+ w?: 'full' | 'auto' | 'fit';
34
+ h?: 'full' | 'auto' | 'fit';
35
+ children?: ReactNode;
36
+ }
37
+ /** Maps layout props to the utility class names emitted by core. */
38
+ export declare function layoutClasses(p: LayoutProps): (string | false | null | undefined)[];
@@ -0,0 +1,54 @@
1
+ import type { ReactNode } from 'react';
2
+ export type MultiSelectOption = {
3
+ value: string;
4
+ label: string;
5
+ /** Optional muted description shown next to the label. */
6
+ description?: string;
7
+ /** Optional icon rendered before the label. */
8
+ icon?: ReactNode;
9
+ /** Optional group label — items with the same group end up together. */
10
+ group?: string;
11
+ /** Prevent selection. */
12
+ disabled?: boolean;
13
+ };
14
+ export type MultiSelectSize = 'sm' | 'md' | 'lg';
15
+ export type MultiSelectColor = 'primary' | 'danger' | 'warning' | 'success';
16
+ export interface MultiSelectProps {
17
+ /** Flat list of options. `group` on each option produces sectioned dropdown. */
18
+ options: MultiSelectOption[];
19
+ /** Controlled selected values. */
20
+ value?: string[];
21
+ /** Uncontrolled initial selection. */
22
+ defaultValue?: string[];
23
+ /** Called when the selection changes. */
24
+ onValueChange?: (next: string[]) => void;
25
+ /** Shown inside the trigger when nothing is selected. */
26
+ placeholder?: string;
27
+ /** Placeholder inside the dropdown search input. */
28
+ searchPlaceholder?: string;
29
+ /** Empty-state text inside the dropdown. */
30
+ emptyText?: string;
31
+ /** Cap on how many can be selected. */
32
+ maxItems?: number;
33
+ /** Size of the trigger. */
34
+ size?: MultiSelectSize;
35
+ /** Validation color. */
36
+ color?: MultiSelectColor;
37
+ /** Disable the control. */
38
+ disabled?: boolean;
39
+ /** `id` for Field-threading. */
40
+ id?: string;
41
+ /** aria-invalid / aria-describedby threaded in from Field. */
42
+ 'aria-invalid'?: boolean;
43
+ 'aria-describedby'?: string;
44
+ /** aria-label for the combobox if no Field label is present. */
45
+ 'aria-label'?: string;
46
+ /** Extra class on the trigger. */
47
+ className?: string;
48
+ }
49
+ /**
50
+ * MultiSelect — a combobox with a searchable list and chip tokens for
51
+ * the selected values. Built on @radix-ui/react-popover (positioning +
52
+ * focus management) and cmdk (search + filtering).
53
+ */
54
+ export declare function MultiSelect({ options, value, defaultValue, onValueChange, placeholder, searchPlaceholder, emptyText, maxItems, size, color, disabled, id, className, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, 'aria-label': ariaLabel, }: MultiSelectProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { MultiSelect } from './MultiSelect';
2
+ export type { MultiSelectProps, MultiSelectOption, MultiSelectSize, MultiSelectColor, } from './MultiSelect';
@@ -0,0 +1,6 @@
1
+ import type { NavbarProps, NavbarBrandProps, NavbarNavProps, NavbarItemProps, NavbarActionsProps } from './Navbar.types';
2
+ export declare const Navbar: import("react").ForwardRefExoticComponent<NavbarProps & import("react").RefAttributes<HTMLElement>>;
3
+ export declare const NavbarBrand: import("react").ForwardRefExoticComponent<NavbarBrandProps & import("react").RefAttributes<HTMLAnchorElement>>;
4
+ export declare const NavbarNav: import("react").ForwardRefExoticComponent<NavbarNavProps & import("react").RefAttributes<HTMLElement>>;
5
+ export declare const NavbarItem: import("react").ForwardRefExoticComponent<NavbarItemProps & import("react").RefAttributes<HTMLAnchorElement>>;
6
+ export declare const NavbarActions: import("react").ForwardRefExoticComponent<NavbarActionsProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,19 @@
1
+ import type { AnchorHTMLAttributes, HTMLAttributes, ReactNode } from 'react';
2
+ export interface NavbarProps extends HTMLAttributes<HTMLElement> {
3
+ solid?: boolean;
4
+ children: ReactNode;
5
+ }
6
+ export interface NavbarBrandProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
7
+ mark?: boolean;
8
+ children: ReactNode;
9
+ }
10
+ export interface NavbarNavProps extends HTMLAttributes<HTMLElement> {
11
+ children: ReactNode;
12
+ }
13
+ export interface NavbarItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
14
+ active?: boolean;
15
+ children: ReactNode;
16
+ }
17
+ export interface NavbarActionsProps extends HTMLAttributes<HTMLDivElement> {
18
+ children: ReactNode;
19
+ }