@tanishqkancharla/maui 0.0.2 → 0.0.3

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 (39) hide show
  1. package/README.md +51 -2
  2. package/dist/components/Button.js +1 -0
  3. package/dist/components/Code.d.ts +5 -0
  4. package/dist/components/Code.js +35 -0
  5. package/dist/components/Icons.d.ts +8 -0
  6. package/dist/components/Icons.js +16 -0
  7. package/dist/components/Input.js +2 -0
  8. package/dist/components/Select.js +1 -0
  9. package/dist/maui.d.ts +1 -0
  10. package/dist/maui.js +1 -0
  11. package/dist/tokens/background.d.ts +0 -1
  12. package/dist/tokens/background.js +0 -1
  13. package/package.json +4 -2
  14. package/skills/maui/SKILL.md +16 -20
  15. package/src/apps/Calendar/Calendar.tsx +1774 -0
  16. package/src/components/Button.tsx +1 -0
  17. package/src/components/Code.tsx +61 -0
  18. package/src/components/Icons.tsx +109 -0
  19. package/src/components/Input.tsx +2 -0
  20. package/src/components/Select.tsx +1 -0
  21. package/src/dev/AgentationDev.tsx +11 -0
  22. package/src/index.html +4 -4
  23. package/src/index.tsx +15 -2
  24. package/src/maui.ts +1 -0
  25. package/src/pages/BackgroundColorTokenPage.tsx +4 -13
  26. package/src/pages/BordersTokenPage.tsx +1 -1
  27. package/src/pages/CalendarPage.tsx +37 -0
  28. package/src/pages/{CodeBlockPage.tsx → CodePage.tsx} +39 -9
  29. package/src/pages/Maui.tsx +17 -6
  30. package/src/pages/ShadowTokenPage.tsx +1 -1
  31. package/src/patterns/Sidebar.tsx +2 -2
  32. package/src/public/apple-touch-icon.png +0 -0
  33. package/src/public/favicon-dark.png +0 -0
  34. package/src/public/favicon-light.png +0 -0
  35. package/src/public/favicon.svg +1 -1
  36. package/src/tokens/background.ts +0 -1
  37. package/src/vite-env.d.ts +1 -0
  38. package/src/pages/TreePage.tsx +0 -156
  39. package/src/patterns/Tree.tsx +0 -354
package/README.md CHANGED
@@ -1,6 +1,55 @@
1
- Frontend app boilerplate built with esbuild, typescript, vercel.
1
+ # Maui
2
2
 
3
+ TypeScript-first design system styled with [`purse-styles`](https://www.npmjs.com/package/purse-styles). This repo is the published package and a gallery of tokens, components, patterns, and demo apps.
4
+
5
+ **Gallery:** [maui.tanishqkancharla.dev](https://maui.tanishqkancharla.dev)
6
+ **Package:** [`@tanishqkancharla/maui`](https://www.npmjs.com/package/@tanishqkancharla/maui)
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install @tanishqkancharla/maui
3
12
  ```
13
+
14
+ Wrap the app in `MauiProvider`, then import tokens and components:
15
+
16
+ ```tsx
17
+ import { MauiProvider, Button } from "@tanishqkancharla/maui"
18
+
19
+ function App() {
20
+ return (
21
+ <MauiProvider>
22
+ <Button>Hello</Button>
23
+ </MauiProvider>
24
+ )
25
+ }
26
+ ```
27
+
28
+ Put the exported `themeFoucScript` in a classic inline `<script>` in `<head>` so `data-theme` is correct on first paint.
29
+
30
+ ## Develop
31
+
32
+ ```bash
33
+ npm install
4
34
  npm run dev
5
- npm run build
6
35
  ```
36
+
37
+ Vite serves the gallery at [http://localhost:5173/](http://localhost:5173/).
38
+
39
+ | Script | What it does |
40
+ | --- | --- |
41
+ | `npm run dev` | Gallery dev server |
42
+ | `npm run build` | Static gallery → `website/` |
43
+ | `npm run build:lib` | Package ESM + types → `dist/` |
44
+ | `npm run serve` | Preview the gallery build |
45
+ | `npx tsc --noEmit` | Type-check |
46
+
47
+ ## Package
48
+
49
+ Published as [`@tanishqkancharla/maui`](https://www.npmjs.com/package/@tanishqkancharla/maui). The barrel exports the provider, theme, tokens, and components. Patterns and demo apps in this repo are reference implementations, not part of the package barrel.
50
+
51
+ Agent conventions for consuming Maui: [`skills/maui`](./skills/maui/SKILL.md).
52
+
53
+ ## License
54
+
55
+ MIT
@@ -18,6 +18,7 @@ const buttonBaseClass = style(text("xs", 400, "highContrast"), focusRing("&:focu
18
18
  gap: spacing.value(3),
19
19
  borderRadius: "4px",
20
20
  width: "fit-content",
21
+ height: "28px",
21
22
  border: "none",
22
23
  textOverflow: "ellipsis",
23
24
  overflow: "hidden",
@@ -0,0 +1,5 @@
1
+ import type React from "react";
2
+ type CodeProps = React.HTMLAttributes<HTMLElement>;
3
+ export declare function Code({ className, children, ...props }: CodeProps): React.JSX.Element;
4
+ export declare function Kbd({ className, children, ...props }: CodeProps): React.JSX.Element;
5
+ export {};
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { style, useStyles } from "purse-styles";
3
+ import { colors } from "../tokens/colors";
4
+ import { radius } from "../tokens/radius";
5
+ import { spacing } from "../tokens/spacing";
6
+ import { monospace, text } from "../tokens/text";
7
+ const codeClass = style(monospace, radius.sm, spacing.padding({ x: 2, y: 1 }), {
8
+ backgroundColor: colors.gray[3],
9
+ color: colors.gray[12],
10
+ display: "inline",
11
+ boxDecorationBreak: "clone",
12
+ fontSize: "0.875em",
13
+ whiteSpace: "nowrap",
14
+ });
15
+ const kbdClass = style(text("xs", 400, "lowContrast"), radius.sm, {
16
+ backgroundColor: colors.gray[3],
17
+ boxDecorationBreak: "clone",
18
+ display: "inline-flex",
19
+ alignItems: "center",
20
+ justifyContent: "center",
21
+ paddingInline: 3,
22
+ paddingBlock: 0,
23
+ whiteSpace: "nowrap",
24
+ });
25
+ export function Code({ className, children, ...props }) {
26
+ const codeClassName = useStyles(codeClass);
27
+ return (_jsx("code", { ...props, className: joinClassNames(codeClassName, className), children: children }));
28
+ }
29
+ export function Kbd({ className, children, ...props }) {
30
+ const kbdClassName = useStyles(kbdClass);
31
+ return (_jsx("kbd", { ...props, className: joinClassNames(kbdClassName, className), children: children }));
32
+ }
33
+ function joinClassNames(...classNames) {
34
+ return classNames.filter(Boolean).join(" ");
35
+ }
@@ -12,6 +12,10 @@ declare function Trash(props: React.SVGProps<SVGSVGElement>): React.JSX.Element;
12
12
  declare function Envelope(props: React.SVGProps<SVGSVGElement>): React.JSX.Element;
13
13
  declare function Clock(props: React.SVGProps<SVGSVGElement>): React.JSX.Element;
14
14
  declare function Pin(props: React.SVGProps<SVGSVGElement>): React.JSX.Element;
15
+ declare function ChevronLeft(props: React.SVGProps<SVGSVGElement>): React.JSX.Element;
16
+ declare function ChevronRight(props: React.SVGProps<SVGSVGElement>): React.JSX.Element;
17
+ declare function Eye(props: React.SVGProps<SVGSVGElement>): React.JSX.Element;
18
+ declare function Sidebar(props: React.SVGProps<SVGSVGElement>): React.JSX.Element;
15
19
  export declare const Icons: {
16
20
  Search: typeof Search;
17
21
  CircleX: typeof CircleX;
@@ -26,5 +30,9 @@ export declare const Icons: {
26
30
  Envelope: typeof Envelope;
27
31
  Clock: typeof Clock;
28
32
  Pin: typeof Pin;
33
+ ChevronLeft: typeof ChevronLeft;
34
+ ChevronRight: typeof ChevronRight;
35
+ Eye: typeof Eye;
36
+ Sidebar: typeof Sidebar;
29
37
  };
30
38
  export {};
@@ -39,6 +39,18 @@ function Clock(props) {
39
39
  function Pin(props) {
40
40
  return (_jsxs("svg", { focusable: "false", "aria-hidden": "true", role: "img", width: 24, height: 24, fill: "none", viewBox: "0 0 24 24", ...props, children: [_jsx("path", { stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.8, d: "M14.83 4.34L19.66 9.17C20.44 9.95 20.44 11.22 19.66 12L17.83 13.83L10.17 6.17L12 4.34C12.78 3.56 14.05 3.56 14.83 4.34Z" }), _jsx("path", { stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.8, d: "M13.5 10.5L6 18M9.5 14.5L4.75 19.25" })] }));
41
41
  }
42
+ function ChevronLeft(props) {
43
+ return (_jsx("svg", { focusable: "false", "aria-hidden": "true", role: "img", width: 24, height: 24, fill: "none", viewBox: "0 0 24 24", ...props, children: _jsx("path", { stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M14.25 5.75L8.75 12L14.25 18.25" }) }));
44
+ }
45
+ function ChevronRight(props) {
46
+ return (_jsx("svg", { focusable: "false", "aria-hidden": "true", role: "img", width: 24, height: 24, fill: "none", viewBox: "0 0 24 24", ...props, children: _jsx("path", { stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M9.75 5.75L15.25 12L9.75 18.25" }) }));
47
+ }
48
+ function Eye(props) {
49
+ return (_jsxs("svg", { focusable: "false", "aria-hidden": "true", role: "img", width: 24, height: 24, fill: "none", viewBox: "0 0 24 24", ...props, children: [_jsx("path", { stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3.75 12C5.5 8.75 8.4 6.75 12 6.75C15.6 6.75 18.5 8.75 20.25 12C18.5 15.25 15.6 17.25 12 17.25C8.4 17.25 5.5 15.25 3.75 12Z" }), _jsx("circle", { cx: "12", cy: "12", r: "2.25", stroke: "currentColor", strokeWidth: 1.5 })] }));
50
+ }
51
+ function Sidebar(props) {
52
+ return (_jsxs("svg", { focusable: "false", "aria-hidden": "true", role: "img", width: 24, height: 24, fill: "none", viewBox: "0 0 24 24", ...props, children: [_jsx("path", { stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M5.75 5.75H18.25V18.25H5.75V5.75Z" }), _jsx("path", { stroke: "currentColor", strokeLinecap: "round", strokeWidth: 1.5, d: "M9.25 5.75V18.25" })] }));
53
+ }
42
54
  export const Icons = {
43
55
  Search,
44
56
  CircleX,
@@ -53,4 +65,8 @@ export const Icons = {
53
65
  Envelope,
54
66
  Clock,
55
67
  Pin,
68
+ ChevronLeft,
69
+ ChevronRight,
70
+ Eye,
71
+ Sidebar,
56
72
  };
@@ -17,6 +17,7 @@ const numberFieldDivider = `color-mix(in oklch, ${colors.gray[12]} 5%, ${backgro
17
17
  const inputClass = style(inputText, focusRing("&:focus-visible", shadowVars.subtle), motion.standard("background", "border-color"), radius.sm, spacing.padding({ x: 4, y: 2 }), shadow.subtle, {
18
18
  width: "100%",
19
19
  minWidth: 0,
20
+ height: "28px",
20
21
  color: colors.gray[12],
21
22
  border: "none",
22
23
  background: backgroundColor.element,
@@ -167,6 +168,7 @@ export function NumberField(props) {
167
168
  const quietInputClass = style(inputText, focusRing(), motion.standard("background", "border-color"), radius.sm, spacing.padding({ x: 4, y: 2 }), {
168
169
  width: "100%",
169
170
  minWidth: 0,
171
+ height: "28px",
170
172
  color: colors.gray[12],
171
173
  background: "transparent",
172
174
  border: "none",
@@ -21,6 +21,7 @@ const selectClass = style({
21
21
  const triggerClass = style(text("sm", 400, "highContrast"), focusRing("&:focus-visible", shadowVars.subtle), motion.standard("background", "border-color"), radius.sm, spacing.padding({ x: 4, y: 2 }), shadow.subtle, {
22
22
  display: "flex",
23
23
  alignItems: "center",
24
+ height: "28px",
24
25
  minWidth: 0,
25
26
  color: colors.gray[12],
26
27
  border: "none",
package/dist/maui.d.ts CHANGED
@@ -38,5 +38,6 @@ export { FuzzyString } from "./components/FuzzyString";
38
38
  export { Flex, Padding, Gap, Spacer, Divider } from "./components/Utils";
39
39
  export { H1, H2, H3, H4, P, Label, labelText, Blockquote, Ul, Ol, Li, Link, } from "./components/Typography";
40
40
  export { CodeBlock } from "./components/CodeBlock";
41
+ export { Code, Kbd } from "./components/Code";
41
42
  export { CollectionPopover, type CollectionPopoverProps, } from "./components/CollectionPopover";
42
43
  export { navigationItem } from "./components/navigationItem";
package/dist/maui.js CHANGED
@@ -41,5 +41,6 @@ export { FuzzyString } from "./components/FuzzyString";
41
41
  export { Flex, Padding, Gap, Spacer, Divider } from "./components/Utils";
42
42
  export { H1, H2, H3, H4, P, Label, labelText, Blockquote, Ul, Ol, Li, Link, } from "./components/Typography";
43
43
  export { CodeBlock } from "./components/CodeBlock";
44
+ export { Code, Kbd } from "./components/Code";
44
45
  export { CollectionPopover, } from "./components/CollectionPopover";
45
46
  export { navigationItem } from "./components/navigationItem";
@@ -6,7 +6,6 @@ export declare const backgroundColor: {
6
6
  };
7
7
  export declare const background: {
8
8
  app: import("purse-styles").StyleElement;
9
- subtle: import("purse-styles").StyleElement;
10
9
  element: import("purse-styles").StyleElement;
11
10
  elementHover: import("purse-styles").StyleElement;
12
11
  elementActive: import("purse-styles").StyleElement;
@@ -25,7 +25,6 @@ export const backgroundColor = {
25
25
  };
26
26
  export const background = {
27
27
  app: style({ backgroundColor: backgroundColor.app }),
28
- subtle: style({ backgroundColor: colors.gray[2] }),
29
28
  element: style({ backgroundColor: backgroundColor.element }),
30
29
  elementHover: style({ backgroundColor: backgroundColor.elementHover }),
31
30
  elementActive: style({ backgroundColor: backgroundColor.elementActive }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanishqkancharla/maui",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Maui design system",
5
5
  "type": "module",
6
6
  "main": "./dist/maui.js",
@@ -41,6 +41,7 @@
41
41
  "deploy": "npx vercel deploy",
42
42
  "test": "vitest",
43
43
  "mcp:browser": "node .cursor/libretto-browser-mcp.mjs",
44
+ "mcp:agentation": "node .cursor/agentation-mcp.mjs",
44
45
  "release": "npm run build:lib && npm publish"
45
46
  },
46
47
  "author": "Tanishq Kancharla",
@@ -54,6 +55,8 @@
54
55
  "@types/react": "^19.2.17",
55
56
  "@types/react-dom": "^19.2.3",
56
57
  "@vitejs/plugin-react": "^6.0.2",
58
+ "agentation": "^3.0.2",
59
+ "agentation-mcp": "^1.2.0",
57
60
  "esbuild": "^0.28.0",
58
61
  "libretto-browser-tools": "^0.1.2",
59
62
  "process": "^0.11.10",
@@ -77,7 +80,6 @@
77
80
  "@types/inline-style-prefixer": "^5.0.3",
78
81
  "dedent": "^1.7.2",
79
82
  "inline-style-prefixer": "^7.0.1",
80
- "leva": "^0.10.1",
81
83
  "lodash": "^4.18.1",
82
84
  "purse-styles": "^0.2.1",
83
85
  "react": "^19.2.7",
@@ -5,7 +5,7 @@ description: Conventions for consuming the Maui design system. Use when building
5
5
 
6
6
  # Maui
7
7
 
8
- TypeScript-first design system styled with `purse-styles`. Wrap the app in `MauiProvider`, then import tokens and components from `"maui"`.
8
+ TypeScript-first design system styled with `purse-styles`. Wrap the app in `MauiProvider`, then import tokens and components from `"@tanishqkancharla/maui"`.
9
9
 
10
10
  ```ts
11
11
  import { style } from "purse-styles"
@@ -16,7 +16,7 @@ import {
16
16
  colors,
17
17
  radius,
18
18
  shadow,
19
- } from "maui"
19
+ } from "@tanishqkancharla/maui"
20
20
 
21
21
  function App() {
22
22
  return (
@@ -29,9 +29,9 @@ function App() {
29
29
 
30
30
  The published package exposes:
31
31
 
32
- - `"maui"` — built barrel (`dist/`) of provider, theme, tokens, and components
33
- - `"maui/src/*"` — TypeScript source for deep imports
34
- - `"maui/skills/maui"` — this skill file
32
+ - `"@tanishqkancharla/maui"` — built barrel (`dist/`) of provider, theme, tokens, and components
33
+ - `"@tanishqkancharla/maui/src/*"` — TypeScript source for deep imports
34
+ - `"@tanishqkancharla/maui/skills/maui"` — this skill file
35
35
 
36
36
  `MauiProvider` sets up theme (`data-theme` / `color-scheme`), `PurseProvider`, design-system globals, and the focus UI database used by Button/Dialog.
37
37
 
@@ -57,7 +57,7 @@ internal button or segment.
57
57
 
58
58
  ## Focus
59
59
 
60
- `focusRing()` applies a theme-aware Radix blue shadow (`blueAlpha[8]` hard edge + `blueAlpha[5]` glow). Do not hand-roll a competing outline or box-shadow for keyboard focus.
60
+ `focusRing()` applies a theme-aware Radix blue shadow (`blueA8` hard edge + `blueA5` glow). Do not hand-roll a competing outline or box-shadow for keyboard focus.
61
61
 
62
62
  ## Layout utilities
63
63
 
@@ -65,23 +65,19 @@ internal button or segment.
65
65
 
66
66
  ## Reference: patterns and apps
67
67
 
68
- Patterns and demo apps are **not** part of the `"maui"` package barrel. Use them as in-repo reference implementations (also available via `"maui/src/..."` when the package ships source):
68
+ Patterns and demo apps are **not** part of the `"@tanishqkancharla/maui"` package barrel. Use them as in-repo reference implementations (also available via `"@tanishqkancharla/maui/src/..."` when the package ships source):
69
69
 
70
70
  ### Patterns — `src/patterns/`
71
71
 
72
- | Path | Role |
73
- | --- | --- |
74
- | `src/patterns/AssistantMessage.tsx` | Streaming markdown reply (Streamdown + Maui prose) |
75
- | `src/patterns/Editor.tsx` | TipTap markdown composer |
76
- | `src/patterns/Loader.tsx` | Game-of-life loader |
77
- | `src/patterns/Sidebar.tsx` | App sidebar chrome |
78
- | `src/patterns/Tree.tsx` | Nested tree navigation |
79
- | `src/patterns/Inbox.tsx` | Mail inbox layout |
80
- | `src/patterns/MessageList.tsx` | Message list rows |
72
+ - `src/patterns/AssistantMessage.tsx` — Streaming markdown reply (Streamdown + Maui prose)
73
+ - `src/patterns/Editor.tsx` — TipTap markdown composer
74
+ - `src/patterns/Loader.tsx` — Game-of-life loader
75
+ - `src/patterns/Sidebar.tsx` — App sidebar chrome
76
+ - `src/patterns/Inbox.tsx` — Mail inbox layout
77
+ - `src/patterns/MessageList.tsx` — Message list rows
81
78
 
82
79
  ### Apps — `src/apps/`
83
80
 
84
- | Path | Role |
85
- | --- | --- |
86
- | `src/apps/AiChat/` | Mock streaming AI chat (Editor + AssistantMessage) |
87
- | `src/apps/EmailClient/` | Email client demo composing inbox patterns |
81
+ - `src/apps/AiChat/` — Mock streaming AI chat (Editor + AssistantMessage)
82
+ - `src/apps/EmailClient/` — Email client demo composing inbox patterns
83
+ - `src/apps/Calendar/` — Three-pane schedule (mini month, week grid, event details)