@nightstem/ui 0.0.2-alpha.1 → 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.
- package/README.md +98 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/ui/Buttons/Button/Button.d.ts +11 -0
- package/dist/components/ui/Buttons/Button/Button.d.ts.map +1 -0
- package/dist/components/ui/Buttons/Button/index.d.ts +3 -0
- package/dist/components/ui/Buttons/Button/index.d.ts.map +1 -0
- package/dist/components/ui/Buttons/LinkButton/LinkButton.d.ts +13 -0
- package/dist/components/ui/Buttons/LinkButton/LinkButton.d.ts.map +1 -0
- package/dist/components/ui/Buttons/LinkButton/index.d.ts +3 -0
- package/dist/components/ui/Buttons/LinkButton/index.d.ts.map +1 -0
- package/dist/components/ui/Buttons/constants.d.ts +21 -0
- package/dist/components/ui/Buttons/constants.d.ts.map +1 -0
- package/dist/components/ui/Buttons/index.d.ts +3 -0
- package/dist/components/ui/Buttons/index.d.ts.map +1 -0
- package/dist/components/ui/Buttons/themes.d.ts +5 -0
- package/dist/components/ui/Buttons/themes.d.ts.map +1 -0
- package/dist/components/ui/Buttons/types.d.ts +6 -0
- package/dist/components/ui/Buttons/types.d.ts.map +1 -0
- package/dist/components/ui/Kbd/Kbd.d.ts +5 -0
- package/dist/components/ui/Kbd/Kbd.d.ts.map +1 -0
- package/dist/components/ui/Kbd/index.d.ts +4 -0
- package/dist/components/ui/Kbd/index.d.ts.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/package.json +22 -6
package/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# @nightstem/ui
|
|
2
|
+
|
|
3
|
+
React UI primitives for the Nightstem design system.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pnpm add @nightstem/ui @nightstem/tokens
|
|
9
|
+
pnpm add -D tailwindcss
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Peer requirements
|
|
13
|
+
|
|
14
|
+
- React 19+
|
|
15
|
+
- `@nightstem/tokens` — provides the CSS design tokens (colors, typography, spacing). Technically optional but required for visual correctness.
|
|
16
|
+
- Tailwind CSS v4 (transitive via `@nightstem/tokens`)
|
|
17
|
+
|
|
18
|
+
## Set up tokens
|
|
19
|
+
|
|
20
|
+
Import the tokens CSS once in your app's global stylesheet (before any component styles):
|
|
21
|
+
|
|
22
|
+
```css
|
|
23
|
+
@import '@nightstem/tokens/theme.css';
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Optional Inter variable font:
|
|
27
|
+
|
|
28
|
+
```css
|
|
29
|
+
@import '@nightstem/tokens/fonts.css';
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
### Button
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
import { Button, BUTTON_VARIANT, BUTTON_COLORS } from '@nightstem/ui';
|
|
38
|
+
|
|
39
|
+
<Button>Click me</Button>
|
|
40
|
+
<Button variant="outlined" color="secondary">Secondary</Button>
|
|
41
|
+
<Button variant="ghost" color="primary" size="lg" disabled>Disabled</Button>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Props: `variant` (`solid` | `outlined` | `ghost` | `text`), `color` (`primary` | `secondary` | `neutral`), `size` (`sm` | `md` | `lg`), `shape` (`square` | `circle`). Extends all `<button>` HTML attributes.
|
|
45
|
+
|
|
46
|
+
### LinkButton
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { LinkButton } from '@nightstem/ui';
|
|
50
|
+
|
|
51
|
+
// Plain anchor (default)
|
|
52
|
+
<LinkButton href="/about">About</LinkButton>
|
|
53
|
+
|
|
54
|
+
// External link
|
|
55
|
+
<LinkButton href="https://example.com" target="_blank" rel="noreferrer noopener">
|
|
56
|
+
Open externally
|
|
57
|
+
</LinkButton>
|
|
58
|
+
|
|
59
|
+
// Using next/link
|
|
60
|
+
import Link from 'next/link';
|
|
61
|
+
<LinkButton href="/dashboard" linkComponent={Link}>Dashboard</LinkButton>
|
|
62
|
+
|
|
63
|
+
// Using react-router
|
|
64
|
+
import { Link } from 'react-router-dom';
|
|
65
|
+
<LinkButton href="/home" linkComponent={Link}>Home</LinkButton>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Props: same visual props as `Button`, plus `linkComponent?: ElementType` (defaults to `<a>`). Extends all anchor HTML attributes.
|
|
69
|
+
|
|
70
|
+
> **Migration note:** the upstream `isExternal` prop was removed. For external links, pass `target="_blank" rel="noreferrer noopener"` directly.
|
|
71
|
+
|
|
72
|
+
### Kbd
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
import { Kbd } from '@nightstem/ui';
|
|
76
|
+
|
|
77
|
+
Press <Kbd>Ctrl</Kbd> + <Kbd>K</Kbd> to open the command palette.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Extends all `HTMLAttributes<HTMLElement>`.
|
|
81
|
+
|
|
82
|
+
## Utilities
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { cn, hashIndex, randomInt } from '@nightstem/ui';
|
|
86
|
+
|
|
87
|
+
cn('flex', isActive && 'bg-primary-500', 'p-4'); // clsx + tailwind-merge
|
|
88
|
+
hashIndex('/some/path', 5); // deterministic int 0-4
|
|
89
|
+
randomInt(10); // cryptographic random int 0-9
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Token note
|
|
93
|
+
|
|
94
|
+
The `neutral` button color uses Tailwind's default `neutral-*` palette — it is not yet a named Nightstem brand token. All other colors (`primary-*`, `secondary-*`) are defined in `@nightstem/tokens`.
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ButtonHTMLAttributes, DetailedHTMLProps } from 'react';
|
|
2
|
+
import { ButtonColor, ButtonShape, ButtonSize, ButtonVariant } from '../types';
|
|
3
|
+
export type ButtonProps = DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> & {
|
|
4
|
+
size?: ButtonSize;
|
|
5
|
+
color?: ButtonColor;
|
|
6
|
+
shape?: ButtonShape;
|
|
7
|
+
variant?: ButtonVariant;
|
|
8
|
+
};
|
|
9
|
+
declare const Button: ({ className, type, color, size, shape, variant, ...props }: ButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export default Button;
|
|
11
|
+
//# sourceMappingURL=Button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/Buttons/Button/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAIrE,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,aAAa,EACd,MAAM,+BAA+B,CAAC;AAcvC,MAAM,MAAM,WAAW,GAAG,iBAAiB,CACzC,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,iBAAiB,CAClB,GAAG;IACF,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB,CAAC;AAEF,QAAA,MAAM,MAAM,GAAI,4DAQb,WAAW,4CAqBb,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/Buttons/Button/index.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,uCAAuC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AnchorHTMLAttributes, ElementType } from 'react';
|
|
2
|
+
import { ButtonColor, ButtonShape, ButtonSize, ButtonVariant } from '../types';
|
|
3
|
+
export type LinkButtonProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
4
|
+
/** Element or component used to render the link. Defaults to a plain <a>. Pass next/link, react-router Link, etc. */
|
|
5
|
+
linkComponent?: ElementType;
|
|
6
|
+
size?: ButtonSize;
|
|
7
|
+
color?: ButtonColor;
|
|
8
|
+
shape?: ButtonShape;
|
|
9
|
+
variant?: ButtonVariant;
|
|
10
|
+
};
|
|
11
|
+
declare const LinkButton: ({ className, linkComponent, color, size, shape, variant, ...props }: LinkButtonProps) => import('react').ReactElement<any, string | import('react').JSXElementConstructor<any>>;
|
|
12
|
+
export default LinkButton;
|
|
13
|
+
//# sourceMappingURL=LinkButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkButton.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/Buttons/LinkButton/LinkButton.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,WAAW,EACjB,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,aAAa,EACd,MAAM,+BAA+B,CAAC;AAcvC,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,GAAG;IACtE,qHAAqH;IACrH,aAAa,CAAC,EAAE,WAAW,CAAC;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB,CAAC;AAEF,QAAA,MAAM,UAAU,GAAI,qEAQjB,eAAe,2FAejB,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/Buttons/LinkButton/index.ts"],"names":[],"mappings":"AAAA,cAAc,+CAA+C,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,+CAA+C,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const BUTTON_SHAPE: {
|
|
2
|
+
readonly SQUARE: "square";
|
|
3
|
+
readonly CIRCLE: "circle";
|
|
4
|
+
};
|
|
5
|
+
export declare const BUTTON_VARIANT: {
|
|
6
|
+
readonly SOLID: "solid";
|
|
7
|
+
readonly OUTLINED: "outlined";
|
|
8
|
+
readonly GHOST: "ghost";
|
|
9
|
+
readonly TEXT: "text";
|
|
10
|
+
};
|
|
11
|
+
export declare const BUTTON_SIZE: {
|
|
12
|
+
readonly SM: "sm";
|
|
13
|
+
readonly MD: "md";
|
|
14
|
+
readonly LG: "lg";
|
|
15
|
+
};
|
|
16
|
+
export declare const BUTTON_COLORS: {
|
|
17
|
+
readonly PRIMARY: "primary";
|
|
18
|
+
readonly SECONDARY: "secondary";
|
|
19
|
+
readonly NEUTRAL: "neutral";
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/Buttons/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAEX,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC;AAEX,eAAO,MAAM,WAAW;;;;CAId,CAAC;AAEX,eAAO,MAAM,aAAa;;;;CAIhB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/Buttons/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oCAAoC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ButtonColor, ButtonShape, ButtonSize, ButtonVariant } from './types';
|
|
2
|
+
export declare const THEME_SIZE: Record<ButtonSize, string>;
|
|
3
|
+
export declare const THEME_SHAPE: Record<ButtonShape, string>;
|
|
4
|
+
export declare const THEME_VARIANT: Record<ButtonVariant, Record<ButtonColor, string>>;
|
|
5
|
+
//# sourceMappingURL=themes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/Buttons/themes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,aAAa,EACd,MAAM,+BAA+B,CAAC;AAIvC,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAIxC,CAAC;AAEX,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAG1C,CAAC;AAEX,eAAO,MAAM,aAAa,EAAE,MAAM,CAChC,aAAa,EACb,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAkFnB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BUTTON_COLORS, BUTTON_SHAPE, BUTTON_SIZE, BUTTON_VARIANT } from './constants';
|
|
2
|
+
export type ButtonSize = (typeof BUTTON_SIZE)[keyof typeof BUTTON_SIZE];
|
|
3
|
+
export type ButtonShape = (typeof BUTTON_SHAPE)[keyof typeof BUTTON_SHAPE];
|
|
4
|
+
export type ButtonColor = (typeof BUTTON_COLORS)[keyof typeof BUTTON_COLORS];
|
|
5
|
+
export type ButtonVariant = (typeof BUTTON_VARIANT)[keyof typeof BUTTON_VARIANT];
|
|
6
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/Buttons/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,YAAY,EACZ,WAAW,EACX,cAAc,EACf,MAAM,mCAAmC,CAAC;AAE3C,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AACxE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAC3E,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC;AAC7E,MAAM,MAAM,aAAa,GACvB,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,OAAO,cAAc,CAAC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { DetailedHTMLProps, HTMLAttributes } from 'react';
|
|
2
|
+
export type KbdProps = DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
3
|
+
declare const Kbd: ({ className, ...props }: KbdProps) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export default Kbd;
|
|
5
|
+
//# sourceMappingURL=Kbd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Kbd.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/Kbd/Kbd.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAI/D,MAAM,MAAM,QAAQ,GAAG,iBAAiB,CACtC,cAAc,CAAC,WAAW,CAAC,EAC3B,WAAW,CACZ,CAAC;AAEF,QAAA,MAAM,GAAG,GAAI,yBAAyB,QAAQ,4CAQ7C,CAAC;AAEF,eAAe,GAAG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/Kbd/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { cn as e } from "@nightstem/utils";
|
|
2
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
3
|
+
import { createElement as n } from "react";
|
|
4
|
+
//#region src/components/ui/Buttons/constants.ts
|
|
5
|
+
var r = {
|
|
6
|
+
SQUARE: "square",
|
|
7
|
+
CIRCLE: "circle"
|
|
8
|
+
}, i = {
|
|
9
|
+
SOLID: "solid",
|
|
10
|
+
OUTLINED: "outlined",
|
|
11
|
+
GHOST: "ghost",
|
|
12
|
+
TEXT: "text"
|
|
13
|
+
}, a = {
|
|
14
|
+
SM: "sm",
|
|
15
|
+
MD: "md",
|
|
16
|
+
LG: "lg"
|
|
17
|
+
}, o = {
|
|
18
|
+
PRIMARY: "primary",
|
|
19
|
+
SECONDARY: "secondary",
|
|
20
|
+
NEUTRAL: "neutral"
|
|
21
|
+
}, s = {
|
|
22
|
+
lg: "text-lg px-5 py-2.5",
|
|
23
|
+
md: "text-base px-4 py-2",
|
|
24
|
+
sm: "text-sm px-3 py-1.5"
|
|
25
|
+
}, c = {
|
|
26
|
+
circle: "rounded-full",
|
|
27
|
+
square: "rounded-md"
|
|
28
|
+
}, l = {
|
|
29
|
+
solid: {
|
|
30
|
+
primary: e("text-dark bg-primary-500", "hover:bg-primary-400 active:bg-primary-400", "focus-visible:ring-primary-500", "disabled:opacity-60 disabled:hover:bg-primary-500 disabled:active:bg-primary-500"),
|
|
31
|
+
secondary: e("text-dark bg-secondary-500", "hover:bg-secondary-400 active:bg-secondary-400", "focus-visible:ring-secondary-500", "disabled:opacity-60 disabled:hover:bg-secondary-500 disabled:active:bg-secondary-500"),
|
|
32
|
+
neutral: e("text-dark bg-neutral-400", "hover:bg-neutral-300 active:bg-neutral-300", "focus-visible:ring-neutral-400", "disabled:opacity-60 disabled:hover:bg-neutral-400 disabled:active:bg-neutral-400")
|
|
33
|
+
},
|
|
34
|
+
outlined: {
|
|
35
|
+
primary: e("text-primary-500 bg-transparent border border-primary-500", "hover:border-primary-400 active:border-primary-400 hover:bg-primary-500/20 active:bg-primary-500/20", "focus-visible:ring-primary-500", "disabled:opacity-60 disabled:hover:border-primary-500 disabled:active:border-primary-500"),
|
|
36
|
+
secondary: e("text-white bg-transparent border border-secondary-500", "hover:border-secondary-400 active:border-secondary-400 hover:bg-secondary-500/20 active:bg-secondary-500/20", "focus-visible:ring-secondary-500", "disabled:opacity-60 disabled:hover:border-secondary-500 disabled:active:border-secondary-500"),
|
|
37
|
+
neutral: e("text-neutral-400 bg-transparent border border-neutral-400", "hover:border-neutral-300 active:border-neutral-300 hover:bg-neutral-400/20 active:bg-neutral-400/20", "focus-visible:ring-neutral-400", "disabled:opacity-60 disabled:hover:border-neutral-400 disabled:active:border-neutral-400")
|
|
38
|
+
},
|
|
39
|
+
ghost: {
|
|
40
|
+
primary: e("text-primary-500 bg-transparent", "hover:text-dark hover:bg-primary-500/60 active:bg-primary-500/60", "focus-visible:ring-primary-500", "disabled:opacity-60 disabled:hover:text-primary-500 disabled:hover:bg-transparent disabled:active:bg-transparent"),
|
|
41
|
+
secondary: e("text-secondary-500 bg-transparent", "hover:text-dark hover:bg-secondary-500/60 active:bg-secondary-500/60", "focus-visible:ring-secondary-500", "disabled:opacity-60 disabled:hover:text-secondary-500 disabled:hover:bg-transparent disabled:active:bg-transparent"),
|
|
42
|
+
neutral: e("text-neutral-400 bg-transparent", "hover:text-dark hover:bg-neutral-400/60 active:bg-neutral-400/60", "focus-visible:ring-neutral-400", "disabled:opacity-60 disabled:hover:text-neutral-400 disabled:hover:bg-transparent disabled:active:bg-transparent")
|
|
43
|
+
},
|
|
44
|
+
text: {
|
|
45
|
+
primary: e("text-primary-500", "hover:text-primary-400 active:text-primary-400", "focus-visible:ring-primary-500", "disabled:opacity-60 disabled:hover:text-primary-500 disabled:hover:bg-transparent disabled:active:bg-transparent"),
|
|
46
|
+
secondary: e("text-secondary-500", "hover:text-secondary-400 active:text-secondary-400", "focus-visible:ring-secondary-500", "disabled:opacity-60 disabled:hover:text-secondary-500 disabled:hover:bg-transparent disabled:active:bg-transparent"),
|
|
47
|
+
neutral: e("text-neutral-400", "hover:text-neutral-300 active:text-neutral-300", "focus-visible:ring-neutral-400", "disabled:opacity-60 disabled:hover:text-neutral-400 disabled:hover:bg-transparent disabled:active:bg-transparent")
|
|
48
|
+
}
|
|
49
|
+
}, u = ({ className: n, type: u = "button", color: d = o.PRIMARY, size: f = a.MD, shape: p = r.SQUARE, variant: m = i.SOLID, ...h }) => {
|
|
50
|
+
let g = s[f], _ = c[p], v = l[m][d];
|
|
51
|
+
return /* @__PURE__ */ t("button", {
|
|
52
|
+
type: u,
|
|
53
|
+
className: e("font-medium whitespace-nowrap select-none", "cursor-pointer disabled:cursor-not-allowed", "transition-colors duration-200 motion-reduce:transition-none", "ring-offset-dark focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none", g, _, v, n),
|
|
54
|
+
...h
|
|
55
|
+
});
|
|
56
|
+
}, d = ({ className: t, linkComponent: u, color: d = o.PRIMARY, size: f = a.MD, shape: p = r.SQUARE, variant: m = i.SOLID, ...h }) => n(u ?? "a", {
|
|
57
|
+
className: e("select-none whitespace-nowrap font-medium", "cursor-pointer", "transition-colors duration-200 motion-reduce:transition-none", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 ring-offset-dark", s[f], c[p], l[m][d], t),
|
|
58
|
+
...h
|
|
59
|
+
}), f = ({ className: n, ...r }) => /* @__PURE__ */ t("kbd", {
|
|
60
|
+
...r,
|
|
61
|
+
className: e("rounded border border-foreground/20 p-1.5 leading-[50%] shadow-2xl", n)
|
|
62
|
+
});
|
|
63
|
+
//#endregion
|
|
64
|
+
export { u as Button, f as Kbd, d as LinkButton };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/components/ui/Buttons/constants.ts","../src/components/ui/Buttons/themes.ts","../src/components/ui/Buttons/Button/Button.tsx","../src/components/ui/Buttons/LinkButton/LinkButton.tsx","../src/components/ui/Kbd/Kbd.tsx"],"sourcesContent":["export const BUTTON_SHAPE = {\n SQUARE: 'square',\n CIRCLE: 'circle',\n} as const;\n\nexport const BUTTON_VARIANT = {\n SOLID: 'solid',\n OUTLINED: 'outlined',\n GHOST: 'ghost',\n TEXT: 'text',\n} as const;\n\nexport const BUTTON_SIZE = {\n SM: 'sm',\n MD: 'md',\n LG: 'lg',\n} as const;\n\nexport const BUTTON_COLORS = {\n PRIMARY: 'primary',\n SECONDARY: 'secondary',\n NEUTRAL: 'neutral',\n} as const;\n","import type {\n ButtonColor,\n ButtonShape,\n ButtonSize,\n ButtonVariant,\n} from '@/components/ui/Buttons/types';\n\nimport { cn } from '@nightstem/utils';\n\nexport const THEME_SIZE: Record<ButtonSize, string> = {\n lg: 'text-lg px-5 py-2.5',\n md: 'text-base px-4 py-2',\n sm: 'text-sm px-3 py-1.5',\n} as const;\n\nexport const THEME_SHAPE: Record<ButtonShape, string> = {\n circle: 'rounded-full',\n square: 'rounded-md',\n} as const;\n\nexport const THEME_VARIANT: Record<\n ButtonVariant,\n Record<ButtonColor, string>\n> = {\n solid: {\n primary: cn(\n 'text-dark bg-primary-500',\n 'hover:bg-primary-400 active:bg-primary-400',\n 'focus-visible:ring-primary-500',\n 'disabled:opacity-60 disabled:hover:bg-primary-500 disabled:active:bg-primary-500',\n ),\n secondary: cn(\n 'text-dark bg-secondary-500',\n 'hover:bg-secondary-400 active:bg-secondary-400',\n 'focus-visible:ring-secondary-500',\n 'disabled:opacity-60 disabled:hover:bg-secondary-500 disabled:active:bg-secondary-500',\n ),\n neutral: cn(\n 'text-dark bg-neutral-400',\n 'hover:bg-neutral-300 active:bg-neutral-300',\n 'focus-visible:ring-neutral-400',\n 'disabled:opacity-60 disabled:hover:bg-neutral-400 disabled:active:bg-neutral-400',\n ),\n },\n outlined: {\n primary: cn(\n 'text-primary-500 bg-transparent border border-primary-500',\n 'hover:border-primary-400 active:border-primary-400 hover:bg-primary-500/20 active:bg-primary-500/20',\n 'focus-visible:ring-primary-500',\n 'disabled:opacity-60 disabled:hover:border-primary-500 disabled:active:border-primary-500',\n ),\n secondary: cn(\n 'text-white bg-transparent border border-secondary-500',\n 'hover:border-secondary-400 active:border-secondary-400 hover:bg-secondary-500/20 active:bg-secondary-500/20',\n 'focus-visible:ring-secondary-500',\n 'disabled:opacity-60 disabled:hover:border-secondary-500 disabled:active:border-secondary-500',\n ),\n neutral: cn(\n 'text-neutral-400 bg-transparent border border-neutral-400',\n 'hover:border-neutral-300 active:border-neutral-300 hover:bg-neutral-400/20 active:bg-neutral-400/20',\n 'focus-visible:ring-neutral-400',\n 'disabled:opacity-60 disabled:hover:border-neutral-400 disabled:active:border-neutral-400',\n ),\n },\n ghost: {\n primary: cn(\n 'text-primary-500 bg-transparent',\n 'hover:text-dark hover:bg-primary-500/60 active:bg-primary-500/60',\n 'focus-visible:ring-primary-500',\n 'disabled:opacity-60 disabled:hover:text-primary-500 disabled:hover:bg-transparent disabled:active:bg-transparent',\n ),\n secondary: cn(\n 'text-secondary-500 bg-transparent',\n 'hover:text-dark hover:bg-secondary-500/60 active:bg-secondary-500/60',\n 'focus-visible:ring-secondary-500',\n 'disabled:opacity-60 disabled:hover:text-secondary-500 disabled:hover:bg-transparent disabled:active:bg-transparent',\n ),\n neutral: cn(\n 'text-neutral-400 bg-transparent',\n 'hover:text-dark hover:bg-neutral-400/60 active:bg-neutral-400/60',\n 'focus-visible:ring-neutral-400',\n 'disabled:opacity-60 disabled:hover:text-neutral-400 disabled:hover:bg-transparent disabled:active:bg-transparent',\n ),\n },\n text: {\n primary: cn(\n 'text-primary-500',\n 'hover:text-primary-400 active:text-primary-400',\n 'focus-visible:ring-primary-500',\n 'disabled:opacity-60 disabled:hover:text-primary-500 disabled:hover:bg-transparent disabled:active:bg-transparent',\n ),\n secondary: cn(\n 'text-secondary-500',\n 'hover:text-secondary-400 active:text-secondary-400',\n 'focus-visible:ring-secondary-500',\n 'disabled:opacity-60 disabled:hover:text-secondary-500 disabled:hover:bg-transparent disabled:active:bg-transparent',\n ),\n neutral: cn(\n 'text-neutral-400',\n 'hover:text-neutral-300 active:text-neutral-300',\n 'focus-visible:ring-neutral-400',\n 'disabled:opacity-60 disabled:hover:text-neutral-400 disabled:hover:bg-transparent disabled:active:bg-transparent',\n ),\n },\n} as const;\n","import type { ButtonHTMLAttributes, DetailedHTMLProps } from 'react';\n\nimport { cn } from '@nightstem/utils';\n\nimport type {\n ButtonColor,\n ButtonShape,\n ButtonSize,\n ButtonVariant,\n} from '@/components/ui/Buttons/types';\n\nimport {\n BUTTON_COLORS,\n BUTTON_SHAPE,\n BUTTON_SIZE,\n BUTTON_VARIANT,\n} from '@/components/ui/Buttons/constants';\nimport {\n THEME_SHAPE,\n THEME_SIZE,\n THEME_VARIANT,\n} from '@/components/ui/Buttons/themes';\n\nexport type ButtonProps = DetailedHTMLProps<\n ButtonHTMLAttributes<HTMLButtonElement>,\n HTMLButtonElement\n> & {\n size?: ButtonSize;\n color?: ButtonColor;\n shape?: ButtonShape;\n variant?: ButtonVariant;\n};\n\nconst Button = ({\n className,\n type = 'button',\n color = BUTTON_COLORS.PRIMARY,\n size = BUTTON_SIZE.MD,\n shape = BUTTON_SHAPE.SQUARE,\n variant = BUTTON_VARIANT.SOLID,\n ...props\n}: ButtonProps) => {\n const sizeClassNames = THEME_SIZE[size];\n const shapeClassNames = THEME_SHAPE[shape];\n const colorClassNames = THEME_VARIANT[variant][color];\n\n return (\n <button\n type={type}\n className={cn(\n 'font-medium whitespace-nowrap select-none',\n 'cursor-pointer disabled:cursor-not-allowed',\n 'transition-colors duration-200 motion-reduce:transition-none',\n 'ring-offset-dark focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none',\n sizeClassNames,\n shapeClassNames,\n colorClassNames,\n className,\n )}\n {...props}\n />\n );\n};\n\nexport default Button;\n","import {\n createElement,\n type AnchorHTMLAttributes,\n type ElementType,\n} from 'react';\n\nimport { cn } from '@nightstem/utils';\n\nimport type {\n ButtonColor,\n ButtonShape,\n ButtonSize,\n ButtonVariant,\n} from '@/components/ui/Buttons/types';\n\nimport {\n BUTTON_COLORS,\n BUTTON_SHAPE,\n BUTTON_SIZE,\n BUTTON_VARIANT,\n} from '@/components/ui/Buttons/constants';\nimport {\n THEME_SHAPE,\n THEME_SIZE,\n THEME_VARIANT,\n} from '@/components/ui/Buttons/themes';\n\nexport type LinkButtonProps = AnchorHTMLAttributes<HTMLAnchorElement> & {\n /** Element or component used to render the link. Defaults to a plain <a>. Pass next/link, react-router Link, etc. */\n linkComponent?: ElementType;\n size?: ButtonSize;\n color?: ButtonColor;\n shape?: ButtonShape;\n variant?: ButtonVariant;\n};\n\nconst LinkButton = ({\n className,\n linkComponent,\n color = BUTTON_COLORS.PRIMARY,\n size = BUTTON_SIZE.MD,\n shape = BUTTON_SHAPE.SQUARE,\n variant = BUTTON_VARIANT.SOLID,\n ...props\n}: LinkButtonProps) => {\n const Tag = linkComponent ?? 'a';\n\n const classNames = cn(\n 'select-none whitespace-nowrap font-medium',\n 'cursor-pointer',\n 'transition-colors duration-200 motion-reduce:transition-none',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 ring-offset-dark',\n THEME_SIZE[size],\n THEME_SHAPE[shape],\n THEME_VARIANT[variant][color],\n className,\n );\n\n return createElement(Tag, { className: classNames, ...props });\n};\n\nexport default LinkButton;\n","import type { DetailedHTMLProps, HTMLAttributes } from 'react';\n\nimport { cn } from '@nightstem/utils';\n\nexport type KbdProps = DetailedHTMLProps<\n HTMLAttributes<HTMLElement>,\n HTMLElement\n>;\n\nconst Kbd = ({ className, ...props }: KbdProps) => (\n <kbd\n {...props}\n className={cn(\n 'rounded border border-foreground/20 p-1.5 leading-[50%] shadow-2xl',\n className,\n )}\n />\n);\n\nexport default Kbd;\n"],"mappings":";;;;AAAA,IAAa,IAAe;CAC1B,QAAQ;CACR,QAAQ;CACT,EAEY,IAAiB;CAC5B,OAAO;CACP,UAAU;CACV,OAAO;CACP,MAAM;CACP,EAEY,IAAc;CACzB,IAAI;CACJ,IAAI;CACJ,IAAI;CACL,EAEY,IAAgB;CAC3B,SAAS;CACT,WAAW;CACX,SAAS;CACV,ECbY,IAAyC;CACpD,IAAI;CACJ,IAAI;CACJ,IAAI;CACL,EAEY,IAA2C;CACtD,QAAQ;CACR,QAAQ;CACT,EAEY,IAGT;CACF,OAAO;EACL,SAAS,EACP,4BACA,8CACA,kCACA,mFACD;EACD,WAAW,EACT,8BACA,kDACA,oCACA,uFACD;EACD,SAAS,EACP,4BACA,8CACA,kCACA,mFACD;EACF;CACD,UAAU;EACR,SAAS,EACP,6DACA,uGACA,kCACA,2FACD;EACD,WAAW,EACT,yDACA,+GACA,oCACA,+FACD;EACD,SAAS,EACP,6DACA,uGACA,kCACA,2FACD;EACF;CACD,OAAO;EACL,SAAS,EACP,mCACA,oEACA,kCACA,mHACD;EACD,WAAW,EACT,qCACA,wEACA,oCACA,qHACD;EACD,SAAS,EACP,mCACA,oEACA,kCACA,mHACD;EACF;CACD,MAAM;EACJ,SAAS,EACP,oBACA,kDACA,kCACA,mHACD;EACD,WAAW,EACT,sBACA,sDACA,oCACA,qHACD;EACD,SAAS,EACP,oBACA,kDACA,kCACA,mHACD;EACF;CACF,ECvEK,KAAU,EACd,cACA,UAAO,UACP,WAAQ,EAAc,SACtB,UAAO,EAAY,IACnB,WAAQ,EAAa,QACrB,aAAU,EAAe,OACzB,GAAG,QACc;CACjB,IAAM,IAAiB,EAAW,IAC5B,IAAkB,EAAY,IAC9B,IAAkB,EAAc,GAAS;AAE/C,QACE,kBAAC,UAAD;EACQ;EACN,WAAW,EACT,6CACA,8CACA,gEACA,gGACA,GACA,GACA,GACA,EACD;EACD,GAAI;EACJ,CAAA;GCxBA,KAAc,EAClB,cACA,kBACA,WAAQ,EAAc,SACtB,UAAO,EAAY,IACnB,WAAQ,EAAa,QACrB,aAAU,EAAe,OACzB,GAAG,QAeI,EAbK,KAAiB,KAaH;CAAE,WAXT,EACjB,6CACA,kBACA,gEACA,gGACA,EAAW,IACX,EAAY,IACZ,EAAc,GAAS,IACvB,EAGqC;CAAY,GAAG;CAAO,CAAC,ECjD1D,KAAO,EAAE,cAAW,GAAG,QAC3B,kBAAC,OAAD;CACE,GAAI;CACJ,WAAW,EACT,sEACA,EACD;CACD,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nightstem/ui",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "React UI components for the Nightstem design system",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
7
8
|
"main": "./dist/index.js",
|
|
8
9
|
"types": "./dist/index.d.ts",
|
|
9
10
|
"files": [
|
|
@@ -12,8 +13,8 @@
|
|
|
12
13
|
],
|
|
13
14
|
"exports": {
|
|
14
15
|
".": {
|
|
15
|
-
"
|
|
16
|
-
"
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
17
18
|
},
|
|
18
19
|
"./package.json": "./package.json"
|
|
19
20
|
},
|
|
@@ -25,7 +26,15 @@
|
|
|
25
26
|
"access": "public"
|
|
26
27
|
},
|
|
27
28
|
"scripts": {
|
|
28
|
-
"build": "vite build",
|
|
29
|
+
"build": "rimraf dist && vite build",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"test": "vitest run --passWithNoTests",
|
|
32
|
+
"test:watch": "vitest",
|
|
33
|
+
"coverage": "vitest run --coverage --passWithNoTests",
|
|
34
|
+
"lint": "eslint .",
|
|
35
|
+
"format": "prettier --write . --ignore-unknown",
|
|
36
|
+
"format:check": "prettier --check . --ignore-unknown",
|
|
37
|
+
"storybook": "pnpm --filter @nightstem/storybook storybook",
|
|
29
38
|
"clean": "rimraf dist"
|
|
30
39
|
},
|
|
31
40
|
"peerDependencies": {
|
|
@@ -33,11 +42,18 @@
|
|
|
33
42
|
"react-dom": "^19.2.5"
|
|
34
43
|
},
|
|
35
44
|
"dependencies": {
|
|
36
|
-
"@nightstem/tokens": "workspace:*"
|
|
45
|
+
"@nightstem/tokens": "workspace:*",
|
|
46
|
+
"@nightstem/utils": "workspace:*"
|
|
37
47
|
},
|
|
38
48
|
"devDependencies": {
|
|
49
|
+
"@storybook/react": "^10.3.6",
|
|
50
|
+
"@types/react": "^19.0.0",
|
|
51
|
+
"@types/react-dom": "^19.0.0",
|
|
39
52
|
"@vitejs/plugin-react": "^6.0.1",
|
|
53
|
+
"rimraf": "^6.0.1",
|
|
40
54
|
"typescript": "^6.0.3",
|
|
41
|
-
"vite": "^8.0.10"
|
|
55
|
+
"vite": "^8.0.10",
|
|
56
|
+
"vite-plugin-dts": "^5.0.0",
|
|
57
|
+
"vitest-axe": "1.0.0-pre.5"
|
|
42
58
|
}
|
|
43
59
|
}
|