@teja-app/ui 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +169 -0
  2. package/dist/components/Button/Button.d.ts +13 -0
  3. package/dist/components/Button/Button.d.ts.map +1 -0
  4. package/dist/components/Button/Button.types.d.ts +18 -0
  5. package/dist/components/Button/Button.types.d.ts.map +1 -0
  6. package/dist/components/Button/index.d.ts +3 -0
  7. package/dist/components/Button/index.d.ts.map +1 -0
  8. package/dist/components/index.d.ts +5 -0
  9. package/dist/components/index.d.ts.map +1 -0
  10. package/dist/hooks/index.cjs +2 -0
  11. package/dist/hooks/index.cjs.map +1 -0
  12. package/dist/hooks/index.d.ts +10 -0
  13. package/dist/hooks/index.d.ts.map +1 -0
  14. package/dist/hooks/index.js +2 -0
  15. package/dist/hooks/index.js.map +1 -0
  16. package/dist/index.cjs +96 -0
  17. package/dist/index.cjs.map +1 -0
  18. package/dist/index.d.ts +13 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +96 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/tailwind/colors.d.ts +46 -0
  23. package/dist/tailwind/colors.d.ts.map +1 -0
  24. package/dist/tailwind/index.cjs +138 -0
  25. package/dist/tailwind/index.cjs.map +1 -0
  26. package/dist/tailwind/index.d.ts +17 -0
  27. package/dist/tailwind/index.d.ts.map +1 -0
  28. package/dist/tailwind/index.js +138 -0
  29. package/dist/tailwind/index.js.map +1 -0
  30. package/dist/tailwind/preset.d.ts +20 -0
  31. package/dist/tailwind/preset.d.ts.map +1 -0
  32. package/dist/tailwind/spacing.d.ts +53 -0
  33. package/dist/tailwind/spacing.d.ts.map +1 -0
  34. package/dist/tailwind/typography.d.ts +41 -0
  35. package/dist/tailwind/typography.d.ts.map +1 -0
  36. package/dist/utils/cn.d.ts +12 -0
  37. package/dist/utils/cn.d.ts.map +1 -0
  38. package/dist/utils/index.cjs +3027 -0
  39. package/dist/utils/index.cjs.map +1 -0
  40. package/dist/utils/index.d.ts +10 -0
  41. package/dist/utils/index.d.ts.map +1 -0
  42. package/dist/utils/index.js +3027 -0
  43. package/dist/utils/index.js.map +1 -0
  44. package/package.json +121 -0
package/README.md ADDED
@@ -0,0 +1,169 @@
1
+ # @teja-app/ui
2
+
3
+ Shared UI component library for Teja applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @teja-app/ui
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ ### 1. Configure Tailwind
14
+
15
+ ```ts
16
+ // tailwind.config.js
17
+ import tejaPreset from '@teja-app/ui/tailwind';
18
+
19
+ export default {
20
+ presets: [tejaPreset],
21
+ content: [
22
+ "./src/**/*.{js,ts,jsx,tsx}",
23
+ "./node_modules/@teja-app/ui/dist/**/*.{js,mjs}",
24
+ ],
25
+ theme: {
26
+ extend: {
27
+ // App-specific overrides
28
+ },
29
+ },
30
+ };
31
+ ```
32
+
33
+ ### 2. Use Components
34
+
35
+ ```tsx
36
+ import { Button, Input, Modal } from '@teja-app/ui';
37
+ import { cn } from '@teja-app/ui/utils';
38
+
39
+ function App() {
40
+ return (
41
+ <Button variant="primary" size="md">
42
+ Click me
43
+ </Button>
44
+ );
45
+ }
46
+ ```
47
+
48
+ ## Component Design Philosophy
49
+
50
+ All components follow these principles:
51
+
52
+ ### 1. Modularity
53
+
54
+ Each component is self-contained with its own styles, types, and logic. No hidden dependencies between components. Import individually or as a bundle.
55
+
56
+ ```tsx
57
+ // Individual import
58
+ import { Button } from '@teja-app/ui';
59
+
60
+ // Bundle import
61
+ import { Button, Input, Modal } from '@teja-app/ui';
62
+ ```
63
+
64
+ ### 2. Extensibility
65
+
66
+ All components accept standard HTML attributes via spread props, support `className` for style overrides, and use `forwardRef` for DOM access.
67
+
68
+ ```tsx
69
+ <Button
70
+ className="my-custom-class"
71
+ data-testid="submit-btn"
72
+ aria-label="Submit form"
73
+ {...otherProps}
74
+ >
75
+ Submit
76
+ </Button>
77
+ ```
78
+
79
+ ### 3. Loose Coupling
80
+
81
+ Components use composition over inheritance. No hard-coded values - everything is configurable via props or Tailwind classes.
82
+
83
+ ```tsx
84
+ // Compose with children
85
+ <Button>
86
+ <Icon name="save" />
87
+ Save
88
+ </Button>
89
+
90
+ // Override with className
91
+ <Button className="bg-purple-500 hover:bg-purple-600">
92
+ Custom Color
93
+ </Button>
94
+ ```
95
+
96
+ ### 4. Composition Patterns
97
+
98
+ ```tsx
99
+ // Slot pattern for complex components
100
+ <Modal>
101
+ <Modal.Header>Title</Modal.Header>
102
+ <Modal.Body>Content</Modal.Body>
103
+ <Modal.Footer>
104
+ <Button variant="ghost">Cancel</Button>
105
+ <Button variant="primary">Save</Button>
106
+ </Modal.Footer>
107
+ </Modal>
108
+
109
+ // Polymorphic components
110
+ <Button as="a" href="/link">
111
+ Link Button
112
+ </Button>
113
+ ```
114
+
115
+ ## Customization
116
+
117
+ ### Tailwind Preset Override
118
+
119
+ Each app can extend the preset and override specific tokens:
120
+
121
+ ```ts
122
+ // tailwind.config.js
123
+ import tejaPreset from '@teja-app/ui/tailwind';
124
+
125
+ export default {
126
+ presets: [tejaPreset],
127
+ theme: {
128
+ extend: {
129
+ colors: {
130
+ brand: {
131
+ primary: '#0ea5e9', // Override for portal
132
+ },
133
+ },
134
+ },
135
+ },
136
+ };
137
+ ```
138
+
139
+ ### Design Tokens
140
+
141
+ Access individual tokens for custom configurations:
142
+
143
+ ```ts
144
+ import { colors, fontFamily, spacing } from '@teja-app/ui/tailwind';
145
+ ```
146
+
147
+ ## API Reference
148
+
149
+ ### Button
150
+
151
+ | Prop | Type | Default | Description |
152
+ |------|------|---------|-------------|
153
+ | `variant` | `'primary' \| 'secondary' \| 'ghost' \| 'danger'` | `'primary'` | Visual style |
154
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Button size |
155
+ | `loading` | `boolean` | `false` | Show loading spinner |
156
+ | `disabled` | `boolean` | `false` | Disable button |
157
+ | `className` | `string` | - | Additional CSS classes |
158
+
159
+ ### Input
160
+
161
+ | Prop | Type | Default | Description |
162
+ |------|------|---------|-------------|
163
+ | `error` | `string` | - | Error message |
164
+ | `label` | `string` | - | Input label |
165
+ | `className` | `string` | - | Additional CSS classes |
166
+
167
+ ## Contributing
168
+
169
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on adding new components.
@@ -0,0 +1,13 @@
1
+ import type { ButtonProps } from './Button.types';
2
+ /**
3
+ * Button component with multiple variants, sizes, and loading state.
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * <Button variant="primary" size="md">Click me</Button>
8
+ * <Button variant="danger" loading>Deleting...</Button>
9
+ * <Button icon={<SaveIcon />} iconPosition="left">Save</Button>
10
+ * ```
11
+ */
12
+ export declare const Button: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
13
+ //# sourceMappingURL=Button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/Button/Button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAA6B,MAAM,gBAAgB,CAAC;AAmB7E;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,2GAwElB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ButtonHTMLAttributes, ReactNode } from 'react';
2
+ export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger';
3
+ export type ButtonSize = 'sm' | 'md' | 'lg';
4
+ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
5
+ /** The visual style variant */
6
+ variant?: ButtonVariant;
7
+ /** The size of the button */
8
+ size?: ButtonSize;
9
+ /** Shows a loading spinner when true */
10
+ loading?: boolean;
11
+ /** Icon element to display */
12
+ icon?: ReactNode;
13
+ /** Position of the icon */
14
+ iconPosition?: 'left' | 'right';
15
+ /** Makes the button full width */
16
+ fullWidth?: boolean;
17
+ }
18
+ //# sourceMappingURL=Button.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.types.d.ts","sourceRoot":"","sources":["../../../src/components/Button/Button.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7D,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,QAAQ,CAAC;AACzE,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,MAAM,WAAW,WAAY,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC1E,+BAA+B;IAC/B,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,wCAAwC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,2BAA2B;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,kCAAkC;IAClC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB"}
@@ -0,0 +1,3 @@
1
+ export { Button } from './Button';
2
+ export type { ButtonProps, ButtonVariant, ButtonSize } from './Button.types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Button/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Component exports for @teja-app/ui
3
+ */
4
+ export * from './Button';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Hook exports for @teja-app/ui
3
+ *
4
+ * Usage:
5
+ * ```ts
6
+ * import { useDisclosure } from '@teja-app/ui/hooks';
7
+ * ```
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/dist/index.cjs ADDED
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const utils_index = require("./utils/index.cjs");
4
+ const jsxRuntime = require("react/jsx-runtime");
5
+ const react = require("react");
6
+ const variantStyles = {
7
+ primary: "bg-brand-primary text-white border border-brand-primary hover:bg-brand-primary-hover focus:ring-brand-primary/20",
8
+ secondary: "bg-white text-neutral-900 border border-neutral-300 hover:bg-neutral-50 hover:border-neutral-400 focus:ring-neutral-500/20",
9
+ ghost: "text-neutral-700 hover:text-neutral-900 hover:bg-neutral-100 focus:ring-neutral-500/20",
10
+ danger: "bg-error text-white border border-error hover:bg-error/90 focus:ring-error/20"
11
+ };
12
+ const sizeStyles = {
13
+ sm: "px-3 py-1.5 text-sm h-8",
14
+ md: "px-4 py-2 text-base h-10",
15
+ lg: "px-6 py-3 text-lg h-12"
16
+ };
17
+ const Button = react.forwardRef(
18
+ ({
19
+ variant = "primary",
20
+ size = "md",
21
+ loading = false,
22
+ disabled = false,
23
+ icon,
24
+ iconPosition = "left",
25
+ fullWidth = false,
26
+ children,
27
+ className,
28
+ ...props
29
+ }, ref) => {
30
+ return /* @__PURE__ */ jsxRuntime.jsx(
31
+ "button",
32
+ {
33
+ ref,
34
+ className: utils_index.cn(
35
+ // Base styles
36
+ "inline-flex items-center justify-center gap-2 font-medium rounded-md",
37
+ "transition-colors duration-normal",
38
+ "focus:outline-none focus:ring-2 focus:ring-offset-2",
39
+ "disabled:opacity-50 disabled:cursor-not-allowed",
40
+ // Variant styles
41
+ variantStyles[variant],
42
+ // Size styles
43
+ sizeStyles[size],
44
+ // Width styles
45
+ fullWidth && "w-full",
46
+ // Custom className (allows override)
47
+ className
48
+ ),
49
+ disabled: disabled || loading,
50
+ ...props,
51
+ children: loading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
52
+ /* @__PURE__ */ jsxRuntime.jsxs(
53
+ "svg",
54
+ {
55
+ className: "animate-spin h-5 w-5",
56
+ fill: "none",
57
+ viewBox: "0 0 24 24",
58
+ xmlns: "http://www.w3.org/2000/svg",
59
+ "aria-hidden": "true",
60
+ children: [
61
+ /* @__PURE__ */ jsxRuntime.jsx(
62
+ "circle",
63
+ {
64
+ className: "opacity-25",
65
+ cx: "12",
66
+ cy: "12",
67
+ r: "10",
68
+ stroke: "currentColor",
69
+ strokeWidth: "4"
70
+ }
71
+ ),
72
+ /* @__PURE__ */ jsxRuntime.jsx(
73
+ "path",
74
+ {
75
+ className: "opacity-75",
76
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z",
77
+ fill: "currentColor"
78
+ }
79
+ )
80
+ ]
81
+ }
82
+ ),
83
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading..." })
84
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
85
+ icon && iconPosition === "left" && icon,
86
+ children,
87
+ icon && iconPosition === "right" && icon
88
+ ] })
89
+ }
90
+ );
91
+ }
92
+ );
93
+ Button.displayName = "Button";
94
+ exports.cn = utils_index.cn;
95
+ exports.Button = Button;
96
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/components/Button/Button.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { cn } from '@/utils';\nimport type { ButtonProps, ButtonVariant, ButtonSize } from './Button.types';\n\nconst variantStyles: Record<ButtonVariant, string> = {\n primary:\n 'bg-brand-primary text-white border border-brand-primary hover:bg-brand-primary-hover focus:ring-brand-primary/20',\n secondary:\n 'bg-white text-neutral-900 border border-neutral-300 hover:bg-neutral-50 hover:border-neutral-400 focus:ring-neutral-500/20',\n ghost:\n 'text-neutral-700 hover:text-neutral-900 hover:bg-neutral-100 focus:ring-neutral-500/20',\n danger:\n 'bg-error text-white border border-error hover:bg-error/90 focus:ring-error/20',\n};\n\nconst sizeStyles: Record<ButtonSize, string> = {\n sm: 'px-3 py-1.5 text-sm h-8',\n md: 'px-4 py-2 text-base h-10',\n lg: 'px-6 py-3 text-lg h-12',\n};\n\n/**\n * Button component with multiple variants, sizes, and loading state.\n *\n * @example\n * ```tsx\n * <Button variant=\"primary\" size=\"md\">Click me</Button>\n * <Button variant=\"danger\" loading>Deleting...</Button>\n * <Button icon={<SaveIcon />} iconPosition=\"left\">Save</Button>\n * ```\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n variant = 'primary',\n size = 'md',\n loading = false,\n disabled = false,\n icon,\n iconPosition = 'left',\n fullWidth = false,\n children,\n className,\n ...props\n },\n ref\n ) => {\n return (\n <button\n ref={ref}\n className={cn(\n // Base styles\n 'inline-flex items-center justify-center gap-2 font-medium rounded-md',\n 'transition-colors duration-normal',\n 'focus:outline-none focus:ring-2 focus:ring-offset-2',\n 'disabled:opacity-50 disabled:cursor-not-allowed',\n // Variant styles\n variantStyles[variant],\n // Size styles\n sizeStyles[size],\n // Width styles\n fullWidth && 'w-full',\n // Custom className (allows override)\n className\n )}\n disabled={disabled || loading}\n {...props}\n >\n {loading ? (\n <>\n <svg\n className=\"animate-spin h-5 w-5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n fill=\"currentColor\"\n />\n </svg>\n <span>Loading...</span>\n </>\n ) : (\n <>\n {icon && iconPosition === 'left' && icon}\n {children}\n {icon && iconPosition === 'right' && icon}\n </>\n )}\n </button>\n );\n }\n);\n\nButton.displayName = 'Button';\n"],"names":["forwardRef","jsx","cn","jsxs","Fragment"],"mappings":";;;;;AAIA,MAAM,gBAA+C;AAAA,EACnD,SACE;AAAA,EACF,WACE;AAAA,EACF,OACE;AAAA,EACF,QACE;AACJ;AAEA,MAAM,aAAyC;AAAA,EAC7C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAYO,MAAM,SAASA,MAAAA;AAAAA,EACpB,CACE;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW;AAAA,IACX;AAAA,IACA,eAAe;AAAA,IACf,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAWC,YAAAA;AAAAA;AAAAA,UAET;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,UAEA,cAAc,OAAO;AAAA;AAAA,UAErB,WAAW,IAAI;AAAA;AAAA,UAEf,aAAa;AAAA;AAAA,UAEb;AAAA,QAAA;AAAA,QAEF,UAAU,YAAY;AAAA,QACrB,GAAG;AAAA,QAEH,oBACCC,2BAAAA,KAAAC,WAAAA,UAAA,EACE,UAAA;AAAA,UAAAD,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,OAAM;AAAA,cACN,eAAY;AAAA,cAEZ,UAAA;AAAA,gBAAAF,2BAAAA;AAAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,WAAU;AAAA,oBACV,IAAG;AAAA,oBACH,IAAG;AAAA,oBACH,GAAE;AAAA,oBACF,QAAO;AAAA,oBACP,aAAY;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEdA,2BAAAA;AAAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,WAAU;AAAA,oBACV,GAAE;AAAA,oBACF,MAAK;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACP;AAAA,YAAA;AAAA,UAAA;AAAA,UAEFA,2BAAAA,IAAC,UAAK,UAAA,aAAA,CAAU;AAAA,QAAA,EAAA,CAClB,IAEAE,2BAAAA,KAAAC,WAAAA,UAAA,EACG,UAAA;AAAA,UAAA,QAAQ,iBAAiB,UAAU;AAAA,UACnC;AAAA,UACA,QAAQ,iBAAiB,WAAW;AAAA,QAAA,EAAA,CACvC;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,OAAO,cAAc;;;"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @teja-app/ui - Shared UI component library for Teja applications
3
+ *
4
+ * @example
5
+ * ```tsx
6
+ * import { Button, Input, Modal } from '@teja-app/ui';
7
+ * import tejaPreset from '@teja-app/ui/tailwind';
8
+ * import { cn } from '@teja-app/ui/utils';
9
+ * ```
10
+ */
11
+ export * from './components';
12
+ export { cn } from './utils';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,cAAc,cAAc,CAAC;AAG7B,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,96 @@
1
+ import { cn } from "./utils/index.js";
2
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
3
+ import { forwardRef } from "react";
4
+ const variantStyles = {
5
+ primary: "bg-brand-primary text-white border border-brand-primary hover:bg-brand-primary-hover focus:ring-brand-primary/20",
6
+ secondary: "bg-white text-neutral-900 border border-neutral-300 hover:bg-neutral-50 hover:border-neutral-400 focus:ring-neutral-500/20",
7
+ ghost: "text-neutral-700 hover:text-neutral-900 hover:bg-neutral-100 focus:ring-neutral-500/20",
8
+ danger: "bg-error text-white border border-error hover:bg-error/90 focus:ring-error/20"
9
+ };
10
+ const sizeStyles = {
11
+ sm: "px-3 py-1.5 text-sm h-8",
12
+ md: "px-4 py-2 text-base h-10",
13
+ lg: "px-6 py-3 text-lg h-12"
14
+ };
15
+ const Button = forwardRef(
16
+ ({
17
+ variant = "primary",
18
+ size = "md",
19
+ loading = false,
20
+ disabled = false,
21
+ icon,
22
+ iconPosition = "left",
23
+ fullWidth = false,
24
+ children,
25
+ className,
26
+ ...props
27
+ }, ref) => {
28
+ return /* @__PURE__ */ jsx(
29
+ "button",
30
+ {
31
+ ref,
32
+ className: cn(
33
+ // Base styles
34
+ "inline-flex items-center justify-center gap-2 font-medium rounded-md",
35
+ "transition-colors duration-normal",
36
+ "focus:outline-none focus:ring-2 focus:ring-offset-2",
37
+ "disabled:opacity-50 disabled:cursor-not-allowed",
38
+ // Variant styles
39
+ variantStyles[variant],
40
+ // Size styles
41
+ sizeStyles[size],
42
+ // Width styles
43
+ fullWidth && "w-full",
44
+ // Custom className (allows override)
45
+ className
46
+ ),
47
+ disabled: disabled || loading,
48
+ ...props,
49
+ children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
50
+ /* @__PURE__ */ jsxs(
51
+ "svg",
52
+ {
53
+ className: "animate-spin h-5 w-5",
54
+ fill: "none",
55
+ viewBox: "0 0 24 24",
56
+ xmlns: "http://www.w3.org/2000/svg",
57
+ "aria-hidden": "true",
58
+ children: [
59
+ /* @__PURE__ */ jsx(
60
+ "circle",
61
+ {
62
+ className: "opacity-25",
63
+ cx: "12",
64
+ cy: "12",
65
+ r: "10",
66
+ stroke: "currentColor",
67
+ strokeWidth: "4"
68
+ }
69
+ ),
70
+ /* @__PURE__ */ jsx(
71
+ "path",
72
+ {
73
+ className: "opacity-75",
74
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z",
75
+ fill: "currentColor"
76
+ }
77
+ )
78
+ ]
79
+ }
80
+ ),
81
+ /* @__PURE__ */ jsx("span", { children: "Loading..." })
82
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
83
+ icon && iconPosition === "left" && icon,
84
+ children,
85
+ icon && iconPosition === "right" && icon
86
+ ] })
87
+ }
88
+ );
89
+ }
90
+ );
91
+ Button.displayName = "Button";
92
+ export {
93
+ Button,
94
+ cn
95
+ };
96
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/components/Button/Button.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { cn } from '@/utils';\nimport type { ButtonProps, ButtonVariant, ButtonSize } from './Button.types';\n\nconst variantStyles: Record<ButtonVariant, string> = {\n primary:\n 'bg-brand-primary text-white border border-brand-primary hover:bg-brand-primary-hover focus:ring-brand-primary/20',\n secondary:\n 'bg-white text-neutral-900 border border-neutral-300 hover:bg-neutral-50 hover:border-neutral-400 focus:ring-neutral-500/20',\n ghost:\n 'text-neutral-700 hover:text-neutral-900 hover:bg-neutral-100 focus:ring-neutral-500/20',\n danger:\n 'bg-error text-white border border-error hover:bg-error/90 focus:ring-error/20',\n};\n\nconst sizeStyles: Record<ButtonSize, string> = {\n sm: 'px-3 py-1.5 text-sm h-8',\n md: 'px-4 py-2 text-base h-10',\n lg: 'px-6 py-3 text-lg h-12',\n};\n\n/**\n * Button component with multiple variants, sizes, and loading state.\n *\n * @example\n * ```tsx\n * <Button variant=\"primary\" size=\"md\">Click me</Button>\n * <Button variant=\"danger\" loading>Deleting...</Button>\n * <Button icon={<SaveIcon />} iconPosition=\"left\">Save</Button>\n * ```\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n variant = 'primary',\n size = 'md',\n loading = false,\n disabled = false,\n icon,\n iconPosition = 'left',\n fullWidth = false,\n children,\n className,\n ...props\n },\n ref\n ) => {\n return (\n <button\n ref={ref}\n className={cn(\n // Base styles\n 'inline-flex items-center justify-center gap-2 font-medium rounded-md',\n 'transition-colors duration-normal',\n 'focus:outline-none focus:ring-2 focus:ring-offset-2',\n 'disabled:opacity-50 disabled:cursor-not-allowed',\n // Variant styles\n variantStyles[variant],\n // Size styles\n sizeStyles[size],\n // Width styles\n fullWidth && 'w-full',\n // Custom className (allows override)\n className\n )}\n disabled={disabled || loading}\n {...props}\n >\n {loading ? (\n <>\n <svg\n className=\"animate-spin h-5 w-5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n fill=\"currentColor\"\n />\n </svg>\n <span>Loading...</span>\n </>\n ) : (\n <>\n {icon && iconPosition === 'left' && icon}\n {children}\n {icon && iconPosition === 'right' && icon}\n </>\n )}\n </button>\n );\n }\n);\n\nButton.displayName = 'Button';\n"],"names":[],"mappings":";;;AAIA,MAAM,gBAA+C;AAAA,EACnD,SACE;AAAA,EACF,WACE;AAAA,EACF,OACE;AAAA,EACF,QACE;AACJ;AAEA,MAAM,aAAyC;AAAA,EAC7C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAYO,MAAM,SAAS;AAAA,EACpB,CACE;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW;AAAA,IACX;AAAA,IACA,eAAe;AAAA,IACf,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA;AAAA,UAET;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,UAEA,cAAc,OAAO;AAAA;AAAA,UAErB,WAAW,IAAI;AAAA;AAAA,UAEf,aAAa;AAAA;AAAA,UAEb;AAAA,QAAA;AAAA,QAEF,UAAU,YAAY;AAAA,QACrB,GAAG;AAAA,QAEH,oBACC,qBAAA,UAAA,EACE,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,OAAM;AAAA,cACN,eAAY;AAAA,cAEZ,UAAA;AAAA,gBAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,WAAU;AAAA,oBACV,IAAG;AAAA,oBACH,IAAG;AAAA,oBACH,GAAE;AAAA,oBACF,QAAO;AAAA,oBACP,aAAY;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEd;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,WAAU;AAAA,oBACV,GAAE;AAAA,oBACF,MAAK;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACP;AAAA,YAAA;AAAA,UAAA;AAAA,UAEF,oBAAC,UAAK,UAAA,aAAA,CAAU;AAAA,QAAA,EAAA,CAClB,IAEA,qBAAA,UAAA,EACG,UAAA;AAAA,UAAA,QAAQ,iBAAiB,UAAU;AAAA,UACnC;AAAA,UACA,QAAQ,iBAAiB,WAAW;AAAA,QAAA,EAAA,CACvC;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,OAAO,cAAc;"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Design token colors for the Teja UI component library.
3
+ * Based on /business/ux/Patterns/Design-Tokens.md
4
+ */
5
+ export declare const colors: {
6
+ readonly brand: {
7
+ readonly primary: "#2563EB";
8
+ readonly 'primary-hover': "#1D4ED8";
9
+ readonly secondary: "#64748B";
10
+ };
11
+ readonly success: {
12
+ readonly DEFAULT: "#16A34A";
13
+ readonly light: "#DCFCE7";
14
+ };
15
+ readonly warning: {
16
+ readonly DEFAULT: "#CA8A04";
17
+ readonly light: "#FEF9C3";
18
+ };
19
+ readonly error: {
20
+ readonly DEFAULT: "#DC2626";
21
+ readonly light: "#FEE2E2";
22
+ };
23
+ readonly info: {
24
+ readonly DEFAULT: "#2563EB";
25
+ readonly light: "#DBEAFE";
26
+ };
27
+ readonly neutral: {
28
+ readonly 50: "#F8FAFC";
29
+ readonly 100: "#F1F5F9";
30
+ readonly 200: "#E2E8F0";
31
+ readonly 300: "#CBD5E1";
32
+ readonly 500: "#64748B";
33
+ readonly 700: "#334155";
34
+ readonly 900: "#0F172A";
35
+ };
36
+ readonly status: {
37
+ readonly scheduled: "#3B82F6";
38
+ readonly completed: "#16A34A";
39
+ readonly cancelled: "#6B7280";
40
+ readonly 'no-show': "#EF4444";
41
+ readonly draft: "#F59E0B";
42
+ readonly signed: "#16A34A";
43
+ };
44
+ };
45
+ export type Colors = typeof colors;
46
+ //# sourceMappingURL=colors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/tailwind/colors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CT,CAAC;AAEX,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC"}