@northslopetech/altitude-ui 1.2.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 ADDED
@@ -0,0 +1,124 @@
1
+ # @nslp/altitude
2
+
3
+ React UI components for the Altitude design system, built on top of [shadcn/ui](https://ui.shadcn.com/) and styled with Altitude design tokens.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @nslp/altitude
9
+ # or
10
+ pnpm add @nslp/altitude
11
+ ```
12
+
13
+ ## Architecture
14
+
15
+ This package combines the best of both worlds:
16
+
17
+ - **shadcn/ui**: Provides the foundation, accessibility, and component patterns
18
+ - **Altitude Design Tokens**: Replaces shadcn/ui's default colors and typography with our design system
19
+
20
+ Components are built using:
21
+ - **Radix UI**: For accessibility and behavior
22
+ - **class-variance-authority**: For type-safe variant management
23
+ - **Tailwind CSS**: For styling with Altitude design tokens
24
+
25
+ ## Usage
26
+
27
+ ### Button
28
+
29
+ The Button component is built on shadcn/ui's Button but styled with Altitude design tokens.
30
+
31
+ ```tsx
32
+ import { Button } from '@nslp/altitude';
33
+
34
+ function Example() {
35
+ return (
36
+ <div className="flex gap-2 flex-wrap">
37
+ {/* Default variant */}
38
+ <Button>Primary Button</Button>
39
+
40
+ {/* Other variants */}
41
+ <Button variant="secondary">Secondary</Button>
42
+ <Button variant="outline">Outline</Button>
43
+ <Button variant="ghost">Ghost</Button>
44
+ <Button variant="link">Link</Button>
45
+ <Button variant="destructive">Destructive</Button>
46
+
47
+ {/* Different sizes */}
48
+ <Button size="sm">Small</Button>
49
+ <Button size="lg">Large</Button>
50
+ <Button size="xl">Extra Large</Button>
51
+ <Button size="icon">🎯</Button>
52
+ </div>
53
+ );
54
+ }
55
+ ```
56
+
57
+ #### Button Props
58
+
59
+ | Prop | Type | Default | Description |
60
+ |------|------|---------|-------------|
61
+ | `variant` | `'default' \| 'secondary' \| 'outline' \| 'ghost' \| 'link' \| 'destructive'` | `'default'` | Visual style variant |
62
+ | `size` | `'sm' \| 'default' \| 'lg' \| 'xl' \| 'icon'` | `'default'` | Size of the button |
63
+ | `asChild` | `boolean` | `false` | Render as child element (for composition) |
64
+
65
+ All standard HTML button attributes are also supported.
66
+
67
+ #### Design Token Integration
68
+
69
+ The Button component uses Altitude design tokens:
70
+
71
+ - **Colors**: `primary-*`, `neutral-*`, `semantic-error`, `base-white`
72
+ - **Typography**: `body-xs`, `body-sm`, `body-md`, `body-lg` font sizes
73
+ - **Focus states**: `primary-500` ring color
74
+ - **Hover states**: Consistent with design system color scales
75
+
76
+ ### asChild Pattern
77
+
78
+ Use the `asChild` prop for composition with other components (powered by Radix UI Slot):
79
+
80
+ ```tsx
81
+ import { Button } from '@nslp/altitude';
82
+ import Link from 'next/link';
83
+
84
+ <Button asChild>
85
+ <Link href="/dashboard">Go to Dashboard</Link>
86
+ </Button>
87
+ ```
88
+
89
+ ## shadcn/ui Integration
90
+
91
+ This package is configured to work with shadcn/ui:
92
+
93
+ - Uses the same component patterns and APIs
94
+ - Configured with `components.json` for CLI compatibility
95
+ - Can add more shadcn/ui components with: `npx shadcn@latest add [component]`
96
+ - All components are automatically styled with Altitude design tokens
97
+
98
+ ## Development
99
+
100
+ ```bash
101
+ # Build the package
102
+ pnpm build
103
+
104
+ # Watch for changes
105
+ pnpm dev
106
+
107
+ # Run linting
108
+ pnpm lint
109
+
110
+ # Type checking
111
+ pnpm check-types
112
+
113
+ # Add more shadcn/ui components
114
+ npx shadcn@latest add [component-name]
115
+ ```
116
+
117
+ ## Adding New Components
118
+
119
+ To add more shadcn/ui components:
120
+
121
+ 1. Run `npx shadcn@latest add [component-name]`
122
+ 2. Update the generated component to use Altitude design tokens
123
+ 3. Export the component from `src/index.ts`
124
+ 4. Update this README with usage examples
@@ -0,0 +1,56 @@
1
+ import * as class_variance_authority_types from 'class-variance-authority/types';
2
+ import * as React from 'react';
3
+ import { VariantProps } from 'class-variance-authority';
4
+ import * as SelectPrimitive from '@radix-ui/react-select';
5
+
6
+ declare const buttonVariants: (props?: ({
7
+ variant?: "default" | "outline" | "destructive" | "destructive-subtle" | "ghost" | "link" | null | undefined;
8
+ size?: "default" | "sm" | "lg" | "icon" | null | undefined;
9
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
10
+ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
11
+ asChild?: boolean;
12
+ }
13
+ declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
14
+
15
+ declare const typographyVariants: (props?: ({
16
+ variant?: "display-xl" | "display-lg" | "display-md" | "display-sm" | "display-xs" | "heading-xl" | "heading-lg" | "heading-md" | "heading-sm" | "heading-xs" | "body-xl" | "body-lg" | "body-md" | "body-sm" | "body-xs" | "label-xl" | "label-xl-bold" | "label-lg" | "label-lg-bold" | "label-md" | "label-md-bold" | "label-sm" | "label-sm-bold" | "label-xs" | "label-xs-bold" | null | undefined;
17
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
18
+ interface TypographyProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof typographyVariants> {
19
+ as?: React.ElementType;
20
+ }
21
+ declare const Typography: React.ForwardRefExoticComponent<TypographyProps & React.RefAttributes<HTMLElement>>;
22
+
23
+ declare const selectTriggerVariants: (props?: class_variance_authority_types.ClassProp | undefined) => string;
24
+ declare const selectContentVariants: (props?: ({
25
+ position?: "popper" | "item-aligned" | null | undefined;
26
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
27
+ declare const Select: React.FC<SelectPrimitive.SelectProps>;
28
+ declare const SelectGroup: React.ForwardRefExoticComponent<SelectPrimitive.SelectGroupProps & React.RefAttributes<HTMLDivElement>>;
29
+ declare const SelectValue: React.ForwardRefExoticComponent<SelectPrimitive.SelectValueProps & React.RefAttributes<HTMLSpanElement>>;
30
+ interface SelectTriggerProps extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>, VariantProps<typeof selectTriggerVariants> {
31
+ className?: string;
32
+ children?: React.ReactNode;
33
+ }
34
+ declare const SelectTrigger: React.ForwardRefExoticComponent<SelectTriggerProps & React.RefAttributes<HTMLButtonElement>>;
35
+ declare const SelectScrollUpButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollUpButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
36
+ declare const SelectScrollDownButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollDownButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
37
+ interface SelectContentProps extends Omit<React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>, 'position'>, VariantProps<typeof selectContentVariants> {
38
+ }
39
+ declare const SelectContent: React.ForwardRefExoticComponent<SelectContentProps & React.RefAttributes<HTMLDivElement>>;
40
+ declare const SelectLabel: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectLabelProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
41
+ declare const SelectItem: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
42
+ declare const SelectSeparator: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectSeparatorProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
43
+
44
+ interface FormFieldProps {
45
+ label?: string;
46
+ helperText?: string;
47
+ error?: boolean;
48
+ required?: boolean;
49
+ children: React.ReactNode;
50
+ className?: string;
51
+ id?: string;
52
+ compact?: boolean;
53
+ }
54
+ declare const FormField: React.ForwardRefExoticComponent<FormFieldProps & React.RefAttributes<HTMLDivElement>>;
55
+
56
+ export { Button, type ButtonProps, FormField, type FormFieldProps, Select, SelectContent, type SelectContentProps, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, type SelectTriggerProps, SelectValue, Typography, type TypographyProps, buttonVariants, selectTriggerVariants, typographyVariants };
@@ -0,0 +1,56 @@
1
+ import * as class_variance_authority_types from 'class-variance-authority/types';
2
+ import * as React from 'react';
3
+ import { VariantProps } from 'class-variance-authority';
4
+ import * as SelectPrimitive from '@radix-ui/react-select';
5
+
6
+ declare const buttonVariants: (props?: ({
7
+ variant?: "default" | "outline" | "destructive" | "destructive-subtle" | "ghost" | "link" | null | undefined;
8
+ size?: "default" | "sm" | "lg" | "icon" | null | undefined;
9
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
10
+ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
11
+ asChild?: boolean;
12
+ }
13
+ declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
14
+
15
+ declare const typographyVariants: (props?: ({
16
+ variant?: "display-xl" | "display-lg" | "display-md" | "display-sm" | "display-xs" | "heading-xl" | "heading-lg" | "heading-md" | "heading-sm" | "heading-xs" | "body-xl" | "body-lg" | "body-md" | "body-sm" | "body-xs" | "label-xl" | "label-xl-bold" | "label-lg" | "label-lg-bold" | "label-md" | "label-md-bold" | "label-sm" | "label-sm-bold" | "label-xs" | "label-xs-bold" | null | undefined;
17
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
18
+ interface TypographyProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof typographyVariants> {
19
+ as?: React.ElementType;
20
+ }
21
+ declare const Typography: React.ForwardRefExoticComponent<TypographyProps & React.RefAttributes<HTMLElement>>;
22
+
23
+ declare const selectTriggerVariants: (props?: class_variance_authority_types.ClassProp | undefined) => string;
24
+ declare const selectContentVariants: (props?: ({
25
+ position?: "popper" | "item-aligned" | null | undefined;
26
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
27
+ declare const Select: React.FC<SelectPrimitive.SelectProps>;
28
+ declare const SelectGroup: React.ForwardRefExoticComponent<SelectPrimitive.SelectGroupProps & React.RefAttributes<HTMLDivElement>>;
29
+ declare const SelectValue: React.ForwardRefExoticComponent<SelectPrimitive.SelectValueProps & React.RefAttributes<HTMLSpanElement>>;
30
+ interface SelectTriggerProps extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>, VariantProps<typeof selectTriggerVariants> {
31
+ className?: string;
32
+ children?: React.ReactNode;
33
+ }
34
+ declare const SelectTrigger: React.ForwardRefExoticComponent<SelectTriggerProps & React.RefAttributes<HTMLButtonElement>>;
35
+ declare const SelectScrollUpButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollUpButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
36
+ declare const SelectScrollDownButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollDownButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
37
+ interface SelectContentProps extends Omit<React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>, 'position'>, VariantProps<typeof selectContentVariants> {
38
+ }
39
+ declare const SelectContent: React.ForwardRefExoticComponent<SelectContentProps & React.RefAttributes<HTMLDivElement>>;
40
+ declare const SelectLabel: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectLabelProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
41
+ declare const SelectItem: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
42
+ declare const SelectSeparator: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectSeparatorProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
43
+
44
+ interface FormFieldProps {
45
+ label?: string;
46
+ helperText?: string;
47
+ error?: boolean;
48
+ required?: boolean;
49
+ children: React.ReactNode;
50
+ className?: string;
51
+ id?: string;
52
+ compact?: boolean;
53
+ }
54
+ declare const FormField: React.ForwardRefExoticComponent<FormFieldProps & React.RefAttributes<HTMLDivElement>>;
55
+
56
+ export { Button, type ButtonProps, FormField, type FormFieldProps, Select, SelectContent, type SelectContentProps, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, type SelectTriggerProps, SelectValue, Typography, type TypographyProps, buttonVariants, selectTriggerVariants, typographyVariants };
package/dist/index.js ADDED
@@ -0,0 +1,450 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ Button: () => Button,
34
+ FormField: () => FormField,
35
+ Select: () => Select,
36
+ SelectContent: () => SelectContent,
37
+ SelectGroup: () => SelectGroup,
38
+ SelectItem: () => SelectItem,
39
+ SelectLabel: () => SelectLabel,
40
+ SelectScrollDownButton: () => SelectScrollDownButton,
41
+ SelectScrollUpButton: () => SelectScrollUpButton,
42
+ SelectSeparator: () => SelectSeparator,
43
+ SelectTrigger: () => SelectTrigger,
44
+ SelectValue: () => SelectValue,
45
+ Typography: () => Typography,
46
+ buttonVariants: () => buttonVariants,
47
+ selectTriggerVariants: () => selectTriggerVariants,
48
+ typographyVariants: () => typographyVariants
49
+ });
50
+ module.exports = __toCommonJS(index_exports);
51
+
52
+ // src/components/ui/button.tsx
53
+ var React = __toESM(require("react"));
54
+ var import_react_slot = require("@radix-ui/react-slot");
55
+ var import_class_variance_authority2 = require("class-variance-authority");
56
+
57
+ // src/lib/utils.ts
58
+ var import_clsx = require("clsx");
59
+ var import_tailwind_merge = require("tailwind-merge");
60
+ var import_class_variance_authority = require("class-variance-authority");
61
+ function cn(...inputs) {
62
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
63
+ }
64
+
65
+ // src/components/ui/button.tsx
66
+ var import_jsx_runtime = require("react/jsx-runtime");
67
+ var buttonVariants = (0, import_class_variance_authority2.cva)(
68
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
69
+ {
70
+ variants: {
71
+ variant: {
72
+ default: "bg-canvas-primary text-light shadow-sm hover:brightness-[60%] active:brightness-[80%] focus-visible:ring-2 focus-visible:ring-border-interactive focus-visible:ring-offset-2",
73
+ outline: "bg-canvas-light text-dark border border-edge-strong shadow-sm hover:brightness-[70%] active:brightness-[90%] focus-visible:ring-2 focus-visible:ring-border-interactive focus-visible:ring-offset-2",
74
+ destructive: "bg-canvas-error-strong text-light shadow-sm hover:brightness-[60%] active:brightness-[80%] focus-visible:ring-2 focus-visible:ring-border-error focus-visible:ring-offset-2",
75
+ "destructive-subtle": "bg-canvas-light text-error border border-edge-default shadow-sm hover:brightness-[70%] active:brightness-[90%] focus-visible:ring-2 focus-visible:ring-border-error focus-visible:ring-offset-2",
76
+ ghost: "bg-canvas-light text-dark hover:brightness-[70%] active:brightness-[90%] focus-visible:ring-2 focus-visible:ring-border-interactive focus-visible:ring-offset-2",
77
+ link: "bg-canvas-light text-dark underline underline-offset-4 hover:brightness-[70%] active:brightness-[90%] focus-visible:ring-2 focus-visible:ring-border-interactive focus-visible:ring-offset-2"
78
+ },
79
+ size: {
80
+ sm: "h-8 rounded-md px-2 py-2 min-w-[120px]",
81
+ default: "h-10 rounded-md px-3 py-2 min-w-[125px]",
82
+ lg: "h-12 rounded-lg px-4 py-2 min-w-[141px]",
83
+ icon: "h-10 w-10 rounded-md"
84
+ }
85
+ },
86
+ compoundVariants: [],
87
+ defaultVariants: {
88
+ variant: "default",
89
+ size: "default"
90
+ }
91
+ }
92
+ );
93
+ function getButtonTypographyStyles(size) {
94
+ switch (size) {
95
+ case "sm":
96
+ return { font: "var(--typography-label-sm-bold)" };
97
+ case "lg":
98
+ return { font: "var(--typography-label-lg-bold)" };
99
+ case "icon":
100
+ case "default":
101
+ default:
102
+ return { font: "var(--typography-label-md-bold)" };
103
+ }
104
+ }
105
+ var Button = React.forwardRef(
106
+ ({ className, variant, size, asChild = false, style, ...props }, ref) => {
107
+ const Comp = asChild ? import_react_slot.Slot : "button";
108
+ const typographyStyles = getButtonTypographyStyles(size);
109
+ const tokenStyles = {
110
+ ...typographyStyles,
111
+ ...style
112
+ };
113
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
114
+ Comp,
115
+ {
116
+ className: cn(buttonVariants({ variant, size }), className),
117
+ style: tokenStyles,
118
+ ref,
119
+ ...props
120
+ }
121
+ );
122
+ }
123
+ );
124
+ Button.displayName = "Button";
125
+
126
+ // src/components/ui/typography.tsx
127
+ var React2 = __toESM(require("react"));
128
+ var import_class_variance_authority3 = require("class-variance-authority");
129
+ var import_jsx_runtime2 = require("react/jsx-runtime");
130
+ var typographyVariants = (0, import_class_variance_authority3.cva)(
131
+ "text-foreground",
132
+ {
133
+ variants: {
134
+ variant: {
135
+ "display-xl": "[font:var(--typography-display-xl)]",
136
+ "display-lg": "[font:var(--typography-display-lg)]",
137
+ "display-md": "[font:var(--typography-display-md)]",
138
+ "display-sm": "[font:var(--typography-display-sm)]",
139
+ "display-xs": "[font:var(--typography-display-xs)]",
140
+ "heading-xl": "[font:var(--typography-heading-xl)]",
141
+ "heading-lg": "[font:var(--typography-heading-lg)]",
142
+ "heading-md": "[font:var(--typography-heading-md)]",
143
+ "heading-sm": "[font:var(--typography-heading-sm)]",
144
+ "heading-xs": "[font:var(--typography-heading-xs)]",
145
+ "body-xl": "[font:var(--typography-body-xl)]",
146
+ "body-lg": "[font:var(--typography-body-lg)]",
147
+ "body-md": "[font:var(--typography-body-md)]",
148
+ "body-sm": "[font:var(--typography-body-sm)]",
149
+ "body-xs": "[font:var(--typography-body-xs)]",
150
+ "label-xl": "[font:var(--typography-label-xl-regular)]",
151
+ "label-xl-bold": "[font:var(--typography-label-xl-bold)]",
152
+ "label-lg": "[font:var(--typography-label-lg-regular)]",
153
+ "label-lg-bold": "[font:var(--typography-label-lg-bold)]",
154
+ "label-md": "[font:var(--typography-label-md-regular)]",
155
+ "label-md-bold": "[font:var(--typography-label-md-bold)]",
156
+ "label-sm": "[font:var(--typography-label-sm-regular)]",
157
+ "label-sm-bold": "[font:var(--typography-label-sm-bold)]",
158
+ "label-xs": "[font:var(--typography-label-xs-regular)]",
159
+ "label-xs-bold": "[font:var(--typography-label-xs-bold)]"
160
+ }
161
+ },
162
+ defaultVariants: {
163
+ variant: "body-md"
164
+ }
165
+ }
166
+ );
167
+ function getDefaultElement(variant) {
168
+ if (!variant) return "p";
169
+ if (variant.startsWith("display-")) return "h1";
170
+ if (variant.startsWith("heading-")) return "h2";
171
+ if (variant.startsWith("label-")) return "label";
172
+ if (variant.startsWith("body-")) return "p";
173
+ return "p";
174
+ }
175
+ var Typography = React2.forwardRef(
176
+ ({ className, variant, as, style, ...props }, ref) => {
177
+ const Component = as || getDefaultElement(variant);
178
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
179
+ Component,
180
+ {
181
+ className: cn(typographyVariants({ variant }), className),
182
+ style,
183
+ ref,
184
+ ...props
185
+ }
186
+ );
187
+ }
188
+ );
189
+ Typography.displayName = "Typography";
190
+
191
+ // src/components/ui/select.tsx
192
+ var React3 = __toESM(require("react"));
193
+ var SelectPrimitive = __toESM(require("@radix-ui/react-select"));
194
+ var import_class_variance_authority4 = require("class-variance-authority");
195
+ var import_lucide_react = require("lucide-react");
196
+ var import_jsx_runtime3 = require("react/jsx-runtime");
197
+ var selectTriggerVariants = (0, import_class_variance_authority4.cva)(
198
+ "flex w-full items-center justify-between border bg-canvas-light text-dark focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 transition-colors h-10 rounded-md px-3 py-2 min-w-80"
199
+ );
200
+ var selectContentVariants = (0, import_class_variance_authority4.cva)(
201
+ "relative z-50 max-h-60 min-w-32 overflow-hidden rounded-lg border border-edge-default bg-canvas-light text-dark shadow-lg animate-in fade-in-0 zoom-in-95 duration-200",
202
+ {
203
+ variants: {
204
+ position: {
205
+ "popper": "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
206
+ "item-aligned": ""
207
+ }
208
+ },
209
+ defaultVariants: {
210
+ position: "popper"
211
+ }
212
+ }
213
+ );
214
+ var Select = SelectPrimitive.Root;
215
+ Select.displayName = "Select";
216
+ var SelectGroup = SelectPrimitive.Group;
217
+ SelectGroup.displayName = "SelectGroup";
218
+ var SelectValue = SelectPrimitive.Value;
219
+ SelectValue.displayName = "SelectValue";
220
+ var SelectTrigger = React3.forwardRef(({ className, children, style, ...props }, ref) => {
221
+ const tokenStyles = {
222
+ font: "var(--typography-label-md-regular)",
223
+ ...style
224
+ };
225
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
226
+ SelectPrimitive.Trigger,
227
+ {
228
+ ref,
229
+ className: cn(selectTriggerVariants(), "border-edge-default focus-visible:border-2 focus-visible:border-edge-strong data-[state=open]:[&_svg]:rotate-180", className),
230
+ style: tokenStyles,
231
+ ...props,
232
+ children: [
233
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "flex-1 text-left truncate", children }),
234
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.ChevronDown, { className: "h-5 w-5 text-secondary flex-shrink-0 transition-transform duration-200" }) })
235
+ ]
236
+ }
237
+ );
238
+ });
239
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
240
+ var SelectScrollUpButton = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
241
+ SelectPrimitive.ScrollUpButton,
242
+ {
243
+ ref,
244
+ className: cn(
245
+ "flex cursor-default items-center justify-center py-1 text-secondary",
246
+ className
247
+ ),
248
+ ...props,
249
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.ChevronUp, { className: "h-4 w-4" })
250
+ }
251
+ ));
252
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
253
+ var SelectScrollDownButton = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
254
+ SelectPrimitive.ScrollDownButton,
255
+ {
256
+ ref,
257
+ className: cn(
258
+ "flex cursor-default items-center justify-center py-1 text-secondary",
259
+ className
260
+ ),
261
+ ...props,
262
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.ChevronDown, { className: "h-4 w-4" })
263
+ }
264
+ ));
265
+ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
266
+ var SelectContent = React3.forwardRef(({ className, children, position = "popper", ...props }, ref) => {
267
+ const contentPosition = position || "popper";
268
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SelectPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
269
+ SelectPrimitive.Content,
270
+ {
271
+ ref,
272
+ className: cn(selectContentVariants({ position: contentPosition }), className),
273
+ position: contentPosition,
274
+ ...props,
275
+ children: [
276
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SelectScrollUpButton, {}),
277
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
278
+ SelectPrimitive.Viewport,
279
+ {
280
+ className: cn(
281
+ "p-1",
282
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
283
+ ),
284
+ children
285
+ }
286
+ ),
287
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SelectScrollDownButton, {})
288
+ ]
289
+ }
290
+ ) });
291
+ });
292
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
293
+ var SelectLabel = React3.forwardRef(({ className, children, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
294
+ SelectPrimitive.Label,
295
+ {
296
+ ref,
297
+ className: cn(
298
+ "py-1.5 pl-8 pr-2 text-secondary",
299
+ className
300
+ ),
301
+ style: { font: "var(--typography-label-xs-regular)", ...style },
302
+ ...props,
303
+ children
304
+ }
305
+ ));
306
+ SelectLabel.displayName = SelectPrimitive.Label.displayName;
307
+ var SelectItem = React3.forwardRef(({ className, children, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
308
+ SelectPrimitive.Item,
309
+ {
310
+ ref,
311
+ className: cn(
312
+ "relative flex w-full cursor-pointer select-none items-center rounded-md h-11 px-4 text-dark outline-none transition-colors",
313
+ "focus:bg-canvas-gray focus:text-dark",
314
+ "hover:bg-canvas-gray/50",
315
+ "data-[state=checked]:bg-canvas-surface-info data-[state=checked]:text-dark",
316
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
317
+ className
318
+ ),
319
+ style: { font: "var(--typography-label-md-regular)", ...style },
320
+ ...props,
321
+ children: [
322
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SelectPrimitive.ItemText, { className: "flex-1 truncate", children }),
323
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SelectPrimitive.ItemIndicator, { className: "flex h-4 w-4 items-center justify-center ml-auto", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.Check, { className: "h-4 w-4 text-edge-strong" }) })
324
+ ]
325
+ }
326
+ ));
327
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
328
+ var SelectSeparator = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
329
+ SelectPrimitive.Separator,
330
+ {
331
+ ref,
332
+ className: cn("-mx-1 my-1 h-px bg-edge-default", className),
333
+ ...props
334
+ }
335
+ ));
336
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
337
+
338
+ // src/components/ui/form-field.tsx
339
+ var React4 = __toESM(require("react"));
340
+ var import_jsx_runtime4 = require("react/jsx-runtime");
341
+ var FormField = React4.forwardRef(({
342
+ label,
343
+ helperText,
344
+ error = false,
345
+ required = false,
346
+ children,
347
+ className,
348
+ id,
349
+ compact = false,
350
+ ...props
351
+ }, ref) => {
352
+ const generatedId = React4.useId();
353
+ const fieldId = id || generatedId;
354
+ const helperTextId = `${fieldId}-helper`;
355
+ const labelId = `${fieldId}-label`;
356
+ if (compact) {
357
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { ref, className: cn("w-full space-y-2", className), ...props, children: [
358
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "relative", children: [
359
+ React4.cloneElement(children, {
360
+ id: fieldId,
361
+ "aria-labelledby": label ? labelId : void 0,
362
+ "aria-describedby": helperText ? helperTextId : void 0,
363
+ "aria-required": required,
364
+ "aria-invalid": error,
365
+ className: cn(
366
+ "pt-7 pb-2 h-14 items-end",
367
+ error ? "border-2 border-error-500 focus:border-error-500" : "",
368
+ children.props.className
369
+ )
370
+ }),
371
+ label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
372
+ "label",
373
+ {
374
+ id: labelId,
375
+ htmlFor: fieldId,
376
+ className: "absolute left-3 top-2 text-xs text-semantic-text-info [font:var(--typography-label-xs-bold)] pointer-events-none",
377
+ children: label
378
+ }
379
+ )
380
+ ] }),
381
+ helperText && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
382
+ Typography,
383
+ {
384
+ variant: "body-xs",
385
+ id: helperTextId,
386
+ className: cn(
387
+ error ? "text-semantic-text-error" : "text-semantic-text-secondary"
388
+ ),
389
+ children: helperText
390
+ }
391
+ )
392
+ ] });
393
+ }
394
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { ref, className: cn("w-full space-y-3", className), ...props, children: [
395
+ (label || required) && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center justify-between", children: [
396
+ label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
397
+ "label",
398
+ {
399
+ id: labelId,
400
+ htmlFor: fieldId,
401
+ className: "text-semantic-text-primary [font:var(--typography-label-sm-regular)]",
402
+ children: label
403
+ }
404
+ ),
405
+ required && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-semantic-text-secondary [font:var(--typography-label-xs-regular)]", children: "*required" })
406
+ ] }),
407
+ React4.cloneElement(children, {
408
+ id: fieldId,
409
+ "aria-labelledby": label ? labelId : void 0,
410
+ "aria-describedby": helperText ? helperTextId : void 0,
411
+ "aria-required": required,
412
+ "aria-invalid": error,
413
+ className: cn(
414
+ error ? "border-2 border-error-500 focus:border-error-500" : "",
415
+ children.props.className
416
+ )
417
+ }),
418
+ helperText && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
419
+ Typography,
420
+ {
421
+ variant: "body-xs",
422
+ id: helperTextId,
423
+ className: cn(
424
+ error ? "text-semantic-text-error" : "text-semantic-text-secondary"
425
+ ),
426
+ children: helperText
427
+ }
428
+ )
429
+ ] });
430
+ });
431
+ FormField.displayName = "FormField";
432
+ // Annotate the CommonJS export names for ESM import in node:
433
+ 0 && (module.exports = {
434
+ Button,
435
+ FormField,
436
+ Select,
437
+ SelectContent,
438
+ SelectGroup,
439
+ SelectItem,
440
+ SelectLabel,
441
+ SelectScrollDownButton,
442
+ SelectScrollUpButton,
443
+ SelectSeparator,
444
+ SelectTrigger,
445
+ SelectValue,
446
+ Typography,
447
+ buttonVariants,
448
+ selectTriggerVariants,
449
+ typographyVariants
450
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,398 @@
1
+ // src/components/ui/button.tsx
2
+ import * as React from "react";
3
+ import { Slot } from "@radix-ui/react-slot";
4
+ import { cva as cva2 } from "class-variance-authority";
5
+
6
+ // src/lib/utils.ts
7
+ import { clsx } from "clsx";
8
+ import { twMerge } from "tailwind-merge";
9
+ import { cva } from "class-variance-authority";
10
+ function cn(...inputs) {
11
+ return twMerge(clsx(inputs));
12
+ }
13
+
14
+ // src/components/ui/button.tsx
15
+ import { jsx } from "react/jsx-runtime";
16
+ var buttonVariants = cva2(
17
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
18
+ {
19
+ variants: {
20
+ variant: {
21
+ default: "bg-canvas-primary text-light shadow-sm hover:brightness-[60%] active:brightness-[80%] focus-visible:ring-2 focus-visible:ring-border-interactive focus-visible:ring-offset-2",
22
+ outline: "bg-canvas-light text-dark border border-edge-strong shadow-sm hover:brightness-[70%] active:brightness-[90%] focus-visible:ring-2 focus-visible:ring-border-interactive focus-visible:ring-offset-2",
23
+ destructive: "bg-canvas-error-strong text-light shadow-sm hover:brightness-[60%] active:brightness-[80%] focus-visible:ring-2 focus-visible:ring-border-error focus-visible:ring-offset-2",
24
+ "destructive-subtle": "bg-canvas-light text-error border border-edge-default shadow-sm hover:brightness-[70%] active:brightness-[90%] focus-visible:ring-2 focus-visible:ring-border-error focus-visible:ring-offset-2",
25
+ ghost: "bg-canvas-light text-dark hover:brightness-[70%] active:brightness-[90%] focus-visible:ring-2 focus-visible:ring-border-interactive focus-visible:ring-offset-2",
26
+ link: "bg-canvas-light text-dark underline underline-offset-4 hover:brightness-[70%] active:brightness-[90%] focus-visible:ring-2 focus-visible:ring-border-interactive focus-visible:ring-offset-2"
27
+ },
28
+ size: {
29
+ sm: "h-8 rounded-md px-2 py-2 min-w-[120px]",
30
+ default: "h-10 rounded-md px-3 py-2 min-w-[125px]",
31
+ lg: "h-12 rounded-lg px-4 py-2 min-w-[141px]",
32
+ icon: "h-10 w-10 rounded-md"
33
+ }
34
+ },
35
+ compoundVariants: [],
36
+ defaultVariants: {
37
+ variant: "default",
38
+ size: "default"
39
+ }
40
+ }
41
+ );
42
+ function getButtonTypographyStyles(size) {
43
+ switch (size) {
44
+ case "sm":
45
+ return { font: "var(--typography-label-sm-bold)" };
46
+ case "lg":
47
+ return { font: "var(--typography-label-lg-bold)" };
48
+ case "icon":
49
+ case "default":
50
+ default:
51
+ return { font: "var(--typography-label-md-bold)" };
52
+ }
53
+ }
54
+ var Button = React.forwardRef(
55
+ ({ className, variant, size, asChild = false, style, ...props }, ref) => {
56
+ const Comp = asChild ? Slot : "button";
57
+ const typographyStyles = getButtonTypographyStyles(size);
58
+ const tokenStyles = {
59
+ ...typographyStyles,
60
+ ...style
61
+ };
62
+ return /* @__PURE__ */ jsx(
63
+ Comp,
64
+ {
65
+ className: cn(buttonVariants({ variant, size }), className),
66
+ style: tokenStyles,
67
+ ref,
68
+ ...props
69
+ }
70
+ );
71
+ }
72
+ );
73
+ Button.displayName = "Button";
74
+
75
+ // src/components/ui/typography.tsx
76
+ import * as React2 from "react";
77
+ import { cva as cva3 } from "class-variance-authority";
78
+ import { jsx as jsx2 } from "react/jsx-runtime";
79
+ var typographyVariants = cva3(
80
+ "text-foreground",
81
+ {
82
+ variants: {
83
+ variant: {
84
+ "display-xl": "[font:var(--typography-display-xl)]",
85
+ "display-lg": "[font:var(--typography-display-lg)]",
86
+ "display-md": "[font:var(--typography-display-md)]",
87
+ "display-sm": "[font:var(--typography-display-sm)]",
88
+ "display-xs": "[font:var(--typography-display-xs)]",
89
+ "heading-xl": "[font:var(--typography-heading-xl)]",
90
+ "heading-lg": "[font:var(--typography-heading-lg)]",
91
+ "heading-md": "[font:var(--typography-heading-md)]",
92
+ "heading-sm": "[font:var(--typography-heading-sm)]",
93
+ "heading-xs": "[font:var(--typography-heading-xs)]",
94
+ "body-xl": "[font:var(--typography-body-xl)]",
95
+ "body-lg": "[font:var(--typography-body-lg)]",
96
+ "body-md": "[font:var(--typography-body-md)]",
97
+ "body-sm": "[font:var(--typography-body-sm)]",
98
+ "body-xs": "[font:var(--typography-body-xs)]",
99
+ "label-xl": "[font:var(--typography-label-xl-regular)]",
100
+ "label-xl-bold": "[font:var(--typography-label-xl-bold)]",
101
+ "label-lg": "[font:var(--typography-label-lg-regular)]",
102
+ "label-lg-bold": "[font:var(--typography-label-lg-bold)]",
103
+ "label-md": "[font:var(--typography-label-md-regular)]",
104
+ "label-md-bold": "[font:var(--typography-label-md-bold)]",
105
+ "label-sm": "[font:var(--typography-label-sm-regular)]",
106
+ "label-sm-bold": "[font:var(--typography-label-sm-bold)]",
107
+ "label-xs": "[font:var(--typography-label-xs-regular)]",
108
+ "label-xs-bold": "[font:var(--typography-label-xs-bold)]"
109
+ }
110
+ },
111
+ defaultVariants: {
112
+ variant: "body-md"
113
+ }
114
+ }
115
+ );
116
+ function getDefaultElement(variant) {
117
+ if (!variant) return "p";
118
+ if (variant.startsWith("display-")) return "h1";
119
+ if (variant.startsWith("heading-")) return "h2";
120
+ if (variant.startsWith("label-")) return "label";
121
+ if (variant.startsWith("body-")) return "p";
122
+ return "p";
123
+ }
124
+ var Typography = React2.forwardRef(
125
+ ({ className, variant, as, style, ...props }, ref) => {
126
+ const Component = as || getDefaultElement(variant);
127
+ return /* @__PURE__ */ jsx2(
128
+ Component,
129
+ {
130
+ className: cn(typographyVariants({ variant }), className),
131
+ style,
132
+ ref,
133
+ ...props
134
+ }
135
+ );
136
+ }
137
+ );
138
+ Typography.displayName = "Typography";
139
+
140
+ // src/components/ui/select.tsx
141
+ import * as React3 from "react";
142
+ import * as SelectPrimitive from "@radix-ui/react-select";
143
+ import { cva as cva4 } from "class-variance-authority";
144
+ import { Check, ChevronDown, ChevronUp } from "lucide-react";
145
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
146
+ var selectTriggerVariants = cva4(
147
+ "flex w-full items-center justify-between border bg-canvas-light text-dark focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 transition-colors h-10 rounded-md px-3 py-2 min-w-80"
148
+ );
149
+ var selectContentVariants = cva4(
150
+ "relative z-50 max-h-60 min-w-32 overflow-hidden rounded-lg border border-edge-default bg-canvas-light text-dark shadow-lg animate-in fade-in-0 zoom-in-95 duration-200",
151
+ {
152
+ variants: {
153
+ position: {
154
+ "popper": "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
155
+ "item-aligned": ""
156
+ }
157
+ },
158
+ defaultVariants: {
159
+ position: "popper"
160
+ }
161
+ }
162
+ );
163
+ var Select = SelectPrimitive.Root;
164
+ Select.displayName = "Select";
165
+ var SelectGroup = SelectPrimitive.Group;
166
+ SelectGroup.displayName = "SelectGroup";
167
+ var SelectValue = SelectPrimitive.Value;
168
+ SelectValue.displayName = "SelectValue";
169
+ var SelectTrigger = React3.forwardRef(({ className, children, style, ...props }, ref) => {
170
+ const tokenStyles = {
171
+ font: "var(--typography-label-md-regular)",
172
+ ...style
173
+ };
174
+ return /* @__PURE__ */ jsxs(
175
+ SelectPrimitive.Trigger,
176
+ {
177
+ ref,
178
+ className: cn(selectTriggerVariants(), "border-edge-default focus-visible:border-2 focus-visible:border-edge-strong data-[state=open]:[&_svg]:rotate-180", className),
179
+ style: tokenStyles,
180
+ ...props,
181
+ children: [
182
+ /* @__PURE__ */ jsx3("span", { className: "flex-1 text-left truncate", children }),
183
+ /* @__PURE__ */ jsx3(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx3(ChevronDown, { className: "h-5 w-5 text-secondary flex-shrink-0 transition-transform duration-200" }) })
184
+ ]
185
+ }
186
+ );
187
+ });
188
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
189
+ var SelectScrollUpButton = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx3(
190
+ SelectPrimitive.ScrollUpButton,
191
+ {
192
+ ref,
193
+ className: cn(
194
+ "flex cursor-default items-center justify-center py-1 text-secondary",
195
+ className
196
+ ),
197
+ ...props,
198
+ children: /* @__PURE__ */ jsx3(ChevronUp, { className: "h-4 w-4" })
199
+ }
200
+ ));
201
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
202
+ var SelectScrollDownButton = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx3(
203
+ SelectPrimitive.ScrollDownButton,
204
+ {
205
+ ref,
206
+ className: cn(
207
+ "flex cursor-default items-center justify-center py-1 text-secondary",
208
+ className
209
+ ),
210
+ ...props,
211
+ children: /* @__PURE__ */ jsx3(ChevronDown, { className: "h-4 w-4" })
212
+ }
213
+ ));
214
+ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
215
+ var SelectContent = React3.forwardRef(({ className, children, position = "popper", ...props }, ref) => {
216
+ const contentPosition = position || "popper";
217
+ return /* @__PURE__ */ jsx3(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
218
+ SelectPrimitive.Content,
219
+ {
220
+ ref,
221
+ className: cn(selectContentVariants({ position: contentPosition }), className),
222
+ position: contentPosition,
223
+ ...props,
224
+ children: [
225
+ /* @__PURE__ */ jsx3(SelectScrollUpButton, {}),
226
+ /* @__PURE__ */ jsx3(
227
+ SelectPrimitive.Viewport,
228
+ {
229
+ className: cn(
230
+ "p-1",
231
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
232
+ ),
233
+ children
234
+ }
235
+ ),
236
+ /* @__PURE__ */ jsx3(SelectScrollDownButton, {})
237
+ ]
238
+ }
239
+ ) });
240
+ });
241
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
242
+ var SelectLabel = React3.forwardRef(({ className, children, style, ...props }, ref) => /* @__PURE__ */ jsx3(
243
+ SelectPrimitive.Label,
244
+ {
245
+ ref,
246
+ className: cn(
247
+ "py-1.5 pl-8 pr-2 text-secondary",
248
+ className
249
+ ),
250
+ style: { font: "var(--typography-label-xs-regular)", ...style },
251
+ ...props,
252
+ children
253
+ }
254
+ ));
255
+ SelectLabel.displayName = SelectPrimitive.Label.displayName;
256
+ var SelectItem = React3.forwardRef(({ className, children, style, ...props }, ref) => /* @__PURE__ */ jsxs(
257
+ SelectPrimitive.Item,
258
+ {
259
+ ref,
260
+ className: cn(
261
+ "relative flex w-full cursor-pointer select-none items-center rounded-md h-11 px-4 text-dark outline-none transition-colors",
262
+ "focus:bg-canvas-gray focus:text-dark",
263
+ "hover:bg-canvas-gray/50",
264
+ "data-[state=checked]:bg-canvas-surface-info data-[state=checked]:text-dark",
265
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
266
+ className
267
+ ),
268
+ style: { font: "var(--typography-label-md-regular)", ...style },
269
+ ...props,
270
+ children: [
271
+ /* @__PURE__ */ jsx3(SelectPrimitive.ItemText, { className: "flex-1 truncate", children }),
272
+ /* @__PURE__ */ jsx3(SelectPrimitive.ItemIndicator, { className: "flex h-4 w-4 items-center justify-center ml-auto", children: /* @__PURE__ */ jsx3(Check, { className: "h-4 w-4 text-edge-strong" }) })
273
+ ]
274
+ }
275
+ ));
276
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
277
+ var SelectSeparator = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx3(
278
+ SelectPrimitive.Separator,
279
+ {
280
+ ref,
281
+ className: cn("-mx-1 my-1 h-px bg-edge-default", className),
282
+ ...props
283
+ }
284
+ ));
285
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
286
+
287
+ // src/components/ui/form-field.tsx
288
+ import * as React4 from "react";
289
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
290
+ var FormField = React4.forwardRef(({
291
+ label,
292
+ helperText,
293
+ error = false,
294
+ required = false,
295
+ children,
296
+ className,
297
+ id,
298
+ compact = false,
299
+ ...props
300
+ }, ref) => {
301
+ const generatedId = React4.useId();
302
+ const fieldId = id || generatedId;
303
+ const helperTextId = `${fieldId}-helper`;
304
+ const labelId = `${fieldId}-label`;
305
+ if (compact) {
306
+ return /* @__PURE__ */ jsxs2("div", { ref, className: cn("w-full space-y-2", className), ...props, children: [
307
+ /* @__PURE__ */ jsxs2("div", { className: "relative", children: [
308
+ React4.cloneElement(children, {
309
+ id: fieldId,
310
+ "aria-labelledby": label ? labelId : void 0,
311
+ "aria-describedby": helperText ? helperTextId : void 0,
312
+ "aria-required": required,
313
+ "aria-invalid": error,
314
+ className: cn(
315
+ "pt-7 pb-2 h-14 items-end",
316
+ error ? "border-2 border-error-500 focus:border-error-500" : "",
317
+ children.props.className
318
+ )
319
+ }),
320
+ label && /* @__PURE__ */ jsx4(
321
+ "label",
322
+ {
323
+ id: labelId,
324
+ htmlFor: fieldId,
325
+ className: "absolute left-3 top-2 text-xs text-semantic-text-info [font:var(--typography-label-xs-bold)] pointer-events-none",
326
+ children: label
327
+ }
328
+ )
329
+ ] }),
330
+ helperText && /* @__PURE__ */ jsx4(
331
+ Typography,
332
+ {
333
+ variant: "body-xs",
334
+ id: helperTextId,
335
+ className: cn(
336
+ error ? "text-semantic-text-error" : "text-semantic-text-secondary"
337
+ ),
338
+ children: helperText
339
+ }
340
+ )
341
+ ] });
342
+ }
343
+ return /* @__PURE__ */ jsxs2("div", { ref, className: cn("w-full space-y-3", className), ...props, children: [
344
+ (label || required) && /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between", children: [
345
+ label && /* @__PURE__ */ jsx4(
346
+ "label",
347
+ {
348
+ id: labelId,
349
+ htmlFor: fieldId,
350
+ className: "text-semantic-text-primary [font:var(--typography-label-sm-regular)]",
351
+ children: label
352
+ }
353
+ ),
354
+ required && /* @__PURE__ */ jsx4("span", { className: "text-semantic-text-secondary [font:var(--typography-label-xs-regular)]", children: "*required" })
355
+ ] }),
356
+ React4.cloneElement(children, {
357
+ id: fieldId,
358
+ "aria-labelledby": label ? labelId : void 0,
359
+ "aria-describedby": helperText ? helperTextId : void 0,
360
+ "aria-required": required,
361
+ "aria-invalid": error,
362
+ className: cn(
363
+ error ? "border-2 border-error-500 focus:border-error-500" : "",
364
+ children.props.className
365
+ )
366
+ }),
367
+ helperText && /* @__PURE__ */ jsx4(
368
+ Typography,
369
+ {
370
+ variant: "body-xs",
371
+ id: helperTextId,
372
+ className: cn(
373
+ error ? "text-semantic-text-error" : "text-semantic-text-secondary"
374
+ ),
375
+ children: helperText
376
+ }
377
+ )
378
+ ] });
379
+ });
380
+ FormField.displayName = "FormField";
381
+ export {
382
+ Button,
383
+ FormField,
384
+ Select,
385
+ SelectContent,
386
+ SelectGroup,
387
+ SelectItem,
388
+ SelectLabel,
389
+ SelectScrollDownButton,
390
+ SelectScrollUpButton,
391
+ SelectSeparator,
392
+ SelectTrigger,
393
+ SelectValue,
394
+ Typography,
395
+ buttonVariants,
396
+ selectTriggerVariants,
397
+ typographyVariants
398
+ };
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@northslopetech/altitude-ui",
3
+ "version": "1.2.0",
4
+ "private": false,
5
+ "description": "React UI components for the Altitude design system",
6
+ "author": "Northslope",
7
+ "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/northslopetech/altitude-design-system.git",
11
+ "directory": "packages/altitude-ui"
12
+ },
13
+ "homepage": "https://github.com/northslopetech/altitude-design-system#readme",
14
+ "keywords": [
15
+ "react",
16
+ "ui",
17
+ "components",
18
+ "design-system",
19
+ "tailwind"
20
+ ],
21
+ "main": "dist/index.js",
22
+ "types": "dist/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "import": "./dist/index.mjs",
27
+ "require": "./dist/index.js"
28
+ },
29
+ "./tokens.css": "./dist/tokens.css",
30
+ "./tailwind": "./tailwind.preset.js",
31
+ "./*": {
32
+ "types": "./dist/*.d.ts",
33
+ "import": "./dist/*.mjs",
34
+ "require": "./dist/*.js"
35
+ }
36
+ },
37
+ "files": [
38
+ "dist",
39
+ "tailwind.preset.js"
40
+ ],
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^22.15.3",
46
+ "@types/react": "19.1.0",
47
+ "@types/react-dom": "19.1.1",
48
+ "eslint": "^9.31.0",
49
+ "tailwindcss": "^4.1.11",
50
+ "tsup": "^8.0.0",
51
+ "typescript": "5.8.2",
52
+ "@repo/eslint-config": "0.0.0",
53
+ "@repo/typescript-config": "0.0.0",
54
+ "@northslopetech/altitude-tokens": "1.0.0"
55
+ },
56
+ "dependencies": {
57
+ "@radix-ui/react-dropdown-menu": "^2.1.15",
58
+ "@radix-ui/react-label": "^2.1.7",
59
+ "@radix-ui/react-select": "^2.2.6",
60
+ "@radix-ui/react-slot": "^1.2.3",
61
+ "class-variance-authority": "^0.7.1",
62
+ "clsx": "^2.1.1",
63
+ "lucide-react": "^0.536.0",
64
+ "tailwind-merge": "^2.5.4"
65
+ },
66
+ "peerDependencies": {
67
+ "react": "^18.0.0 || ^19.0.0",
68
+ "react-dom": "^18.0.0 || ^19.0.0"
69
+ },
70
+ "scripts": {
71
+ "prebuild": "cd ../altitude-tokens && npm run build",
72
+ "build": "tsup src/index.ts --format cjs,esm --dts --external react --external react-dom",
73
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch --external react --external react-dom --external altitude-tokens",
74
+ "clean": "rm -rf dist",
75
+ "lint": "eslint . --max-warnings 0",
76
+ "generate:component": "turbo gen react-component",
77
+ "check-types": "tsc --noEmit"
78
+ }
79
+ }