@pycolors/ui 1.1.1 → 1.1.2

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.
package/README.md CHANGED
@@ -65,8 +65,8 @@ This repository is a **distribution mirror**.
65
65
 
66
66
  - NPM publishing happens from the **PyColors monorepo** (Changesets)
67
67
  - This mirror receives version bumps + CHANGELOG via sync PRs
68
- - A GitHub Release is automatically created when `package.json` and
69
- `CHANGELOG.md` change on `main`
68
+ - A GitHub Release is created only when the mirror `main` branch and npm both
69
+ expose the same `@pycolors/ui` version
70
70
 
71
71
  If you want to propose changes, contribute to the monorepo:
72
72
  https://github.com/pycolors-io/pycolors/tree/main/packages/ui
@@ -21,7 +21,7 @@ export function Alert({ className, variant, ariaLive = 'polite', ...props }) {
21
21
  : ariaLive === 'polite'
22
22
  ? 'status'
23
23
  : undefined;
24
- return (_jsx("div", { "data-slot": "alert", role: role, "aria-live": ariaLive === 'off' ? undefined : ariaLive, className: cn(alertVariants({ variant }), className), ...props }));
24
+ return (_jsx("div", { "data-slot": "alert", ...props, role: role, "aria-live": ariaLive === 'off' ? undefined : ariaLive, className: cn(alertVariants({ variant }), className) }));
25
25
  }
26
26
  export function AlertTitle({ className, ...props }) {
27
27
  return (_jsx("h5", { "data-slot": "alert-title", className: cn('mb-1 font-medium leading-none tracking-tight', className), ...props }));
@@ -1 +1 @@
1
- {"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../../src/components/ui/card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGlE,eAAO,MAAM,YAAY;;;8EAqBxB,CAAC;AAIF,MAAM,WAAW,SACf,SACE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,YAAY,CAAC,OAAO,YAAY,CAAC;IACnC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;AAC5D,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC;AAEpE,eAAO,MAAM,IAAI,kFAmBhB,CAAC;AAIF,MAAM,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;AAEnE,wBAAgB,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,2CAQlE;AAED,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;AAEtE,wBAAgB,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,2CAWhE;AAED,MAAM,MAAM,oBAAoB,GAC9B,KAAK,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC;AAE7C,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,oBAAoB,2CAQtB;AAED,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;AAEpE,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,gBAAgB,2CAQlB;AAED,MAAM,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;AAEnE,wBAAgB,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,2CAQlE"}
1
+ {"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../../src/components/ui/card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGlE,eAAO,MAAM,YAAY;;;8EAqBxB,CAAC;AAIF,MAAM,WAAW,SACf,SACE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,YAAY,CAAC,OAAO,YAAY,CAAC;IACnC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;AAC5D,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC;AAEpE,eAAO,MAAM,IAAI,kFAmChB,CAAC;AAIF,MAAM,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;AAEnE,wBAAgB,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,2CAQlE;AAED,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;AAEtE,wBAAgB,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,2CAWhE;AAED,MAAM,MAAM,oBAAoB,GAC9B,KAAK,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC;AAE7C,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,oBAAoB,2CAQtB;AAED,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;AAEpE,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,gBAAgB,2CAQlB;AAED,MAAM,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;AAEnE,wBAAgB,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,2CAQlE"}
@@ -21,9 +21,19 @@ export const cardVariants = cva('rounded-lg border text-card-foreground', {
21
21
  interactive: false,
22
22
  },
23
23
  });
24
- export const Card = React.forwardRef(({ className, variant, interactive, asChild = false, ...props }, ref) => {
24
+ export const Card = React.forwardRef(({ className, variant, interactive, asChild = false, onKeyDown, ...props }, ref) => {
25
25
  const Comp = asChild ? Slot : 'div';
26
- return (_jsx(Comp, { ref: ref, "data-slot": "card", className: cn(cardVariants({ variant, interactive }), className), ...props }));
26
+ const isInteractiveElement = Boolean(interactive) && !asChild;
27
+ const handleKeyDown = (event) => {
28
+ onKeyDown?.(event);
29
+ if (isInteractiveElement &&
30
+ !event.defaultPrevented &&
31
+ (event.key === 'Enter' || event.key === ' ')) {
32
+ event.preventDefault();
33
+ event.currentTarget.click();
34
+ }
35
+ };
36
+ return (_jsx(Comp, { ref: ref, "data-slot": "card", role: isInteractiveElement ? 'button' : undefined, tabIndex: isInteractiveElement ? 0 : undefined, onKeyDown: handleKeyDown, className: cn(cardVariants({ variant, interactive }), className), ...props }));
27
37
  });
28
38
  Card.displayName = 'Card';
29
39
  export function CardHeader({ className, ...props }) {
@@ -1 +1 @@
1
- {"version":3,"file":"password-input.d.ts","sourceRoot":"","sources":["../../../src/components/ui/password-input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,UAAU,EACV,MAAM,GAAG,WAAW,CACrB,CAAC;AAEF,eAAO,MAAM,aAAa,6FAoCxB,CAAC"}
1
+ {"version":3,"file":"password-input.d.ts","sourceRoot":"","sources":["../../../src/components/ui/password-input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,UAAU,EACV,MAAM,GAAG,WAAW,CACrB,CAAC;AAEF,eAAO,MAAM,aAAa,6FAwCxB,CAAC"}
@@ -3,8 +3,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import * as React from 'react';
4
4
  import { Eye, EyeOff } from 'lucide-react';
5
5
  import { Input } from './input.js';
6
- export const PasswordInput = React.forwardRef((props, ref) => {
6
+ export const PasswordInput = React.forwardRef(({ disabled, ...props }, ref) => {
7
7
  const [visible, setVisible] = React.useState(false);
8
- return (_jsx(Input, { ...props, ref: ref, type: visible ? 'text' : 'password', rightIcon: _jsx("button", { type: "button", "aria-label": visible ? 'Hide password' : 'Show password', "aria-pressed": visible, onClick: () => setVisible((v) => !v), className: "\n rounded-sm p-1\n text-muted-foreground\n hover:text-foreground\n focus-visible:outline-none\n focus-visible:ring-2\n focus-visible:ring-ring\n focus-visible:ring-offset-1\n ", children: visible ? (_jsx(EyeOff, { className: "h-4 w-4", "aria-hidden": "true" })) : (_jsx(Eye, { className: "h-4 w-4", "aria-hidden": "true" })) }) }));
8
+ return (_jsx(Input, { ...props, disabled: disabled, ref: ref, type: visible ? 'text' : 'password', rightIcon: _jsx("button", { type: "button", disabled: disabled, "aria-label": visible ? 'Hide password' : 'Show password', "aria-pressed": visible, onClick: () => setVisible((v) => !v), className: "\n rounded-sm p-1\n text-muted-foreground\n hover:text-foreground\n focus-visible:outline-none\n focus-visible:ring-2\n focus-visible:ring-ring\n focus-visible:ring-offset-1\n disabled:pointer-events-none\n disabled:opacity-50\n ", children: visible ? (_jsx(EyeOff, { className: "h-4 w-4", "aria-hidden": "true" })) : (_jsx(Eye, { className: "h-4 w-4", "aria-hidden": "true" })) }) }));
9
9
  });
10
10
  PasswordInput.displayName = 'PasswordInput';
@@ -1 +1 @@
1
- {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/components/ui/table.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,wBAAgB,KAAK,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,gBAAgB,CAAC,2CASxC;AAED,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC,2CAI/C;AAED,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC,2CAO/C;AAED,wBAAgB,QAAQ,CAAC,EACvB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,mBAAmB,CAAC,2CAU3C;AAED,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,2CAU9C;AAED,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,2CAI9C;AAED,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC,2CAO/C;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAoB,EACpB,WAAgE,GACjE,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,2CAaA;AAED,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,2CAW5D"}
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/components/ui/table.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,wBAAgB,KAAK,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,gBAAgB,CAAC,2CASxC;AAED,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC,2CAI/C;AAED,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC,2CAO/C;AAED,wBAAgB,QAAQ,CAAC,EACvB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,mBAAmB,CAAC,2CAU3C;AAED,wBAAgB,SAAS,CAAC,EAExB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,2CAU9C;AAED,wBAAgB,SAAS,CAAC,EAExB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,2CAI9C;AAED,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC,2CAO/C;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAoB,EACpB,WAAgE,GACjE,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,2CAaA;AAED,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,2CAkB5D"}
@@ -12,10 +12,14 @@ export function TableBody({ className, ...props }) {
12
12
  export function TableRow({ className, ...props }) {
13
13
  return (_jsx("tr", { className: cn('border-b border-border/60 transition-colors hover:bg-accent/30', className), ...props }));
14
14
  }
15
- export function TableHead({ className, ...props }) {
15
+ export function TableHead({
16
+ // eslint-disable-next-line react/prop-types -- TypeScript validates intrinsic table header props.
17
+ className, ...props }) {
16
18
  return (_jsx("th", { className: cn('h-10 px-4 text-left align-middle font-medium text-muted-foreground', className), ...props }));
17
19
  }
18
- export function TableCell({ className, ...props }) {
20
+ export function TableCell({
21
+ // eslint-disable-next-line react/prop-types -- TypeScript validates intrinsic table cell props.
22
+ className, ...props }) {
19
23
  return (_jsx("td", { className: cn('p-4 align-middle', className), ...props }));
20
24
  }
21
25
  export function TableCaption({ className, ...props }) {
@@ -25,5 +29,5 @@ export function TableEmpty({ colSpan, title = 'No results', description = 'Try a
25
29
  return (_jsx(TableRow, { className: "hover:bg-transparent", children: _jsx(TableCell, { colSpan: colSpan, className: "py-10", children: _jsxs("div", { className: "text-center", children: [_jsx("div", { className: "font-medium", children: title }), _jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: description })] }) }) }));
26
30
  }
27
31
  export function TableLoading({ colSpan }) {
28
- return (_jsx(TableRow, { className: "hover:bg-transparent", children: _jsx(TableCell, { colSpan: colSpan, className: "py-10", children: _jsxs("div", { className: "flex items-center justify-center gap-2 text-sm text-muted-foreground", children: [_jsx("span", { className: "inline-block size-4 animate-spin rounded-full border-2 border-muted-foreground/30 border-t-muted-foreground" }), "Loading\u2026"] }) }) }));
32
+ return (_jsx(TableRow, { className: "hover:bg-transparent", children: _jsx(TableCell, { colSpan: colSpan, className: "py-10", children: _jsxs("div", { role: "status", "aria-live": "polite", className: "flex items-center justify-center gap-2 text-sm text-muted-foreground", children: [_jsx("span", { "aria-hidden": "true", className: "inline-block size-4 animate-spin rounded-full border-2 border-muted-foreground/30 border-t-muted-foreground" }), "Loading\u2026"] }) }) }));
29
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pycolors/ui",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Production-ready UI primitives for modern SaaS apps (Radix + Tailwind-friendly).",
5
5
  "keywords": [
6
6
  "pycolors",
@@ -66,19 +66,24 @@
66
66
  "devDependencies": {
67
67
  "@pycolors/eslint-config": "^1.0.0",
68
68
  "@pycolors/typescript-config": "^1.0.0",
69
+ "@testing-library/jest-dom": "^6.9.1",
70
+ "@testing-library/react": "^16.3.2",
69
71
  "@types/node": "^22.15.3",
70
72
  "@types/react": "19.2.2",
71
73
  "@types/react-dom": "19.2.2",
72
74
  "eslint": "^9.39.1",
73
- "typescript": "5.9.2"
75
+ "jsdom": "^29.1.1",
76
+ "typescript": "5.9.2",
77
+ "vitest": "^4.1.10"
74
78
  },
75
79
  "scripts": {
76
80
  "clean": "rm -rf dist",
77
81
  "build": "tsc -p tsconfig.json",
78
82
  "lint": "eslint . --max-warnings 0",
83
+ "test": "vitest run --config vitest.config.ts",
79
84
  "types:check": "tsc --noEmit",
80
- "verify": "pnpm lint && pnpm types:check && pnpm build",
85
+ "verify": "pnpm test && pnpm lint && pnpm types:check && pnpm build",
81
86
  "generate:component": "turbo gen react-component",
82
- "release": "pnpm clean && pnpm build:ts && pnpm publish --access public"
87
+ "release": "pnpm clean && pnpm build && pnpm publish --access public"
83
88
  }
84
89
  }