@lettuceai/crisp 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 (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +130 -0
  3. package/dist/components/Accordion.d.ts +15 -0
  4. package/dist/components/ActionBar.d.ts +25 -0
  5. package/dist/components/Alert.d.ts +19 -0
  6. package/dist/components/AppBar.d.ts +29 -0
  7. package/dist/components/AppShell.d.ts +42 -0
  8. package/dist/components/AudioItem.d.ts +22 -0
  9. package/dist/components/Avatar.d.ts +11 -0
  10. package/dist/components/AvatarGroup.d.ts +17 -0
  11. package/dist/components/AvatarPicker.d.ts +20 -0
  12. package/dist/components/Badge.d.ts +8 -0
  13. package/dist/components/Banner.d.ts +17 -0
  14. package/dist/components/Breadcrumb.d.ts +23 -0
  15. package/dist/components/Button.d.ts +15 -0
  16. package/dist/components/ButtonGroup.d.ts +21 -0
  17. package/dist/components/Card.d.ts +16 -0
  18. package/dist/components/Carousel.d.ts +16 -0
  19. package/dist/components/CharacterCard.d.ts +30 -0
  20. package/dist/components/Chart.d.ts +35 -0
  21. package/dist/components/Checkbox.d.ts +11 -0
  22. package/dist/components/Chip.d.ts +11 -0
  23. package/dist/components/ChoiceCard.d.ts +22 -0
  24. package/dist/components/CodeBlock.d.ts +16 -0
  25. package/dist/components/Collapsible.d.ts +20 -0
  26. package/dist/components/ColorPicker.d.ts +15 -0
  27. package/dist/components/Combobox.d.ts +30 -0
  28. package/dist/components/CommandPalette.d.ts +34 -0
  29. package/dist/components/Composer.d.ts +49 -0
  30. package/dist/components/ContextMenu.d.ts +18 -0
  31. package/dist/components/CopyButton.d.ts +13 -0
  32. package/dist/components/DatePicker.d.ts +23 -0
  33. package/dist/components/Dialog.d.ts +15 -0
  34. package/dist/components/Diff.d.ts +17 -0
  35. package/dist/components/Dock.d.ts +6 -0
  36. package/dist/components/DownloadItem.d.ts +28 -0
  37. package/dist/components/Dropzone.d.ts +21 -0
  38. package/dist/components/EmptyState.d.ts +24 -0
  39. package/dist/components/Field.d.ts +20 -0
  40. package/dist/components/FilterBar.d.ts +21 -0
  41. package/dist/components/Form.d.ts +44 -0
  42. package/dist/components/Highlight.d.ts +14 -0
  43. package/dist/components/HoverCard.d.ts +15 -0
  44. package/dist/components/Icon.d.ts +37 -0
  45. package/dist/components/IconButton.d.ts +14 -0
  46. package/dist/components/ImageViewer.d.ts +16 -0
  47. package/dist/components/InfiniteScroll.d.ts +14 -0
  48. package/dist/components/Input.d.ts +14 -0
  49. package/dist/components/Kbd.d.ts +5 -0
  50. package/dist/components/List.d.ts +25 -0
  51. package/dist/components/Masonry.d.ts +16 -0
  52. package/dist/components/MediaCard.d.ts +23 -0
  53. package/dist/components/MediaTile.d.ts +21 -0
  54. package/dist/components/Menu.d.ts +34 -0
  55. package/dist/components/Message.d.ts +76 -0
  56. package/dist/components/Meter.d.ts +20 -0
  57. package/dist/components/ModelSelect.d.ts +35 -0
  58. package/dist/components/MultiItemDownloadCard.d.ts +39 -0
  59. package/dist/components/NavRail.d.ts +37 -0
  60. package/dist/components/NumberInput.d.ts +19 -0
  61. package/dist/components/Page.d.ts +18 -0
  62. package/dist/components/Pagination.d.ts +10 -0
  63. package/dist/components/Panel.d.ts +18 -0
  64. package/dist/components/PartitionBar.d.ts +39 -0
  65. package/dist/components/Popover.d.ts +45 -0
  66. package/dist/components/Progress.d.ts +9 -0
  67. package/dist/components/Prose.d.ts +13 -0
  68. package/dist/components/Radio.d.ts +19 -0
  69. package/dist/components/ReorderableList.d.ts +21 -0
  70. package/dist/components/Resizable.d.ts +20 -0
  71. package/dist/components/ScrollArea.d.ts +17 -0
  72. package/dist/components/SearchField.d.ts +14 -0
  73. package/dist/components/SecretInput.d.ts +26 -0
  74. package/dist/components/Segmented.d.ts +16 -0
  75. package/dist/components/Select.d.ts +15 -0
  76. package/dist/components/SelectMenu.d.ts +48 -0
  77. package/dist/components/Sheet.d.ts +50 -0
  78. package/dist/components/Shelf.d.ts +17 -0
  79. package/dist/components/Skeleton.d.ts +12 -0
  80. package/dist/components/Slider.d.ts +11 -0
  81. package/dist/components/Spinner.d.ts +13 -0
  82. package/dist/components/StatTile.d.ts +33 -0
  83. package/dist/components/Stepper.d.ts +21 -0
  84. package/dist/components/Surface.d.ts +56 -0
  85. package/dist/components/Switch.d.ts +9 -0
  86. package/dist/components/TabBar.d.ts +12 -0
  87. package/dist/components/Table.d.ts +35 -0
  88. package/dist/components/Tabs.d.ts +31 -0
  89. package/dist/components/TagInput.d.ts +18 -0
  90. package/dist/components/Text.d.ts +293 -0
  91. package/dist/components/ThemeEditor.d.ts +8 -0
  92. package/dist/components/Timeline.d.ts +17 -0
  93. package/dist/components/TitleBar.d.ts +17 -0
  94. package/dist/components/Toast.d.ts +50 -0
  95. package/dist/components/ToggleGroup.d.ts +22 -0
  96. package/dist/components/Toolbar.d.ts +18 -0
  97. package/dist/components/Tooltip.d.ts +15 -0
  98. package/dist/components/Tour.d.ts +22 -0
  99. package/dist/components/Tree.d.ts +21 -0
  100. package/dist/components/VirtualList.d.ts +18 -0
  101. package/dist/components/WindowControls.d.ts +38 -0
  102. package/dist/components/Wizard.d.ts +33 -0
  103. package/dist/components/confirm.d.ts +24 -0
  104. package/dist/components/index.d.ts +103 -0
  105. package/dist/components/nav.d.ts +19 -0
  106. package/dist/components/primitives.d.ts +14 -0
  107. package/dist/index.d.ts +15 -0
  108. package/dist/index.js +8035 -0
  109. package/dist/index.js.map +1 -0
  110. package/dist/layout/Box.d.ts +6 -0
  111. package/dist/layout/Center.d.ts +2 -0
  112. package/dist/layout/Container.d.ts +8 -0
  113. package/dist/layout/Divider.d.ts +9 -0
  114. package/dist/layout/Flex.d.ts +16 -0
  115. package/dist/layout/Grid.d.ts +13 -0
  116. package/dist/layout/Spacer.d.ts +4 -0
  117. package/dist/layout/Stack.d.ts +13 -0
  118. package/dist/layout/index.d.ts +8 -0
  119. package/dist/lib/cn.d.ts +2 -0
  120. package/dist/lib/color.d.ts +16 -0
  121. package/dist/lib/format.d.ts +6 -0
  122. package/dist/lib/frame.d.ts +25 -0
  123. package/dist/lib/icon.d.ts +24 -0
  124. package/dist/lib/imageBrightness.d.ts +8 -0
  125. package/dist/lib/motion.d.ts +54 -0
  126. package/dist/lib/polymorphic.d.ts +12 -0
  127. package/dist/lib/tint.d.ts +9 -0
  128. package/dist/lib/useLongPress.d.ts +19 -0
  129. package/dist/lib/useMediaQuery.d.ts +8 -0
  130. package/dist/lib/useModal.d.ts +8 -0
  131. package/dist/theme/ThemeProvider.d.ts +19 -0
  132. package/dist/theme/index.d.ts +2 -0
  133. package/dist/theme/theme.d.ts +36 -0
  134. package/package.json +81 -0
  135. package/src/styles.css +392 -0
@@ -0,0 +1,6 @@
1
+ import type { PolymorphicComponent } from "../lib/polymorphic";
2
+ /**
3
+ * The root primitive. A `div` by default; `as` swaps the element, `className` styles it.
4
+ * Styling is Tailwind classes, not style props — that keeps one styling language across the codebase.
5
+ */
6
+ export declare const Box: PolymorphicComponent<"div">;
@@ -0,0 +1,2 @@
1
+ import type { PolymorphicComponent } from "../lib/polymorphic";
2
+ export declare const Center: PolymorphicComponent<"div">;
@@ -0,0 +1,8 @@
1
+ import type { PolymorphicComponent } from "../lib/polymorphic";
2
+ export interface ContainerOwnProps {
3
+ /** sm 640 · md 768 · lg 1024 · xl 1280 · prose 65ch (reading column) */
4
+ size?: "sm" | "md" | "lg" | "xl" | "prose";
5
+ /** Drop the horizontal padding — for containers nested in something already padded. */
6
+ flush?: boolean;
7
+ }
8
+ export declare const Container: PolymorphicComponent<"div", ContainerOwnProps>;
@@ -0,0 +1,9 @@
1
+ import { type HTMLAttributes, type ReactNode } from "react";
2
+ export interface DividerProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
3
+ orientation?: "horizontal" | "vertical";
4
+ /** Text set into the line — "or", a date, a section name. */
5
+ label?: ReactNode;
6
+ /** Vertical rhythm around a horizontal divider. */
7
+ spacing?: "none" | "sm" | "md" | "lg";
8
+ }
9
+ export declare const Divider: import("react").ForwardRefExoticComponent<DividerProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,16 @@
1
+ import type { PolymorphicComponent } from "../lib/polymorphic";
2
+ export type Gap = 0 | 0.5 | 1 | 1.5 | 2 | 2.5 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16;
3
+ export type Align = "start" | "center" | "end" | "stretch" | "baseline";
4
+ export type Justify = "start" | "center" | "end" | "between" | "around" | "evenly";
5
+ export declare const gapClass: Record<Gap, string>;
6
+ export declare const alignClass: Record<Align, string>;
7
+ export declare const justifyClass: Record<Justify, string>;
8
+ export interface FlexOwnProps {
9
+ direction?: "row" | "column" | "row-reverse" | "column-reverse";
10
+ align?: Align;
11
+ justify?: Justify;
12
+ wrap?: boolean;
13
+ gap?: Gap;
14
+ inline?: boolean;
15
+ }
16
+ export declare const Flex: PolymorphicComponent<"div", FlexOwnProps>;
@@ -0,0 +1,13 @@
1
+ import type { PolymorphicComponent } from "../lib/polymorphic";
2
+ import { type Gap } from "./Flex";
3
+ export type Columns = 1 | 2 | 3 | 4 | 5 | 6 | 12;
4
+ export type Breakpoint = "base" | "sm" | "md" | "lg" | "xl";
5
+ export type ResponsiveColumns = Columns | Partial<Record<Breakpoint, Columns>>;
6
+ export interface GridOwnProps {
7
+ /** A number, or per-breakpoint: `{ base: 1, sm: 2, lg: 3 }`. */
8
+ columns?: ResponsiveColumns;
9
+ gap?: Gap;
10
+ /** Auto-fit columns with a minimum track width — for card grids that should just flow. */
11
+ minChildWidth?: string;
12
+ }
13
+ export declare const Grid: PolymorphicComponent<"div", GridOwnProps>;
@@ -0,0 +1,4 @@
1
+ /** Fills the free space in a Flex/HStack so siblings push to the edges. */
2
+ export declare function Spacer({ className }: {
3
+ className?: string;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,13 @@
1
+ import type { PolymorphicComponent } from "../lib/polymorphic";
2
+ import { type Align, type Gap, type Justify } from "./Flex";
3
+ export interface StackOwnProps {
4
+ gap?: Gap;
5
+ align?: Align;
6
+ justify?: Justify;
7
+ wrap?: boolean;
8
+ }
9
+ /** Vertical rhythm. Children stretch to full width. */
10
+ export declare const Stack: PolymorphicComponent<"div", StackOwnProps>;
11
+ export declare const VStack: PolymorphicComponent<"div", StackOwnProps>;
12
+ /** Horizontal row with vertically centred children. */
13
+ export declare const HStack: PolymorphicComponent<"div", StackOwnProps>;
@@ -0,0 +1,8 @@
1
+ export * from "./Box";
2
+ export * from "./Center";
3
+ export * from "./Container";
4
+ export * from "./Divider";
5
+ export * from "./Flex";
6
+ export * from "./Grid";
7
+ export * from "./Spacer";
8
+ export * from "./Stack";
@@ -0,0 +1,2 @@
1
+ import { type ClassValue } from "clsx";
2
+ export declare function cn(...inputs: ClassValue[]): string;
@@ -0,0 +1,16 @@
1
+ /** Colour helpers. Deriving is left to CSS `color-mix`; this is only the maths CSS can't do. */
2
+ export declare function hexToRgb(hex: string): {
3
+ r: number;
4
+ g: number;
5
+ b: number;
6
+ } | null;
7
+ export declare function normaliseHex(input: string): string | null;
8
+ /** WCAG relative luminance. */
9
+ export declare function luminance(hex: string): number;
10
+ /** WCAG contrast ratio, 1–21. Body text wants 4.5, large text and UI edges 3. */
11
+ export declare function contrastRatio(a: string, b: string): number;
12
+ export declare function isLight(hex: string): boolean;
13
+ /** Black or white, whichever is readable on the given background. */
14
+ export declare function readableOn(background: string): string;
15
+ /** Blend two hex colours in sRGB. Used where a literal value is needed, not a var. */
16
+ export declare function mixHex(a: string, b: string, amount: number): string;
@@ -0,0 +1,6 @@
1
+ /** "Just now", "4 min ago", "Yesterday", "3 wk ago" — how a list says when. */
2
+ export declare function relativeTime(when: Date | number, now?: Date | number): string;
3
+ /** 950 → "950", 1 240 → "1.2k", 18 300 → "18k", 2 140 000 → "2.1M". */
4
+ export declare function compactNumber(n: number): string;
5
+ /** 1 536 000 → "1.5 MB". */
6
+ export declare function fileSize(bytes: number): string;
@@ -0,0 +1,25 @@
1
+ import { type ReactNode } from "react";
2
+ interface FrameValue {
3
+ /** Where overlays portal to. `null` is the document body — the real app. */
4
+ portal: HTMLElement | null;
5
+ /** Force the phone or desktop layout for this subtree, whatever the viewport says. */
6
+ compact?: boolean;
7
+ }
8
+ /**
9
+ * Runs a piece of the app inside a device frame on the lab page: overlays open inside
10
+ * the frame instead of at the bottom of the browser window, and layout decisions follow
11
+ * the device being simulated rather than the monitor it is being viewed on.
12
+ *
13
+ * The element passed as `portal` must establish a containing block for fixed-position
14
+ * descendants (a `transform` does it), or sheets will still pin to the viewport.
15
+ *
16
+ * The real app never mounts this. Every hook falls back to the document and the
17
+ * viewport, so components written against it behave identically outside a frame.
18
+ */
19
+ export declare function FrameProvider({ portal, compact, children }: FrameValue & {
20
+ children: ReactNode;
21
+ }): import("react").JSX.Element;
22
+ export declare function useFrame(): FrameValue;
23
+ /** The node overlays should portal into. */
24
+ export declare function usePortalTarget(): HTMLElement | null;
25
+ export {};
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The icon ladder. Five steps, mapped to what an icon sits next to, so nobody has to
3
+ * pick a number again.
4
+ *
5
+ * Before this file Crisp had eleven sizes in use — 10, 11, 12, 13, 14, 15, 16, 17, 18,
6
+ * 20, 22 — which is the same drift the README criticises the app for. Fifteen next to
7
+ * sixteen is a difference nobody sees and everybody maintains.
8
+ *
9
+ * Type, spacing, radius, density and motion all went through a scale. This is the one
10
+ * axis that never did.
11
+ */
12
+ export declare const icon: {
13
+ /** Inline with 11–12px meta: a pin beside a timestamp, a dot in a badge. */
14
+ readonly xs: 12;
15
+ /** Small controls and dense rows — `sm` buttons, chips, clear buttons. */
16
+ readonly sm: 14;
17
+ /** The default. `md` controls, menu items, inputs, a chevron. */
18
+ readonly md: 16;
19
+ /** `lg` controls, the icon tile in a list row, toolbars, nav destinations. */
20
+ readonly lg: 18;
21
+ /** Standing alone with no label: empty states, a composer's primary action. */
22
+ readonly xl: 20;
23
+ };
24
+ export type IconSize = keyof typeof icon;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Mean relative luminance of an image, 0–1. Sampled at 12×12 — enough to tell a lit
3
+ * room from a dark one, cheap enough to run on every background change.
4
+ *
5
+ * Returns `null` while loading, or if the canvas is tainted by a cross-origin image.
6
+ * Callers must treat `null` as "unknown" and keep a safe default, never guess bright.
7
+ */
8
+ export declare function useImageBrightness(src?: string | null): number | null;
@@ -0,0 +1,54 @@
1
+ import type { Transition } from "framer-motion";
2
+ /**
3
+ * Every animation in Crisp goes through one of these. Before this file there were
4
+ * seven durations and six springs scattered inline — the same drift the app has with
5
+ * fifteen icon sizes, just in milliseconds.
6
+ *
7
+ * Pick by what the motion is *for*, not by how long it should take.
8
+ */
9
+ /** Something swapped in place: an icon, a tooltip, a popover, a context menu. */
10
+ export declare const instant: Transition;
11
+ /** Something appeared or resolved: a fade, a disclosure, a dialog. */
12
+ export declare const quick: Transition;
13
+ /** Something travelled: a progress bar, a large reveal. */
14
+ export declare const slow: Transition;
15
+ /** A small control snapping to a new position: a switch knob. */
16
+ export declare const snap: Transition;
17
+ /** A moving indicator settling: active tab, segmented control, stepper. */
18
+ export declare const settle: Transition;
19
+ /** A large surface arriving: sheets, panels, spotlight. */
20
+ export declare const surface: Transition;
21
+ /** Easing for height and layout changes, where a spring would overshoot. */
22
+ export declare const easeOut: readonly [0.25, 1, 0.5, 1];
23
+ /** Collapsing and expanding, which must not overshoot or the content clips. */
24
+ export declare const collapse: Transition;
25
+ /** A sheet presenting from an edge. Covers the distance quickly, lands without a wobble. */
26
+ export declare const sheetIn: Transition;
27
+ /** A sheet dismissed. Faster than it came, and it never bounces on the way out. */
28
+ export declare const sheetOut: Transition;
29
+ /** A sheet let go short of closing. Returns from the speed it was thrown at, and stops
30
+ at its resting place — an overshoot there would lift it off the edge. */
31
+ export declare const sheetSettle: Transition;
32
+ /** A side panel widening or folding back. No overshoot: the content beside it reflows
33
+ with it, and a bounce would shake every line of text twice. */
34
+ export declare const sidebar: Transition;
35
+ /** A dragged card letting go and returning to rest. Stiff, so it snaps rather than drifts. */
36
+ export declare const rebound: Transition;
37
+ /** A looping ambient cycle — the typing indicator. Not a transition; it never resolves. */
38
+ export declare const pulse: Transition;
39
+ export declare const motion: {
40
+ readonly instant: Transition;
41
+ readonly quick: Transition;
42
+ readonly slow: Transition;
43
+ readonly snap: Transition;
44
+ readonly settle: Transition;
45
+ readonly surface: Transition;
46
+ readonly sheetIn: Transition;
47
+ readonly sheetOut: Transition;
48
+ readonly sheetSettle: Transition;
49
+ readonly sidebar: Transition;
50
+ readonly rebound: Transition;
51
+ readonly collapse: Transition;
52
+ readonly pulse: Transition;
53
+ readonly easeOut: readonly [0.25, 1, 0.5, 1];
54
+ };
@@ -0,0 +1,12 @@
1
+ import type { ComponentPropsWithoutRef, ComponentPropsWithRef, ElementType, PropsWithChildren } from "react";
2
+ type AsProp<C extends ElementType> = {
3
+ as?: C;
4
+ };
5
+ type PropsToOmit<C extends ElementType, P> = keyof (AsProp<C> & P);
6
+ /** Props for a component that can render as any element via `as`, keeping that element's own props. */
7
+ export type PolymorphicProps<C extends ElementType, Props = object> = PropsWithChildren<Props & AsProp<C>> & Omit<ComponentPropsWithoutRef<C>, PropsToOmit<C, Props>>;
8
+ export type PolymorphicRef<C extends ElementType> = ComponentPropsWithRef<C>["ref"];
9
+ export type PolymorphicComponent<DefaultTag extends ElementType, Props = object> = <C extends ElementType = DefaultTag>(props: PolymorphicProps<C, Props> & {
10
+ ref?: PolymorphicRef<C>;
11
+ }) => React.ReactElement | null;
12
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Deterministic tint from a name, used as the backdrop when an item has no image.
3
+ * The app derives this from the avatar's own colours; the fallback only has to be
4
+ * stable, so the same character always looks the same.
5
+ */
6
+ export declare function tintFromName(name: string): {
7
+ hue: number;
8
+ background: string;
9
+ };
@@ -0,0 +1,19 @@
1
+ import type { MouseEvent, PointerEvent } from "react";
2
+ /**
3
+ * Long-press (and right-click) on a button, without swallowing the normal click.
4
+ * Returns handlers to spread on the element.
5
+ */
6
+ export declare function useLongPress(onLongPress: (() => void) | undefined, { delay, enabled }?: {
7
+ delay?: number | undefined;
8
+ enabled?: boolean | undefined;
9
+ }): {
10
+ handlers: {
11
+ onPointerDown: (event: PointerEvent<HTMLElement>) => void;
12
+ onPointerMove: (event: PointerEvent<HTMLElement>) => void;
13
+ onPointerUp: () => void;
14
+ onPointerLeave: () => void;
15
+ onPointerCancel: () => void;
16
+ onContextMenu: (event: MouseEvent<HTMLElement>) => void;
17
+ };
18
+ guardClick: (handler: () => void) => (event: MouseEvent<HTMLElement>) => void;
19
+ };
@@ -0,0 +1,8 @@
1
+ /** Subscribes to a media query. SSR-safe: returns `false` on the server. */
2
+ export declare function useMediaQuery(query: string): boolean;
3
+ /**
4
+ * "Is this a touch-first, phone-sized viewport?"
5
+ * Width alone is wrong (a small desktop window still has a mouse) and pointer alone
6
+ * is wrong (a Surface has both), so we ask for narrow OR coarse.
7
+ */
8
+ export declare function useCompactLayout(): boolean;
@@ -0,0 +1,8 @@
1
+ import { type RefObject } from "react";
2
+ /**
3
+ * Shared modal behaviour for Sheet and Dialog: Escape closes, body scroll locks,
4
+ * focus moves inside on open and returns to the opener on close.
5
+ */
6
+ export declare function useModal(open: boolean, onClose: () => void, panelRef: RefObject<HTMLElement | null>, { lockScroll }?: {
7
+ lockScroll?: boolean;
8
+ }): void;
@@ -0,0 +1,19 @@
1
+ import { type ReactNode } from "react";
2
+ import { type Theme, type ThemeColors, type ThemeDensity, type ThemeRadius } from "./theme";
3
+ interface ThemeContextValue {
4
+ theme: Theme;
5
+ presets: readonly Theme[];
6
+ setTheme: (theme: Theme) => void;
7
+ /** Change one colour and repaint immediately — this is the live-editing path. */
8
+ setColor: (key: keyof ThemeColors, value: string) => void;
9
+ setRadius: (radius: ThemeRadius) => void;
10
+ setDensity: (density: ThemeDensity) => void;
11
+ reset: () => void;
12
+ isCustom: boolean;
13
+ }
14
+ export declare function useTheme(): ThemeContextValue;
15
+ export declare function ThemeProvider({ children, initial }: {
16
+ children: ReactNode;
17
+ initial?: Theme;
18
+ }): import("react").JSX.Element;
19
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from "./theme";
2
+ export * from "./ThemeProvider";
@@ -0,0 +1,36 @@
1
+ /**
2
+ * A theme is a handful of source colours. Everything else — the four text tiers, the
3
+ * three fills, the three lines, the elevated and nav surfaces — is derived, so changing
4
+ * one value re-colours the whole app consistently instead of leaving half of it behind.
5
+ */
6
+ export interface ThemeColors {
7
+ /** The page. Decides light vs dark on its own. */
8
+ surface: string;
9
+ /** Text and everything tinted from it: fills, lines, the muted tiers. */
10
+ fg: string;
11
+ accent: string;
12
+ danger: string;
13
+ warning: string;
14
+ info: string;
15
+ secondary: string;
16
+ /** Navigation and title bars. Defaults to the elevated surface. */
17
+ nav?: string;
18
+ }
19
+ export type ThemeRadius = "sharp" | "default" | "round";
20
+ export type ThemeDensity = "default" | "compact";
21
+ export interface Theme {
22
+ id: string;
23
+ name: string;
24
+ colors: ThemeColors;
25
+ radius?: ThemeRadius;
26
+ density?: ThemeDensity;
27
+ }
28
+ /**
29
+ * Turns a theme into the CSS custom properties the components read.
30
+ * Tiers mix toward `transparent` rather than the surface colour, so the same formula
31
+ * works on a flat background, over a photo, and inside a gradient card.
32
+ */
33
+ export declare function themeToVars(theme: Theme): Record<string, string>;
34
+ export declare function applyTheme(theme: Theme, target?: HTMLElement): void;
35
+ export declare const PRESETS: readonly Theme[];
36
+ export declare const DEFAULT_THEME: Theme;
package/package.json ADDED
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "@lettuceai/crisp",
3
+ "version": "1.0.0",
4
+ "description": "React components, design tokens and motion for LettuceAI.",
5
+ "keywords": [
6
+ "react",
7
+ "design-system",
8
+ "component-library",
9
+ "tailwindcss",
10
+ "framer-motion",
11
+ "typescript",
12
+ "design-tokens",
13
+ "cross-platform"
14
+ ],
15
+ "license": "MIT",
16
+ "homepage": "https://github.com/LettuceAI/crisp#readme",
17
+ "bugs": {
18
+ "url": "https://github.com/LettuceAI/crisp/issues"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/LettuceAI/crisp"
23
+ },
24
+ "type": "module",
25
+ "files": [
26
+ "dist",
27
+ "src/styles.css"
28
+ ],
29
+ "sideEffects": [
30
+ "**/*.css"
31
+ ],
32
+ "main": "./dist/index.js",
33
+ "module": "./dist/index.js",
34
+ "types": "./dist/index.d.ts",
35
+ "exports": {
36
+ ".": {
37
+ "types": "./dist/index.d.ts",
38
+ "import": "./dist/index.js"
39
+ },
40
+ "./styles.css": "./src/styles.css"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public",
44
+ "provenance": true
45
+ },
46
+ "scripts": {
47
+ "build": "vite build && tsc -p tsconfig.build.json",
48
+ "typecheck": "tsc -p tsconfig.json --noEmit",
49
+ "lint": "oxlint src",
50
+ "prepublishOnly": "bun run build"
51
+ },
52
+ "peerDependencies": {
53
+ "framer-motion": ">=12",
54
+ "lucide-react": ">=1",
55
+ "react": ">=19",
56
+ "react-dom": ">=19",
57
+ "tailwindcss": ">=4"
58
+ },
59
+ "dependencies": {
60
+ "@tanstack/react-virtual": "^3.14.11",
61
+ "clsx": "^2.1.1",
62
+ "react-markdown": "^10.1.0",
63
+ "recharts": "^3.10.1",
64
+ "remark-gfm": "^4.0.1",
65
+ "sonner": "^2.0.8",
66
+ "tailwind-merge": "^3.6.0"
67
+ },
68
+ "devDependencies": {
69
+ "@types/react": "^19.2.18",
70
+ "@types/react-dom": "^19.2.4",
71
+ "@vitejs/plugin-react": "^6.1.0",
72
+ "framer-motion": "^13.2.0",
73
+ "lucide-react": "^1.43.0",
74
+ "oxlint": "^1.79.0",
75
+ "react": "^19.2.8",
76
+ "react-dom": "^19.2.8",
77
+ "tailwindcss": "^4.3.3",
78
+ "typescript": "~6.0.2",
79
+ "vite": "^8.2.2"
80
+ }
81
+ }