corestack-ui 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -1,18 +1,307 @@
1
- # Corestack UI
1
+ # corestack-ui
2
2
 
3
- Minimal, production-ready React + TypeScript component library scaffold.
3
+ A minimal, production-ready React + TypeScript component library. Built with **Tailwind CSS**, **tsup**, and modern tooling for seamless integration into your projects.
4
4
 
5
- Build
5
+ ## Features
6
+
7
+ - ✅ **React 17+ Compatible** — Supports React 17, 18, and 19
8
+ - ✅ **TypeScript First** — Fully typed components with JSDoc support
9
+ - ✅ **Tailwind CSS Ready** — All components styled with Tailwind utilities
10
+ - ✅ **Tree-Shakeable** — Optimized for bundle size with ESM and CommonJS exports
11
+ - ✅ **CSS Module Support** — Optional scoped styles for component-specific styling
12
+ - ✅ **Zero Dependencies** — Only peers React and Tailwind CSS
13
+ - ✅ **Headless & Composable** — Flexible component APIs, accept custom classNames
14
+
15
+ ## Installation
16
+
17
+ ### Via npm
18
+
19
+ ```bash
20
+ npm install corestack-ui
21
+ ```
22
+
23
+ ### Via yarn
24
+
25
+ ```bash
26
+ yarn add corestack-ui
27
+ ```
28
+
29
+ ### Via pnpm
30
+
31
+ ```bash
32
+ pnpm add corestack-ui
33
+ ```
34
+
35
+ ### Peer Dependencies
36
+
37
+ Make sure you have the following installed:
38
+
39
+ ```bash
40
+ npm install react react-dom tailwindcss
41
+ ```
42
+
43
+ ## Quick Start
44
+
45
+ ### 1. Configure Tailwind CSS
46
+
47
+ Ensure your Tailwind config scans the library's built files:
48
+
49
+ ```typescript
50
+ // tailwind.config.ts
51
+ import type { Config } from "tailwindcss";
52
+
53
+ const config: Config = {
54
+ content: [
55
+ "./src/**/*.{js,ts,jsx,tsx}",
56
+ "./node_modules/corestack-ui/**/*.{js,mjs}",
57
+ ],
58
+ };
59
+
60
+ export default config;
61
+ ```
62
+
63
+ ### 2. Import Styles (Optional)
64
+
65
+ If you're using component-specific CSS:
66
+
67
+ ```typescript
68
+ import "corestack-ui/styles.css";
69
+ ```
70
+
71
+ ### 3. Use Components
72
+
73
+ ```tsx
74
+ import { Button } from "corestack-ui";
75
+
76
+ export default function App() {
77
+ return (
78
+ <Button
79
+ variant="primary"
80
+ size="md"
81
+ onClick={() => alert("Clicked!")}
82
+ >
83
+ Click Me
84
+ </Button>
85
+ );
86
+ }
87
+ ```
88
+
89
+ ## Components
90
+
91
+ ### Button
92
+
93
+ The `Button` component is a flexible, accessible button with optional ripple effect and loading state.
94
+
95
+ #### Props
96
+
97
+ | Prop | Type | Default | Description |
98
+ |------|------|---------|-------------|
99
+ | `variant` | `"primary" \| "secondary" \| "ghost"` | `"primary"` | Button variant style |
100
+ | `size` | `"sm" \| "md" \| "lg"` | `"md"` | Button size |
101
+ | `isLoading` | `boolean` | `false` | Show loading spinner |
102
+ | `disableRipple` | `boolean` | `false` | Disable ripple effect on click |
103
+ | `className` | `string` | `undefined` | Additional Tailwind classes to merge |
104
+ | ...rest | `HTMLButtonElement` props | — | Standard HTML button attributes |
105
+
106
+ #### Example
107
+
108
+ ```tsx
109
+ import { Button } from "corestack-ui";
110
+ import { useState } from "react";
111
+
112
+ export default function Demo() {
113
+ const [loading, setLoading] = useState(false);
114
+
115
+ const handleClick = async () => {
116
+ setLoading(true);
117
+ // Perform action
118
+ setLoading(false);
119
+ };
120
+
121
+ return (
122
+ <div className="space-y-4">
123
+ <Button variant="primary" size="lg">
124
+ Primary Large
125
+ </Button>
126
+
127
+ <Button
128
+ variant="secondary"
129
+ size="md"
130
+ isLoading={loading}
131
+ onClick={handleClick}
132
+ >
133
+ Submit
134
+ </Button>
135
+
136
+ <Button
137
+ variant="ghost"
138
+ className="text-blue-600 hover:bg-blue-50"
139
+ >
140
+ Custom Styling
141
+ </Button>
142
+
143
+ <Button disabled>
144
+ Disabled
145
+ </Button>
146
+ </div>
147
+ );
148
+ }
149
+ ```
150
+
151
+ ## Build Instructions
152
+
153
+ ### Develop with Watch Mode
154
+
155
+ ```bash
156
+ npm run dev
157
+ ```
158
+
159
+ This will rebuild the library whenever you modify source files.
160
+
161
+ ### Production Build
6
162
 
7
163
  ```bash
8
- npm install --save-dev tsup typescript
9
164
  npm run build
10
165
  ```
11
166
 
12
- Usage
167
+ This command:
168
+ 1. Compiles TypeScript to JavaScript
169
+ 2. Generates type definitions (`.d.ts`)
170
+ 3. Creates both ESM and CommonJS outputs
171
+ 4. Copies CSS files to `dist/`
172
+
173
+ ### Clean Build
174
+
175
+ ```bash
176
+ npm run clean && npm run build
177
+ ```
178
+
179
+ ## Project Structure
13
180
 
14
- Import from package to enable tree-shaking:
181
+ ```
182
+ corestack-ui/
183
+ ├── src/
184
+ │ ├── components/
185
+ │ │ ├── Button/
186
+ │ │ │ ├── Button.tsx
187
+ │ │ │ ├── Button.types.ts
188
+ │ │ │ ├── Button.module.css
189
+ │ │ │ └── index.ts
190
+ │ │ └── index.ts
191
+ │ ├── utils/
192
+ │ │ ├── cn.ts # className merger utility
193
+ │ │ └── index.ts
194
+ │ ├── styles/
195
+ │ │ ├── styles.css # Global component styles
196
+ │ │ └── index.ts
197
+ │ ├── types/
198
+ │ ├── providers/
199
+ │ └── index.ts # Main entry point
200
+ ├── dist/ # Built output (ESM + CJS)
201
+ ├── tsup.config.ts # Build configuration
202
+ ├── tailwind.config.ts # Tailwind config (for dev)
203
+ ├── tsconfig.json
204
+ └── package.json
205
+ ```
206
+
207
+ ## Usage with Custom Tailwind Styling
15
208
 
16
- ```js
17
- import { Button } from 'corestack-ui'
209
+ All components accept a `className` prop to merge custom Tailwind utilities:
210
+
211
+ ```tsx
212
+ import { Button } from "corestack-ui";
213
+
214
+ export function CustomButton() {
215
+ return (
216
+ <Button
217
+ className="bg-gradient-to-r from-purple-500 to-pink-500 shadow-lg"
218
+ >
219
+ Gradient Button
220
+ </Button>
221
+ );
222
+ }
18
223
  ```
224
+
225
+ The `cn()` utility merges classes intelligently, preventing conflicts and allowing overrides.
226
+
227
+ ## Exports
228
+
229
+ ### Named Exports
230
+
231
+ ```tsx
232
+ // Components
233
+ import { Button, Autocomplete } from "corestack-ui";
234
+
235
+ // Utilities
236
+ import { cn } from "corestack-ui";
237
+
238
+ // Types
239
+ import type { ButtonProps } from "corestack-ui";
240
+
241
+ // Styles
242
+ import "corestack-ui/styles.css";
243
+ ```
244
+
245
+ ## TypeScript Support
246
+
247
+ All components ship with full TypeScript support. Type definitions are included in the package:
248
+
249
+ ```tsx
250
+ import type { ButtonProps } from "corestack-ui";
251
+
252
+ const buttonProps: ButtonProps = {
253
+ variant: "primary",
254
+ size: "lg",
255
+ isLoading: false,
256
+ };
257
+ ```
258
+
259
+ ## Browser Support
260
+
261
+ - Chrome (latest)
262
+ - Firefox (latest)
263
+ - Safari (latest)
264
+ - Edge (latest)
265
+ - Mobile browsers (iOS Safari, Chrome Mobile)
266
+
267
+ ## Performance
268
+
269
+ - **Tree-shakeable**: Only import what you use
270
+ - **No runtime CSS-in-JS**: Styles are static Tailwind classes
271
+ - **Minimal bundle size**: ~10 KB gzipped (excluding React)
272
+ - **Zero dependencies**: Only React and Tailwind as peer dependencies
273
+
274
+ ## Contributing
275
+
276
+ Contributions are welcome! Please follow these steps:
277
+
278
+ 1. Fork the repository
279
+ 2. Create your feature branch (`git checkout -b feature/amazing-component`)
280
+ 3. Commit your changes (`git commit -m "Add amazing component"`)
281
+ 4. Push to the branch (`git push origin feature/amazing-component`)
282
+ 5. Open a Pull Request
283
+
284
+ ## License
285
+
286
+ MIT © 2024 — [ProNabowy](https://github.com/ProNabowy)
287
+
288
+ ## Author
289
+
290
+ **ProNabowy**
291
+
292
+ - GitHub: [@ProNabowy](https://github.com/ProNabowy)
293
+ - NPM: [corestack-ui](https://www.npmjs.com/package/corestack-ui)
294
+
295
+ ## Repository
296
+
297
+ [github.com/ProNabowy/corestack-ui](https://github.com/ProNabowy/corestack-ui)
298
+
299
+ ## Changelog
300
+
301
+ ### v0.2.0 (Initial Release)
302
+
303
+ - Initial release with Button component
304
+ - Tailwind CSS integration
305
+ - TypeScript support
306
+ - ESM + CommonJS builds
307
+ - CSS Module support
package/dist/index.css ADDED
@@ -0,0 +1,20 @@
1
+ button:has(span.ripple) {
2
+ overflow: hidden;
3
+ position: relative;
4
+ }
5
+
6
+ span.ripple {
7
+ position: absolute !important;
8
+ border-radius: 50%;
9
+ transform: scale(0);
10
+ animation: ripple 600ms linear;
11
+ background-color: rgba(255, 255, 255, 0.199);
12
+ z-index: 100;
13
+ }
14
+
15
+ @keyframes ripple {
16
+ to {
17
+ transform: scale(4);
18
+ opacity: 0;
19
+ }
20
+ }
package/dist/index.d.mts CHANGED
@@ -1,40 +1,257 @@
1
- import * as React from 'react';
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React$1 from 'react';
3
+ import React__default from 'react';
2
4
 
3
- type ButtonVariant = 'primary' | 'secondary' | 'ghost';
4
- type ButtonSize = 'sm' | 'md' | 'lg';
5
- interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
6
- variant?: ButtonVariant;
7
- size?: ButtonSize;
5
+ type AutocompleteChangeReason = "selectOption" | "removeOption" | "clear" | "blur";
6
+ interface AutocompleteRenderOptionState {
7
+ selected: boolean;
8
+ index: number;
8
9
  }
9
-
10
- declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
11
-
12
- interface AutocompleteOption {
13
- label: string;
10
+ interface RenderInputParams {
11
+ ref: React$1.Ref<HTMLInputElement>;
14
12
  value: string;
13
+ placeholder?: string;
14
+ disabled?: boolean;
15
+ onChange: React$1.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>;
16
+ onKeyDown: React$1.KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>;
17
+ onFocus: React$1.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
18
+ onBlur: React$1.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
19
+ role: string;
20
+ "aria-autocomplete": "list";
21
+ "aria-controls"?: string;
22
+ "aria-expanded": boolean;
23
+ "aria-activedescendant"?: string;
24
+ autoComplete?: string;
25
+ InputProps: {
26
+ startAdornment?: React$1.ReactNode;
27
+ endAdornment?: React$1.ReactNode;
28
+ className?: string;
29
+ };
15
30
  }
16
- interface AutocompleteProps {
17
- options: AutocompleteOption[];
18
- value?: string;
19
- onChange?: (value?: string) => void;
31
+ interface BaseAutocompleteProps<T> {
32
+ options: T[];
33
+ getOptionLabel: (option: T) => string;
34
+ isOptionEqualToValue?: (option: T, value: T) => boolean;
35
+ renderInput: (params: RenderInputParams) => React$1.ReactNode;
36
+ renderOption?: (props: React$1.HTMLAttributes<HTMLLIElement>, option: T, state: AutocompleteRenderOptionState) => React$1.ReactNode;
37
+ loading?: boolean;
38
+ disabled?: boolean;
20
39
  placeholder?: string;
21
- renderItem?: (option: AutocompleteOption) => React.ReactNode;
40
+ className?: string;
41
+ /** Text to show when there are no options and not loading */
42
+ emptyText?: string;
43
+ }
44
+ type NativeInputProps = Omit<React$1.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value" | "defaultValue">;
45
+ interface SingleAutocompleteProps<T> extends BaseAutocompleteProps<T>, NativeInputProps {
46
+ multiple?: false;
47
+ value?: T | null;
48
+ defaultValue?: T | null;
49
+ disableCloseOnSelect?: boolean;
50
+ onChange?: (event: React$1.SyntheticEvent, value: T | null, reason: AutocompleteChangeReason) => void;
22
51
  }
52
+ interface MultipleAutocompleteProps<T> extends BaseAutocompleteProps<T>, NativeInputProps {
53
+ multiple: true;
54
+ value?: T[];
55
+ defaultValue?: T[];
56
+ disableCloseOnSelect?: boolean;
57
+ onChange?: (event: React$1.SyntheticEvent, value: T[], reason: AutocompleteChangeReason) => void;
58
+ }
59
+ type AutocompleteProps<T> = SingleAutocompleteProps<T> | MultipleAutocompleteProps<T>;
23
60
 
24
- declare const Autocomplete: React.FC<AutocompleteProps>;
61
+ declare function Autocomplete<T>(props: AutocompleteProps<T>): react_jsx_runtime.JSX.Element;
25
62
 
26
- declare function useAutocomplete(options: AutocompleteOption[]): {
27
- readonly input: string;
28
- readonly setInput: React.Dispatch<React.SetStateAction<string>>;
29
- readonly filtered: AutocompleteOption[];
30
- };
63
+ type ButtonVariant = "primary" | "secondary" | "ghost";
64
+ type ButtonSize = "sm" | "md" | "lg";
65
+ interface ButtonProps extends React$1.ButtonHTMLAttributes<HTMLButtonElement> {
66
+ variant?: ButtonVariant;
67
+ size?: ButtonSize;
68
+ disableRipple?: boolean;
69
+ isLoading?: boolean;
70
+ }
31
71
 
32
- declare const cn: (...parts: Array<string | false | null | undefined>) => string;
72
+ declare function Button({ children, disableRipple, isLoading, className, onClick, ...props }: ButtonProps): react_jsx_runtime.JSX.Element;
73
+
74
+ declare const TextField: React__default.ForwardRefExoticComponent<{
75
+ value?: string | number | null | readonly string[];
76
+ defaultValue?: string | number | readonly string[];
77
+ onChange?: React__default.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>;
78
+ onBlur?: React__default.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
79
+ onFocus?: React__default.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
80
+ placeholder?: string;
81
+ label?: string | React__default.ReactNode;
82
+ helperText?: string | false | undefined;
83
+ error?: boolean;
84
+ disabled?: boolean;
85
+ required?: boolean;
86
+ multiline?: boolean;
87
+ rows?: number;
88
+ type?: string;
89
+ name?: string;
90
+ id?: string;
91
+ fullWidth?: boolean;
92
+ size?: "small" | "medium";
93
+ variant?: "outlined" | "filled" | "standard";
94
+ InputProps?: {
95
+ startAdornment?: React__default.ReactNode;
96
+ endAdornment?: React__default.ReactNode;
97
+ inputComponent?: React__default.ElementType;
98
+ className?: string;
99
+ };
100
+ className?: string;
101
+ } & Omit<React__default.InputHTMLAttributes<HTMLInputElement> & React__default.TextareaHTMLAttributes<HTMLTextAreaElement>, "size" | "disabled" | "name" | "type" | "value" | "defaultValue" | "id" | "onFocus" | "onBlur" | "onChange" | "placeholder" | "required"> & React__default.RefAttributes<HTMLInputElement | HTMLTextAreaElement>>;
102
+
103
+ declare const defaultTheme: {
104
+ colors: {
105
+ primary: string;
106
+ secondary: string;
107
+ success: string;
108
+ danger: string;
109
+ warning: string;
110
+ background: string;
111
+ surface: string;
112
+ border: string;
113
+ textPrimary: string;
114
+ textSecondary: string;
115
+ };
116
+ fonts: {
117
+ body: string;
118
+ heading: string;
119
+ monospace: string;
120
+ size: {
121
+ sm: string;
122
+ md: string;
123
+ lg: string;
124
+ xl: string;
125
+ };
126
+ weight: {
127
+ regular: number;
128
+ medium: number;
129
+ bold: number;
130
+ };
131
+ };
132
+ spacing: {
133
+ xs: string;
134
+ sm: string;
135
+ md: string;
136
+ lg: string;
137
+ xl: string;
138
+ };
139
+ };
140
+ declare const ThemeProvider: ({ theme, children, }: {
141
+ theme?: Partial<typeof defaultTheme>;
142
+ children: React__default.ReactNode;
143
+ }) => react_jsx_runtime.JSX.Element;
144
+ declare const useTheme: () => {
145
+ colors: {
146
+ primary: string;
147
+ secondary: string;
148
+ success: string;
149
+ danger: string;
150
+ warning: string;
151
+ background: string;
152
+ surface: string;
153
+ border: string;
154
+ textPrimary: string;
155
+ textSecondary: string;
156
+ };
157
+ fonts: {
158
+ body: string;
159
+ heading: string;
160
+ monospace: string;
161
+ size: {
162
+ sm: string;
163
+ md: string;
164
+ lg: string;
165
+ xl: string;
166
+ };
167
+ weight: {
168
+ regular: number;
169
+ medium: number;
170
+ bold: number;
171
+ };
172
+ };
173
+ spacing: {
174
+ xs: string;
175
+ sm: string;
176
+ md: string;
177
+ lg: string;
178
+ xl: string;
179
+ };
180
+ };
33
181
 
34
182
  declare const tokens: {
35
183
  colors: {
36
184
  primary: string;
185
+ secondary: string;
186
+ success: string;
187
+ danger: string;
188
+ warning: string;
189
+ background: string;
190
+ surface: string;
191
+ border: string;
192
+ textPrimary: string;
193
+ textSecondary: string;
194
+ };
195
+ fonts: {
196
+ body: string;
197
+ heading: string;
198
+ monospace: string;
199
+ size: {
200
+ sm: string;
201
+ md: string;
202
+ lg: string;
203
+ xl: string;
204
+ };
205
+ weight: {
206
+ regular: number;
207
+ medium: number;
208
+ bold: number;
209
+ };
37
210
  };
211
+ spacing: {
212
+ xs: string;
213
+ sm: string;
214
+ md: string;
215
+ lg: string;
216
+ xl: string;
217
+ };
218
+ };
219
+
220
+ type TextFieldSize = "small" | "medium";
221
+ type TextFieldVariant = "outlined" | "filled" | "standard";
222
+ type TextFieldInputProps = {
223
+ startAdornment?: React.ReactNode;
224
+ endAdornment?: React.ReactNode;
225
+ inputComponent?: React.ElementType;
226
+ className?: string;
38
227
  };
228
+ type TextFieldProps = {
229
+ value?: string | number | null | readonly string[];
230
+ defaultValue?: string | number | readonly string[];
231
+ onChange?: React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>;
232
+ onBlur?: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
233
+ onFocus?: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
234
+ placeholder?: string;
235
+ label?: string | React.ReactNode;
236
+ helperText?: string | false | undefined;
237
+ error?: boolean;
238
+ disabled?: boolean;
239
+ required?: boolean;
240
+ multiline?: boolean;
241
+ rows?: number;
242
+ type?: string;
243
+ name?: string;
244
+ id?: string;
245
+ fullWidth?: boolean;
246
+ size?: TextFieldSize;
247
+ variant?: TextFieldVariant;
248
+ InputProps?: TextFieldInputProps;
249
+ className?: string;
250
+ } & Omit<React.InputHTMLAttributes<HTMLInputElement> & React.TextareaHTMLAttributes<HTMLTextAreaElement>, "size" | "type" | "onChange" | "value" | "defaultValue" | "disabled" | "required" | "name" | "id" | "placeholder" | "onBlur" | "onFocus">;
251
+
252
+ type ClassValue = string | false | null | undefined;
253
+ declare const cn: (...parts: ClassValue[]) => string;
254
+
255
+ declare const cssFile = "./styles.css";
39
256
 
40
- export { Autocomplete, type AutocompleteOption, type AutocompleteProps, Button, type ButtonProps, cn, tokens, useAutocomplete };
257
+ export { Autocomplete, type AutocompleteProps, Button, type ButtonProps, type ClassValue, TextField, type TextFieldProps, ThemeProvider, cn, cssFile, tokens, useTheme };